diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..f3f797d2c --- /dev/null +++ b/404.html @@ -0,0 +1,3728 @@ + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ +

404 - Not found

+ +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/API/REST_API_Doc/index.html b/API/REST_API_Doc/index.html new file mode 100644 index 000000000..855c1c186 --- /dev/null +++ b/API/REST_API_Doc/index.html @@ -0,0 +1,5446 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

REST API - Public

+

The FreeTAKServer REST API is a human-readable approach to the TAK world. +The API allows you to easily connect third parties to the TAK family, +without the need to understand the complexity of the CoT structure or what a TCP connection is. +FTS also supports an Internal API.

+

How FTS manages the information

+

FTS will send the information coming through the API to all the connected clients, +additionally it will save it to the persistency, to be queried in the future.

+

List of supported API

+

In the current release (1.9), FTS supports following API:

+
    +
  • ManageAPI/getHelp
  • +
  • ManageGeoObject/postGeoObject
  • +
  • ManageGeoObject/putGeoObject
  • +
  • ManageGeoObject/getGeoObject
  • +
  • ManageGeoObject/getGeoObjectByZone
  • +
  • ManageEmergency/postEmergency
  • +
  • ManageEmergency/getEmergency
  • +
  • ManageEmergency/deleteEmergency
  • +
  • ManageChat/postChatToAll
  • +
  • ManageRoute/postRoute
  • +
  • ManagePresence/postPresence
  • +
  • ManagePresence/putPresence
  • +
  • ManageVideoStream/postVideoStream
  • +
  • Sensor/postDrone
  • +
  • Sensor/postSPI
  • +
  • /ManageKML/postKML
  • +
+

General Configuration

+
+

To quickly test the API, you can use a browser extension like ARC Advanced rest client (Chrome). +REST APIs are easy to use, however they require a minimum amount of knowledge, +we DO NOT provide support to explain WHAT an API is. +Please refer to an online tutorial such as this.

+
+

Endpoint

+

The API uses the following format:

+
VERB [Protocol]://IP:PORT/APIName/action
+
+

For example:

+
POST http://104.58.20.216:19023/manageGeoObject/postGeoObject
+
+

Authorization

+

To use the API you need to have a REST API key. +The authorization is placed in the header of the message.

+
Authorization: Bearer [YOUR_API_KEY]
+
+
+

You need to use the string 'Bearer' before YOUR_API_KEY

+
+

A valid key is generated from FTS' CLI or, +since 1.4 also from the Web UI, +and stored into the DB.

+

To add an API user in the CLI type:

+
add_api_user
+
+

See CLI help for details. +To create a REST API key using the Web UI, go to the User section and give a user token.

+

Token +: gives a unique combination that this user can leverage for the FTS REST API.

+

NOTICE: the field token is for any alphanumeric string. +the prefix 'bearer' is NOT part of the token. +The name "Bearer 'authentication'". +To consume the API you will need to request a key to your FTS admin.

+

The following is a non-working example of a key:

+
{
+  "Authorization": "Bearer meg@secre7apip@guesmeIfyouCan"
+}
+
+

Message

+

In most end points, the message is placed in the body of the request as JSON formatted. +See below for detailed examples. +In the API using the Get verbs it's a variable.

+

API Details

+

manageAPI

+

Set of commands relative to API management.

+

getHelp

+

Retrieve API version and supported endpoints.

+
    +
  • verb: GET
  • +
  • endpoint: /manageAPI/getHelp
  • +
  • returns: json containing API version and supported endpoints
  • +
+
getHelp Example: return data (1.9.5)
+
{"APIVersion": "1.9.5", "SupportedEndpoints":
+["/ManageNotification/getNotification", "/ManageVideoStream/deleteVideoStream", "/ManageVideoStream/postVideoStream", "/ManageVideoStream/getVideoStream", "/ManageSystemUser/putSystemUser",
+"/ManageEmergency/deleteEmergency",
+"/ManageGeoObject/postGeoObject",
+"/ManageEmergency/postEmergency",
+"/ManageGeoObject/getGeoObject", "/ManageGeoObject/putGeoObject", "/ManageEmergency/getEmergency", "/ManagePresence/postPresence", "/ManagePresence/putPresence", "/ManageRoute/postRoute", "/SystemUser/deleteSystemUser", "/SystemUser/postSystemUser", "/ManageChat/postChatToAll", "/ManageCoT/getZoneCoT", "/ManageKML/postKML", "/manageAPI/getHelp", "/Sensor/postDrone", "/Sensor/postSPI", "/BroadcastDataPackage", "/ManageVideoStream", "/AuthenticateUser", "/DataPackageTable", "/ManageGeoObject", "/ManageEmergency", "/FederationTable", "/ManagePresence", "/MissionTable", "/ExCheckTable", "/SendGeoChat", "/ManageRoute", "/checkStatus", "/GenerateQR", "/ManageChat", "/RecentCoT", "/APIUser", "/Clients", "/Sensor", "/MapVid", "/Alive", "/URL"]}
+
+

manageGeoObject

+

A GeoObject is an element place on a map. It has a name, characteristics, and an attitude.

+

postGeoObject

+
    +
  • verb: POST
  • +
  • endPoint: /ManageGeoObject/postGeoObject
  • +
  • returns: UID
  • +
+
Parameters
+
    +
  • GeoObject: It's the information that will determine which type will be placed on the tak maps including his icon. Please see API documentation for a list of valid entries. Since 1.7 you can also use nicknames for the geo objects.
  • +
  • longitude: OPTIONAL the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.
  • +
  • latitude: OPTIONAL the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).
  • +
  • how: the way in which this geo information has been acquired. Please see API documentation for a list of valid entries.
  • +
  • attitude: OPTIONAL the kind of expected behavior of the GeoObject (e.g. friendly, hostile, unknown). Please see API documentation for a list of valid entries.
  • +
  • name: a string to ID the GeoObject on a map.
  • +
  • bearing: OPTIONAL since 1.7, the direction expressed in degrees (1-360). Default: 0.
  • +
  • distance: OPTIONAL since 1.7, the distance in meters from the Lat/long or address.
  • +
  • timeout: OPTIONAL the length, expressed in seconds until the point will stale out. Default is 300 seconds or 5 minutes.
  • +
  • uid: optional input parameter, need to be a Unique Id for this element, if not present will be server generated, if sent ATAK will try to update an existing geoObject. Use putGeoObject instead
  • +
  • address: OPTIONAL address of destination. If sent will try to solve the exact geolocation of the destination. Possible valid examples are:
      +
    • Big Arkansas River Park, Wichita, KS, USA
    • +
    • Wichita, KS, USA
    • +
    • Big Arkansas River Park, Wichita
    • +
    • and so on.
    • +
    +
  • +
+
Example body
+
{
+  "longitude": -77.0104,
+  "latitude": 38.889,
+  "attitude": "hostile",
+  "bearing": 132, 
+  "distance": 1,
+  "geoObject": "Gnd Combat Infantry Sniper",
+  "how": "nonCoT",
+  "name": "Putin",
+  "timeout": 600  
+}
+
+
Example body alternate
+
{
+  "address": "Washington, DC, USA",
+  "attitude": "hostile",
+  "geoObject": "Gnd Combat Infantry Sniper",
+  "how": "nonCoT",
+  "name": "Putin",
+  "timeout": 600  
+}
+
+
Other Example body alternate
+
{
+  "longitude": -77.0104,
+  "latitude": 38.889,
+  "distance": 500,
+  "bearing": 92,
+  "attitude": "hostile",
+  "geoObject": "Gnd Combat Infantry Sniper",
+  "how": "nonCoT",
+  "name": "Putin",
+  "timeout": 600  
+}
+
+
Example 1.7 body
+
{
+  "longitude": -77.0104,
+  "latitude": 38.889,
+  "attitude": "hostile",
+  "bearing": 132, 
+  "distance": 1,
+  "geoObject": "Medevac",
+  "how": "nonCoT",
+  "name": "Medevac",
+  "timeout": 600  
+}
+
+
Response
+
    +
  • 200 Success: uid. you have created the geoObject.
  • +
  • [MISSING PARAMETERNAME]: you have omitted a parameter that is required.
  • +
  • server error 500: you have probably misspelled the list of parameters (e.g. geoObjects/supported attitude). The names are case-sensitive!
  • +
  • server error 400: you have probably an error in the format of your JSON query.
  • +
  • server error 404: you have an error in the end point definition.
  • +
+
Basic GeoObjects
+
    +
  • "Gnd Combat Infantry Rifleman", Nickname: "Rifleman"
  • +
  • "Gnd Combat Infantry grenadier", Nickname: "Grenadier"
  • +
  • "Gnd Combat Infantry Mortar" , Nickname: "Mortar"
  • +
  • "Gnd Combat Infantry MachineGunner (LMG)", Nickname: "LMG"
  • +
  • "Gnd Combat Infantry Medic" , Nickname: "Medic"
  • +
  • "Gnd Combat Infantry Sniper", Nickname: "Sniper"
  • +
  • "Gnd Combat Infantry Recon" , Nickname: "Recon"
  • +
  • "Gnd Combat Infantry anti Tank" , Nickname: "anti Tank"
  • +
  • "Gnd Combat Infantry air defense", Nickname: "AA"
  • +
  • "Gnd Combat Infantry Engineer", Nickname: "Engineer"
  • +
  • "Ground"
  • +
+
GeoObjects Extensions for EMS
+

Extensions since 1.7

+
    +
  • "Gnd Equip Vehic Civilian", Nickname: Vehicle (OK)
  • +
  • "Gnd Equip Vehic Ambulance": "a-.-G-E-V-m" , Nickname: Ambulance (OK)
  • +
  • "Gnd Structure IM Facilities Emergency Management": "a-.-G-I-i-e" Nickname: Emergency Station (empty shape)
  • +
  • "Gnd Structure IM Facilities Law Enforcement": "a-.-G-I-i-l", Nickname: Police Station (empty shape)
  • +
  • "Gnd Structure petroleum gas oil": "a-.-G-I-R-P", Nickname: gas Station (empty shape)
  • +
  • "Gnd Structure Utility Electric Power": "a-.-G-I-U-E", Nickname: Power Station (empty shape)
  • +
  • "Gnd Structure Utility Telecommunications": "a-.-G-I-U-T", Nickname: Telco Station (empty shape)
  • +
  • "Gnd Structure Hospital": "a-.-G-I-X-H", Nickname: Hospital (empty shape)
  • +
  • "Gnd IM Resources": "a-.-G-U-i" Nickname: Resources (empty shape)
  • +
  • "FOOD DISTRIBUTION": "b-r-.-O-O-O", Nickname: Food (OK, only label, need to implement nick)
  • +
  • "Gnd Crowd Control Team": "a-.-G-U-i-l-cct" Nickname: Police (OK)
  • +
  • "Gnd Generators ": "a-.-G-U-i-p-gen" Nickname: Generator (empty shape)
  • +
  • "Other incident other": "a-.-X-i-o" Nickname: Incident (OK, missing nick name?)
  • +
  • "Combat search & rescue (CSAR)": "a-.-A-M-F-Q-H", Nickname: SAR (OK)
  • +
  • "Medevac": "a-.-G-U-C-V-R-E",, Nickname: Medevac (OK)
  • +
  • "Alarm": "b-l", Nickname: Alarm
  • +
  • "Alarm/Security/Law Enforcement/Civil Disturbance or Disorder": "b-l-l-l-cd", Nickname: Disorder
  • +
  • "REFUGEES": "b-r-.-O-I-R" Nickname: Refugees
  • +
  • "VANDALISM/RAPE/LOOT/RANSACK/PLUNDER/SACK": "b-r-.-O-I-V" Nickname: Riot
  • +
+

extensions in 1.8

+
    +
  • "Other incident geo": "a-.-X-i-g", , Nickname: geo incident
  • +
  • "Other incident geo avalanche": "a-.-X-i-g-a", Nickname: avalanche
  • +
  • "Other incident geo earthquake": "a-.-X-i-g-e", Nickname: earthquake
  • +
  • "Other incident geo landslide": "a-.-X-i-g-l", Nickname: landslide
  • +
  • "Other incident geo subsistance": "a-.-X-i-g-s", Nickname: subsistance
  • +
  • "Other incident geo volcano": "a-.-X-i-g-v", Nickname: volcano
  • +
  • "Other incident geo eruption": "a-.-X-i-g-v-e", Nickname: eruption
  • +
  • "Other incident met drought": "a-.-X-i-m-d", Nickname: drought
  • +
  • "Other incident met cyclone": "a-.-X-i-m-c", Nickname: cyclone
  • +
  • "Other incident met tsunami": "a-.-X-i-m-n", Nickname: tsunami
  • +
  • "Other incident fire": "a-.-X-i-f", Nickname: fire
  • +
  • "Other incident medical public health": "a-.-X-i-h", Nickname: medical incident
  • +
  • "Other incident transportation vehicle accident": "a-.-X-i-t-v-a", Nickname: vehicle accident
  • +
+
List of supported Attitudes
+
    +
  • "friend"
  • +
  • "friendly"
  • +
  • "hostile"
  • +
  • "unknown"
  • +
  • "pending"
  • +
  • "assumed"
  • +
  • "neutral"
  • +
  • "suspect"
  • +
+
List of supported HOW
+

the following list contains +API term : Translation in the CoT

+
    +
  • "nonCoT": "h-g-i-g-o",
  • +
  • "mensurated": "m-i",
  • +
  • "human": "h-t",
  • +
  • "retyped": "h-t",
  • +
  • "machine": "m-",
  • +
  • "gps": "m-g",
  • +
  • "gigo": "h-g-i-g-o",
  • +
  • "mayday": "a-f-G-E-V-9-1-1",
  • +
  • "estimated": "h-e",
  • +
  • "calculated": "h-c",
  • +
  • "transcribed": "h-t",
  • +
  • "pasted": "h-p",
  • +
  • "magnetic": "m-m",
  • +
  • "ins": "m-n",
  • +
  • "simulated": "m-s",
  • +
  • "configured": "m-c",
  • +
  • "radio": "m-r",
  • +
  • "passed": "m-p",
  • +
  • "propagated": "m-p",
  • +
  • "fused": "m-f",
  • +
  • "tracker": "m-a",
  • +
  • "ins+gps": "m-g-n",
  • +
  • "dgps": "m-g-d",
  • +
  • "eplrs": "m-r-e",
  • +
  • "plrs": "m-r-p",
  • +
  • "doppler": "m-r-d",
  • +
  • "vhf": "m-r-v",
  • +
  • "tadil": "m-r-t",
  • +
  • "tadila": "m-r-t-a",
  • +
  • "tadilb": "m-r-t-b",
  • +
  • "tadilj": "m-r-t-j"}
  • +
+

putGeoObject

+

update an existing geoObject coordinates (can also update other features)

+
    +
  • verb: PUT
  • +
  • endPoint: /ManageGeoObject/putGeoObject
  • +
  • returns: UID
  • +
+
Parameters
+

uid +: REQUIRED, input parameter, need to be a Unique Id for this element, if not present will be server generated, if sent ATAK will try to update an existing geoObject. Use putGeoObject instead.

+

longitude +: REQUIRED, the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: REQUIRED, the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).

+

attitude +: REQUIRED, the kind of expected behavior of the GeoObject (e.g. friendly, hostile, unknown). Please see API documentation for a list of valid entries.

+

how +: the way in which this geo information has been acquired. Please see API documentation for a list of valid entries.

+

name +: a string to ID the GeoObject on a map.

+

bearing +: since 1.7, the direction expressed in degrees (1-360).

+

distance +: since 1.7, the distance in meters from the Lat/long.

+

timeout +: the length, expressed in seconds until the point will stale out. Default is 300 seconds or 5 minutes.

+
Example body
+
{
+  "uid": "44455566775623",
+  "longitude": -66.12614,
+  "latitude": 43.96552,
+  "attitude": "hostile",
+  "geoObject": "Sniper"
+}
+
+
Response
+
    +
  • 200 with UID
  • +
+

getGeoObject

+

retrieve in a array all geoObjects in a given radius. It uses JSON variables, not the json body

+

verb +: GET

+

endPoint +: /ManageGeoObject/getGeoObject

+
Parameters
+

NOTE: these should be provided in the form of url encoded variables.

+

radius +: radius in meters where geoObjects, default(100).

+

longitude +: longitude from which radius is calculated, default(0).

+

latitude +: latitude from which radius is calculated, default(0).

+

attitude +: (optional) the attitude which will be filtered, default(any). See list of supported attitudes above.

+
Example Variables
+
{
+  "longitude": -77.02385,
+  "latitude": 38.989,
+  "attitude": "Hostile",
+  "radius": 500
+}
+
+

Params in the URL +http://[IP]:[PORT]/ManageGeoObject/getGeoObject?longitude=-77.0104&latitude=38.889&radius=5000

+

GetRepeatedMessages

+

get geo objects that are regularly resend by the servers

+

verb +: GET

+

endPoint +: /ManageGeoObject/GetRepeatedMessages

+

ManageChat

+

SendGeoChatObject

+

verb +: POST

+

endPoint +: /ManageChat/postChatToAll

+
Parameters
+

message +: the text of the GeoChat message

+

sender +: the name of the chat's sender, changing this will also change the chat room for the client.

+
Example body
+
{
+  "message": "sending this over Rest API",
+  "sender": "Admin"
+}
+
+

ManageEmergency

+

postEmergency

+

create an emergency into the server

+

verb +: POST

+

endPoint +: /ManageEmergency/postEmergency

+
Parameters
+
    +
  • name: the name of the person that has an emergency.
  • +
  • emergencyType: the type of emergency to be displayed
  • +
  • longitude: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.
  • +
  • latitude: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682)
  • +
  • uid: server generated Unique Id of this element.
  • +
  • address: OPTIONAL address of emergency.
  • +
+
List of supported Emergency Types
+
    +
  • "911 Alert"
  • +
  • "Ring The Bell"
  • +
  • "Geo-fence Breached"
  • +
  • "In Contact"
  • +
+
Example body
+
{
+  "name": "Corvo",
+  "emergencyType": "In Contact",
+  "longitude": -77.01395,
+  "latitude": 38.889
+}
+
+

getEmergency

+

get a list of current active emergencies

+

verb +: GET

+

endPoint +: /ManageEmergency/getEmergency

+

no parameter required

+
Example response
+
{
+  "json_list": [
+    {
+      "PrimaryKey": 1,
+      "event_id": "459b5874-1ebf-11eb-9e70-4e58de281c19"
+    }
+  ]
+}
+
+

deleteEmergency

+

delete an active emergency. +(TODO: delete of emergencies can be only done by the originator of it.)

+

verb +: DELETE

+

endPoint +: /ManageEmergency/deleteEmergency

+
Parameters
+

uid +: server generated Unique Id of this emergency

+

status +: if the emergency is currently active or not (on/off)

+
Example body
+
{
+  "uid": "459b5874-1ebf-11eb-9e70-4e58de281c19",
+  "status": "off"
+}
+
+

ManagePresence

+

Manage a team member position

+

postPresence

+

verb +: POST

+

endPoint +: /ManagePresence/postPresence

+

returns +: UID

+
Parameters
+

longitude +: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682)

+

how +: the way in which this geo information has been acquired. Please see API documentation for a list of valid entries.

+

role +: the given role within the team . Please see API documentation for a list of valid entries.

+

name +: a string to ID the GeoObject on a map.

+

team +: the color of the team

+

uid +: optional Unique Id of this element. if present will update an existing element. use the PUT instead *V. 1.7 only If you send the UID an existing CLI will be updated#

+
Example body
+
{
+  "uid": "999b5874-1ebf-11zz-9e70-4e58de281c19",
+  "how": "nonCoT",
+  "name": "POTUS",
+  "longitude": -77.01385,
+  "latitude": 38.889,
+  "role": "Team Member",
+  "team": "Yellow"
+}
+
+

putPresence

+

Updates the location of a team member

+

verb +: PUT

+

endPoint +: /ManagePresence/putPresence

+

returns +: UID

+
Parameters
+

uid +: server generated Unique Id of this emergency

+

ManageRoute

+

manage routes on the map

+

postRoute

+

verb +: POST

+

endpoint +: /ManageRoute/postRoute

+

returns +: uid

+
parameters
+

timeout +: OPTIONAL the length, expressed in seconds until the point will stale out. Default is 300 seconds or 5 minutes.

+

address +: OPTIONAL address of destination. If sent will try to solve the exact geolocation of the destination. Possible valid examples are:

+
 - Big Arkansas River Park, Wichita, KS, USA 
+ - Wichita, KS, USA 
+ - Big Arkansas River Park, Wichita
+ - and so on.
+
+

method +: OPTIONAL the method we plan to use for the route (Driving, Flying, Walking, Swimming, Watercraft). currently not used and set to Driving in the client.

+

longitudeDest +: OPTIONAL if address is not sent.

+

latitudeDest +: OPTIONAL if address is not sent.

+

uid +: OPTIONAL server generated Unique Id of this element. it will update the existing element.

+

routeName +: OPTIONAL the name of the route.

+

endName +: OPTIONAL the name of the destination (end point on the route).

+

startName +: OPTIONAL the name of the start (start point of the route).

+

uid +: OPTIONAL server generated Unique Id of this element. it will update an existing route.

+

longitude +: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).

+
Example body
+
{
+  "longitude": -77.02385,
+  "latitude": 38.999,
+  "routeName": "trip to Phil",
+  "startName": "Washington",
+  "endName": "Philadelphia",
+  "timeout": 40000,
+  "latitudeDest": 39.940,
+  "longitudeDest": -75.01385
+}
+
+
Example body 2
+
{
+  "longitude": -77.01385,
+  "latitude": 38.889,
+  "routeName": "trip to wichita",
+  "timeout": 40000,
+  "address": "Wichita, KS, USA"
+}
+
+
Example body 3
+
{
+  "longitude": -77.02385,
+  "latitude": 38.999,
+  "routeName": "trip to halifax",
+  "latitudeDest": 44.69,
+  "longitudeDest": -63.57,
+  "method": "Flying"
+}
+
+

ManageVideoStream

+

Manages creation of videos endpoints in the clients. The videos are visible under 'Video Player'

+

postVideoStream

+

verb +: POST

+

endpoint +: /ManageVideoStream/postVideoStream

+

returns +: uid

+
parameters
+

streamAddress +: the IP of the video server.

+

streamPort +: the port the video server respond to.

+

streamPath +: the unique path of the video stream* "alias": a name for the stream.

+

streamProtocol +: the type of protocol used (e.g. rtsp, rtmp, raw).

+
Example body
+
 {
+  "streamAddress": "64.227.70.77",
+  "streamPort": "1935",
+  "streamPath": "/LiveApp/342508189321134315564775",
+  "alias": "Demo Stream From Drone ",
+  "streamProtocol": "rtmp"
+}
+
+
Example body 2
+

streamPort and streamPort params still required but will be ignored

+
{
+  "streamAddress": "rtsp://64.227.70.77:1935/LiveApp/342508189321134315564775",
+  "alias": "raw Stream From Drone ",
+  "streamPort": "1935",
+  "streamPath": "/LiveApp/342508189321134315564775",
+  "streamProtocol": "raw"
+}
+
+

getVideoStream

+

retrieves list of stream paths

+

verb +: GET

+

endpoint +: /ManageVideoStream/getVideoStream

+

returns +: json with path

+
example return
+
{
+  "video_stream": [
+    "/LiveApp/342508189321134315564775",
+    "/test/other"
+  ]
+}
+
+

Sensor

+

since 1.9 +manage sensors (name to be changed in ManageSensor)

+

image

+

postDrone

+

create a drone object with a field of view, a current aiming point a video stream

+

verb +: POST

+

endpoint +: /Sensor/postDrone

+

returns +: DRONE_UID, SPI_UID

+
parameters
+

timeout +: OPTIONAL the length, expressed in seconds until the point will stale out. Default is 300 seconds or 5 minutes.

+

name +: the name of the drone, will become also the name of the video stream.

+

Range +: the range of view of the sensor in meters.

+

Bearing +: the direction in which the sensor is aimed in degrees.

+

FieldOfView +: the field of view of the drone in degrees.

+

VideoURLUID +: the address of the video stream. DJI drones only support RTMP protocol. You need to have FreeTAKHub Video service active to see a stream.

+

longitude +: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).

+

uid +: OPTIONAL input parameter, needed to update existing drone CoT.

+

SPIName +: the name of the Sensor Point of Interest the UAS is currently aiming to. currently will NOT work in an update message (when you send the UID).

+

SPILongitude +: longitude of target. currently will NOT work in an update message (when you send the UID).

+

SPILatitude +: latitude of target. currently will NOT work in an update message (when you send the UID).

+
Example body: create sensor
+
{
+  "name": "Putin air",
+  "Bearing": "90",
+  "longitude": -77.01383,
+  "latitude": 38.883,
+  "FieldOfView":"20",
+  "Range": "500",
+  "VideoURLUID": "rtmp://64.227.50.48:1935/live/PutinAirVideo",
+  "SPILongitude": -77.01393,
+  "SPILatitude": 38.885,
+  "SPIName": "Putin air SPI"
+ }
+
+
Example body creation: update existing sensor
+
{
+  "uid": "d033fd0c-d5ac-11eb-ab27-4e58de281c19",
+  "name": "Putin air",
+  "timeout": 40000,
+  "Bearing": "0",
+  "longitude": -77.01399,
+  "latitude": 38.889,
+  "FieldOfView": "20",
+  "Range": "500",
+  "VideoURLUID": "rtmp://64.227.50.49:1935/live/PutinAirVideo"
+}
+
+

postSPI

+

Creates an SPI at a point or update an existing SPI. +If the video source is a UAV, and the UAV is also publishing its own position +and sensor point of interest (SPI), those will be plotted on the map. +Being able to see the position of the aircraft and know where on the map the camera is looking in real time, while being able to see the video on the same screen, is a huge boost to SA.

+
    +
  • verb: POST
  • +
  • endpoint: /Sensor/postSPI
  • +
  • returns: uid
  • +
+
parameters
+

timeout +: OPTIONAL the length, expressed in seconds until the point will stale out. Default is 300 seconds or 5 minutes.

+

uid +: OPTIONAL input parameter, needed to update existing SPI,

+

longitude +: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).

+

droneUid +: the uid of the connected drone.

+

name +: the name of the drone, will become also the name of the video stream.

+
Example Body
+
{
+  "uid": "e452b6bf-d4f0-11eb-b818-2cf05d092d98",
+  "timeout": 500,
+  "longitude": 4,
+  "latitude": 8,
+  "droneUid": "d76f608a-d4f0-11eb-b375-2cf05d092d98",
+  "name": "test"
+}
+
+

ManageKML

+

allows to post a set of geo information with attached metadata in tabular format

+

image

+

postKML

+
    +
  • verb: POST
  • +
  • endpoint: /ManageKML/postKML
  • +
  • returns: "successful" or HTTP error
  • +
+
parameters
+

name +: the name of the report.

+

longitude +: the angular distance of the geoobject from the meridian of the greenwich, UK expressed in positive or negative float. (e.g. -76.107.7998). Remember to set the display of your TAK in decimal coordinates, where West 77.08 is equal to '-77.08' in the API.

+

latitude +: the angular distance of the geoobject from the earths equator expressed in positive or negative float. (e.g. 43.855682).

+

body +: a JSON structure of key pairs (name, value).

+
Example Body
+
{
+  "name": "Putin Report",
+  "longitude": -77.01399,
+  "latitude": 38.889,
+  "body": {
+    "userCallsign": "Mr Putin",
+    "dateTime": "2021-07-13",
+    "type": "Surveillance",
+    "eventScale": "Capital",
+    "importance": "Routine",
+    "status": "FurtherInvestigation",
+    "Time Observed": "2021-05-13T13:55:05.19Z",
+    "Duration of Event": "All day",
+    "Method Of Detection": "General Observation",
+    "Surveillance Type": "Discreet",
+    "Assessed Threats": "Threat to Mission",
+    "Final Remarks": "SNAFU"
+  }
+}
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/API/REST_API_InternalDoc/index.html b/API/REST_API_InternalDoc/index.html new file mode 100644 index 000000000..e9409bfd4 --- /dev/null +++ b/API/REST_API_InternalDoc/index.html @@ -0,0 +1,4523 @@ + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

REST API - Internal

+

Internal APIs are primarily used by the FTS UI to communicate with the server. +See also the REST API DOC for APIs used in integration +they may be used to create other user interfaces such as CLI.

+

In the current release (1.9), FTS supports following Internal API :

+
    +
  • authenticate
  • +
  • users
  • +
  • logs
  • +
  • serviceInfo
  • +
  • serverHealth
  • +
  • systemStatus
  • +
  • DataPackageTable
  • +
  • MissionTable
  • +
  • ExCheck
  • +
  • Federation
  • +
+

there are two types of Internal API: +- Websocket, using socketIO +- REST

+

Websocket, using SocketIO

+

FTS uses SocketIO for the communication, ensure that you understand SocketIO concepts:

+
    +
  • Emits: those are events sent from/to the client with requests
  • +
  • Listener: are events that client/server can subscribe to
  • +
+

Authorization Websocket

+

to use websocket events you need to trigger the event 'authenticate' after connection and pass +as the body of the message {"Authenticate": [YOUR WEBSOCKET KEY]}

+

Connect

+

description

+

event triggered on initial connection to server
+Event: connect (this is a special event as it is called automatically on connection)
+Subscription: connectUpdate

+

returns

+

{
+    "starttime": "", 
+    "version": "" 
+}
+
+- "starttime": the time at which server was started +- "version": the version of FTS currently running

+

Authenticate

+

description

+

event used to authenticate new clients in the websocket

+

Event +: authenticate

+

Subscription +: authentication

+

returns

+

will call the event authentication on client with message body +

{ "successful": "True" }
+
+depending on whether the authentication was accepted.

+

parameters

+

a JSON body in the following format +

{"Authorization": ["YOUR WEBSOCKET KEY"]}
+

+

Users

+

description

+

event used to access list of connected client as well as data +relating to each client.

+

Event: users
+Subscription: userUpdate

+

returns

+

a JSON message containing connected clients +

{
+  "Users":[
+    "user:", {"ip": "24.114.74.13", "callsign": "CorvoMobile", "team": "Yellow"},
+    "user:", {"ip": "24.144.79.13", "callsign": "Ghost", "team": "Blue"}
+  ]
+}
+

+

parameters

+

None

+

Manage System users

+

systemUser

+

retrieve all system users and their associated information

+

Event: systemUser
+Subscription: systemUserUpdate

+

returns

+

system user information +

{
+    "systemUsers": [
+          {"Name": "Dan", "Group": "Yellow", "Token": "", "Password": "", "Certs": "a.zip", "Uid": ""},
+          {"Name": "Joe", "Group": "Yellow", "Token": "", "Password": "", "Certs": "b.zip", "Uid": ""},
+          {"Name": "Bill", "Group": "Yellow", "Token": "", "Password": "", "Certs": "c.zip", "Uid": ""}
+    ]
+}
+

+

parameters

+

None

+

addSystemUser

+

description

+

add one or many system users to the server

+

Event: addSystemUser

+

returns

+

None

+

parameters

+
{
+    "systemUsers": [
+          {"Name": "Dan", "Group": "Yellow", "Token": "", "Password": "", "Certs": "true"},
+          {"Name": "Joe", "Group": "Blue", "Token": "", "Password": "", "Certs": "true"},
+          {"Name": "Bill", "Group": "Red", "Token": "", "Password": "", "Certs": "true"}
+    ]
+}
+
+

removeSystemUser

+

description

+

remove a system user from the server

+

Event: removeSystemUser

+

returns

+

None

+

parameters

+
{
+  "systemUsers": [
+    {"uid": "[uid of system user to be deleted]"},
+    {"uid": "[uid of system user to be deleted]"},
+    {"uid": "[uid of system user to be deleted]"}
+  ]
+}
+
+

logs

+

description

+

event used to retrieve recent error log entries +from the server

+

Event: logs

+

Subscription: logUpdate

+

returns

+

recent error logs in JSON to the client event logUpdate with data in the following format +

{
+  "log_data": [
+    {"time": "2020-12-16 21:15:14,618", "type": "ERROR", "file":"TCPCoTServiceController.py:31", "message": "there has been an exception in Data Package service startup maximum recursion depth exceeded while calling a Python object"}
+  ]
+}
+

+

parameters

+

the timestamp on the most recent log entry in format %Y-%m-%d %H:%M:%S,%f

+

events

+

description

+

event used to retrieve last 5 events

+

Event: events
+Subscription: eventsUpdate

+

returns

+
{
+  "events": ["server event 1", "server event 2", "server event 3", "server event 4", "server event 5"]
+}
+
+

parameters

+

None

+

serviceInfo

+

description

+

event used to retrieve information about all services including +their current status and port

+

Event: serviceInfo
+Subscription: serviceInfoUpdate

+

returns

+

status and port of each service as well as the server start time to the client event serviceInfoUpdate +with body data in the following format +

{
+    "services": {
+        "SSL_CoT_service": {
+                      "status": "on",
+                      "port": 11111
+                  },
+        "TCP_CoT_service": {
+                      "status": "off",
+                      "port": 55555
+                  },
+        "SSL_DataPackage_service": {
+                      "status": "on",
+                      "port": 52345
+                  },
+        "TCP_DataPackage_service": {
+                      "status": "on",
+                      "port": 55235
+                  },
+        "Federation_server_service": {
+                      "status": "on",
+                      "port": 55235
+                  },
+        "Rest_API_service": {
+                      "status": "on",
+                      "port": 55235
+                  }
+    },
+    "IP": "127.0.0.1"
+}
+

+

parameters

+

None

+

serverHealth

+

description

+

event used to retrieve information regarding +the status of the server hardware including +cpu, disk and memory usage.

+

Event: serverHealth
+Subscription: serverHealthUpdate

+

returns

+

current hardware usage to the client event serverHealthUpdate with body

+
{
+    "CPU": 56,
+    "memory": 39,
+    "disk": 94
+}
+
+

parameters

+

None

+

systemStatus

+

description

+

event used to execute test of all currently active +services and return their respective status.

+

Event: systemStatus
+ Subscription: systemStatusUpdate

+

returns

+

current and expected status of all services on the server in JSON format +to the event systemStatusUpdate on the client with the body of the message +in the following format

+
{
+  "services": {
+      "SSL_CoT_service": {
+          "status_expected": "on",
+          "status_actual": "off"
+      },
+      "TCP_CoT_service": {
+          "status_expected": "on",
+          "satus_actual": "on"
+      },
+      "SSL_DataPackage_service": {
+          "status_expected": "on",
+          "status_actual": "on"
+      },
+      "TCP_DataPackage_service": {
+          "status_expected": "on",
+          "status_actual": "on"
+      },
+      "SSL_Federation_service": {
+          "status_expected": "off",
+          "status_actual": "off"
+      },
+      "TCP_API_service": {
+          "status_expected": "on",
+          "status_actual": "on"
+      }
+  }
+}
+
+

parameters

+

None

+

changeServiceInfo

+

description

+

Event used to change the status of each service running on the server
+Event: changeServiceInfo
+Subscription: systemStatusUpdate

+

returns

+
{
+"services": {
+    "SSL_CoT_service": {
+                  "status": "on",
+                  "port": 11111
+              },
+    "TCP_CoT_service": {
+                  "status": "off",
+                  "port": 55555
+              },
+    "SSL_DataPackage_service": {
+                  "status": "on",
+                  "port": 52345
+              },
+    "TCP_DataPackage_service": {
+                  "status": "on",
+                  "port": 55235
+              }
+},
+"ip": "127.0.0.1"
+}
+
+

parameters

+

accepts JSON data containing information regarding the desired status of each service in the following format +

{
+  "services": {
+      "SSL_CoT_service": {
+                    "status": "on",
+                    "port": 11111
+                },
+      "TCP_CoT_service": {
+                    "status": "off",
+                    "port": 55555
+                },
+      "SSL_DataPackage_service": {
+                    "status": "on",
+                    "port": 52345
+                },
+      "TCP_DataPackage_service": {
+                    "status": "on",
+                    "port": 55235
+                }
+  },
+  "ip": "127.0.0.1"
+}
+

+

ip: ip on which the server should be listening eg: 0.0.0.0
+status: whether the service is to be started or stopped eg: on, off
+port(optional): the port on which the service should be listening eg: 8089
+not all services need to be in every message only those you would like to change

+

systemUsers

+

Event used to retrieve all system users
+ Event: systemUsers
+ Subscription: systemUsersUpdate

+

returns

+

the metadata of each user +

{
+  "systemUsers":[
+    {"Name": "Dan", "Group": "Yellow", "Token": "Token1", "Password": "psw1", "Certs": "a.zip"},
+    {"Name": "Joe", "Group": "Yellow", "Token": "Token1", "Password": "psw1", "Certs": "a.zip"},
+    {"Name": "Bill", "Group": "Yellow", "Token": "Token1", "Password": "psw1", "Certs": "a.zip"}
+  ]
+}
+

+

parameters

+

None

+

addSystemUsers

+

used to create a new system user on the server
+Event: addSystemUsers

+

returns

+

None

+

parameters

+
{
+  "systemUsers":[
+    {"Name":"dan", "Group":"Yellow", "Token":"token", "Password": "psw1", "Certs":"true" }
+    ]
+}
+
+
    +
  • Name: name of user
  • +
  • Group: group of user
  • +
  • Token: api token of user(optional)
  • +
  • Password: password for user(optional)
  • +
  • Certs: whether the user should have certs generated(should be true in ui)
  • +
+

removeSystemUsers

+

used to remove a system user and their associated files from the server
+Event: removeSystemUsers

+

returns

+

None

+

parameters

+
{ "systemUsers": 
+  [ 
+    { "uid": "46b3de87-85f5-400d-a098-536f2e1421ce" } 
+  ] 
+}
+
+
    +
  • uid: uid of user to remove
  • +
+

REST Services

+

Authorization: API

+

to use the REST API you need to have a REST API key. +the authorization is placed in the header of the message. +Authorization: Bearer [YOUR_API_KEY]

+
+

you need to use the string 'Bearer' before your API KEY

+
+

ManageSystemUser

+

nested resources

+
    +
  • postSystemUser
  • +
  • deleteSystemUser
  • +
  • putSystemUser
  • +
+

postSystemUser

+

used to create a new system user on the server

+

methods

+

POST

+

returns

+

user created
+code: 201

+

body

+
{
+  "systemUsers":[
+    {"Name":"dan", "Group":"Yellow", "Token":"token", "Password": "psw1", "Certs":"true", "DeviceType": "mobile" }
+  ]
+}
+
+
    +
  • Name: name of user
  • +
  • Group: group of user
  • +
  • DeviceType: the device type [mobile, WinTAK]
  • +
  • Token: api token of user(optional)
  • +
  • Password: password for user(optional)
  • +
  • Certs: whether the user should have certs generated(should be true in ui)
  • +
+

deleteSystemUser

+

used to remove a system user and their associated files from the server as well as revoking the users certificate

+

methods

+

DELETE

+

returns

+

user deleted
+code: 200

+

body

+
{ "systemUsers": 
+  [ 
+    { "uid": "46b3de87-85f5-400d-a098-536f2e1421ce" } 
+  ] 
+}
+
+
    +
  • uid: uid of user to remove
  • +
+

putSystemUser

+

update an existing system user

+

methods

+

PUT

+

returns

+

user updated
+code: 200

+
{"systemUsers": [
+        {"uid": "existing user id", "password": "new user password", "token": "new user token", "group": "new user group"}
+    ]
+}
+
+
    +
  • uid: uid of the user
  • +
  • Group: new user group (optional)
  • +
  • Token: new api token of user(optional)
  • +
  • Password: new password for user(optional)
  • +
+

DataPackageTable

+

description

+

Endpoint used to access data regarding DataPackages

+

methods

+
    +
  • POST
  • +
  • GET
  • +
  • DELETE
  • +
+

GET

+

returns JSON data containing information regarding all DataPackages currently on server +

{
+  "DataPackages":[
+    {"Keywords": "88.104.44.76", "name": "WWIII Locations","privacy":"public", "size":"345KB", "submitted":"2020-02-10" },
+    {"Keywords": "112.144.567.257", "name": "WWIII Locations","privacy":"public", "size":"345KB", "submitted":"2020-02-10" }
+  ]
+}
+

+

POST

+

accepts the zipped form of the file in the body of the message and the following arguments in the url

+
    +
  • filename: the name of the zipped file
  • +
  • creatorUid(optional): the uid of the user associated with the DataPackage defaults to server if none is provided
  • +
+

DELETE

+

accepts the following JSON data +

{
+  "DataPackages":[
+    {"hash": "194728885783f87ws84888943fjew"},
+    {"hash": "19472mw45783f7ws848758943fjegr"}
+  ]
+}
+
+the hash values are the hashes of DataPackages to be deleted

+

PUT

+

accepts the following JSON data +

{
+  "DataPackages":[
+    {"PrimaryKey": "1", "Name": "new_name", "Keywords": "new keywords", "Privacy": "0"}
+  ]
+}
+

+
    +
  • PrimaryKey: primary key of DataPackage to be modified
  • +
  • Name: optional new name of DataPackage if not set name will not be changed
  • +
  • Keywords: optional new keywords of DataPackage if not set keywords will not be changed
  • +
  • Privacy: optional new privacy of DataPackage if not set privacy will not be changed must be 1(Private) or 0(Public)
  • +
+

MissionTable

+

description

+

Endpoint used to access data regarding mission packages

+

methods

+
    +
  • GET
  • +
  • POST
  • +
  • DELETE
  • +
+

GET

+

return JSON data containing information about all current Missions +with the following format +

{
+    "version": "3",
+    "type": "Mission",
+    "data": [{
+            "name": "save the world",
+            "description": "Protect the world from Aliens",
+            "chatRoom": "",
+            "tool": "public",
+            "keywords": ["War"],
+            "creatorUid": "Anonymous",
+            "createTime": "2020-12-09T15:53:42.873Z",
+            "groups": ["__ANON__"],
+            "externalData": [],
+            "uids": [{
+                    "data": "32e9089c-6ae0-4c7e-b4cd-cb16d3f46933",
+                    "timestamp": "2020-12-09T15:58:10.635Z",
+                    "creatorUid": "aa0b0312-b5cd-4c2c-bbbc-9c4c70216261",
+                    "details": {
+                        "type": "a-h-G",
+                        "callsign": "R.9.155734",
+                        "iconsetPath": "COT_MAPPING_2525B/a-h/a-h-G"
+                    }
+                }
+            ],
+            "contents": [{
+                    "data": {
+                        "filename": "Sout",
+                        "keywords": [],
+                        "mimeType": "application/octet-stream",
+                        "name": "SWN Threat",
+                        "submissionTime": "2020-12-09T15:55:21.468Z",
+                        "submitter": "anonymous",
+                        "uid": "3ec22850-d6de-44a5-b79c-3af16695af60",
+                        "hash": "8a99e610d223426caaf267f12c3100513bbb62a66d07c5feb624d4cf5b90b69b",
+                        "size": 18360
+                    },
+                    "timestamp": "2020-12-09T15:55:21.559Z",
+                    "creatorUid": "Anonymous"
+                }
+            ],
+            "passwordProtected": false
+        }
+    ],
+    "nodeId": "6ff99444fa124679a3943ee90308a44c9d794c02-e5a5-42b5-b4c8-625203ea1287"
+}
+

+

POST

+

not yet implemented

+

DELETE

+

not yet implemented

+

ExCheckTable

+

Endpoint used to access data regarding ExCheck items such as checklists and templates

+

POST

+

creates a template on the server from a supplied xml file accepting the following URL encoded values:

+
    +
  • clientUid: the uid of the client to be recognized as the creator of the template
  • +
+

body of the message should be the xml of the template

+

DELETE

+

accepts the following data +

{
+  "ExCheck": 
+  {
+    "Templates": [{"uid": "TemplateUID1"}, {"uid": "TemplateUID2"}],
+    "Checklists": [{"uid": "ChecklistUID1"}, {"uid": "ChecklistUID2"}]  
+  }
+}
+

+

uid: the uid of those Checklists and Templates to be deleted

+

GET

+

return JSON data containing the following information about Checklists and Templates present on the server +

{
+  "ExCheck": {
+    "Templates": [
+      {
+        "filename": "cdd39d06-b43e-42f4-839d-32362febe9a1.xml", 
+        "name": "test from atak",
+        "submissionTime": "2020-12-22T22:07:31.749284Z", 
+        "submitter": "[('NOVA',)]", 
+        "uid": "cdd39d06-b43e-42f4-839d-32362febe9a1", 
+        "hash": "bfb97ed985f789b0c97cf3a93a4354e36eadadd0b6d156c4e4a5ad25330a8c45", 
+        "size": 1735, 
+        "description": "test from atak desc" 
+      }
+    ],
+    "Checklists": [
+      {
+        "filename": "c5322e53-5b95-4def-953d-6be9e42e79fd.xml", 
+        "name": "test from atak", 
+        "startTime": "2020-12-22T22:07:32.841000Z", 
+        "submitter": "NOVA", 
+        "uid": "c5322e53-5b95-4def-953d-6be9e42e79fd", 
+        "description": "test from atak desc",
+        "template":"cdd39d06-b43e-42f4-839d-32362febe9a1" 
+      }
+    ]
+  }
+}
+

+

Templates

+
    +
  • "filename": name of file containing template xml
  • +
  • "name": name associated with template
  • +
  • "submissionTime": time template was submitted to server
  • +
  • "submitter": callsign of submitter
  • +
  • "uid": uid of template
  • +
  • hash": hash of template
  • +
  • "size": size of template in bytes
  • +
  • "description": description of template
  • +
+

Checklists

+
    +
  • "filename": name of file containing checklist xml
  • +
  • "name": name associated with template
  • +
  • "startTime": time checklist was created
  • +
  • "submitter": callsign of user to submit checklist
  • +
  • "uid": uid of checklist
  • +
  • "description": "description of checklist
  • +
  • "template":"uid of template of which the checklist is an instance
  • +
+

FederationTable

+

endpoint used to access federation objects

+

GET

+

return JSON data containing the following information regarding current checklists and templates present on the server +

{
+"activeFederations":
+    [
+        {
+            "id": "111-111-111",
+            "address": "127.0.0.1",
+            "port": "9000",
+            "initiator": "Self",
+            "readCount": "0",
+            "processedCount": "0"
+        },
+        {
+            "id": "111-111-112",
+            "address": "1.1.1.1",
+            "port": "11111",
+            "initiator": "Remote",
+            "readCount": "0",
+            "processedCount": "0"
+        }
+    ],
+"federations": 
+  [
+    {
+        "name": "federation 1",
+        "id": "111-111-111",
+        "address": "127.0.0.1",
+        "port": "9000",
+        "fallBack": "federation 2",
+        "status": "Disabled",
+        "reconnectInterval": "32",
+        "maxRetries": "15",
+        "lastError": "Timeout"
+    }
+  ]
+}
+

+

POST

+

create a new federation configuration +

{
+"outgoingFederations":
+    [
+      {
+        "name": "federation 1",
+        "address": "127.0.0.1",
+        "port": "9000",
+        "fallBack": "federation 2",
+        "status": "Disabled",
+        "reconnectInterval": "32",
+        "maxRetries": "15"
+      }
+    ]
+}
+

+

DELETE

+

delete an existing federation configuration +

{
+  "federations": 
+    [
+      {
+        "id": "111-111-111"
+      }
+    ]
+}
+

+

PUT

+

modify an existing federation configuration +

{
+  "federations": 
+    [
+      {
+        "id": "111-111-111",
+        "name": "new federation 1",
+        "fallBack": "new fallback",
+        "status": "Enabled",
+        "reconnectInterval": "15",
+        "maxRetries": "10"
+      } 
+    ]
+}
+

+
    +
  • id: must be id of existing federation configuration
  • +
  • name(optional): new name of federation configuration
  • +
  • fallback(optional): name of new fallback
  • +
  • status(optional): new status of connection
  • +
  • reconnectInterval(optional): new reconnect interval
  • +
  • maxRetries(optional): new maximum number of retries
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/FAQ/index.html b/About/FAQ/index.html new file mode 100644 index 000000000..2f1427be2 --- /dev/null +++ b/About/FAQ/index.html @@ -0,0 +1,3863 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Frequently Asked Questions (FAQ) about FreeTAKServer (FTS)

+

What is FTS?

+

FTS is a TAK server written in Python that connects all your TAK devices.

+

Is FTS really 'Free'?

+

We released our software under the "Eclipse Public License" allowing not only private usage but also commercial products built on top of it.

+

TAK clients on the same network can communicate directly! So, why should I use a server?

+

There are many reasons for using a server, including the availability of a centralized repository of information (data packages), +the administration of users and security (SSL), +server-side functions (e.g., ExCheck, Data Sync), +and integration with other non-TAK systems (e.g., video, audio, Telegram) using the FTS API.

+

There are other servers for TAK. Why should I use FTS?

+

FTS is not only powerful–it's also more user-friendly when compared to other systems. +Also, FTS is a community-driven Open Source project at its core. +Under the covers, FTS is based on a domain model, +so it is the only TAK server that can provide analysis and interpretation +of the information it collects–not just receive requests from clients +and provides the requested data or perform the requested actions. +Other TAK servers, on the other hand, act only as information brokers: +they are services that collect, organize, and disseminate information. +The bottom line is that FTS is "smarter" than other TAK servers.

+

How can I install FTS?

+

For information on how to set up FTS, +please see one of the Installation Guides.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/FeaturesCompared/index.html b/About/FeaturesCompared/index.html new file mode 100644 index 000000000..9fb8aec4f --- /dev/null +++ b/About/FeaturesCompared/index.html @@ -0,0 +1,4065 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAKServer Compared

+

Users have spoken: FTS is the best TAK server on GitHub!

+

GitHub Star History

+

Star History Chart

+

Functional Comparison

+

Legend

+
    +
  • X: Not Supported
  • +
  • Ø : 50%
  • +
  • Partial: Only covers basic / base functions.
  • +
  • Initial: Prototype Demonstrator
  • +
  • O:
  • +
  • Full: 100% implementation of the specs
  • +
  • Extended: > 100% the functions exceed the original Specification
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionFTS 1.9TAKServerFTS 2.XOther
Web AdministrationO (Single Page Web App)OO (Extended Multi Server)X
WebUI ConfigurationOOO (Full)X
Federation ServiceØ (No Group)O (Full)O (Extended)X
Data PackageOOOO
Data SyncXOOX
Easy CertificateOXOX
CoT Database RecordingOOOO
KML GenerationOOOX
ExCheck SupportOOOX
SSL EncryptionOOOO
REST APIO (Full)ØO (Extended)X
XML CoTOOOO
Protobuf CoTXOOX
WebMAPOOOX
Video ServerOXOX
Voice ServerOXOX
FTP ServerXOOX
ZeroTouch InstallerØXO (Multi-Server)X
Telegram IntegrationØXOX
LDAP / AD supportXOOX
Replay HistoryXOOX
Geo SQL queryXOOX
+

Technology

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TechnologyFTS 1.9TAKServerFTS 2.XOther
Data SyncXOXX
Android EditionØXO (Extended)X
Cloud SupportOXO (Extended)X
Recommended OSUbuntu 22.04CentOSUbuntu 22.04???
LanguagePython 3.8JavaPython 3.11???
+

## Past stars history + stars +stars

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/Manifesto/index.html b/About/Manifesto/index.html new file mode 100644 index 000000000..782c36b9a --- /dev/null +++ b/About/Manifesto/index.html @@ -0,0 +1,3785 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Manifesto for FreeTAKTeam

+

We are FreeTAKTeam, a group of individuals passionate about democratizing Situational Awareness through the power of technology. +We believe that access to situational awareness software should be available to everyone, regardless of their technical expertise or financial resources. +Our mission is to create open-source software that is user-friendly, intuitive, and based on the latest and most advanced technologies. +We strive to make our software accessible to anyone who needs it, whether it be first responders, humanitarian aid workers, or military personnel. +We believe that by democratizing Situational Awareness, we can make the world a safer and more connected place. +Our software is designed to be interoperable, allowing different organizations and agencies to share critical information in real-time, across multiple platforms and devices.

+

We are committed to constantly improving our software and keeping it up-to-date with the latest advances in technology. +We believe in the power of community and welcome feedback, contributions, and collaboration from anyone who shares our vision.

+

Join us in our mission to democratize Situational Awareness and create a safer and more connected world. +Together, we can make a difference.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/PubServer/index.html b/About/PubServer/index.html new file mode 100644 index 000000000..71c22d837 --- /dev/null +++ b/About/PubServer/index.html @@ -0,0 +1,3900 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Public Server

+ +

Connecting to FTS Public Server

+

DigitalOcean Referral Badge

+

We support a public instance of FTS hosted by DigitalOcean.

+

The Public server (PUB) is an instance of FTS made available for you to test and play with. +We are not going to spy on you, but keep in mind that information will be shared with all the connected users. +For production consider to install your own instance.

+

FTS Public Instance Server Rules

+
    +
  • Please be respectful of others.
  • +
  • This is a free service, but that cost money, do NOT upload huge data packages
  • +
  • We will use PUB to test new features, that means it can not be accessible during certain periods
  • +
  • Failure to respect those rules will be punished by our Killer Pirate Parrot (FreeTAKServer Developers), YOU HAVE BEEN WARNED.
  • +
+

Configure ATAK for FreeTakServer (FTS) on the public server

+

Download required files

+

The easiest way is to open this article in your Android phone, so that all the files will be already available there.

+ +

Configure using Import Manager

+
    +
  • Start ATAK on Android
  • +
  • Tap the "..." (Three-dot-Menu) on the Upper Right of the ATAK Screen.
  • +
  • Tap Import Manager
  • +
  • Tap "Local SD"
  • +
  • Go to the place where you have downloaded the files
  • +
  • Select "Google_Mapsources.zip" and "fts-official-pub.zip"
  • +
  • Optionally select "MOBAC-Maps-master.zip"
  • +
  • Click OK
  • +
  • A message will appear to inform you that you are connected to the FTS Official (Public) Server
  • +
+

Configure using Settings

+
    +
  • Tap ...
  • +
  • Tap the "..." (Three-dot-Menu) on the Upper Right of the ATAK Screen.
  • +
  • Go to Settings
  • +
  • Select "TAK Servers"
  • +
  • Tap the "..." and Click "Add"
  • +
  • Click Advanced Options
  • +
  • Select TCP as Streaming Protocol
  • +
  • Use this address: 137.184.101.250
  • +
  • Server port : 8087
  • +
  • Leave the rest unchecked. Username or Password are not required.
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/architecture/cot_domain/index.html b/About/architecture/cot_domain/index.html new file mode 100644 index 000000000..682d99b99 --- /dev/null +++ b/About/architecture/cot_domain/index.html @@ -0,0 +1,9164 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

CoT Domain Model

+

The Cursor-On-Target (CoT) Event data model defines a Domain model +as a system of abstractions that describes selected aspects +of a sphere of knowledge for the TAK domain. +It is represented as a platform-independent model (PIM) +that is independent of the specific technological platform used to implement it. +The Domain model can be translated into an XML data schema +for exchanging time sensitive position of moving objects, +or "what", "when", and "where" (WWW) information, between systems.

+

FTS CoT domain Model

+

__serverdestination

+

The destination of a certain message. +Indicates how to communicate back to the sender.

+

__serverdestination attributes

+ + + + + + + + + + + + + +
NameDocumentation
destinationsstring composed by IP:port:protocol:machineID.
e.g. 192.168.0.103:4242:tcp:ANDROID-R52JB0CDC4E
+

_flow-tags_

+

This is a Cursor On Target detail class that holds "fingerprints" of the system that have processed a particular CoT event. +This information aids in the routine of CoT messages along a particular processing chain. +Each system that touches a particular CoT event is expected to add its own attribute to this entity. +The attribute name should reflect the particular system name, +and the value should be the time stamp when the information was sent out from that system. +Some illustrative _flow-tags_ attributes are adocs, fbcb2, and tadilj, but the attribute list is not a closed set.

+

_flow-tags_ attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
version
adocs
fbcb2
tadilj
+

_medevac_

+

the medevac class is used to describe a case of someone in need to be evacuated

+

_medevac_ attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
litter
freq
terrain_none
zone_prot_selection
Title
Priority
medline_remarks
Security
routine
equipment_none
hlz_marking
casevac
urgent
+

_radio

+

_radio attributes

+ + + + + + + + + + + + + + + + + +
NameDocumentation
rssi
gps
+

Attitude

+

Attitude attributes

+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
roll
pitch
yaw
+

chat

+

Class that holds information regarding chat. +When communicating with a group, +the __chat attributes specify the unique ID of the chat group, +and the common name as to be read by the user. +The recipient, upon receipt, will see that these fields do not match their information, +and create the appropriate group. +Members will be populated from the attributes of the chatgrp element.

+

### chat attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
senderCallsignthe call sign of the sender
chatroomTBD: the callsign of the receiver?
groupOwnerTBD,
idTBD: the unique ID of the sender?
parentthe group where this chat is attached
+

chatgrp

+

Class hosting IDs regarding the from and to

+

chatgrp attributes

+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
uid0the machine ID of the sender
uid1another ID
idthird ID
+

** checklist**

+
    +
  1. +

    ** checklist attributes**

    +
  2. +
  3. +

    ** checklistColumn**

    +
  4. +
  5. +

    ** checklistColumn attributes**

    +
  6. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
columnName
columnType
columnWidth
+
    +
  1. +

    ** checklistColumns**

    +
  2. +
  3. +

    ** checklistColumns attributes**

    +
  4. +
  5. +

    ** checklistDetails**

    +
  6. +
  7. +

    ** checklistDetails attributes**

    +
  8. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
name
uid
description
startTime
templateName
+
    +
  1. +

    ** checklistTask**

    +
  2. +
  3. +

    ** checklistTask attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
value
status
completeDTG
notes
dueRelativeTime
+
    +
  1. +

    ** checklistTasks**

    +
  2. +
  3. +

    ** checklistTasks attributes**

    +
  4. +
  5. +

    ** color**

    +
  6. +
  7. +

    ** color attributes**

    +
  8. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
argbinteger with a colore.g. 65536
value
+
    +
  1. +

    ** contact**

    +
  2. +
+

This is a Cursor On Target Class representing communications parameters for contacting a friendly element for human-to-human communications. The objective of this Class is to carry the essential information needed to contact this entity by a variety of means. Multiple ways of establishing contact can be specified;

+

noThe attributes callsign, phone, and email should be self-explanatory. particular mode of contact is required. Other attributes, freq, dsn, modulation, and hostname, are also available.

+
    +
  1. +

    ** contact attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
iconsetpath
callsignThe unit's voice call sign
freqThe frequency (in MHz) on which the unit may be contacted via voice.
emaile-mail address for this element (if applicable)
endpointTBD
dsnDSN number for this element (if applicable)
phonePhone number for this element (if applicable)
modulationAmplifies the radio frequency information provided. Contains the modulation type for the communication. (Coding tbd, should cover complex modulations such as SINCGARS hopping, csma, etc...) am|fm
hostnameDNS-resolvable host name
versionVersion tag for this sub schema. Necessary to ensure upward compatibility with future revisions.
xmppUsernameuser name in the xmpp network. A private, unique, and memorable "petname" or "alias" assigned by a contact to a user; represented in the 'name' attribute of the item associated with that user's JID in the contact's roster
+
    +
  1. +

    ** contentResource**

    +
  2. +
  3. +

    ** contentResource attributes**

    +
  4. +
  5. +

    ** CoT**

    +
  6. +
+

The Cursor-On-Target (CoT) Event data model defines an XML data schema for exchanging time sensitive position of moving objects, or "what", "when", and "where" (WWW) information, between systems.

+
    +
  1. +

    ** CoT attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Identity
dimension
entity
type
lat
lon
uid
+
    +
  1. +

    ** creatorUid**

    +
  2. +
  3. +

    ** creatorUid attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** dest**

    +
  2. +
  3. +

    ** dest attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
callsignthe call sign of the destination
+
    +
  1. +

    ** detail**

    +
  2. +
+

An optional element used to hold CoT sub-schema. Detail has no special properties.

+

Detail entities...

+

The "detail" entity is intended to carry information that is specific to smaller communities of producers and consumers and require more intimate knowledge of the operating domain. For example, mensurated "target" events may come from dramatically different sources and need to propagate dramatically different "detail" information. A close-air-support mission will augment target details with initial point and callsign details to facilitate coordination of weapon delivery. In contrast, a

+

mission planning system may augment planned targets with target catalog information and weapon fuzing requirements.

+

Because the "details" portion of the event are of interest only to a subset of subscribers, that entity may be mentioned by reference when the event is communicated. This reduces the congestion when events are transmitted over bandwidth limited links and also prevents the retransmission of static data elements.

+
    +
  1. +

    ** detail attributes**

    +
  2. +
  3. +

    ** DimensionTypes**

    +
  4. +
  5. +

    ** DimensionTypes attributes**

    +
  6. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
space
air
land-unit
land-equipment
land-installation
sea-surface
sea-subsurface
subsurface
other
+
    +
  1. +

    ** DJI**

    +
  2. +
+

A class to handle DJI Drones

+
    +
  1. +

    ** DJI attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
spoiuid
homelat
gimbalroll
gimbalpitch
homelon
gimbalyaw
+
    +
  1. +

    ** dxf**

    +
  2. +
+

This is a hook for an arbitrary 3D DXF description of a volume of space.

+
    +
  1. +

    ** dxf attributes**

    +
  2. +
+ + + + + + + + + + + + + +
NameDocumentation
level"level" is used to indicate the preferred ordering of multiple shape sub-schemas. For instance, if a polyline and ellipse are both present on the shape attribute, the one with the higher level value will be the "more desirable" representation of the object. This allows producers to provide alternative representation of an objects shape while ensuring that consumers will know which of the available representation is the best. (Note that not all consumers will implement all shape variations, hence the need for the allowing multiple shape objects.)See the documentation for shape/ellipse/@level for remarks on determining the precedence order when level values are equal or are missing.
+
    +
  1. +

    ** dxf**

    +
  2. +
  3. +

    ** dxf attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
level"level" is used to indicate the preferred ordering of multiple shape sub-schemas. For instance, if a polyline and ellipse are both present on the shape attribute, the one with the higher level value will be the "more desirable" representation of the object. This allows producers to provide alternative representation of an objects shape while ensuring that consumers will know which of the available representation is the best. (Note that not all consumers will implement all shape variations, hence the need for the allowing multiple shape objects.)See the documentation for shape/ellipse/@level for remarks on determining the precedence order when level values are equal or are missing.
+
    +
  1. +

    ** ellipse**

    +
  2. +
+

The "ellipse" is a common shape abstraction used by many geomanipulation applications; it is supported natively

+
    +
  1. +

    ** ellipse attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
majorEllipse major axis (meters)
minorEllipse minor axis (meters)
angleOrientation of major axis with respect to true north.
level"level" is used to indicate the preferred ordering of multiple shape sub-schemas.For instance, if a polyline and ellipse are both present on the shape attribute, the one with the higher level value will be the "more desirable" representation of the object. This allows producers to provide alternative representation of an objects shape while ensuring that consumers will know which of the available representation is the best. (Note that not all consumers will implement all shape variations, hence the need for the allowing multiple shape objects.)Since the level attribute is optional, it is necesary for precedence rules to exist to ensure all consumersprocess the shape definition the same way.1. The shape definition with the highest value level attribute is considered the most accurate interpretation. 2. If all shape definitions specify the same level, the order from least to most accurate interpretation is presumed to be ellipse, polyline, dxf. 3. A shape that specifies the level attribute has precedence over any that do not specify it. 4. If the level attribute is absent from all shape definitions, the order from least to most accurate interpretation is presumed to be ellipse, polyline, dxf.
extrudeA "Height" of the ellipse used to make the flat object encompas a volume.
+
    +
  1. +

    ** emergency**

    +
  2. +
+

An emergency beacon the is continually send to all the connected clients until deactivated from the original creator

+
    +
  1. +

    ** emergency attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
typedefault constructor def __init__(self):
Alert
cancelif true the emergency beacon is canceled
+
    +
  1. +

    ** EntityTypes**

    +
  2. +
  3. +

    ** EntityTypes attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
military
civilian
+
    +
  1. +

    ** environment**

    +
  2. +
  3. +

    ** environment attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
temperature
windDirection
windSpeed
+
    +
  1. +

    ** Event**

    +
  2. +
+

represents a TAK event: this class is instantiated with a standard set of values.

+

The opex field is intended to indicate that the event is part of a live operation, an exercise, or a simulation. For backward compatibility, absence of the opex indicates "no statement", which will be interpreted in an installation specific manner.

+

opex="o-<name>" or "e-<nickname>" or "s-<nickname>",

+

where "-<name>" is optional. That is, it is permissible to specify only "o", "e", or "s" for the opex value.

+
    +
  • o = operations
  • +
  • e = exercise
  • +
+

s = simulation

+
    +
  1. +

    ** Event attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
howGives a hint about how the coordinates were generated. It is used specifically to relay a hint about the types of errors that may be expected in the data and to weight the data in systems that fuse multiple inputs.
versionSchema version of this event instance (e.g. 2.0)
timetime stamp with respect to Zulu time indicating when an event was generated in extended ISO 8601 formatin ProtoBuff expressed is in milliseconds
typeEvent.type contains the Code for the Center on Target object. It Defines what the Event is about. An event may describe a physical object, a set of raw, unprocessed bits, or a tasking.# Hierarchically organized hint about event type (defaultis 'a-f-G-I' for "Friendly Ground infrastructure)The "type" attribute is a composite of components delimited by the semi-colon character. The first component of this composite attribute is defined below.Future versions of this schema will define other components which we expect will aid in machine filtering. Despite the exclusion of definitions for additional components in this version of the schema, users of this schema should expect and design an optional trailing field delimited by the semi-colon character. This field can be ignored.- component1;optional fieldThe first component (component1) is a hierarchically organized hint about type.The intention is that this hierarchy be flexible and extensible and facilitate simple filtering, translation and display. To facilitate filtering, the hierarchy needs to present key fields in an easily parsed and logical order. To facilitate this, this component is a composite of fields separated by the "-" punctuation character, so a valid type would be: x-x-X-X-x. Using a punctuation for field separation allows arbitrary expansion of the type space,_e.g., a-fzp-mlk-gm-..._Field meanings are type specific. That is, the third field of an "atom" type may represent air vs. ground while the same field for a "reservation" type may represent purpose.MEANING of 'a' in the first positionThe "Atoms" portion of the type tree requires some additional explanation past the taxonomy defined below. The "Atoms" portion of the type tree contains CoT defined fields and part of theMIL-STD-2525type definition.To distinguish MIL-STD-2525 type strings from CoT defined fields, the MIL-STD-2525 types must be represented in all upper case. Differentiation of type namespace with upper/lower case facilitates extension of CoT types and MIL-STD-2525 types without name space conflict. An example:a-f-A-B-C-x- a = Atom - f = attitude or disposition (friendly in this case)- A-B-C =the SDIC 2525 separated by dashs - x = COT specific extensionThe organization of CoT and MIL-STD-2525 types can be determined from the taxonomy below, but additional details are provided here.The "Atoms" portion of the "type" tree contains the "Battle Dimension" and "Function ID" fields taken from MIL-STD-2525."Battle Dimension" is a single character taken from MIL-STD-2525 and is located in the position 5.a-.-G-I-M-N-B- P - Space - A - Air - G - Ground - S - Sea Surface - U - Sea Subsurface - SF - Special Operations ForcesThe typical 2525 representation for "Function ID" is three groups of two characters separated by a space (e.g. "12 34 56"). The CoT schema maps this to a "-" delimited list of characters. (e.g. "1-2-3-4-5-6").The concatenation of the "Battle Dimension" and "Function ID" fields from the MIL-STD-2525 specification represented in the CoT schema will be as follows:battle dimension-func id char1-func id char2- ... -func id char6When an appropriate MIL-STD-2525 type exists, it should be used. If there is a MIL-STD-2525 representation which is close, but may be refined, a CoT extension to the 2525 type can be appended.for example:a-h-X-X-X-X-X-i might represent hostile MIL-STD-2525 type X-X-X-X-X of Israeli(the 'i')manufacture. Again, the CoT extension uses lower case.Conceptually, this extension defines further branching from the nearest MIL-STD-2525 tree point.If no appropriate 2525 representation exists, a type definition can be added to the CoT tree defined here. The resulting definition would be represented in all lower case. For examplea-h-G-p-imight define atoms-hostile-Ground-photon cannon-infrared.The taxonomy currently looks like this: Note that the coding of the sub fields are determined entirely by the preceding fields!) The current type tree is defined here.+--- First position, this event describes- a - Atoms - this event describes an actual "thing"+--- 2nd CoT affiliation of these atoms- *p - Pending - u - Unknown - a - Assumed friend - f - Friend - n - Neutral - s - Suspect - h - Hostile - j - Joker - k - Faker - o - None specified - x - Other*+--- Battle dimension| Taken from MIL-STD-2525 "Battle Dimension" (upper case)- P - Space- A - Air - G - Ground - S - Sea Surface - U - Sea Subsurface- SF - Special Operations Forces+--- Function (dimension specific!)*_See MIL-STD-2525B specification for function fields (must be upper case)_Any number of char before the first "dash", it express also the hierarchy(Hundreds of options)*+--- The event describes ...**b - Bits- Events in the "Bit" group (pos 1163++ ) carry meta information about raw data sources. For example, range-doppler radar returns or SAR imagery represent classes of information that are "bits". However, tracks derived from such sources represent objects on the battlespace and this have event type "A-..."The intention with the "Bit" type is to facilitate the identification of germane information products.This hierarchy is not intended to replace more detailed domain-specific meta information (such as that contained in NITF image headers or the GMTI data formats), rather it is intended to provide a domain-neutral mechanism for rapid filtering of information products.+--- Dimensionsecond position, Like battle dimension but for 'b' types- i - Imagery1. e - Electro-optical 2. i - Infra red 3. s - SAR 4. v - video- ... - r - Radar1. m - MTI data- ... - d - Sensor detection events1. s - Seismic 2. d - Doppler 3. a - Acoustic 4. m - Motion (e.g., IR)- m - Mapping1. p - Designated point (rally point, etc.) 2. i - initial points 3. r - rally points 4. ...r - Reservation/Restriction/ReferencesEvents in this category are generally "notices" about specific areas. These events are used for deconfliction and conveyance of significant "area" conditions. Generally, the "point" entity will describe a conical region that completely encloses the affected area. The details entity will provide more specific bounds on precisely the region affected.- u - Unsafe (hostile capability) - o - Occupied (e.g., SOF forces on ground) - c - Contaminated (NBC event) - c - chemical - x - agents, direction, - y - z - f - Flight restrictionst - Tasking (requests/orders)Events in this category are generalized requests for service. These may be used to request for data collection, request mesuration of a specific object, order an asset to take action against a specific point. Generally, the "details" entity will identify the general or specific entity being tasked.- s - Surveillance - r - Relocate - e - Engage - m - Mensuratec - Capability (applied to an area)- s - Surveillance - r - Rescue - f - Fires - d - Direct fires - i - Indirect fires - l - Logistics (supply) - f - Fuel...c - Communications
staleThe "stale" attribute defines the ending time of the event's validity interval. The start and stale fields together define an interval in time.It has the same format as time and start.ending time when an event should no longer be considered valid l (with respect to Zulu time in extended ISO 8601 format)In protobuff is in milliseconds
uidThe "uid" attribute is a globally unique name for this specific piece of information.Several "events" may be associated with one UID, but in that case, the latest (ordered by timestamp),overwrites all previous events for that UID.can have additional information attached.[EventTYPE].[MACHINESENDERID].Nichname.UniqueIDe.g. -_ping_means that this event is a ping,_GeoChat_indicates a chat type structure.TheUID should be in the following format: GeoChat.<sender uid>.<recipient callsign or name of the group>.<random string for uniqueness>. Diverging from this format should not cause significant issues; however, the UID is used as a fallback if other information cannot be parsed from the message, so issues may still be experienced. If uid does not contain any "." characters, the chat room will default to "All Chat Rooms".GeoChat.ANDROID-7C:91:22:E8:6E:4D.DIPPER.44bf77cd-289e-4ea4-8756-ce295de168ca
startformat - DTGThe "start" attribute defines the starting time of the event's validity interval. The start and stale fields together define an interval in time.It has the same format as time and stale.starting time of the event's validity interval (with respect to Zulu time in extended ISO 8601 format). As different from the moment in which the element was generatedin protobuff this is expressed in milliseconds
accessSpecifies access controls that should be applied to the event
opexOPTIONAL: Specifies whether the event is part of a live operation, an exercise, or a simulation.The access field is intended to indicates who has access to this event. (e.g. unrestricted, nato, army, coalition...)It is currently defined as a string, and is optional in V2.0.Future version of the event schema will provide formal definition of this field.
cot2525
qosOPTIONAL: Specifies a quality of service desired from applications processing or routing the event
+
    +
  1. +

    ** filename**

    +
  2. +
  3. +

    ** filename attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** fileshare**

    +
  2. +
  3. +

    ** fileshare attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
filename
name
senderCallsign
senderUid
senderUrl
sha256
sizeInBytes
+
    +
  1. +

    ** fillColor**

    +
  2. +
  3. +

    ** fillColor attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
value
+
    +
  1. +

    ** FilterGroup**

    +
  2. +
+

the name of the group authorized to see the CoT

+
    +
  1. +

    ** FilterGroup attributes**

    +
  2. +
  3. +

    ** group**

    +
  4. +
  5. +

    ** group attributes**

    +
  6. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
role
name
uidunique ID of the group
+
    +
  1. +

    ** hash**

    +
  2. +
  3. +

    ** hash attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** Health**

    +
  2. +
+

this class contains information regarding the current physical status of a connected user, measured with sensors.

+
    +
  1. +

    ** Health attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
heartRate
steps
stress
+
    +
  1. +

    ** Hierarchy**

    +
  2. +
  3. +

    ** Hierarchy attributes**

    +
  4. +
  5. +

    ** IdentityTypes**

    +
  6. +
  7. +

    ** IdentityTypes attributes**

    +
  8. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
pendingpending
unknownunknown
friendfriend
neutral
hostile
assumed-friend
suspect
joker
faker
+
    +
  1. +

    ** image**

    +
  2. +
+

This is a Cursor On TargeClass for abstract image product metadata. It is specifically limited to geographically located (though not necessarily geographically registered) image products.

+

It is not intended to contain all the meta data typically found in the NITF header associated with such images, but rather provides sufficient "hints" about the ISR product to facilitate collection queuing and ipl searching. Full meta data will reside in the NITF header or other IPL-specific schemas.

+

This class borrows from the NITF standard. Note, also, that this class presumes is is contained within a CoT Evebnt element which provides information about center poiint, etc. Similarly, the CoT_shape schema can be used to delimit the bounds of the image. Furthermore, this element may conatin a base64 encoded image file. In this case, the 'mime' attribute should indicate the image type.

+
    +
  1. +

    ** image attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
typeImage type, drawn from NITF specification. E.g., SL - side-looking radar, TI - thermal infrared, FL - forward looking infrared, RD - radar, EO - electro-optical, OP - optical, HR - high resolution radar, HS - hyperspectral, CP - color frame photography, BP - black/white frame photography, SAR - synthetic aperture radar, SARIQ - SAR radio hologram, IR - infrared, MS - multispectral, ...
georegistered(DEPRECATED) True if this image has been properly geo-registered
source(REVISED) The source of this image, specifically the CoT UID of the producer. (The intention is to indicate equipment type used to collect imagery, not organization owning image.)
resolutionImage product resolution (expressed in meters per pixel)
urlURL link to image if the image is not embedded
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
sizeApproximate image file size (bytes)
analysis(DEPRECATED) True if image analysis (e.g., markup) is available
mimeIf an in-lined image is contained in this entity, then this attribute describes the mime type of that image. The actual image data will be base64 encoded. See http://www.w3schools.com/media/media_mimeref.asp for list of common mime types.
widthThe width of the image (in pixels)
heightThe height of the image (in pixels)
reason(NEW) The reason this image was originally produced (BHA, BDA, ISR, ...) Coding is TBD but will reflect the CoT type coding structure. E.g., a-d-b Assesment-Damage-Bomb, etc...
bandsNumber of data bands within the image. For example, an RGB image as 3 bands (Red, Green, Blue bands/channels)
mimecsvUsed only if the attribute 'mime' references a container type (e.g., image/x-nitf21). In this case, 'mimecsv' holds a list of Comma Separated Values to supplement the MIME type in the mime field. Nominally, the values in 'mimecsv' wil lbe mime types of the elements in the composite image. For example, if 'mime' 'image/x-nitf21', then 'mimecsv' may hold 'image/jpeg', 'image/jpeg2000', or 'image/x-eagleeye'.
qualityThis expresses how the tradeoff between image quality and compression were made for this image. This is usually a 'relative' quality measure, an unsigned floating point value between 0.0 (highest compression) and 1.0 (highest quality). Implementers should attempt to map this scalar value to an approximate linear progression of visual quality as determined on a typical sample image. If the field's value carries an explicit sign (+/-) including +0 or -0, it represents the exact value expressed in a range appropriate to the compression type expressed in 'mime' or 'mimecsv'. For example, with 'image/x-eagleeye' the EagleEye clip setting, the quality setting may range from -4096.0 to +4096.0.
+
    +
  1. +

    ** Input**

    +
  2. +
+

this class can drive input filtering without auth messages.

+
    +
  1. +

    ** Input attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
name
Protocol
Port
authPreviously the only valid value for the <input> "auth" attribute was "ldap". "file" is now another valid value.
+
    +
  1. +

    ** keywords**

    +
  2. +
  3. +

    ** keywords attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** labels_on**

    +
  2. +
  3. +

    ** labels_on attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
value
+
    +
  1. + +
  2. +
+

This is a Cursor On Target Class for linking to either another CoT event or an arbitrary Internet resource. The objective of this class is to provide an abstract way to express a relationship between a CoT object and other object. This allows, for example, a sensor point of interest to be linked back to its source, or a PPLI from a wingman to be associated with his flight lead. Linkages are always unidirectional.

+

One entity may have multiple links (i.e., it may be related to multiples other entities). For processing simplicity, it is required that the relationship graphs will directed and acyclic (no cycles). The link, itself, names the relationship (using a hierarchy similar to the CoT type), the UID of the related object (whether CoT or not), possibly provides a URL for retrieving that object.

+

links are used for example in routes.

+
    +
  1. + +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
uid
production_timethe time in which this link has been produced (e.g. "2020-11-26T14:19:02Z")
relationThe type of relationship (e.g, subject, object, indirect object) that this link describes. This is a hierarchy much like the event type field.Common values: "c"
typeThe CoT type of the referenced MIL 2525 object. This is included because it is generally the key item needed in a tasking. Common types are:- Control Point: "b-m-p-c" - Waypoint: "b-m-p-w"
urlIf present, this is a URL through which the linked object can be retrieved. If the URL is missing, then the object should be a periodic message (e.g., blue force track) that can be read from a CoT stream.
parent_callsignthe call sign of the client that produced this link
remarksRemarks associated with this link.
mimeInternet Media type of the referenced object. If the link is to a CoT event, the mime attribute is optional and its type may be application/xml or text/xml as described in RFC 3023, "XML Media Types", or the unregistered type, application/cot+xml. If the link is to an arbitrary resource, the mime attribute is required and and appropriate Internet media type must be specified. Registered media types are managed by the IANA and are listed at http://www.iana.org/assignments/media-types/.
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
pointlocation of a point in Format: "Lat,Lng" decimal values. e.g.38.843641314210366,-77.04564214131744
+
    +
  1. +

    ** Marti**

    +
  2. +
+

Messages sent through the TAK server require an additional element to assist the server with properly routing your messages. If this element is not included, the server will interpret this as a message to all recipients, and the message will be sent to everyone, and depending upon the client software, this could mean a private message would be displayed publicly.

+
    +
  1. +

    ** Marti attributes**

    +
  2. +
  3. +

    ** mimeType**

    +
  4. +
  5. +

    ** mimeType attributes**

    +
  6. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** mission**

    +
  2. +
  3. +

    ** mission attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
type
tool
name
authorUid
+
    +
  1. +

    ** Mission**

    +
  2. +
+

Represent a TAK Mission

+
    +
  1. +

    ** Mission attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
name
server
description
+
    +
  1. +

    ** MissionChange**

    +
  2. +
  3. +

    ** MissionChange attributes**

    +
  4. +
  5. +

    ** MissionChanges**

    +
  6. +
  7. +

    ** MissionChanges attributes**

    +
  8. +
  9. +

    ** missionName**

    +
  10. +
  11. +

    ** missionName attributes**

    +
  12. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** name**

    +
  2. +
  3. +

    ** name attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** point**

    +
  2. +
  3. +

    ** point attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
latLatitude referred to the WGS 84 ellipsoid in degrees
lonLongitude referred to the WGS 84 in degrees
ceCircular area around the point defined by lat and lon fields in meters. Although named ce, this field is intended to define a circular area around the event point, not necessarily an error (e.g. Describing a reservation area is not an "error").If it is appropriate for the "ce" field to represent an error value (e.g. event describes laser designated target), the value will represent the one sigma point for a zero mean normal (Guassian) distribution.
leLinear Error in meters associated with the HAE field. Although named le, this field is intended to define a height range about the event point, not necessarily an error. This field, along with the ce field allow for the definition of a cylindrical volume about the point. If it is appropriate for the "le" field to represent an error (e.g. event describes laser designated target), the value will represent the one sigma point for a zero mean normal (Guassian) distribution.A height range about the event point in meters associated with the HAE field. When used to represent error, the value represents the one sigma point for a zero mean normal (Gaussian) distribution.
haeHeight above Ellipsoid based on WGS-84 ellipsoid (measured in meters)HAE acronym for Height above Ellipsoid based on WGS-84 ellipsoid (measured in meters).
+
    +
  1. +

    ** polyline**

    +
  2. +
+

The poly line provides a mechanism to express arbitrarily complex two-dimenstional shapes. This is used for representing oddly shaped objects such as exclusion zones, etc. Though generally closed, it is not necessarily a closed line, thus allowing polyline to represent objects such as phasing lines, etc.

+
    +
  1. +

    ** polyline attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
vertex
level"level" is used to indicate the preferred ordering of multiple shape sub-schemas. For instance, if a polyline and ellipse are both present on the shape attribute, the one with the higher level value will be the "more desirable" representation of the object. This allows producers to provide alternative representation of an objects shape while ensuring that consumers will know which of the available representation is the best. (Note that not all consumers will implement all shape variations, hence the need for the allowing multiple shape objects.)See the documentation for shape/ellipse/@level for remarks on determining the precedence order when level values are equal or are missing.
closedTrue if the list of verticies should be considered a closed polygon (an implicit line will be added from vertex N to vertex 0).
+
    +
  1. +

    ** Precisionlocation**

    +
  2. +
+

some type of location?

+
    +
  1. +

    ** Precisionlocation attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
altsrcTDB can be DTED0 or ???
geopointsrc
PRECISE_IMAGE_FILE
PRECISE_IMAGE_FILE_X
PRECISE_IMAGE_FILE_Y
+
    +
  1. +

    ** remarks**

    +
  2. +
+

This is a Cursor On TargetClass for a generic remarks (aka "FreeText").

+

Provides a place to annotate CoT with free text information. e.g. comments from other users about the current CoT. +Used also for the geoChat.

+

the xml body of this class is used to transport the chat message

+

While the use of free text is strongly discouraged (it hampers machine-to-machine communication) it is a pragmatic necessity. This entity attempts to encapsulate freetext in a way that simplifies subsequent machine processing. The content of this entity is presumed to be a human-readable chunk of textual data. The attributes merely aid in the machine handling of the data.

+
    +
  1. +

    ** remarks attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
timethe time of the remark was added to the CoT object
toIntended recipeint(s) of this remark information. Tentative field coding as follows: The to attribute may contain the UID of the entity to whom the message is addressed. (Implementors should expect that future versions of this sub schema will allow a comma separated list of UIDs.) Absense of an explict addressee means the message is broadcast.e.g. ANDROID-359975090666199
sourceSource specifies the sender’s UID – this is what is parsed by recipients to determine the sender, with the UID format being the fallback.
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
keywordsUsed to track a conversation thread. The format is a comma-separated list of freetext keywords.ex. keywords="debriefing" - Describes a conversation about debriefingex. keywords="mission-A" - Describes a conversation about mission-Aex. keywords="tasking_B, subject_C" - Describes a conversation about tasking_B and subject_C
sourceID
+
    +
  1. +

    ** request**

    +
  2. +
+

This is a Cursor On Target sub-schema for a generic request. This schema contains information common to all requests, specifically where responses should be sent, the overall priority of the request, if immediate willco/cantco acknowledgement is needed, etc. Detail information for specific request types are carried in sub-schemas nested within this one.

+

Notice that this is not the same as inTAKRequest

+
    +
  1. +

    ** request attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
notifyNetwork endpoint to which status notifications should be delivered. (A network endpoint is represented as an URL, e.g., tcp://hostname:port, udp://hostname:port. The previous format, host:port, e.g., 192.168.0.1:71556, is deprecated, but implementers should be aware that this format may be in use.
wilcobyAn optional field that requests the receiving system to provide a positive or negative akcnowledgement (WILCO/CANTCO) by a specific time. This is used to ensure that deadline driven requests are made known to the operator.
priorityThis optional field indicates this request's relative priority with respect to other requests. (At present, no specific coding scheme is in mandated, but a floating point value between 0.0(low) and 1.0(high) is in current (limited) use.)
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
toWhen present, this field contains the CoT UID of the specific entity who is being addressed. It is assumed that all CoT entities that can provide a service are reported as friendly atoms.
authorityThis is a 'signature block' which holds the CoT uid of the entity which has uathorized the request. The authorizing entity is not necessarily the originator of the request and might not be associated with the 'notify' field. Authority is intended to provide services (such as a striker) a mechanism to verify that the request has been approved.
streamto
+
    +
  1. +

    ** route**

    +
  2. +
  3. +

    ** route attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
sender
+
    +
  1. +

    ** routeinfo**

    +
  2. +
  3. +

    ** routeinfo attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
__navcues
+
    +
  1. +

    ** sensor**

    +
  2. +
+

This is (the root class of) a Cursor On Target sub-schema for a steerable, staring sensor such as EO, IR, or Radar sensor. The root class is intended to capture only information on the sensor's orientation and field of view is. Details about it's spectrum, sensitivity, resolution, modality, performance, etc., should be captured in a "derived" subschema for that particular type of sensor. All orientation attributes associated with sensor are normalized to an geodedic frame of reference, removing platform factors such as roll, pitch, yaw, etc. Therefore an "azimuth" of 0 means the sensor is pointed north regardless of its platform heading or attitude.

+
    +
  1. +

    ** sensor attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
elevation
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
typeThe sensor type. This is a type hierarchy much like the CoT type tree. E.g., r - raster, r-e - raster EO, r-e-z-c - raster EO zoom continuous. See types.txt for details
vfov
modelThis is the sensor model. E.g., LANTRIN, TARPS, etc.
fovfield of view
roll
fovBlue
displayMagneticReference
range
fovGreen
fovAlpha
hideFov
fovRed
azimuth
+
    +
  1. +

    ** shape**

    +
  2. +
+

This is a Cursor On Target sub-schema for a generic shape description. Many objects are not adequately represented by the simple "point" object in the CoT base schema. However, it is counterproductive to burden all CoT applications to understand arbitrary shapes, so "shape" is an optional attribute that can be used to communicate between shape-aware apprications. The "point" object in the base schema must still be populated and the CE and LE fields in the point entity must be set such that the point completely encloses the area described in any shape entity in the detail section. (This is needed so that CoT applications can quickly filter out objects that are clearly outside an area of interest.

+
    +
  1. +

    ** shape attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
ellipseThe "ellipse" is a common shape abstraction used by many geomanipulation applications; it is supported natively.
link
polylineThe poly line provides a mechanism to express arbitrarily complex two-dimenstional shapes. This is used for representing oddly shaped objects such as exclusion zones, etc. Though generally closed, it is not necessarily a closed line, thus allowing polyline to represent objects such as phasing lines, etc.
dxfThis is a hook for an arbitrary 3D DXF description of a volume of space.
versionVersion tag for this sub schema. Can be used to ensure upward compatibility with future revisions.
+
    +
  1. +

    ** size**

    +
  2. +
  3. +

    ** size attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** spatial**

    +
  2. +
+

This is a Cursor On TargetClass for spatial information of physical entity. It is intended to appear in the detail section of the Cursor On Target schema. It has elements to represent attitude and associated first derivatives (spin). The intention behind the spatial element is to convey the attitude of a body moving through space with respect to its "nominal" flight attitude.

+
    +
  1. +

    ** spatial attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
attitudeAttitude represents the attitude of the entity described by the Cursor On Target base schema.
spinSpin represents the first derivative of attributes found in attitude.
versionVersion tag for this sub schema. Neccessary to ensure upward compatibility with future revisions.
+
    +
  1. +

    ** spin**

    +
  2. +
  3. +

    ** spin attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
roll
pitch
yaw
+
    +
  1. +

    ** status**

    +
  2. +
+

The status element provides a container for elements reporting different kinds of

+

status. e.g. a fuel subschema is used to report the amount of burnable fuel

+

remaining in liters and the current burn rate (in liters per second).

+
    +
  1. +

    ** status attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
battery% of the battery on the phone
readinessprobably boolean to determine if ready or not
+
    +
  1. +

    ** strokeColor**

    +
  2. +
  3. +

    ** strokeColor attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
value
+
    +
  1. +

    ** strokeWeight**

    +
  2. +
  3. +

    ** strokeWeight attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
value
+
    +
  1. +

    ** submissionTime**

    +
  2. +
  3. +

    ** submissionTime attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** submitter**

    +
  2. +
  3. +

    ** submitter attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** TakControl**

    +
  2. +
+

A server which supports the TAK ProtocolMAYsend the following CoT XML message to indicate this support (whitespace added, xml header omitted):

+

<event version='2.0' uid='protouid' type='t-x-takp-v' time='TIME' start='TIME' stale='TIME' how='m-g'>

+

<point lat='0.0' lon='0.0' hae='0.0' ce='999999' le='999999'/>

+

<detail>

+

<TakControl>

+

<TakProtocolSupport version="1"/>

+

</TakControl>

+

</detail>

+

</event>

+

This message may contain one or more TakProtocolSupport elements inside the single <TakControl> detail, each specifying a supported version.

+

The TAK server MUST send this message no more than once per connection.

+

To allow for ancillary information in the negotiation, the TakProtocolSupport element_MAY_contain additional attributes compliant

+

with the Protocol version indicated.

+
    +
  1. +

    ** TakControl attributes**

    +
  2. +
  3. +

    ** TAKControlSupport**

    +
  4. +
+

set from

+
    +
  1. +

    ** TAKControlSupport attributes**

    +
  2. +
+ + + + + + + + + + + + + +
NameDocumentation
versionversion attribute is an integer number specifying a version of the TAK Protocol the server supports.
+
    +
  1. +

    ** TakRequest**

    +
  2. +
  3. +

    ** TakRequest attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
version
+
    +
  1. +

    ** TakResponse**

    +
  2. +
+

is sent in the procedure of negotiating protolcs to indicates if the server is accepting the client request to switch to an higher level of the protocol

+
    +
  1. +

    ** TakResponse attributes**

    +
  2. +
+ + + + + + + + + + + + + +
NameDocumentation
status
+
    +
  1. +

    ** takv**

    +
  2. +
+

Provides the type and version of the TAK client

+
    +
  1. +

    ** takv attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
platformthe variant of TAK
devicetype of physical device
osthe operating system running TAK
versionthe version of TAK running on the device
+
    +
  1. +

    ** templates**

    +
  2. +
+

a class for checklist templates

+
    +
  1. +

    ** templates attributes**

    +
  2. +
  3. +

    ** timestamp**

    +
  4. +
  5. +

    ** timestamp attributes**

    +
  6. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** tog**

    +
  2. +
  3. +

    ** tog attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
enabled
+
    +
  1. +

    ** tool**

    +
  2. +
  3. +

    ** tool attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** track**

    +
  2. +
+

The track element specifiesdirection and speedof travel. It has two required attributes: course and speed. It also has optional attributes for specifying the vertical component of the motion vector (slope) and errors associated with course, speed, and slope.

+

Coursedenotes the direction of motion and is specified as the number of degrees measured clockwise from true North.

+

Speedis specified in meters per second as speed over ground.

+

There is no constraint on the precision used for these values.

+
    +
  1. +

    ** track attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
speed
eCourse1-sigma error on a Gaussian distribution associated with the course attribute
course
eSpeed1-sigma error on a Gaussian distribution associated with the speed attribute
eSlope1-sigma error on a Gaussian distribution associated with the slope attribute
version
+
    +
  1. +

    ** type**

    +
  2. +
  3. +

    ** type attributes**

    +
  4. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** uastool**

    +
  2. +
  3. +

    ** uastool attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
extendedCot
activeRoute
+
    +
  1. +

    ** uid**

    +
  2. +
+

This is a Cursor On Target detail Class that holds the unique ID assigned by each system that processed this event.

+

Most systems (including CoT) have their own method for assigning system-wide unique identifiers for a particular object. In general, it is not possible for a single UID to be used for all systems. This 'uid' entity provides a common place where each systems can record its particular UID for each CoT event. Like the _flow-tags_ element, each system is responsible for adding its own attribute to this entity. The name of the attribute should represent the system, and the value of the attribute should be the id that system assigned to this CoT object.

+
    +
  1. +

    ** uid attributes**

    +
  2. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
version
DroidTBD, maybe from Android?
+
    +
  1. +

    ** uid**

    +
  2. +
+

special class used in mission only for ID

+
    +
  1. +

    ** uid attributes**

    +
  2. +
+ + + + + + + + + + + + + +
NameDocumentation
INTAG
+
    +
  1. +

    ** usericon**

    +
  2. +
+

the image used to display the COt

+
    +
  1. +

    ** usericon attributes**

    +
  2. +
+ + + + + + + + + + + + + +
NameDocumentation
iconsetpaththe path of the icon image usedMIL 2525 STD- COT_MAPPING_2525B/a-u/a-u-GICON- 34ae1613-9645-4222-a9d2-e5f243dea2865/Military/EA-6B.png - 'f7f71666-8b28-4b57-9fbb-e38e61d33b79/Google/hiker.png'/in alternative for a spot- COT_MAPPING_SPOTMAP/b-m-p-s-m/-65536
+
    +
  1. +

    ** vehicle**

    +
  2. +
  3. +

    ** vehicle attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
goHomeBatteryPercent
hal
flightTimeRemaining
typeTag
batteryRemainingCapacity
isFlying
flightTime
type
batteryMaxCapacity
voltage
+
    +
  1. +

    ** vertex**

    +
  2. +
  3. +

    ** vertex attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
haeHeight Above Ellipsoid (HAE) in Meters. If absent, the value of the point/@hae in the CoT event base schema is used.
latLatitude based on WGS-84 ellipsoid in signed degree-decimal format (e.g. -33.350000). Range -90 -> +90. Positive values denote north.
lonLongitude based on WGS-84 ellipsoid in signed degree-decimal format (e.g. 44.383333). Range -180 -> +180. Positive values denote east.
+
    +
  1. +

    ** video**

    +
  2. +
  3. +

    ** video attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
sensor
spi
url
+
    +
  1. +

    ** Text**

    +
  2. +
  3. +

    ** Text attributes**

    +
  4. +
  5. +

    ** bullseye_bearingRef**

    +
  6. +
  7. +

    ** bullseye_bearingRef attributes**

    +
  8. +
+ + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
T
M
G
+
    +
  1. +

    ** checklistColumnType**

    +
  2. +
  3. +

    ** checklistColumnType attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
ShortString
LongString
Integer
ActualTime
RelativeTime
+
    +
  1. +

    ** checklistStatus**

    +
  2. +
  3. +

    ** checklistStatus attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Pending
Complete
Complete (late)
Late
+
    +
  1. +

    ** checklistTaskStatus**

    +
  2. +
  3. +

    ** checklistTaskStatus attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Pending
Complete
Complete (late)
Late
+
    +
  1. +

    ** MissionType**

    +
  2. +
  3. +

    ** MissionType attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
CREATE
CHANGE
+
    +
  1. +

    ** route_fil**

    +
  2. +
  3. +

    ** route_fil attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
Infil
Exfil
+
    +
  1. +

    ** route_method**

    +
  2. +
  3. +

    ** route_method attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Driving
Walking
Flying
Swimming
Watercraft
+
    +
  1. +

    ** route_order**

    +
  2. +
  3. +

    ** route_order attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
Ascending Check Points
Descending Check Points
+
    +
  1. +

    ** route_routetype**

    +
  2. +
  3. +

    ** route_routetype attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + +
NameDocumentation
Primary
Secondary
+
    +
  1. +

    ** TeamColor**

    +
  2. +
  3. +

    ** TeamColor attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Yellow
Red
Blue
Orange
Magenta
Maroon
Purple
Dark Blue
Cyan
Teal
Green
Dark Green
Brown
+
    +
  1. +

    ** TeamRole**

    +
  2. +
  3. +

    ** TeamRole attributes**

    +
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDocumentation
Team Member
Team Lead
HQ
Sniper
Medic
Forward Observer
RTO
K9
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/architecture/cot_hierarchy/index.html b/About/architecture/cot_hierarchy/index.html new file mode 100644 index 000000000..84105dd92 --- /dev/null +++ b/About/architecture/cot_hierarchy/index.html @@ -0,0 +1,6417 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Work in progress CoT Hierarchy Tree

+
+ CoT Hierarchy Tree + +### Heading + +
+ 1. a + 1. .* + 1. 9 + 1. 1 + 1. 1 +
+
+ 2. A + 1. C + 1. F + 1. q + 2. H + 3. L + 2. M + 1. F + 1. A + 2. B + 3. C + 1. H + 2. L + 3. M + 4. D + 5. F + 1. I + 6. g + 7. H + 8. J + 9. K + 1. B + 2. D + 10. L + 11. M + 12. O + 13. P + 1. M + 2. N + 14. Q + 1. A + 2. B + 3. C + 4. D + 5. F + 6. H + 7. I + 8. J + 9. K + 10. L + 11. M + 12. N + 13. O + 14. P + 15. R + 1. W + 2. X + 3. Z + 16. S + 17. T + 18. U + 19. Y + 15. R + 1. W + 2. X + 3. Z + 16. S + 17. T + 18. U + 1. H + 2. L + 3. M + 19. Y + 2. H + 1. A + 2. C + 1. H + 2. L + 3. M + 3. D + 4. H + 5. I + 6. J + 7. K + 8. M + 9. O + 10. Q + 11. R + 12. S + 13. T + 14. U + 1. H + 2. L + 3. M + 3. L + 3. W + 1. B + 2. D + 3. M + 1. A + 1. A + 2. P + 3. S + 2. B + 3. C + 1. M + 4. L + 5. S + 1. A + 1. f + 2. i + 3. m + 2. B + 3. S + 4. U + 6. U + 3. F + 1. A + 1. F + 1. A + 2. K + 3. U + 1. H + 2. L + 3. M + 2. H + 1. A + 2. H + 3. U + 1. H + 2. L + 3. M + 3. V + 2. B + 3. G + 1. C + 2. P + 1. A + 3. R + 4. S + 4. N + 1. B + 2. N + 3. S + 4. U + 4. G + 1. E + 1. S + 1. E + 2. R + 2. V + 1. A + 1. A + 1. R + 2. C + 3. I + 4. L + 5. S + 6. T + 1. H + 1. R + 2. L + 1. R + 3. M + 1. R + 2. C + 1. A + 1. H + 2. L + 3. M + 2. F + 1. H + 2. L + 3. M + 3. J + 1. H + 2. L + 3. M + 4. M + 1. H + 2. L + 3. M + 5. O + 1. H + 2. L + 3. M + 6. T + 1. H + 2. L + 3. M + 7. U + 1. H + 2. L + 3. M + 3. E + 1. A + 1. A + 2. T + 2. B + 3. C + 4. D + 1. A + 5. E + 6. F + 7. H + 8. M + 1. L + 2. V + 9. R + 10. S + 4. m + 5. M + 6. S + 1. C + 2. P + 3. R + 4. T + 5. W + 7. T + 8. U + 1. A + 1. A + 2. B + 3. L + 4. R + 1. l + 2. m + 3. s + 5. S + 1. H + 2. L + 3. M + 6. T + 1. H + 2. L + 7. X + 3. W + 1. A + 1. H + 2. L + 3. M + 2. D + 1. H + 1. S + 2. L + 1. S + 3. M + 1. S + 3. G + 1. H + 2. L + 3. M + 4. R + 4. H + 1. H + 1. S + 2. L + 1. S + 3. M + 1. S + 5. M + 1. A + 1. I + 1. E + 2. R + 2. L + 1. E + 2. R + 3. S + 1. E + 2. R + 4. T + 1. E + 2. R + 2. S + 1. I + 2. L + 3. S + 3. T + 1. H + 2. L + 3. M + 6. O + 1. H + 2. L + 3. M + 7. R + 1. H + 2. L + 3. R + 8. S + 1. H + 2. L + 3. M + 9. T + 1. H + 2. L + 3. M + 10. X + 1. H + 2. L + 3. M + 11. Z + 1. H + 2. L + 3. M + 4. X + 1. F + 2. L + 3. M + 1. C + 2. L + 4. N + 2. I + 1. B + 1. A + 2. N + 2. c + 1. b + 2. bar + 3. can + 1. l + 4. frm + 5. l + 6. mon + 7. o + 8. rah + 9. rel + 10. res + 11. ret + 12. sch + 13. vip + 14. whs + 3. E + 1. h + 2. l + 3. o + 4. G + 5. i + 1. e + 1. EOC + 2. ic + 3. icc + 4. icp + 5. wr + 2. f + 1. fd + 3. h + 1. md + 4. l + 1. cp + 2. hp + 3. lp + 4. ntz + 5. sd + 6. SP + 5. m + 6. o + 1. AD + 1. ems + 2. f + 3. hwy + 4. mda + 5. pl + 6. ps + 7. tow + 8. ts + 2. bcc + 3. dmz + 4. isp + 5. mc + 1. f + 2. h + 3. l + 6. mes + 7. mob + 1. ems + 2. es + 3. f + 4. hwy + 5. mda + 6. pl + 7. ps + 8. tow + 8. ps + 9. rl + 10. sa + 1. ems + 2. f + 3. hwy + 4. mda + 5. pl + 6. ps + 7. tow + 8. ts + 11. sc + 12. seg + 13. t + 1. IM + 2. tc + 3. td + 4. tm + 14. tmp + 1. f + 2. h + 3. l + 7. p + 6. M + 1. A + 2. C + 3. E + 4. F + 1. A + 2. P + 1. W + 3. S + 5. G + 6. M + 7. N + 1. B + 1. l + 2. m + 3. s + 2. c + 8. S + 9. V + 7. P + 1. D + 8. R + 1. M + 2. N + 1. B + 2. C + 3. N + 3. P + 1. r + 9. r + 1. h + 2. i + 3. ra + 4. u + 10. T + 1. a + 2. hb + 3. hs + 4. l + 5. pg + 6. r + 7. s + 11. U + 1. E + 1. c + 2. D + 3. F + 4. h + 5. N + 6. o + 7. ps + 2. P + 3. R + 4. T + 1. com + 1. af + 2. sat + 3. tow + 2. r + 1. s + 3. tp + 1. ts + 4. tv + 1. c + 2. s + 12. X + 1. H + 2. hcf + 3. U + 1. C + 1. A + 1. A + 1. A + 1. S + 2. T + 3. W + 2. C + 3. D + 4. L + 5. M + 6. O + 1. S + 7. S + 8. U + 2. T + 1. A + 2. H + 3. L + 4. M + 5. R + 6. W + 1. R + 3. W + 1. A + 2. H + 3. L + 4. M + 5. R + 6. S + 7. W + 1. R + 2. D + 1. C + 2. G + 3. H + 1. H + 2. P + 4. M + 1. H + 2. L + 1. A + 3. M + 5. O + 6. S + 1. C + 2. S + 3. V + 7. T + 3. E + 1. C + 1. A + 2. C + 3. H + 4. L + 5. M + 6. O + 7. R + 8. S + 9. T + 10. W + 2. N + 1. N + 4. F + 1. H + 1. A + 2. C + 3. E + 4. H + 5. L + 6. M + 7. O + 8. S + 9. X + 2. M + 1. L + 2. S + 3. T + 1. A + 2. C + 3. O + 4. S + 4. W + 3. O + 1. A + 2. L + 3. O + 4. S + 4. R + 1. M + 1. R + 2. S + 3. T + 2. S + 1. R + 2. S + 3. T + 5. S + 1. A + 2. L + 3. O + 4. S + 6. T + 1. A + 2. C + 1. D + 2. M + 3. F + 4. R + 5. S + 5. I + 1. A + 2. C + 3. d + 4. I + 5. L + 6. M + 7. N + 8. O + 9. S + 10. Z + 6. M + 1. S + 2. T + 7. R + 1. A + 2. C + 3. H + 4. L + 5. O + 6. R + 1. D + 2. F + 3. L + 7. S + 8. V + 1. A + 2. G + 3. M + 4. O + 9. X + 8. S + 1. A + 2. G + 1. A + 2. D + 3. M + 3. M + 4. R + 5. W + 9. V + 1. C + 2. F + 1. A + 2. R + 3. U + 3. R + 1. A + 2. C + 3. d + 4. E + 5. M + 6. S + 7. s + 8. U + 1. C + 2. E + 3. H + 4. L + 5. M + 9. W + 4. S + 5. U + 1. F + 2. R + 6. V + 2. H + 3. i + 1. a + 1. imt + 2. lar + 3. las + 4. lat + 5. SAR + 6. sas + 7. sat + 2. e + 1. acrc + 2. acrt + 3. att + 4. cis + 5. cst + 6. dc + 7. dmt + 8. ect + 9. efa + 10. elt + 11. ems + 12. eos + 13. eps + 14. ial + 15. iat + 16. imt + 17. MCC + 18. mfk + 19. pac + 20. rna + 21. smt + 22. val + 3. f + 1. act + 2. bp + 3. ct + 4. efp + 5. fb + 6. ft + 7. fta + 8. ftf + 9. hc + 10. het + 11. hf + 12. ht + 13. ibt + 14. imt + 15. mcu + 16. nsf + 17. pp + 18. st + 19. wt + 4. h + 1. dmb + 2. dmc + 3. dmm + 4. dmp + 5. dms + 6. mor + 7. msr + 8. mst + 9. vma + 5. l + 1. bs + 2. cct + 3. dt + 4. hps + 5. oa + 6. tt + 6. m + 1. aaf + 2. aar + 3. ag + 4. ast + 5. atf + 6. etf + 7. o + 8. p + 1. acf + 2. ach + 3. act + 4. atc + 5. bh + 6. cah + 7. cc + 8. cce + 9. dat + 10. dmm + 11. dmr + 12. dmt + 13. drt + 14. dt + 15. dtf + 16. dtn + 17. epr + 18. es + 19. fbt + 20. gen + 21. hel + 22. hem + 23. htc + 24. ltc + 25. tb + 26. td + 27. tg + 28. tt + 29. wd + 30. wll + 31. wlm + 32. wls + 33. wpt + 34. wt + 9. s + 1. ar + 2. ast + 3. cas + 4. cav + 5. cdr + 6. clc + 7. col + 8. cwa + 9. cwi + 10. cwt + 11. mnt + 12. mt + 13. rdf + 14. sfd + 15. uis + 16. utf + 17. wi + 4. S + 1. A + 1. C + 2. F + 1. C + 2. T + 3. J + 1. C + 2. T + 4. L + 1. C + 2. T + 5. M + 1. C + 2. T + 6. O + 1. C + 2. T + 7. P + 1. B + 1. C + 2. T + 2. C + 3. M + 1. C + 2. T + 4. T + 8. Q + 1. C + 2. T + 9. R + 1. C + 2. T + 10. S + 1. C + 2. T + 11. T + 12. W + 1. C + 2. T + 13. X + 1. C + 2. T + 2. M + 1. C + 2. D + 1. C + 2. T + 3. M + 1. C + 2. T + 4. P + 1. C + 2. T + 5. T + 6. V + 1. C + 2. T + 3. S + 1. 1 + 1. C + 2. T + 2. 2 + 1. C + 2. T + 3. 3 + 1. A + 1. C + 2. T + 2. C + 3. T + 4. 4 + 1. C + 2. T + 5. 5 + 1. C + 2. T + 6. 6 + 1. C + 2. T + 7. 7 + 1. C + 2. T + 8. 8 + 1. C + 2. T + 9. 9 + 1. C + 2. T + 10. C + 11. d + 12. L + 1. C + 2. T + 13. T + 14. W + 1. C + 2. P + 1. C + 2. T + 3. T + 15. X + 1. C + 2. T + 4. T + 1. A + 1. C + 2. T + 2. C + 3. I + 1. C + 2. T + 4. M + 1. C + 2. T + 5. R + 1. C + 2. T + 6. S + 1. C + 2. T + 7. T + 5. X + 1. C + 2. E + 1. C + 2. T + 3. H + 1. C + 2. T + 4. O + 1. C + 2. M + 1. C + 2. T + 3. T + 5. R + 1. C + 2. T + 6. T + 5. U + 1. A + 1. B + 1. R + 2. C + 1. C + 1. K + 2. M + 2. R + 1. S + 2. W + 3. S + 1. A + 2. M + 3. D + 4. N + 2. E + 3. I + 4. L + 1. C + 2. D + 3. F + 4. M + 5. S + 5. M + 1. A + 2. C + 3. J + 4. M + 1. O + 5. O + 6. Q + 7. R + 1. G + 2. O + 3. S + 1. S + 4. X + 8. S + 1. E + 1. A + 2. C + 3. D + 4. I + 5. J + 6. T + 9. T + 6. P + 7. S + 1. A + 2. C + 1. L + 3. F + 4. M + 1. L + 2. N + 3. S + 5. O + 6. R + 1. S + 2. T + 3. W + 7. S + 8. W + 9. X + 5. P + 1. L + 2. S + 3. T + 4. V + 6. S + 1. C + 1. A + 1. L + 1. A + 2. C + 3. S + 1. M + 2. T + 2. D + 3. G + 4. H + 5. L + 1. B + 1. B + 2. C + 1. C + 2. V + 3. D + 1. D + 4. F + 1. F + 5. L + 1. L + 1. A + 1. S + 2. M + 1. I + 3. S + 1. U + 6. M + 1. M + 1. A + 2. D + 3. H + 4. L + 5. S + 7. P + 1. S + 1. B + 2. U + 1. G + 2. M + 3. T + 8. S + 9. U + 1. M + 2. N + 3. S + 2. G + 1. C + 2. G + 3. T + 4. U + 3. N + 1. F + 2. H + 3. I + 4. M + 5. N + 1. R + 6. R + 7. S + 4. O + 5. S + 1. A + 2. P + 6. X + 1. F + 1. D + 1. F + 2. R + 2. T + 1. R + 2. H + 3. L + 4. M + 1. C + 2. F + 3. H + 4. O + 5. P + 6. R + 7. T + 1. O + 2. U + 5. R + 7. U + 1. N + 1. D + 2. S + 1. C + 1. A + 2. B + 3. F + 4. G + 5. M + 2. F + 3. N + 1. A + 2. B + 3. F + 4. G + 5. M + 4. O + 1. F + 5. S + 1. A + 6. U + 1. M + 2. N + 3. S + 3. W + 1. D + 1. M + 2. M + 1. D + 2. F + 1. D + 3. G + 1. D + 4. M + 1. D + 5. O + 1. D + 3. T + 8. X + 1. i + 1. c + 2. e + 3. f + 1. h + 2. n + 1. h + 2. s + 3. o + 4. p + 5. r + 6. s + 7. w + 4. g + 1. a + 2. e + 1. a + 2. e + 3. l + 4. s + 5. v + 1. e + 2. t + 5. h + 6. i + 7. l + 1. c + 1. d + 2. p + 3. r + 2. l + 1. b + 1. e + 2. t + 2. l + 3. p + 4. s + 8. m + 1. a + 2. c + 3. d + 4. f + 5. g + 6. h + 7. i + 8. n + 9. r + 10. s + 11. t + 12. u + 13. z + 9. o + 10. r + 11. s + 12. t + 1. a + 1. a + 2. h + 2. m + 1. a + 2. h + 3. r + 1. a + 2. h + 4. v + 1. a + 2. h +
+
+ 2. b + 1. d + 1. a + 1. c + 2. i + 3. v + 2. c + 1. b + 1. b + 2. c + 2. e + 1. d + 3. n + 1. n + 1. b + 2. sm + 2. r + 1. dd + 3. i + 1. m + 4. l + 1. b + 2. m + 5. m + 6. n + 7. r + 8. s + 2. g + 1. F + 1. A + 1. A + 2. B + 3. C + 4. F + 5. K + 6. N + 7. P + 8. R + 9. S + 10. T + 2. L + 1. C + 2. F + 3. L + 4. N + 5. P + 6. R + 7. S + 3. P + 1. S + 2. T + 1. C + 2. N + 3. R + 4. S + 2. G + 1. A + 1. A + 1. F + 2. H + 3. M + 1. H + 2. L + 4. R + 5. W + 2. L + 1. C + 2. L + 3. M + 4. S + 5. U + 3. P + 1. C + 2. D + 3. P + 4. U + 2. D + 1. A + 1. B + 1. P + 2. E + 2. L + 1. F + 2. P + 3. P + 1. O + 1. C + 2. F + 3. N + 4. R + 5. S + 2. T + 3. G + 1. A + 1. A + 2. D + 3. E + 4. F + 5. G + 6. L + 7. P + 8. S + 9. X + 10. Y + 11. Z + 2. L + 1. B + 2. C + 3. F + 4. L + 5. P + 3. P + 1. A + 1. A + 2. C + 3. H + 4. K + 5. L + 6. M + 7. O + 8. P + 9. R + 10. S + 11. T + 12. W + 2. F + 3. H + 1. A + 2. Q + 3. X + 4. Y + 4. O + 1. D + 2. P + 3. R + 4. W + 5. Z + 5. P + 1. C + 2. D + 3. E + 4. K + 5. L + 6. O + 7. P + 8. R + 9. S + 10. W + 6. R + 1. D + 2. I + 3. N + 4. S + 7. U + 1. S + 1. A + 2. C + 3. D + 2. U + 1. B + 2. D + 3. L + 4. S + 3. Y + 1. A + 2. B + 3. C + 4. D + 5. K + 6. L + 7. P + 8. R + 9. S + 10. T + 11. V + 8. W + 1. A + 2. D + 3. E + 4. G + 5. I + 6. M + 7. P + 4. O + 1. A + 1. A + 2. F + 3. K + 4. O + 5. P + 6. S + 2. L + 1. A + 1. A + 2. G + 1. M + 2. S + 3. R + 4. V + 2. C + 3. F + 4. I + 5. K + 1. A + 2. G + 1. M + 2. S + 6. L + 7. P + 8. T + 3. P + 1. P + 5. P + 1. A + 2. C + 3. D + 4. F + 5. M + 6. N + 7. Y + 6. S + 1. A + 1. A + 2. B + 3. E + 4. N + 5. O + 6. T + 2. L + 1. A + 2. H + 3. R + 3. M + 1. B + 1. C + 1. A + 2. B + 3. D + 4. E + 5. F + 6. L + 7. P + 8. R + 2. D + 1. D + 2. E + 3. I + 2. N + 1. B + 2. C + 3. D + 1. A + 2. B + 3. D + 4. E + 5. O + 6. P + 7. T + 4. E + 1. B + 2. C + 5. F + 6. L + 7. M + 8. R + 9. Z + 3. O + 1. A + 1. D + 1. C + 2. U + 2. O + 1. F + 2. M + 3. P + 3. R + 4. W + 2. B + 3. E + 1. B + 2. D + 3. F + 4. T + 4. F + 1. A + 2. D + 3. G + 4. S + 5. G + 1. B + 2. F + 3. L + 4. R + 5. Z + 6. M + 1. C + 2. D + 3. E + 4. P + 5. T + 6. U + 7. W + 7. R + 1. A + 2. C + 3. P + 4. S + 8. S + 9. T + 10. U + 11. W + 1. A + 2. C + 1. D + 2. S + 3. T + 3. D + 4. H + 5. L + 6. S + 7. U + 4. S + 1. E + 2. F + 3. L + 4. P + 5. S + 6. U + 7. W + 4. O + 1. B + 1. A + 2. E + 3. O + 4. T + 2. E + 1. D + 2. P + 3. V + 3. F + 1. A + 2. E + 3. O + 4. H + 1. I + 2. M + 3. N + 4. O + 5. S + 1. B + 1. M + 2. N + 3. W + 2. M + 3. S + 5. S + 1. A + 1. D + 2. E + 3. H + 4. R + 5. S + 1. B + 2. D + 3. R + 2. L + 1. C + 1. H + 2. M + 2. R + 1. A + 2. M + 3. O + 4. T + 5. W + 3. P + 1. A + 1. S + 2. T + 2. C + 3. D + 4. E + 5. I + 6. L + 7. M + 8. N + 9. O + 10. R + 11. S + 1. A + 2. B + 3. C + 4. D + 5. E + 6. F + 7. G + 8. H + 9. I + 10. J + 11. Z + 12. T + 13. U + 14. X + 15. Y + 6. T + 1. A + 1. S + 2. B + 3. C + 4. D + 5. E + 6. F + 7. H + 8. I + 9. J + 10. K + 1. F + 11. L + 12. M + 13. N + 14. O + 15. P + 16. Q + 17. R + 18. S + 19. T + 20. U + 1. C + 2. G + 3. S + 21. W + 1. P + 22. X + 23. Y + 24. Z +
+
+ 3. i
+ 1. v +
+
+ 4. l + 1. c + 1. b + 1. b + 2. c + 2. e + 1. d + 3. n + 1. n + 1. b + 2. sm + 2. r + 1. dd + 2. e + 1. h + 3. f + 1. a + 1. a + 2. c + 3. d + 4. f + 5. h + 6. p + 7. s + 8. w + 4. g + 5. h + 1. a + 2. am + 1. s + 6. i + 7. l + 1. l + 1. ad + 2. an + 1. or + 3. as + 4. av + 5. ba + 6. bt + 7. bur + 1. a + 1. d + 2. e + 3. i + 4. o + 5. p + 6. t + 7. x + 2. s + 1. c + 8. c + 1. a + 2. pc + 3. wf + 4. wi + 5. wr + 9. ca + 10. cd + 11. cr + 12. dc + 13. dov + 14. dp + 15. drp + 16. dui + 1. j + 17. dv + 18. ep + 19. hr + 1. wi + 2. wr + 20. hup + 1. a + 2. s + 21. ii + 22. io + 23. jo + 24. k + 25. l + 26. m + 27. mi + 28. mm + 29. mp + 30. od + 31. ph + 32. r + 1. sa + 33. rd + 34. rt + 35. s + 36. sc + 37. sd + 38. sg + 39. si + 40. so + 41. sp + 42. su + 43. sv + 44. te + 45. vt + 8. m + 9. o + 1. byp + 1. s + 1. 24 + 2. b + 3. f + 4. g + 5. sb + 6. zs + 2. can + 1. s + 3. clo + 1. s + 1. sm + 4. far + 1. s + 1. pa + 5. ftt + 1. s + 1. pn + 6. log + 1. s + 1. ad + 2. ap + 3. as + 4. cr + 5. ds + 6. er + 7. es + 8. pe + 9. px + 10. sa + 11. sr + 12. ss + 13. tr + 14. ua + 15. vx + 7. ltc + 1. s + 1. af + 8. lto + 1. s + 9. nul + 1. s + 1. p + 2. pr + 10. opn + 1. s + 1. a + 2. d + 3. e + 4. ex + 5. g + 6. k + 7. l + 8. qa + 9. r + 10. u + 11. up + 11. pan + 12. res + 1. s + 1. er + 13. spc + 1. a + 1. a + 2. e + 3. f + 4. g + 5. l + 6. w + 2. s + 1. f + 2. li + 14. sps + 1. a + 1. g + 2. s + 1. ar + 2. b1 + 3. b2 + 4. dd + 5. rr + 6. rx + 7. sr + 8. tr + 15. tam + 1. a + 2. s + 1. e + 2. p + 3. s + 4. v + 16. tbl + 1. a + 1. b + 2. c + 3. d + 4. ee + 5. l + 6. p + 7. u + 2. s + 1. a + 2. ar + 3. b + 4. b1 + 5. b2 + 6. bt + 7. c + 8. cf + 9. dc + 10. dh + 11. dl + 12. e + 13. e50 + 14. e90 + 15. em + 16. eo + 17. ft + 18. gf + 19. lb + 20. lo + 21. lp + 22. lr + 23. ls + 24. ms + 25. n + 26. o + 27. p + 28. pf + 29. pl + 30. pp + 31. ps + 32. ra + 33. rf + 34. rfb + 35. rr + 36. rs + 37. sh + 38. sl + 39. sp + 40. sr + 41. ss + 42. st + 43. t1 + 44. t2 + 45. ti + 46. tr + 47. x + 48. y + 17. tem + 1. a + 1. h + 2. l + 3. lh + 4. r + 18. tst + 1. s + 1. fa + 2. m + 3. pt + 4. st + 5. wm + 10. r + 11. s + 12. t + 1. v + 1. a + 1. c + 1. f + 2. n + 2. e + 3. f + 4. i + 5. j + 6. o + 7. or + 8. p + 2. o + 5. m + 1. g + 1. o + 2. p + 1. c + 1. cp + 2. ip + 2. m + 1. c + 3. s + 1. m + 2. p + 1. i + 2. loc + 3. op + 4. t + 5. v + 1. p + 1. i + 6. w + 3. r + 6. r + 1. h + 1. c + 2. I + 1. A + 1. S + 1. C + 1. C + 2. O + 3. P + 4. S + 2. R + 1. A + 1. I + 2. S + 2. C + 3. D + 4. E + 5. F + 6. I + 7. M + 1. A + 2. D + 3. F + 4. G + 5. T + 8. T + 1. A + 2. I + 3. T + 9. U + 2. G + 1. S + 1. C + 1. C + 2. O + 3. P + 4. S + 5. T + 2. R + 1. A + 1. A + 2. T + 2. B + 3. C + 1. A + 2. S + 4. D + 5. E + 6. F + 7. H + 8. I + 9. M + 1. A + 2. F + 3. G + 4. M + 5. T + 10. S + 11. T + 1. A + 2. I + 3. T + 12. U + 3. P + 1. S + 1. C + 1. D + 2. R + 1. D + 2. E + 3. I + 4. M + 5. S + 6. T + 7. U + 4. S + 1. S + 1. C + 1. C + 2. O + 3. P + 4. S + 2. R + 1. A + 1. A + 2. T + 2. C + 1. A + 2. I + 3. D + 4. E + 5. F + 6. H + 7. I + 8. M + 1. A + 2. F + 3. G + 4. M + 5. T + 9. S + 10. T + 1. A + 2. I + 3. T + 11. U + 5. U + 1. S + 1. C + 1. O + 2. P + 3. S + 2. R + 1. D + 2. E + 3. M + 4. S + 5. T + 6. U + 3. O + 1. I + 1. D + 2. F + 3. G + 4. I + 5. R + 6. S + 7. V + 2. L + 1. B + 2. G + 3. W + 3. O + 1. A + 2. D + 3. E + 4. F + 5. H + 1. A + 2. T + 3. V + 6. K + 7. M + 8. O + 9. P + 10. R + 1. C + 2. W + 11. S + 12. U + 13. Y + 1. H + 2. T + 3. W + 4. V + 1. A + 2. B + 3. D + 4. M + 5. P + 6. S + 7. Y + 7. w + 1. A + 1. C + 1. a + 2. b + 3. B + 4. c + 5. C + 6. O + 7. P + 8. S + 9. t + 10. W + 2. F + 1. I + 2. V + 3. I + 1. C + 1. L + 2. M + 3. S + 2. M + 1. L + 2. M + 3. S + 3. R + 1. L + 2. M + 3. S + 4. O + 1. B + 2. D + 3. F + 1. F + 4. H + 5. K + 6. S + 7. T + 5. P + 1. F + 1. C + 1. U + 2. O + 3. S + 4. W + 1. U + 2. H + 3. L + 4. X + 1. R + 2. S + 3. T + 6. R + 1. C + 2. H + 3. I + 4. R + 1. D + 1. F + 2. F + 3. S + 5. S + 1. G + 2. S + 7. S + 1. S + 1. H + 2. T + 2. T + 1. F + 2. L + 3. R + 8. t + 9. T + 1. E + 2. L + 3. M + 4. S + 10. W + 1. J + 2. O + 3. S + 8. x.* +
+
   <details>
+
+
    +
  1. c
      +
    1. c
    2. +
    3. f
        +
      1. d
      2. +
      3. i
      4. +
      +
    4. +
    5. l
        +
      1. f
      2. +
      +
    6. +
    7. r
    8. +
    9. s +
    10. +
    +
  2. +
  3. r
      +
    1. c
        +
      1. x
          +
        1. b
            +
          1. b
              +
            1. a
                +
              1. n
              2. +
              3. t
              4. +
              +
            2. +
            3. b
                +
              1. b
              2. +
              3. c
                  +
                1. a
                2. +
                3. b
                4. +
                +
              4. +
              5. p
                  +
                1. n
                2. +
                3. u
                4. +
                +
              6. +
              +
            4. +
            5. c
            6. +
            7. d
            8. +
            9. g
            10. +
            11. l
            12. +
            13. m
            14. +
            15. p
            16. +
            17. t
                +
              1. d
              2. +
              3. j
              4. +
              5. s
              6. +
              7. u
              8. +
              9. w
              10. +
              +
            18. +
            19. y
            20. +
            +
          2. +
          3. c
              +
            1. s
            2. +
            +
          4. +
          5. m
              +
            1. c
            2. +
            +
          6. +
          7. r
              +
            1. q
                +
              1. d
              2. +
              3. w
              4. +
              +
            2. +
            3. r
                +
              1. r
              2. +
              3. u
              4. +
              +
            4. +
            5. t
                +
              1. h
              2. +
              3. m
              4. +
              +
            6. +
            +
          8. +
          9. s
              +
            1. a
            2. +
            3. e
            4. +
            5. f
            6. +
            7. g
                +
              1. bg
              2. +
              3. bs
              4. +
              5. u
              6. +
              +
            8. +
            9. m
            10. +
            11. s
                +
              1. p
              2. +
              3. s
              4. +
              +
            12. +
            13. t
            14. +
            15. w
            16. +
            +
          10. +
          11. t
              +
            1. 3
            2. +
            3. a
            4. +
            5. b
                +
              1. x
              2. +
              3. xr
              4. +
              +
            6. +
            7. c
            8. +
            9. d
            10. +
            11. e
                +
              1. pg
              2. +
              3. uc
              4. +
              +
            12. +
            13. n
            14. +
            15. r
                +
              1. w
              2. +
              3. wa
              4. +
              +
            16. +
            17. s
                +
              1. s
              2. +
              3. t
              4. +
              +
            18. +
            19. t
            20. +
            21. v
            22. +
            23. y
            24. +
            +
          12. +
          13. v
              +
            1. e
                +
              1. e
                  +
                1. e
                2. +
                3. v
                    +
                  1. f
                  2. +
                  3. n
                  4. +
                  5. t
                  6. +
                  +
                4. +
                +
              2. +
              3. j
              4. +
              +
            2. +
            3. r
            4. +
            5. s
            6. +
            7. y
                +
              1. l
              2. +
              3. o
              4. +
              5. u
              6. +
              +
            8. +
            +
          14. +
          +
        2. +
        3. c
            +
          1. a
              +
            1. w
            2. +
            +
          2. +
          3. b
              +
            1. a
            2. +
            3. c
                +
              1. c
              2. +
              3. h
              4. +
              5. p
              6. +
              7. s
              8. +
              +
            4. +
            5. m
            6. +
            7. s
            8. +
            +
          4. +
          5. c
              +
            1. h
            2. +
            +
          6. +
          7. g
              +
            1. b
            2. +
            3. d
            4. +
            5. n
            6. +
            7. p
            8. +
            9. s
            10. +
            +
          8. +
          9. h
              +
            1. e
            2. +
            +
          10. +
          11. i
              +
            1. b
            2. +
            3. o
                +
              1. f
              2. +
              +
            4. +
            +
          12. +
          13. m
              +
            1. a
            2. +
            3. b
            4. +
            5. m
            6. +
            7. t
            8. +
            +
          14. +
          15. n
              +
            1. g
                +
              1. a
              2. +
              3. b
              4. +
              5. d
              6. +
              +
            2. +
            3. v
                +
              1. x
              2. +
              +
            4. +
            +
          16. +
          17. o
              +
            1. b
            2. +
            +
          18. +
          19. p
              +
            1. a
            2. +
            3. b
            4. +
            5. c
            6. +
            7. h
            8. +
            9. i
            10. +
            11. m
            12. +
            13. o
            14. +
            15. p
                +
              1. c
              2. +
              3. d
              4. +
              +
            16. +
            17. r
                +
              1. w
              2. +
              3. y
              4. +
              +
            18. +
            19. s
            20. +
            21. t
            22. +
            +
          20. +
          21. s
              +
            1. cx
            2. +
            3. l
                +
              1. hl
              2. +
              3. l
              4. +
              +
            4. +
            5. m
                +
              1. h
              2. +
              3. hd
              4. +
              5. hl
              6. +
              7. n
              8. +
              9. q
              10. +
              11. s
              12. +
              13. t
              14. +
              +
            6. +
            +
          22. +
          23. v
              +
            1. a +
            2. +
            +
          24. +
          +
        4. +
        +
      2. +
      +
    2. +
    +
  4. +
  5. t
      +
    1. a
        +
      1. c
      2. +
      3. d
      4. +
      5. e
      6. +
      7. k
      8. +
      9. r
      10. +
      11. s
      12. +
      +
    2. +
    3. k
        +
      1. d
      2. +
      3. i
      4. +
      5. t
      6. +
      +
    4. +
    5. m
    6. +
    7. p
        +
      1. a
          +
        1. c
        2. +
        3. f
        4. +
        5. k
        6. +
        +
      2. +
      3. k
          +
        1. d
        2. +
        3. i
        4. +
        5. t
        6. +
        +
      4. +
      5. r
      6. +
      7. s
          +
        1. i
        2. +
        +
      8. +
      +
    8. +
    9. q
    10. +
    11. r
    12. +
    13. s
        +
      1. b
      2. +
      3. i
          +
        1. e
        2. +
        3. i
        4. +
        +
      4. +
      5. r
      6. +
      7. v
          +
        1. e
        2. +
        3. i
        4. +
        +
      8. +
      +
    14. +
    15. u
        +
      1. q
      2. +
      3. z
      4. +
      +
    16. +
    17. x
        +
      1. a
          +
        1. f
        2. +
        3. o
        4. +
        5. s
            +
          1. c
          2. +
          +
        6. +
        +
      2. +
      3. i
          +
        1. l
        2. +
        +
      4. +
      5. m
          +
        1. c
            +
          1. l
          2. +
          3. k
              +
            1. u
            2. +
            3. c
            4. +
            +
          4. +
          5. m
          6. +
          7. n
          8. +
          9. e
          10. +
          +
        2. +
        +
      6. +
      7. v
          +
        1. m +
        2. +
        +
      8. +
      +
    18. +
    +
  6. +
  7. u
      +
    1. d
        +
      1. c
          +
        1. c
        2. +
        +
      2. +
      3. f
          +
        1. m
        2. +
        +
      4. +
      5. r
      6. +
      +
    2. +
    3. r
        +
      1. b
          +
        1. bullseye
        2. +
        3. c
            +
          1. c
          2. +
          +
        4. +
        +
      2. +
      +
    4. +
    5. rb
        +
      1. a
      2. +
      +
    6. +
    +
  8. +
  9. y
      +
    1. a
        +
      1. r
      2. +
      3. w
      4. +
      +
    2. +
    3. c
        +
      1. f
          +
        1. a
        2. +
        3. b
        4. +
        5. d
        6. +
        7. i
        8. +
        9. r
            +
          1. c
          2. +
          3. p
          4. +
          +
        10. +
        11. s
        12. +
        13. x
        14. +
        +
      2. +
      3. s
      4. +
      +
    4. +
    5. s
        +
      1. c
      2. +
      3. e
          +
        1. a
        2. +
        3. d
            +
          1. c
          2. +
          +
        4. +
        +
      4. +
      5. i
      6. +
      7. m
      8. +
      9. p
      10. +
      11. r + +
      12. +
      +
    6. +
    +
  10. +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/architecture/cot_table/index.html b/About/architecture/cot_table/index.html new file mode 100644 index 000000000..ed248d993 --- /dev/null +++ b/About/architecture/cot_table/index.html @@ -0,0 +1,30078 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Center On Target (CoT)

+

The following table combines Center On Target information found in COTTypes.XML, +aligning it to MIL-STD-2525 CIDC code (when possible). +To find more information read the MIL-STD-D-D-D-2525 documentation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
COTIDHierarchyNamenickname"ID"CIDCCategory1Category2Category3
a-.-.*-9-1-1Mayday messageMaydayMayday001Mayday message
a-.-AAir / Air TrackAir TrackAircraft002SA---------Air
a-.-A-CAir / CivCivil aircraftAircraft003SAC---------Air
a-.-A-C-FAir / Civ / fixedFixed wingFixed wing004S*ACF---------Air
a-.-A-C-F-qAir / Civ / fixed / RPV, drone, UAVFixed wing RPV / DroneFixed wing005SACF---------Air
a-.-A-C-HAir / Civ / rotaryRotary wingRotary wing006SACH---------Air
a-.-A-C-LAir / Civ / BlimpLighter than airAircraft007SACL---------Air
a-.-A-MAir / MilMilitary aircraftAircraft008SAM---------Air
a-.-A-M-FAir / Mil / FixedFixed wingFixed wing009SAMF---------Air
a-.-A-M-F-AAir / Mil / Fixed / Attack / StrikeAttack / strikeFixed wing010SAMFA---------Air
a-.-A-M-F-BAir / Mil / Fixed / BomberBomberBomber011SAMFB---------Air
a-.-A-M-F-CAir / Mil / Fixed / TransportCargo airlift (transport)Fixed wing012SAMFC---------Air
a-.-A-M-F-C-HAir / Mil / Fixed / Transport / HeavyCargo airlift (heavy)Fixed wing013SAMFCH---------Air
a-.-A-M-F-C-LAir / Mil / Fixed / Transport / LightCargo airlift (light)Fixed wing014SAMFCL---------Air
a-.-A-M-F-C-MAir / Mil / Fixed / Transport / MediumCargo airlift (medium)Fixed wing015SAMFCM---------Air
a-.-A-M-F-DAir / Mil / Fixed / C2Airborne command post (C2)Fixed wing016SAMFD---------Air
a-.-A-M-F-FAir / Mil / Fixed / FighterFighterFighter017SAMFF---------Air
a-.-A-M-F-F-IAir / Mil / Fixed / InterceptorInterceptorInterceptor018SAMFFI---------Air
a-.-A-M-F-gAir / Mil / Fixed / GunshipFixed wing gunshipFixed wing019SAMF---------Air
a-.-A-M-F-HAir / Mil / Fixed / CSARCombat search and rescue (CSAR)Fixed wing020SAMFH---------Air
a-.-A-M-F-JAir / Mil / Fixed / ECM / JammerElectronic countermeasures (ECM / jammer)Fixed wing021SAMFJ---------Air
a-.-A-M-F-KAir / Mil / Fixed / TankerTankerTanker022SAMFK---------Air
a-.-A-M-F-K-BAir / Mil / Fixed / Tanker / Boom-onlyBoom-onlyBoom-only023SAMFKB---------Air
a-.-A-M-F-K-DAir / Mil / Fixed / Tanker / Drogue-onlyDrogue-onlyDrogue-only024SAMFKD---------Air
a-.-A-M-F-LAir / Mil / Fixed / VSTOLVSTOLVSTOL025SAMFL---------Air
a-.-A-M-F-MAir / Mil / Fixed / SOFSpecial operations forces (SOF)Fixed wing026SAMFM---------Air
a-.-A-M-F-OAir / Mil / Fixed / medevacMedevacMedevac027SAMFO---------Air
a-.-A-M-F-PAir / Mil / Fixed / PatrolPatrolPatrol028SAMFP---------Air
a-.-A-M-F-P-MAir / Mil / Fixed / Mine CountermeasuresMine countermeasuresPatrol029SAMFPM---------Air
a-.-A-M-F-P-NAir / Mil / Fixed / ASUWAntisurface warfare / ASUWPatrol030SAMFPN---------Air
a-.-A-M-F-QAir / Mil / Fixed / Drone,RPV,UAVDrone (RPV / UAV)Fixed wing031SAMFQ---------Air
a-.-A-M-F-Q-AAir / Mil / Fixed / Drone,RPV,UAV / AttackAttackAttack032SAMFQA---------Air
a-.-A-M-F-Q-BAir / Mil / Fixed / Drone,RPV,UAV / BomberBomberBomber033SAMFQB---------Air
a-.-A-M-F-Q-CAir / Mil / Fixed / Drone,RPV,UAV / CargoCargoCargo034SAMFQC---------Air
a-.-A-M-F-Q-DAir / Mil / Fixed / Drone,RPV,UAV / Airborne command postAirborne command postFixed wing035SAMFQD---------Air
a-.-A-M-F-Q-FAir / Mil / Fixed / Drone,RPV,UAV / FighterFighterFighter036SAMFQF---------Air
a-.-A-M-F-Q-HAir / Mil / Fixed / Drone,RPV,UAV / Combat search & rescue (CSAR)Combat search & rescue (CSAR)CSAR037SAMFQH---------Air
a-.-A-M-F-Q-IAir / Mil / Fixed / Drone,RPV,UAV / Mine countermeasuresMine countermeasuresFixed wing038SAMFQI---------Air
a-.-A-M-F-Q-JAir / Mil / Fixed / Drone,RPV,UAV / Electronic countermeasures (jammer)Electronic countermeasures (jammer)Jammer039SAMFQJ---------Air
a-.-A-M-F-Q-KAir / Mil / Fixed / Drone,RPV,UAV / TankerTankerTanker040SAMFQK---------Air
a-.-A-M-F-Q-LAir / Mil / Fixed / Drone,RPV,UAV / VSTOLVSTOLVSTOL041SAMFQL---------Air
a-.-A-M-F-Q-MAir / Mil / Fixed / Drone,RPV,UAV / Special operations forces (SOF)Special operations forces (SOF)SOF042SAMFQM---------Air
a-.-A-M-F-Q-NAir / Mil / Fixed / Drone,RPV,UAV / Anti-surface warfare (ASUW)Anti-surface warfare (ASUW)Fixed wing043SAMFQN---------Air
a-.-A-M-F-Q-OAir / Mil / Fixed / Drone,RPV,UAV / MedevacMedevacMedevac044SAMFQO---------Air
a-.-A-M-F-Q-PAir / Mil / Fixed / Drone,RPV,UAV / PatrolPatrolPatrol045SAMFQP---------Air
a-.-A-M-F-Q-RAir / Mil / Fixed / Drone,RPV,UAV / ReconnaissanceReconnaissanceFixed wing046SAMFQR---------Air
a-.-A-M-F-Q-R-WAir / Mil / Fixed / Drone,RPV,UAV / Airborne early warning (AEW)Airborne early warning (AEW)Fixed wing047SAMFQRW---------Air
a-.-A-M-F-Q-R-XAir / Mil / Fixed / Drone,RPV,UAV / PhotographicPhotographicPhotographic048SAMFQRX---------Air
a-.-A-M-F-Q-R-ZAir / Mil / Fixed / Drone,RPV,UAV / Electronic surveillance measuresElectronic surveillance measuresFixed wing049SAMFQRZ---------Air
a-.-A-M-F-Q-SAir / Mil / Fixed / Drone,RPV,UAV / Anti-submarine warfare (ASW)Anti-submarine warfare (ASW)Fixed wing050SAMFQS---------Air
a-.-A-M-F-Q-TAir / Mil / Fixed / Drone,RPV,UAV / TrainerTrainerTrainer051SAMFQT---------Air
a-.-A-M-F-Q-UAir / Mil / Fixed / Drone,RPV,UAV / UtilityUtilityUtility052SAMFQU---------Air
a-.-A-M-F-Q-YAir / Mil / Fixed / Drone,RPV,UAV / Communications (C3I)Communications (C3I)Fixed wing053SAMFQY---------Air
a-.-A-M-F-RAir / Mil / Fixed / reconnReconnaissanceFixed wing054SAMFR---------Air
a-.-A-M-F-R-WAir / Mil / Fixed / AEWAirborne early warning (AEW)Fixed wing055SAMFRW---------Air
a-.-A-M-F-R-XAir / Mil / Fixed / PhotoPhotographicPhotographic056SAMFRX---------Air
a-.-A-M-F-R-ZAir / Mil / Fixed / esmElectronic surveillance measuresFixed wing057SAMFRZ---------Air
a-.-A-M-F-SAir / Mil / Fixed / ASW / Carrier BasedAntisubmarine warfare (ASW) carrier basedFixed wing058SAMFS---------Air
a-.-A-M-F-TAir / Mil / Fixed / TrainerTrainerTrainer059SAMFT---------Air
a-.-A-M-F-UAir / Mil / Fixed / UtilityUtilityUtility060SAMFU---------Air
a-.-A-M-F-U-HAir / Mil / Fixed / Utility / HeavyUtility (heavy)Utility061SAMFUH---------Air
a-.-A-M-F-U-LAir / Mil / Fixed / Utility / LightUtility (light)Utility062SAMFUL---------Air
a-.-A-M-F-U-MAir / Mil / Fixed / Utility / MediumUtility (medium)Utility063SAMFUM---------Air
a-.-A-M-F-YAir / Mil / Fixed / C3ICommunications (C3I)Fixed wing064SAMFY-----------------Air
a-.-A-M-HAir / Mil / RotorRotary wingRotary wing065SAMH---------Air
a-.-A-M-H-AAir / Mil / Rotor / AttackAttackAttack066SAMHA---------Air
a-.-A-M-H-CAir / Mil / Rotor / TransportCargo airlift (transport)Rotary wing067SAMHC---------Air
a-.-A-M-H-C-HAir / Mil / Rotor / Transport / HeavyCargo airlift (heavy)Rotary wing068SAMHCH---------Air
a-.-A-M-H-C-LAir / Mil / Rotor / Transport / LightCargo airlift (light)Rotary wing069SAMHCL---------Air
a-.-A-M-H-C-MAir / Mil / Rotor / Transport / MediumCargo airlift (medium)Rotary wing070SAMHCM---------Air
a-.-A-M-H-DAir / Mil / Rotor / C2Airborne command post (C2)Rotary wing071SAMHD---------Air
a-.-A-M-H-HAir / Mil / Rotor / CSARCombat search and rescue (CSAR)Rotary wing072SAMHH---------Air
a-.-A-M-H-IAir / Mil / Rotor / Mine CountermeasuresMine countermeasuresRotary wing073SAMHI---------Air
a-.-A-M-H-JAir / Mil / Rotor / ECM / JammerElectronic countermeasures (ECM / jammer)Rotary wing074SAMHJ---------Air
a-.-A-M-H-KAir / Mil / Rotor / TankerTankerTanker075SAMHK---------Air
a-.-A-M-H-MAir / Mil / Rotor / SOFSpecial operations forces (SOF)Rotary wing076SAMHM---------Air
a-.-A-M-H-OAir / Mil / Rotor / medevacMedevacMedevac077SAMHO---------Air
a-.-A-M-H-QAir / Mil / Rotor / Drone,RPV,UAVDrone (RPV / UAV)Rotary wing078SAMHQ---------Air
a-.-A-M-H-RAir / Mil / Rotor / ReconnaissanceReconnaissanceRotary wing079SAMHR---------Air
a-.-A-M-H-SAir / Mil / Rotor / ASW / MPAAntisubmarine warfare / MPARotary wing080SAMHS---------Air
a-.-A-M-H-TAir / Mil / Rotor / TrainerTrainerTrainer081SAMHT---------Air
a-.-A-M-H-UAir / Mil / Rotor / UtilityUtilityUtility082SAMHU---------Air
a-.-A-M-H-U-HAir / Mil / Rotor / Utility / Heavy)Utility (heavy)Utility083SAMHUH---------Air
a-.-A-M-H-U-LAir / Mil / Rotor / Utility / Light)Utility (light)Utility084SAMHUL---------Air
a-.-A-M-H-U-MAir / Mil / Rotor / Utility / Medium)Utility (medium)Utility085SAMHUM---------Air
a-.-A-M-LAir / Mil / BlimpLighter than airAircraft086SAML---------Air
a-.-A-WAir / WeaponWeaponWeapon087SAW---------Air
a-.-A-W-BAir / Weapon / bombBombBomb088SAWB---------Air
a-.-A-W-DAir / Weapon / DecoyDecoyDecoy089SAWD---------Air
a-.-A-W-MAir / Weapon / Missile In FlightMissile in flightWeapon090SAWM---------Air
a-.-A-W-M-AAir / Weapon / Missile / Air LaunchedAir launched missileWeapon091SAWMA---------Air
a-.-A-W-M-A-AAir / Weapon / Missile / Air To AirAir to air missile (AAM)Weapon092SAWMAA---------Air
a-.-A-W-M-A-PAir / Weapon / Missile / Air to spaceAir to space missileMissile093SAWMAP---------Air
a-.-A-W-M-A-SAir / Weapon / Missile / Air To SurfaceAir to surface missile (ASM)Weapon094SAWMAS---------Air
a-.-A-W-M-BAir / Weapon / Missile / Missile In Flight / ballisticBallistic missileMissile095SAWMB---------Air
a-.-A-W-M-C-MAir / Weapon / Missile / Missile In Flight / CruiseCruise missileMissile096SAWMCM---------Air
a-.-A-W-M-LAir / Weapon / Missile / Attack MissileLand attack missileWeapon097SAWML---------Air
a-.-A-W-M-SAir / Weapon / Missile / Land Launched MissileSurface / land launched missileWeapon098SAWMS---------Air
a-.-A-W-M-S-AAir / Weapon / Missile / SAMSurface to air missile (SAM)Weapon099SAWMSA---------Air
a-.-A-W-M-S-A-fAir / Weapon / Missile / SAM / FixedSiteSAM (FixedSite)Weapon100SAWMSA---------Air
a-.-A-W-M-S-A-iAir / Weapon / Missile / SAM / ManpadSAM (Manpad)SAM (Manpad)101SAWMSA---------Air
a-.-A-W-M-S-A-mAir / Weapon / Missile / SAM / MobileSAM (Mobile)SAM (Mobile)102SAWMSA---------Air
a-.-A-W-M-S-BAir / Weapon / Missile / Surface Launched Missile / ABMAnti-ballistic missile (ABM)Missile103SAWMSB---------Air
a-.-A-W-M-S-SAir / Weapon / Missile / Surface To Surface (SSM)Surface to surface missile (SSM)Weapon104SAWMSS---------Air
a-.-A-W-M-S-UAir / Weapon / Missile / Surface Launched MissileSurface to subsurface missileMissile105SAWMSU---------Air
a-.-A-W-M-UAir / Weapon / Missile / Subsurface To Surface (S / SSM)Subsurface to surface missile (S / SSM)Weapon106SAWMU---------Air
a-.-FSpecial Operations Forces (Sof) UnitSOF UnitSOF Unit107SF---------Special Operations Forces (Sof) Unit
a-.-F-ASpecial Operations Forces (Sof) Unit / AviationAviationAviation108SFA---------Special Operations Forces (Sof) Unit
a-.-F-A-FSpecial Operations Forces (Sof) Unit / Aviation / Fixed wingFixed wingFixed wing109SFAF---------Special Operations Forces (Sof) Unit
a-.-F-A-F-ASpecial Operations Forces (Sof) Unit / Aviation / AttackAttackAttack110SFAFA---------Special Operations Forces (Sof) Unit
a-.-F-A-F-KSpecial Operations Forces (Sof) Unit / Aviation / RefuelRefuelRefuel111SFAFK---------Special Operations Forces (Sof) Unit
a-.-F-A-F-USpecial Operations Forces (Sof) Unit / Aviation / UtilityUtilityUtility112SFAFU---------Special Operations Forces (Sof) Unit
a-.-F-A-F-U-HSpecial Operations Forces (Sof) Unit / Aviation / HeavyHeavyHeavy113SFAFUH---------Special Operations Forces (Sof) Unit
a-.-F-A-F-U-LSpecial Operations Forces (Sof) Unit / Aviation / LightLightLight114SFAFUL---------Special Operations Forces (Sof) Unit
a-.-F-A-F-U-MSpecial Operations Forces (Sof) Unit / Aviation / MediumMediumMedium115SFAFUM---------Special Operations Forces (Sof) Unit
a-.-F-A-HSpecial Operations Forces (Sof) Unit / RotaryRotary wingRotary wing116SFAH---------Special Operations Forces (Sof) Unit
a-.-F-A-H-ASpecial Operations Forces (Sof) Unit / Rotary / AttackAttackAttack117SFAHA---------Special Operations Forces (Sof) Unit
a-.-F-A-H-HSpecial Operations Forces (Sof) Unit / Rotary / Combat search and rescueCombat search and rescueRotary wing118SFAHH---------Special Operations Forces (Sof) Unit
a-.-F-A-H-USpecial Operations Forces (Sof) Unit / Rotary / UtilityUtilityUtility119SFAHU---------Special Operations Forces (Sof) Unit
a-.-F-A-H-U-HSpecial Operations Forces (Sof) Unit / Rotary / HeavyHeavyHeavy120SFAHUH---------Special Operations Forces (Sof) Unit
a-.-F-A-H-U-LSpecial Operations Forces (Sof) Unit / Rotary / LightLightLight121SFAHUL---------Special Operations Forces (Sof) Unit
a-.-F-A-H-U-MSpecial Operations Forces (Sof) Unit / Rotary / MediumMediumMedium122SFAHUM---------Special Operations Forces (Sof) Unit
a-.-F-A-VSpecial Operations Forces (Sof) Unit / VSTOLVSTOLVSTOL123SFAV---------Special Operations Forces (Sof) Unit
a-.-F-BSpecial Operations Forces (Sof) Unit / SupportSupportSupport124SFF*B--------------Special Operations Forces (Sof) Unit
a-.-F-GSpecial Operations Forces (Sof) Unit / GroundGroundGround125SFG---------Special Operations Forces (Sof) Unit
a-.-F-G-CSpecial Operations Forces (Sof) Unit / Ground / Civil affairsCivil affairsGround126SFGC---------Special Operations Forces (Sof) Unit
a-.-F-G-PSpecial Operations Forces (Sof) Unit / Ground / psyopPsychological operations (psyop)PSYOP127SFGP---------Special Operations Forces (Sof) Unit
a-.-F-G-P-ASpecial Operations Forces (Sof) Unit / Ground / Fixed wing aviationFixed wing aviationGround128SFGPA---------Special Operations Forces (Sof) Unit
a-.-F-G-RSpecial Operations Forces (Sof) Unit / Ground / RangerRangerRanger129SFGR---------Special Operations Forces (Sof) Unit
a-.-F-G-SSpecial Operations Forces (Sof) Unit / Ground / Special forcesSpecial forcesGround130SFGS---------Special Operations Forces (Sof) Unit
a-.-F-NSpecial Operations Forces (Sof) Unit / NavalNavalNaval131SFN--------------Special Operations Forces (Sof) Unit
a-.-F-N-BSpecial Operations Forces (Sof) Unit / NavalSpecial boatSpecial boat132SFNB---------Special Operations Forces (Sof) Unit
a-.-F-N-NSpecial Operations Forces (Sof) Unit / Naval / Special boatSpecial ssnrSpecial SSNR133SFNN---------Special Operations Forces (Sof) Unit
a-.-F-N-SSpecial Operations Forces (Sof) Unit / Naval / SEALSEALSEAL134SFNS---------Special Operations Forces (Sof) Unit
a-.-F-N-USpecial Operations Forces (Sof) Unit / Naval / Underwater demolition teamUnderwater demolition teamNaval135SFNU---------Special Operations Forces (Sof) Unit
a-.-GGroundGround trackGround136SG---------Ground
a-.-G-EGnd / EquipmentEquipmentEquipment137SGE---------Gnd
a-.-G-E-SGnd / Equip / SensorSensorSensor138SGES---------Gnd
a-.-G-E-S-EGnd / Equip / Sensor / EmplacedEmplaced sensorSensor139SGESE---------Gnd
a-.-G-E-S-RGnd / Equip / Sensor / RadarRadarRadar140SGESR---------Gnd
a-.-G-E-VGnd / Equip / VehicleGround vehicleVehicle141SGEV---------Gnd
a-.-G-E-V-AGnd / Equip / Vehicle / Armor / GunArmor (gun)Armor (gun)142SGEVA---------Gnd
a-.-G-E-V-A-AGnd / Equip / Vehic / Armor / APCArmor (APC)Armor (APC)143SGEVAA---------Gnd
a-.-G-E-V-A-A-RGnd / Equip / Vehic / Armor / APC / RecoveryArmored personnel carrier recoveryArmor (APC)144SGEVAAR---------GndRecovery
a-.-G-E-V-A-CGnd / Equip / Vehic / Armor / C2V / ACVC2V / ACVC2V / ACV145SGEVAC---------GndACV
a-.-G-E-V-A-IGnd / Equip / Vehic / Armor / InfantryArmored infantryArmor (gun)146SGEVAI---------Gnd
a-.-G-E-V-A-LGnd / Equip / Vehic / Armor / LightLight armored vehicleArmor (gun)147SGEVAL---------Gnd
a-.-G-E-V-A-SGnd / Equip / Vehic / Armor / Combat Service SupportCombat service support vehicleArmor (gun)148SGEVAS---------Gnd
a-.-G-E-V-A-TGnd / Equip / Vehic / Armor / TankTankTank149SGEVAT---------Gnd
a-.-G-E-V-A-T-HGnd / Equip / Vehic / Armor / Tank / HeavyTank heavyTank heavy150SGEVATH---------GndHeavy
a-.-G-E-V-A-T-H-RGnd / Equip / Vehic / Armor / Tank / Heavy / RecoveryTank heavy recoveryTank heavy151SGEVATHR---------GndHeavyRecovery
a-.-G-E-V-A-T-LGnd / Equip / Vehic / Armor / Tank / LightTank lightTank light152SGEVATL---------GndLight
a-.-G-E-V-A-T-L-RGnd / Equip / Vehic / Armor / Tank / Light / RecoveryTank light recoveryTank light153SGEVATLR---------GndLightRecovery
a-.-G-E-V-A-T-MGnd / Equip / Vehic / Armor / Tank / MediumTank mediumTank medium154SGEVATM---------GndMedium
a-.-G-E-V-A-T-M-RGnd / Equip / Vehic / Armor / Tank / Medium / RecoveryTank medium recoveryTank medium155SGEVATMR---------GndMediumRecovery
a-.-G-E-V-CGnd / Equip / Vehic / CivilianCivilian vehicleEquipment156SGEVC---------Gnd
a-.-G-E-V-C-AGnd / Equip / Vehic / Civilian / AutomobileAutomobileAutomobile157SGEVCA---------Gnd
a-.-G-E-V-C-A-HGnd / Equip / Vehic / Civilian / Automobile / SedanSedanSedan158SGEVCAH---------GndSedan
a-.-G-E-V-C-A-LGnd / Equip / Vehic / Civilian / Automobile / CompactCompactCompact159SGEVCAL---------GndCompact
a-.-G-E-V-C-A-MGnd / Equip / Vehic / Civilian / Automobile / MidsizeMidsizeMidsize160SGEVCAM---------GndMidsize
a-.-G-E-V-C-FGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Flatbed TrailerTractor trailer truck with flatbed trailerFlatbed161SGEVCF---------Gnd
a-.-G-E-V-C-F-HGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Flatbed Trailer / LargeLarge heavy flatbed trailerEquipment162SGEVCFH---------GndLarge
a-.-G-E-V-C-F-LGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Flatbed Trailer / LightSmall light flatbed trailerEquipment163SGEVCFL---------GndLight
a-.-G-E-V-C-F-MGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Flatbed Trailer / MediumMedium flatbed trailerEquipment164SGEVCFM---------GndMedium
a-.-G-E-V-C-JGnd / Equip / Vehic / Civilian / JeepJeep type vehicleJeep165SGEVCJ---------Gnd
a-.-G-E-V-C-J-HGnd / Equip / Vehic / Civilian / Jeep / Large heavyLarge heavyLarge heavy166SGEVCJH---------GndLarge heavy
a-.-G-E-V-C-J-LGnd / Equip / Vehic / Civilian / Jeep / SmallSmall lightSmall light167SGEVCJL---------GndSmall
a-.-G-E-V-C-J-MGnd / Equip / Vehic / Civilian / Jeep / MediumMediumMedium168SGEVCJM---------GndMedium
a-.-G-E-V-C-MGnd / Equip / Vehic / Civilian / BusMulti-passenger vehicleEquipment169SGEVCM---------Gnd
a-.-G-E-V-C-M-HGnd / Equip / Vehic / Civilian / Bus / LargeLarge busLarge bus170SGEVCMH---------GndLarge
a-.-G-E-V-C-M-LGnd / Equip / Vehic / Civilian / Bus / VanVanVan171SGEVCML---------GndVan
a-.-G-E-V-C-M-MGnd / Equip / Vehic / Civilian / Bus / smallSmall busSmall bus172SGEVCMM---------Gndsmall
a-.-G-E-V-C-OGnd / Equip / Vehic / Civilian / Open-Bed TruckOpen-bed truckTruck173SGEVCO---------Gnd
a-.-G-E-V-C-O-HGnd / Equip / Vehic / Civilian / Open-Bed Truck / LargeLarge open-bed truckEquipment174SGEVCOH---------GndLarge
a-.-G-E-V-C-O-LGnd / Equip / Vehic / Civilian / Open-Bed Truck / Pickup Open-Bed TruckPickup truckPickup truck175SGEVCOL---------GndPickup Open-Bed Truck
a-.-G-E-V-C-O-MGnd / Equip / Vehic / Civilian / Open-Bed Truck / SmallSmall open-bed truckEquipment176SGEVCOM---------GndSmall
a-.-G-E-V-C-TGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Box TrailerTractor trailer truck with box trailerBox truck177SGEVCT---------Gnd
a-.-G-E-V-C-T-HGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Box Trailer / LargeLarge heavy box trailerEquipment178SGEVCTH---------GndLarge
a-.-G-E-V-C-T-LGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Box Trailer / LightSmall light box trailerEquipment179SGEVCTL---------GndLight
a-.-G-E-V-C-T-MGnd / Equip / Vehic / Civilian / Tractor Trailer Truck With Box Trailer / MediumMedium box trailerEquipment180SGEVCTM---------GndMedium
a-.-G-E-V-C-UGnd / Equip / Vehic / Civilian / Utility vehicleUtility vehicleEquipment181SGEVCU---------Gnd
a-.-G-E-V-C-U-HGnd / Equip / Vehic / Civilian / Utility vehicle / Large box truckLarge box truckEquipment182SGEVCUH---------GndLarge box truck
a-.-G-E-V-C-U-LGnd / Equip / Vehic / Civilian / Utility vehicle / SUVSport utility vehicle (SUV)Equipment183SGEVCUL---------GndSUV
a-.-G-E-V-C-U-MGnd / Equip / Vehic / Civilian / Utility vehicle / Small box truckSmall box truckEquipment184SGEVCUM---------GndSmall box truck
a-.-G-E-V-EGnd / Equip / Vehic / EngineerEngineer vehicleEquipment185SGEVE---------Gnd
a-.-G-E-V-E-AGnd / Equip / Vehic / Mine Clearing VehicleMine clearing vehicleEquipment186SGEVEA---------Gnd
a-.-G-E-V-E-A-AGnd / Equip / Vehic / Armored Mounted Mine Clearing VehicleArmored mounted mine clearing vehicleEquipment187SGEVEAA---------Gnd
a-.-G-E-V-E-A-TGnd / Equip / Vehic / Trailer Mounted Mine Clearing VehicleTrailer mounted mine clearing vehicleEquipment188SGEVEAT---------Gnd
a-.-G-E-V-E-BGnd / Equip / Vehic / BridgeBridgeBridge189SGEVEB---------Gnd
a-.-G-E-V-E-CGnd / Equip / Vehic / ConstructionConstruction vehicleEquipment190SGEVEC---------Gnd
a-.-G-E-V-E-DGnd / Equip / Vehic / DozerDozerDozer191SGEVED---------Gnd
a-.-G-E-V-E-D-AGnd / Equip / Vehic / Engineer / Armored dozerArmored dozerDozer192SGEVEDA---------Gnd
a-.-G-E-V-E-EGnd / Equip / Vehic / EarthmoverEarthmoverEarthmover193SGEVEE---------Gnd
a-.-G-E-V-E-FGnd / Equip / Vehic / Engineer / Ferry TransporterFerry transporterFerry194SGEVEF---------Gnd
a-.-G-E-V-E-HGnd / Equip / Vehic / Engineer / BackhoeBackhoeBackhoe195SGEVEH---------Gnd
a-.-G-E-V-E-MGnd / Equip / Vehic / Mine Laying VehicleMine laying vehicleEquipment196SGEVEM---------Gnd
a-.-G-E-V-E-M-LGnd / Equip / Vehic / Truck Mounted With VolcanoTruck mounted with volcanoEquipment197SGEVEML---------Gnd
a-.-G-E-V-E-M-VGnd / Equip / Vehic / Armored Carrier With VolcanoArmored carrier with volcanoEquipment198SGEVEMV---------Gnd
a-.-G-E-V-E-RGnd / Equip / Vehic / Engineer / Armored engineer recon vehicle (AERV)Armored engineer recon vehicle (AERV)AERV199SGEVER---------Gnd
a-.-G-E-V-E-SGnd / Equip / Vehic / Engineer / Armored assaultArmored assaultEquipment200SGEVES---------Gnd
a-.-G-E-V-mGnd / Equip / Vehic / AmbulanceAmbulanceAmbulance201SGEV---------Gnd
a-.-G-E-V-MGnd / Equip / Vehic / Pack animal(s)Pack animal(s)Pack animal202SGEVM---------Gnd
a-.-G-E-V-SGnd / Equip / Vehic / Missile supportMissile supportEquipment203SGEVS---------Gnd
a-.-G-E-V-S-CGnd / Equip / Vehic / Crane loading deviceCrane loading deviceCrane204SGEVSC---------Gnd
a-.-G-E-V-S-PGnd / Equip / Vehic / Propellant transporterPropellant transporterEquipment205SGEVSP---------Gnd
a-.-G-E-V-S-RGnd / Equip / Vehic / TransloaderTransporterTransporter206SGEVSR---------Gnd
a-.-G-E-V-S-TGnd / Equip / Vehic / TransloaderTransloaderTransloader207SGEVST---------Gnd
a-.-G-E-V-S-WGnd / Equip / Vehic / Warhead transporterWarhead transporterEquipment208SGEVSW---------Gnd
a-.-G-E-V-TGnd / Equip / Vehic / LocomotiveLocomotiveLocomotive209SGEVT---------Gnd
a-.-G-E-V-UGnd / Equip / Vehic / UtilityUtility vehicleEquipment210SGEVU---------Gnd
a-.-G-E-V-U-AGnd / Equip / Vehic / Utility / AmbulanceAmbulanceAmbulance211SGEVUA---------Gnd
a-.-G-E-V-U-A-AGnd / Equip / Vehic / Utility / Armored utility vehicleArmored utility vehicleAmbulance212SGEVUAA---------Gnd
a-.-G-E-V-U-BGnd / Equip / Vehic / BusBusBus213SGEVUB---------Gnd
a-.-G-E-V-U-LGnd / Equip / Vehic / Limited Cross Country TruckLimited cross country truckEquipment214SGEVUL---------Gnd
a-.-G-E-V-U-RGnd / Equip / Vehic / BoatWater craftWater craft215SGEVUR---------Gnd
a-.-G-E-V-U-R-lGnd / Equip / Vehic / Boat / LargeBoat (Large)Boat (Large)216SGEVUR---------Gnd
a-.-G-E-V-U-R-mGnd / Equip / Vehic / Boat / MedBoat (Med)Boat (Med)217SGEVUR---------Gnd
a-.-G-E-V-U-R-sGnd / Equip / Vehic / Boat / SmallBoat (Small)Boat (Small)218SGEVUR---------Gnd
a-.-G-E-V-U-SGnd / Equip / Vehic / SemiSemiSemi219SGEVUS---------Gnd
a-.-G-E-V-U-S-HGnd / Equip / Vehic / Semi / Heavy semiHeavy semiHeavy semi220SGEVUSH---------Gnd
a-.-G-E-V-U-S-LGnd / Equip / Vehic / Semi / Light semiLight semiLight semi221SGEVUSL---------Gnd
a-.-G-E-V-U-S-MGnd / Equip / Vehic / Semi / Medium semiMedium semiMedium semi222SGEVUSM---------Gnd
a-.-G-E-V-U-TGnd / Equip / Vehic / Tow TruckTow truckTow truck223SGEVUT---------Gnd
a-.-G-E-V-U-T-HGnd / Equip / Vehic / Tow Truck / heavyHeavy tow truckTow truck224SGEVUTH---------Gnd
a-.-G-E-V-U-T-LGnd / Equip / Vehic / Tow Truck / LightLight tow truckTow truck225SGEVUTL---------Gnd
a-.-G-E-V-U-XGnd / Equip / Vehic / Cross Country TruckCross country truckEquipment226SGEVUX---------Gnd
a-.-G-E-WGnd / Equip / WeaponWeaponWeapon227SGEW---------Gnd
a-.-G-E-W-AGnd / Equip / Weapon / Air Defense GunAir defense gunWeapon228SGEWA---------Gnd
a-.-G-E-W-A-HGnd / Equip / Weapon / AAA / HeavyAAA (Heavy)AAA (Heavy)229SGEWAH---------Gnd
a-.-G-E-W-A-LGnd / Equip / Weapon / AAA / LightAAA (Light)AAA (Light)230SGEWAL---------Gnd
a-.-G-E-W-A-MGnd / Equip / Weapon / AAA / MediumAAA (Medium)AAA (Medium)231SGEWAM---------Gnd
a-.-G-E-W-DGnd / Equip / Weapon / DirectFire /Direct fire gunWeapon232SGEWD---------Gnd
a-.-G-E-W-D-HGnd / Equip / Weapon / DirectFire / HeavyDirect fire gun heavyWeapon233SGEWDH---------Gnd
a-.-G-E-W-D-H-SGnd / Equip / Weapon / DirectFire / Heavy / Self PropelledDirect fire gun heavy self propelledWeapon234SGEWDHS---------GndSelf Propelled
a-.-G-E-W-D-LGnd / Equip / Weapon / DirectFire / LightDirect fire gun lightWeapon235SGEWDL---------Gnd
a-.-G-E-W-D-L-SGnd / Equip / Weapon / DirectFire / Light / Self PropelledDirect fire gun light self propelledWeapon236SGEWDLS---------GndSelf Propelled
a-.-G-E-W-D-MGnd / Equip / Weapon / DirectFire / MediumDirect fire gun mediumWeapon237SGEWDM---------Gnd
a-.-G-E-W-D-M-SGnd / Equip / Weapon / DirectFire / Medium / Self PropelledDirect fire gun medium self propelledWeapon238SGEWDMS---------GndSelf Propelled
a-.-G-E-W-GGnd / Equip / Weapon / AnitTankGunAnti tank gunWeapon239SGEWG---------Gnd
a-.-G-E-W-G-HGnd / Equip / Weapon / Atg / HeavyAnti tank gun heavyWeapon240SGEWGH---------Gnd
a-.-G-E-W-G-LGnd / Equip / Weapon / Atg / LightAnti tank gun lightWeapon241SGEWGL---------Gnd
a-.-G-E-W-G-MGnd / Equip / Weapon / Atg / MediumAnti tank gun mediumWeapon242SGEWGM---------Gnd
a-.-G-E-W-G-RGnd / Equip / Weapon / Atg / RecoillessAnti tank gun recoillessWeapon243SGEWGR---------Gnd
a-.-G-E-W-HGnd / Equip / Weapon / HowitzerHowitzerHowitzer244SGEWH---------Gnd
a-.-G-E-W-H-HGnd / Equip / Weapon / Howitzer / HeavyHowitzer heavyHowitzer245SGEWHH---------Gnd
a-.-G-E-W-H-H-SGnd / Equip / Weapon / Howitzer / Heavy / Self PropelledHowitzer heavy self propelledHowitzer246SGEWHHS---------GndSelf Propelled
a-.-G-E-W-H-LGnd / Equip / Weapon / Howitzer / LightHowitzer lightHowitzer247SGEWHL---------Gnd
a-.-G-E-W-H-L-SGnd / Equip / Weapon / Howitzer / Light / Self PropelledHowitzer light self propelledHowitzer248SGEWHLS---------GndSelf Propelled
a-.-G-E-W-H-MGnd / Equip / Weapon / Howitzer / MediumHowitzer mediumHowitzer249SGEWHM---------Gnd
a-.-G-E-W-H-M-SGnd / Equip / Weapon / Howitzer / Medium / Self PropelledHowitzer medium self propelledHowitzer250SGEWHMS---------GndSelf Propelled
a-.-G-E-W-MGnd / Equip / Weapon / MissileLauncherMissile launcherWeapon251SGEWM---------Gnd
a-.-G-E-W-M-AGnd / Equip / Weapon / MissileLauncher / AD / Air DefenseAir defense (AD) missile launcherWeapon252SGEWMA---------GndAir Defense
a-.-G-E-W-M-A-IGnd / Equip / Weapon / MissileLauncher / AD / Intermediate RangeIntermediate range AD missile launcherWeapon253SGEWMAI---------GndIntermediate Range
a-.-G-E-W-M-A-I-EGnd / Equip / Weapon / MissileLauncher / AD / Intermediate Range / Transporter Erector Launcher And Radar (Telar)Int. range AD missile launcher TELARWeapon254SGEWMAIE---------GndIntermediate RangeTransporter Erector Launcher And Radar (Telar)
a-.-G-E-W-M-A-I-RGnd / Equip / Weapon / MissileLauncher / AD / Intermediate Range /Int. range AD missile launcher TLARWeapon255SGEWMAIR---------GndIntermediate Range
a-.-G-E-W-M-A-LGnd / Equip / Weapon / MissileLauncher / AD / Long RangeLong range AD missile launcherWeapon256SGEWMAL---------GndLong Range
a-.-G-E-W-M-A-L-EGnd / Equip / Weapon / MissileLauncher / AD / Long Range / Transporter Erector Launcher And Radar (Telar)Long range AD missile launcher TELARWeapon257SGEWMALE---------GndLong RangeTransporter Erector Launcher And Radar (Telar)
a-.-G-E-W-M-A-L-RGnd / Equip / Weapon / MissileLauncher / AD / Long Range / Transporter Launcher And Radar (Tlar)Long range AD missile launcher TLARWeapon258SGEWMALR---------GndLong RangeTransporter Launcher And Radar (Tlar)
a-.-G-E-W-M-A-SGnd / Equip / Weapon / MissileLauncher / AD / Short RangeShort range AD missile launcherWeapon259SGEWMAS---------GndShort Range
a-.-G-E-W-M-A-S-EGnd / Equip / Weapon / MissileLauncher / AD / Short Range / TELARShort range AD missile launcher TELARWeapon260SGEWMASE---------GndShort RangeTELAR
a-.-G-E-W-M-A-S-RGnd / Equip / Weapon / MissileLauncher / AD / Short Range / TLARShort range AD missile launcher TLARWeapon261SGEWMASR---------GndShort RangeTLAR
a-.-G-E-W-M-A-TGnd / Equip / Weapon / MissileLauncher / AD / TheaterAD missile launcher theaterWeapon262SGEWMAT---------GndTheater
a-.-G-E-W-M-A-T-EGnd / Equip / Weapon / MissileLauncher / AD / Theater / TELARAD missile launcher theater TELARWeapon263SGEWMATE---------GndTheaterTELAR
a-.-G-E-W-M-A-T-RGnd / Equip / Weapon / MissileLauncher / AD / Theater / TLARAD missile launcher theater TLARWeapon264SGEWMATR---------GndTheaterTLAR
a-.-G-E-W-M-SGnd / Equip / Weapon / MissileLauncher / SS / Surface Surf (SS)Surf surf (SS) missile launcherWeapon265SGEWMS---------GndSurface Surf (SS)
a-.-G-E-W-M-S-IGnd / Equip / Weapon / MissileLauncher / SS / Intermediate RangeIntermediate range SS missile launcherWeapon266SGEWMSI---------GndIntermediate Range
a-.-G-E-W-M-S-LGnd / Equip / Weapon / MissileLauncher / SS / Long RangeLong range SS missile launcherWeapon267SGEWMSL---------GndLong Range
a-.-G-E-W-M-S-SGnd / Equip / Weapon / MissileLauncher / SS / Short RangeShort range SS missile launcherWeapon268SGEWMSS---------GndShort Range
a-.-G-E-W-M-TGnd / Equip / Weapon / MissileLauncher / AT / AntitankMissile launcher antitank (AT)Weapon269SGEWMT---------GndAntitank
a-.-G-E-W-M-T-HGnd / Equip / Weapon / MissileLauncher / AT / HeavyMissile launcher AT heavyWeapon270SGEWMTH---------GndHeavy
a-.-G-E-W-M-T-LGnd / Equip / Weapon / MissileLauncher / AT / LightMissile launcher AT lightWeapon271SGEWMTL---------GndLight
a-.-G-E-W-M-T-MGnd / Equip / Weapon / MissileLauncher / AT / MediumMissile launcher AT mediumWeapon272SGEWMTM---------GndMedium
a-.-G-E-W-OGnd / Equip / Weapon / MortarMortarMortar273SGEWO---------Gnd
a-.-G-E-W-O-HGnd / Equip / Weapon / Mortar / HeavyMortar heavyMortar heavy274SGEWOH---------Gnd
a-.-G-E-W-O-LGnd / Equip / Weapon / Mortar / LightMortar lightMortar light275SGEWOL---------Gnd
a-.-G-E-W-O-MGnd / Equip / Weapon / Mortar / MediumMortar mediumMortar276SGEWOM---------Gnd
a-.-G-E-W-RGnd / Equip / Weapon / Rifle / Automatic WeaponRifle / automatic weaponWeapon277SGEWR---------Gnd
a-.-G-E-W-R-HGnd / Equip / Weapon / Rifle / Heavy Machine GunHeavy machine gunWeapon278SGEWRH---------Gnd
a-.-G-E-W-R-LGnd / Equip / Weapon / Rifle / Light Machine GunLight machine gunWeapon279SGEWRL---------Gnd
a-.-G-E-W-R-RGnd / Equip / Weapon / Rifle / RifleRifleRifle280SGEWRR---------Gnd
a-.-G-E-W-SGnd / Equip / Weapon / RocketLauncher / Single /Single rocket launcherWeapon281SGEWS---------Gnd
a-.-G-E-W-S-HGnd / Equip / Weapon / RocketLauncher / Single / HeavySingle rocket launcher heavyWeapon282SGEWSH---------GndHeavy
a-.-G-E-W-S-LGnd / Equip / Weapon / RocketLauncher / Single / LightSingle rocket launcher lightWeapon283SGEWSL---------GndLight
a-.-G-E-W-S-MGnd / Equip / Weapon / RocketLauncher / Single / MediumSingle rocket launcher mediumWeapon284SGEWSM---------GndMedium
a-.-G-E-W-TGnd / Equip / Weapon / RocketLauncher / AntiTankAnti tank rocket launcherWeapon285SGEWT---------Gnd
a-.-G-E-W-T-HGnd / Equip / Weapon / RocketLauncher / AT / HeavyAnti tank rocket launcher heavyWeapon286SGEWTH---------GndHeavy
a-.-G-E-W-T-LGnd / Equip / Weapon / RocketLauncher / AT / LightAnti tank rocket launcher lightWeapon287SGEWTL---------GndLight
a-.-G-E-W-T-MGnd / Equip / Weapon / RocketLauncher / AT / MediumAnti tank rocket launcher mediumWeapon288SGEWTM---------GndMedium
a-.-G-E-W-XGnd / Equip / Weapon / RocketLauncher / MultipleMultiple rocket launcherWeapon289SGEWX---------Gnd
a-.-G-E-W-X-HGnd / Equip / Weapon / RocketLauncher / Multiple / HeavyMultiple rocket launcher heavyWeapon290SGEWXH---------GndHeavy
a-.-G-E-W-X-LGnd / Equip / Weapon / RocketLauncher / Multiple / LightMultiple rocket launcher lightWeapon291SGEWXL---------GndLight
a-.-G-E-W-X-MGnd / Equip / Weapon / RocketLauncher / Multiple / MediumMultiple rocket launcher mediumWeapon292SGEWXM---------GndMedium
a-.-G-E-W-ZGnd / Equip / Weapon / Grenade LauncherGrenade launcherWeapon293SGEWZ---------Gnd
a-.-G-E-W-Z-HGnd / Equip / Weapon / Grenade Launcher / HeavyGrenade launcher heavyWeapon294SGEWZH---------Gnd
a-.-G-E-W-Z-LGnd / Equip / Weapon / Grenade Launcher / LightGrenade launcher lightWeapon295SGEWZL---------Gnd
a-.-G-E-W-Z-MGnd / Equip / Weapon / Grenade Launcher / MediumGrenade launcher mediumWeapon296SGEWZM---------Gnd
a-.-G-E-XGnd / Equip / Special EquipmentSpecial equipmentEquipment297SGEX---------Gnd
a-.-G-E-X-FGnd / Equip / Flame ThrowerFlame throwerEquipment298SGEXF---------Gnd
a-.-G-E-X-LGnd / Equip / LaserLaserLaser299SGEXL---------Gnd
a-.-G-E-X-MGnd / Equip / Land MinesLand minesMine300SGEXM---------Gnd
a-.-G-E-X-M-CGnd / Equip / ClaymoreClaymoreClaymore301SGEXMC---------Gnd
a-.-G-E-X-M-LGnd / Equip / Less Than LethalLess than lethalLand mines302SGEXML---------Gnd
a-.-G-E-X-NGnd / Equip / NBC EquipmentNBC equipmentEquipment303SGEXN---------Gnd
a-.-G-IGnd / BuildingBuildingBuilding304SGI---------Gnd
a-.-G-I-BGnd / Structure / Base / MilitaryMilitary base / facilityBuilding305SGIB---------Gnd
a-.-G-I-B-AGnd / Structure / Base / AirbaseAirport / airbaseBuilding306SGIBA---------Gnd
a-.-G-I-B-NGnd / Structure / Base / Naval BaseSeaport / naval baseBuilding307SGIBN---------Gnd
a-.-G-I-cGnd / Structure / CivilianCivilianCivilian308SGI---------Gnd
a-.-G-I-c-bGnd / Structure / Civilian / BridgeBridgeBridge309SGI---------Gnd
a-.-G-I-c-barGnd / Structure / Civilian / Fence or Wall or BarrierFence / Wall / BarrierCivilian310SGI---------Gnd
a-.-G-I-c-canGnd / Structure / Civilian / CanalCanalCanal311SGI---------Gnd
a-.-G-I-c-can-lGnd / Structure / Civilian / Canal / LockCanal LockCanal Lock312SGI---------Gnd
a-.-G-I-c-frmGnd / Structure / Civilian / FarmFarmFarm313SGI---------Gnd
a-.-G-I-c-lGnd / Structure / Civilian / LeveeLevyLevy314SGI---------Gnd
a-.-G-I-c-monGnd / Structure / Civilian / MonumentMonumentMonument315SGI---------Gnd
a-.-G-I-c-oGnd / Structure / Civilian / OfficesOfficesOffices316SGI---------Gnd
a-.-G-I-c-rahGnd / Structure / Civilian / Residence or Apartment or HotelResidence / Apartment / HotelCivilian317SGI---------Gnd
a-.-G-I-c-relGnd / Structure / Civilian / ReligiousReligiousReligious318SGI---------Gnd
a-.-G-I-c-resGnd / Structure / Civilian / ReservoirReservoirReservoir319SGI---------Gnd
a-.-G-I-c-retGnd / Structure / Civilian / RetailRetailRetail320SGI---------Gnd
a-.-G-I-c-schGnd / Structure / Civilian / SchoolSchoolSchool321SGI---------Gnd
a-.-G-I-c-vipGnd / Structure / Civilian / vipVipVip322SGI---------Gnd
a-.-G-I-c-whsGnd / Structure / Civilian / WarehouseWarehouseWarehouse323SGI---------Gnd
a-.-G-I-EGnd / Structure / FactoryEquipment manufactureBuilding324SGIE---------Gnd
a-.-G-I-E-hGnd / Structure / Factory / HeavyHeavyHeavy325SGIE---------Gnd
a-.-G-I-E-lGnd / Structure / Factory / LightLightLight326SGIE---------Gnd
a-.-G-I-E-oGnd / Structure / Factory / Plant OtherPlant OtherPlant Other327SGIE---------Gnd
a-.-G-I-GGnd / Structure / GovernmentGovernment leadershipBuilding328SGIG---------Gnd
a-.-G-I-iGnd / Structure / IM FacilitiesIM FacilitiesBuilding329SGI---------Gnd
a-.-G-I-i-eGnd / Structure / IM Facilities / Emergency ManagementEmergency ManagementBuilding330SGI---------Gnd
a-.-G-I-i-e-EOCGnd / Structure / IM Facilities / Emergency Management / Emergency Operations CenterEmergency Operations CenterBuilding331EOBF----H****---------Gnd
a-.-G-I-i-e-icGnd / Structure / IM Facilities / Emergency Management / Incident CommanderIncident CommanderBuilding332SGI---------Gnd
a-.-G-I-i-e-iccGnd / Structure / IM Facilities / Emergency Management / Incident Communications CenterIncident Communications CenterBuilding333SGI---------Gnd
a-.-G-I-i-e-icpGnd / Structure / IM Facilities / Emergency Management / Incident Command PostIncident Command PostBuilding334SGI---------Gnd
a-.-G-I-i-e-wrGnd / Structure / IM Facilities / Emergency Management / War RoomWar RoomWar Room335SGI---------Gnd
a-.-G-I-i-fGnd / Structure / IM Facilities / Fire and HazmatFire / HazmatFire / Hazmat336SGI---------Gnd
a-.-G-I-i-f-fdGnd / Structure / IM Facilities / Fire and Hazmat / Fire DepartmentFire DepartmentFire / Hazmat337SGI---------Gnd
a-.-G-I-i-hGnd / Structure / IM Facilities / Health and MedicalHealth and MedicalBuilding338SGI---------Gnd
a-.-G-I-i-h-mdGnd / Structure / IM Facilities / Health and Medical / Medical DispatchMedical DispatchBuilding339SGI---------Gnd
a-.-G-I-i-lGnd / Structure / IM Facilities / Law EnforcementLaw EnforcementBuilding340SGI---------Gnd
a-.-G-I-i-l-cpGnd / Structure / IM Facilities / Law Enforcement / Police CheckpointPolice CheckpointBuilding341SGI---------Gnd
a-.-G-I-i-l-hpGnd / Structure / IM Facilities / Law Enforcement / Highway PatrolHighway PatrolBuilding342SGI---------Gnd
a-.-G-I-i-l-lpGnd / Structure / IM Facilities / Law Enforcement / Local PoliceLocal PoliceLocal Police343SGI---------Gnd
a-.-G-I-i-l-ntzGnd / Structure / IM Facilities / Law Enforcement / No Trespassing ZoneNo Trespassing ZoneBuilding344SGI---------Gnd
a-.-G-I-i-l-sdGnd / Structure / IM Facilities / Law Enforcement / Sheriffs DepartmentSheriffs DepartmentBuilding345SGI---------Gnd
a-.-G-I-i-l-SPGnd / Structure / IM Facilities / Law Enforcement / State PoliceState PoliceState Police346SGISP---------Gnd
a-.-G-I-i-mGnd / Structure / IM Facilities / Emergency Medical ServicesEmergency Medical ServicesBuilding347SGI---------Gnd
a-.-G-I-i-oGnd / Structure / IM Facilities / OtherOtherOther348SGI---------Gnd
a-.-G-I-i-o-ADGnd / Structure / IM Facilities / Other / Agency DispatchAgency DispatchOther349SGIAD---------Gnd
a-.-G-I-i-o-AD-emsGnd / Structure / IM Facilities / Other / Agency Dispatch / emsEmsEms350SGIAD---------Gndems
a-.-G-I-i-o-AD-fGnd / Structure / IM Facilities / Other / Agency Dispatch / FireFireFire351SGIAD---------GndFire
a-.-G-I-i-o-AD-hwyGnd / Structure / IM Facilities / Other / Agency Dispatch / HighwayHighwayHighway352SGIAD---------GndHighway
a-.-G-I-i-o-AD-mdaGnd / Structure / IM Facilities / Other / Agency Dispatch / MediaMediaMedia353SGIAD---------GndMedia
a-.-G-I-i-o-AD-plGnd / Structure / IM Facilities / Other / Agency Dispatch / Police LocalPolice LocalPolice Local354SGIAD---------GndPolice Local
a-.-G-I-i-o-AD-psGnd / Structure / IM Facilities / Other / Agency Dispatch / Police StationPolice StationOther355SGIAD---------GndPolice Station
a-.-G-I-i-o-AD-towGnd / Structure / IM Facilities / Other / Agency Dispatch / TowTowTow356SGIAD---------GndTow
a-.-G-I-i-o-AD-tsGnd / Structure / IM Facilities / Other / Agency Dispatch / TransitTransitTransit357SGIAD---------GndTransit
a-.-G-I-i-o-bccGnd / Structure / IM Facilities / Other / Border Control CheckpointBorder Control CheckpointOther358SGI---------Gnd
a-.-G-I-i-o-dmzGnd / Structure / IM Facilities / Other / dmzDmzDmz359SGI---------Gnd
a-.-G-I-i-o-ispGnd / Structure / IM Facilities / Other / Independent Service ProviderIndependent Service ProviderOther360SGI---------Gnd
a-.-G-I-i-o-mcGnd / Structure / IM Facilities / Other / Mobile CenterMobile CenterOther361SGI---------Gnd
a-.-G-I-i-o-mc-fGnd / Structure / IM Facilities / Other / Mobile Center / FireFireFire362SGI---------GndFire
a-.-G-I-i-o-mc-hGnd / Structure / IM Facilities / Other / Mobile Center / MedicalMedicalMedical363SGI---------GndMedical
a-.-G-I-i-o-mc-lGnd / Structure / IM Facilities / Other / Mobile Center / Law EnforcementLaw EnforcementOther364SGI---------GndLaw Enforcement
a-.-G-I-i-o-mesGnd / Structure / IM Facilities / Other / Message CenterMessage CenterOther365SGI---------Gnd
a-.-G-I-i-o-mobGnd / Structure / IM Facilities / Other / Mobilization CenterMobilization CenterOther366SGI---------Gnd
a-.-G-I-i-o-mob-emsGnd / Structure / IM Facilities / Other / Mobilization Center / emsEmsEms367SGI---------Gndems
a-.-G-I-i-o-mob-esGnd / Structure / IM Facilities / Other / Mobilization Center / TransitTransitTransit368SGI---------GndTransit
a-.-G-I-i-o-mob-fGnd / Structure / IM Facilities / Other / Mobilization Center / FireFireFire369SGI---------GndFire
a-.-G-I-i-o-mob-hwyGnd / Structure / IM Facilities / Other / Mobilization Center / HighwayHighwayHighway370SGI---------GndHighway
a-.-G-I-i-o-mob-mdaGnd / Structure / IM Facilities / Other / Mobilization Center / MediaMediaMedia371SGI---------GndMedia
a-.-G-I-i-o-mob-plGnd / Structure / IM Facilities / Other / Mobilization Center / Police LocalPloce LocalPloce Local372SGI---------GndPolice Local
a-.-G-I-i-o-mob-psGnd / Structure / IM Facilities / Other / Mobilization Center / Police StationPolice StationOther373SGI---------GndPolice Station
a-.-G-I-i-o-mob-towGnd / Structure / IM Facilities / Other / Mobilization Center / TowTowTow374SGI---------GndTow
a-.-G-I-i-o-psGnd / Structure / IM Facilities / Other / Public SafetyPublic SafetyOther375SGI---------Gnd
a-.-G-I-i-o-rlGnd / Structure / IM Facilities / Other / Reporting LocationsReporting LocationsOther376SGI---------Gnd
a-.-G-I-i-o-saGnd / Structure / IM Facilities / Other / Staging AreaStaging AreaStaging Area377SGI---------Gnd
a-.-G-I-i-o-sa-emsGnd / Structure / IM Facilities / Other / Staging Area / emsEmsEms378SGI---------Gndems
a-.-G-I-i-o-sa-fGnd / Structure / IM Facilities / Other / Staging Area / FireFireFire379SGI---------GndFire
a-.-G-I-i-o-sa-hwyGnd / Structure / IM Facilities / Other / Staging Area / HighwayHighwayHighway380SGI---------GndHighway
a-.-G-I-i-o-sa-mdaGnd / Structure / IM Facilities / Other / Staging Area / MediaMediaMedia381SGI---------GndMedia
a-.-G-I-i-o-sa-plGnd / Structure / IM Facilities / Other / Staging Area / Police LocalPolice LocalPolice Local382SGI---------GndPolice Local
a-.-G-I-i-o-sa-psGnd / Structure / IM Facilities / Other / Staging Area / Police StationPolice StationStaging Area383SGI---------GndPolice Station
a-.-G-I-i-o-sa-towGnd / Structure / IM Facilities / Other / Staging Area / TowTowTow384SGI---------GndTow
a-.-G-I-i-o-sa-tsGnd / Structure / IM Facilities / Other / Staging Area / TransitTransitTransit385SGI---------GndTransit
a-.-G-I-i-o-scGnd / Structure / IM Facilities / Other / Security CheckpointSecurity CheckpointOther386SGI---------Gnd
a-.-G-I-i-o-segGnd / Structure / IM Facilities / Other / SegmentSegmentSegment387SGI---------Gnd
a-.-G-I-i-o-tGnd / Structure / IM Facilities / Other / TransportationTransportationOther388SGI---------Gnd
a-.-G-I-i-o-t-IMGnd / Structure / IM Facilities / Other / Transportation / Transit Incident Management CenterTransit Incident Management CenterOther389SGIIM---------GndTransit Incident Management Center
a-.-G-I-i-o-t-tcGnd / Structure / IM Facilities / Other / Transportation / Transit Management CenterTransit Management CenterOther390SGI---------GndTransit Management Center
a-.-G-I-i-o-t-tdGnd / Structure / IM Facilities / Other / Transportation / Traffic Inc Service Patrol DispatchTraffic Inc Service Patrol DispatchOther391SGI---------GndTraffic Inc Service Patrol Dispatch
a-.-G-I-i-o-t-tmGnd / Structure / IM Facilities / Other / Transportation / Traffic Management CenterTraffic Management CenterOther392SGI---------GndTraffic Management Center
a-.-G-I-i-o-tmpGnd / Structure / IM Facilities / Other / TempTemporaryTemporary393SGI---------Gnd
a-.-G-I-i-o-tmp-fGnd / Structure / IM Facilities / Other / Temp / FireFireFire394SGI---------GndFire
a-.-G-I-i-o-tmp-hGnd / Structure / IM Facilities / Other / Temp / MedicalMedicalMedical395SGI---------GndMedical
a-.-G-I-i-o-tmp-lGnd / Structure / IM Facilities / Other / Temp / Law EnforcementLaw EnforcementTemporary396SGI---------GndLaw Enforcement
a-.-G-I-i-pGnd / Structure / IM Facilities / Public WorksPublic WorksPublic Works397SGI---------Gnd
a-.-G-I-MGnd / Structure / Mil / Military Materiel FacilityMilitary materiel facilityBuilding398SGIM---------Gnd
a-.-G-I-M-AGnd / Structure / Mil / Aircraft ProductionAircraft production / assemblyBuilding399SGIMA---------Gnd
a-.-G-I-M-CGnd / Structure / Mil / NBC Warfare ProductionChemical / biological warfare productionBuilding400SGIMC---------Gnd
a-.-G-I-M-EGnd / Structure / Mil / Ammunition ProductionAmmunition and explosives productionBuilding401SGIME---------Gnd
a-.-G-I-M-FGnd / Structure / Mil / Nuclear EnergyNuclear energyBuilding402SGIMF---------Gnd
a-.-G-I-M-F-AGnd / Structure / Mil / Atomic Energy ReactorAtomic energy reactorBuilding403SGIMFA---------Gnd
a-.-G-I-M-F-PGnd / Structure / Mil / Nuclear Material ProductionNuclear material productionBuilding404SGIMFP---------Gnd
a-.-G-I-M-F-P-WGnd / Structure / Mil / Nuclear / Weapons GradeWeapons gradeBuilding405SGIMFPW---------Gnd
a-.-G-I-M-F-SGnd / Structure / Mil / Nuclear Material StorageNuclear material storageBuilding406SGIMFS---------Gnd
a-.-G-I-M-GGnd / Structure / Mil / Armament ProductionArmament productionBuilding407SGIMG---------Gnd
a-.-G-I-M-MGnd / Structure / Mil / Missile+Space System ProductionMissile / space system productionBuilding408SGIMM---------Gnd
a-.-G-I-M-NGnd / Structure / Mil / Engineering Equipment ProductionEngineering equipment productionBuilding409SGIMN---------Gnd
a-.-G-I-M-N-BGnd / Structure / Mil / BridgeBridgeBridge410SGIMNB---------Gnd
a-.-G-I-M-N-B-lGnd / Structure / Mil / Bridge / LargeBridge (Large)Bridge411SGIMNB---------Gnd
a-.-G-I-M-N-B-mGnd / Structure / Mil / Bridge / MedBridge (Med)Bridge (Med)412SGIMNB---------Gnd
a-.-G-I-M-N-B-sGnd / Structure / Mil / Bridge / SmallBridge (Small)Bridge413SGIMNB---------Gnd
a-.-G-I-M-N-cGnd / Structure / Mil / CanalCanalCanal414SGIMN---------Gnd
a-.-G-I-M-SGnd / Structure / Mil / Ship ConstructionShip constructionBuilding415SGIMS---------Gnd
a-.-G-I-M-VGnd / Structure / Mil / Military Vehicle ProductionMilitary vehicle productionBuilding416SGIMV---------Gnd
a-.-G-I-PGnd / Structure / Processing FacilityProcessing facilityBuilding417SGIP---------Gnd
a-.-G-I-P-DGnd / Structure / DeconDeconDecon418SGIPD---------Gnd
a-.-G-I-RGnd / Structure / Raw Material Production / StorageRaw material production / storageBuilding419SGIR---------Gnd
a-.-G-I-rGnd / Structure / RoadRoadRoad420SGI---------Gnd
a-.-G-I-r-hGnd / Structure / Road / HighwayRoad (Highway)Road421SGI---------Gnd
a-.-G-I-r-iGnd / Structure / Road / ImprovedRoad (Improved)Road422SGI---------Gnd
a-.-G-I-R-MGnd / Structure / MineMineMine423SGIRM---------Gnd
a-.-G-I-R-NGnd / Structure / NBCNBCNBC424SGIRN---------Gnd
a-.-G-I-R-N-BGnd / Structure / BiologicalBiologicalBiological425SGIRNB---------Gnd
a-.-G-I-R-N-CGnd / Structure / ChemicalChemicalChemical426SGIRNC---------Gnd
a-.-G-I-R-N-NGnd / Structure / NuclearNuclearNuclear427SGIRNN---------Gnd
a-.-G-I-R-PGnd / Structure / petroleum / gas / oilPetroleum / gas / oilBuilding428SGIRP---------Gnd
a-.-G-I-R-P-rGnd / Structure / petroleum / gas / oil / RefineryRefineryRefinery429SGIRP---------GndRefinery
a-.-G-I-r-raGnd / Structure / Road / Rest AreaRest AreaRest Area430SGI---------Gnd
a-.-G-I-r-uGnd / Structure / Road / UnimprovedRoad (Un-improved)Road431SGI---------Gnd
a-.-G-I-TGnd / Structure / Transport FacilityTransport facilityBuilding432SGIT---------Gnd
a-.-G-I-T-aGnd / Structure / Transport Facility / AirportAirportAirport433SGIT---------Gnd
a-.-G-I-T-hbGnd / Structure / Transport Facility / HelibaseHelibaseHelibase434SGIT---------Gnd
a-.-G-I-T-hsGnd / Structure / Transport Facility / HelispotHelispotHelispot435SGIT---------Gnd
a-.-G-I-T-lGnd / Structure / Transport Facility / Land PortLand PortLand Port436SGIT---------Gnd
a-.-G-I-T-pgGnd / Structure / Transport Facility / Parking GarageParking GarageBuilding437SGIT---------Gnd
a-.-G-I-T-rGnd / Structure / Transport Facility / RailroadRailroadRailroad438SGIT---------Gnd
a-.-G-I-T-sGnd / Structure / Transport Facility / SeaportSeaportSeaport439SGIT---------Gnd
a-.-G-I-UGnd / Structure / Utility / Service, Research, Utility FacilityService, research, utility facilityBuilding440SGIU---------Gnd
a-.-G-I-U-EGnd / Structure / Utility / Electric PowerElectric power facilityBuilding441SGIUE---------Gnd
a-.-G-I-U-E-cGnd / Structure / Utility / Electric Power / Coal Power PlantCoal Power PlantBuilding442SGIUE---------Gnd
a-.-G-I-U-E-DGnd / Structure / Utility / DamDamDam443SGIUED---------Gnd
a-.-G-I-U-E-FGnd / Structure / Utility / Fossil FuelFossil fuelFossil fuel444SGIUEF---------Gnd
a-.-G-I-U-E-hGnd / Structure / Utility / Electric Power / Hydroelectric Power PlantHydroelectric Power PlantBuilding445SGIUE---------Gnd
a-.-G-I-U-E-NGnd / Structure / Utility / Nuclear PlantNuclear plantBuilding446SGIUEN---------Gnd
a-.-G-I-U-E-oGnd / Structure / Utility / Electric Power / Other PowerOther PowerOther Power447SGIUE---------Gnd
a-.-G-I-U-E-psGnd / Structure / Utility / Electric Power / Power SubstationPower SubstationBuilding448SGIUE---------Gnd
a-.-G-I-U-PGnd / Structure / Utility / Public Water ServicesPublic water servicesBuilding449SGIUP---------Gnd
a-.-G-I-U-RGnd / Structure / Utility / Technological ResearchTechnological research facilityBuilding450SGIUR---------Gnd
a-.-G-I-U-TGnd / Structure / Utility / TelecommunicationsTelecommunications facilityBuilding451SGIUT---------Gnd
a-.-G-I-U-T-comGnd / Structure / Utility / Telecommunications / CommunicationsCommunicationsBuilding452SGIUT---------Gnd
a-.-G-I-U-T-com-afGnd / Structure / Utility / Telecommunications / Communications / Antenna FarmAntenna FarmAntenna Farm453SGIUT---------GndAntenna Farm
a-.-G-I-U-T-com-satGnd / Structure / Utility / Telecommunications / Communications / Satellite CommunicationsSatellite CommunicationsBuilding454SGIUT---------GndSatellite Communications
a-.-G-I-U-T-com-towGnd / Structure / Utility / Telecommunications / Communications / TowerTowerTower455SGIUT---------GndTower
a-.-G-I-U-T-rGnd / Structure / Utility / Telecommunications / RadioRadioRadio456SGIUT---------Gnd
a-.-G-I-U-T-r-sGnd / Structure / Utility / Telecommunications / Radio / StationStationStation457SGIUT---------GndStation
a-.-G-I-U-T-tpGnd / Structure / Utility / Telecommunications / TelephoneTelephoneTelephone458SGIUT---------Gnd
a-.-G-I-U-T-tp-tsGnd / Structure / Utility / Telecommunications / Telephone / Telephone SwitchingTelephone SwitchingTelephone459SGIUT---------GndTelephone Switching
a-.-G-I-U-T-tvGnd / Structure / Utility / Telecommunications / TelevisionTelevisionTelevision460SGIUT---------Gnd
a-.-G-I-U-T-tv-cGnd / Structure / Utility / Telecommunications / Television / CableCableCable461SGIUT---------GndCable
a-.-G-I-U-T-tv-sGnd / Structure / Utility / Telecommunications / Television / StationStationStation462SGIUT---------GndStation
a-.-G-I-XGnd / Structure / Medical FacilityMedical facilityBuilding463SGIX---------Gnd
a-.-G-I-X-HGnd / Structure / HospitalHospitalHospital464SGIXH---------Gnd
a-.-G-I-X-hcfGnd / Structure / Medical Facility / Hospital / Hospital Care FacilityHospital Care FacilityBuilding465SGIX---------Gnd
a-.-G-UGnd / UnitUnitUnit466SGU---------Gnd
a-.-G-U-CGnd / CombatCombatCombat467SGUC---------Gnd
a-.-G-U-C-AGnd / Combat / armorArmorArmor468SGUCA---------Gnd
a-.-G-U-C-A-AGnd / Combat / Armor / anti armorAnti armorAnti armor469SGUCAA---------Gnd
a-.-G-U-C-A-A-AGnd / Combat / Armor / anti armor armoredAnti armor armoredAnti armor470SGUCAAA---------Gnd
a-.-G-U-C-A-A-A-SGnd / Combat / Armor / anti armor armored air assaultAnti armor armored air assaultAnti armor471SGUCAAAS---------Gnd
a-.-G-U-C-A-A-A-TGnd / Combat / Armor / anti armor armored trackedAnti armor armored trackedAnti armor472SGUCAAAT---------Gnd
a-.-G-U-C-A-A-A-WGnd / Combat / Armor / anti armor armored wheeledAnti armor armored wheeledAnti armor473SGUCAAAW---------Gnd
a-.-G-U-C-A-A-CGnd / Combat / Armor / anti armor arcticAnti armor arcticAnti armor474SGUCAAC---------Gnd
a-.-G-U-C-A-A-DGnd / Combat / Armor / anti armor dismountedAnti armor dismountedAnti armor475SGUCAAD---------Gnd
a-.-G-U-C-A-A-LGnd / Combat / Armor / anti armor lightAnti armor lightAnti armor476SGUCAAL---------Gnd
a-.-G-U-C-A-A-MGnd / Combat / Armor / anti armor airborneAnti armor airborneAnti armor477SGUCAAM---------Gnd
a-.-G-U-C-A-A-OGnd / Combat / Armor / anti armor motorizedAnti armor motorizedAnti armor478SGUCAAO---------Gnd
a-.-G-U-C-A-A-O-SGnd / Combat / Armor / anti armor motorized air assaultAnti armor motorized air assaultAnti armor479SGUCAAOS---------Gnd
a-.-G-U-C-A-A-SGnd / Combat / Armor / anti armor air assaultAnti armor air assaultAnti armor480SGUCAAS---------Gnd
a-.-G-U-C-A-A-UGnd / Combat / Armor / anti armor mountainAnti armor mountainAnti armor481SGUCAAU---------Gnd
a-.-G-U-C-A-TGnd / Combat / Armor / armor trackArmor trackArmor track482SGUCAT---------Gnd
a-.-G-U-C-A-T-AGnd / Combat / Armor / armor track airborneArmor track airborneArmor track483SGUCATA---------Gnd
a-.-G-U-C-A-T-HGnd / Combat / Armor / armor track, heavyArmor track, heavyArmor track484SGUCATH---------Gnd
a-.-G-U-C-A-T-LGnd / Combat / Armor / armor track, lightArmor track, lightArmor track485SGUCATL---------Gnd
a-.-G-U-C-A-T-MGnd / Combat / Armor / armor track, mediumArmor track, mediumArmor track486SGUCATM---------Gnd
a-.-G-U-C-A-T-RGnd / Combat / Armor / armor track, recoveryArmor track, recoveryArmor track487SGUCATR---------Gnd
a-.-G-U-C-A-T-WGnd / Combat / Armor / armor track amphibiousArmor track amphibiousArmor track488SGUCATW---------Gnd
a-.-G-U-C-A-T-W-RGnd / Combat / Armor / armor track amphibious recoveryArmor track amphibious recoveryArmor track489SGUCATWR---------Gnd
a-.-G-U-C-A-WGnd / Combat / Armor / armor, wheeledArmor, wheeledArmor490SGUCAW---------Gnd
a-.-G-U-C-A-W-AGnd / Combat / Armor / armor, wheeled airborneArmor, wheeled airborneArmor491SGUCAWA---------Gnd
a-.-G-U-C-A-W-HGnd / Combat / Armor / armor, wheeled heavyArmor, wheeled heavyArmor492SGUCAWH---------Gnd
a-.-G-U-C-A-W-LGnd / Combat / Armor / armor, wheeled lightArmor, wheeled lightArmor493SGUCAWL---------Gnd
a-.-G-U-C-A-W-MGnd / Combat / Armor / armor, wheeled mediumArmor, wheeled mediumArmor494SGUCAWM---------Gnd
a-.-G-U-C-A-W-RGnd / Combat / Armor / armor, wheeled recoveryArmor, wheeled recoveryArmor495SGUCAWR---------Gnd
a-.-G-U-C-A-W-SGnd / Combat / Armor / armor, wheeled air assaultArmor, wheeled air assaultArmor496SGUCAWS---------Gnd
a-.-G-U-C-A-W-WGnd / Combat / Armor / armor, wheeled amphibiousArmor, wheeled amphibiousArmor497SGUCAWW---------Gnd
a-.-G-U-C-A-W-W-RGnd / Combat / Armor / armor, wheeled amphibious recoveryArmor, wheeled amphibious recoveryArmor498SGUCAWWR---------Gnd
a-.-G-U-C-DGnd / Combat / Defense / air defenseAir defenseAir defense499SGUCD---------Gnd
a-.-G-U-C-D-CGnd / Combat / Defense / compositeCompositeComposite500SGUCDC---------Gnd
a-.-G-U-C-D-GGnd / Combat / Defense / gun unitGun unitGun unit501SGUCDG---------Gnd
a-.-G-U-C-D-HGnd / Combat / Defense / H / MADH / MADH / MAD502SGUCDH---------Gnd
a-.-G-U-C-D-H-HGnd / Combat / Defense / hawkHawkHawk503SGUCDHH---------Gnd
a-.-G-U-C-D-H-PGnd / Combat / Defense / patriotPatriotPatriot504SGUCDHP---------Gnd
a-.-G-U-C-D-MGnd / Combat / Defense / air defense missileAir defense missileAir defense505SGUCDM---------Gnd
a-.-G-U-C-D-M-HGnd / Combat / Defense / air defense missile heavyAir defense missile heavyAir defense506SGUCDMH---------Gnd
a-.-G-U-C-D-M-LGnd / Combat / Defense / air defense missile lightAir defense missile lightAir defense507SGUCDML---------Gnd
a-.-G-U-C-D-M-L-AGnd / Combat / Defense / air defense missile motorized (avenger)Air defense missile motorized (avenger)Air defense508SGUCDMLA---------Gnd
a-.-G-U-C-D-M-MGnd / Combat / Defense / air defense missile mediumAir defense missile mediumAir defense509SGUCDMM---------Gnd
a-.-G-U-C-D-OGnd / Combat / Defense / theater missile defense unitTheater missile defense unitAir defense510SGUCDO---------Gnd
a-.-G-U-C-D-SGnd / Combat / Defense / short rangeShort rangeShort range511SGUCDS---------Gnd
a-.-G-U-C-D-S-CGnd / Combat / Defense / ChaparralChaparralChaparral512SGUCDSC---------Gnd
a-.-G-U-C-D-S-SGnd / Combat / Defense / stingerStingerStinger513SGUCDSS---------Gnd
a-.-G-U-C-D-S-VGnd / Combat / Defense / vulcanVulcanVulcan514SGUCDSV---------Gnd
a-.-G-U-C-D-TGnd / Combat / Defense / targeting unitTargeting unitAir defense515SGUCDT---------Gnd
a-.-G-U-C-EGnd / Combat / Engineer / engineerEngineerEngineer516SGUCE---------Gnd
a-.-G-U-C-E-CGnd / Combat / Engineer / engineer combatEngineer combatEngineer517SGUCEC---------Gnd
a-.-G-U-C-E-C-AGnd / Combat / Engineer / engineer combat airborneEngineer combat airborneEngineer518SGUCECA---------Gnd
a-.-G-U-C-E-C-CGnd / Combat / Engineer / engineer combat arcticEngineer combat arcticEngineer519SGUCECC---------Gnd
a-.-G-U-C-E-C-HGnd / Combat / Engineer / engineer combat heavyEngineer combat heavyEngineer520SGUCECH---------Gnd
a-.-G-U-C-E-C-LGnd / Combat / Engineer / engineer combat light (sapper)Engineer combat light (sapper)Engineer521SGUCECL---------Gnd
a-.-G-U-C-E-C-MGnd / Combat / Engineer / engineer combat mediumEngineer combat mediumEngineer522SGUCECM---------Gnd
a-.-G-U-C-E-C-OGnd / Combat / Engineer / engineer combat mountainEngineer combat mountainEngineer523SGUCECO---------Gnd
a-.-G-U-C-E-C-RGnd / Combat / Engineer / engineer combat reconEngineer combat reconEngineer524SGUCECR---------Gnd
a-.-G-U-C-E-C-SGnd / Combat / Engineer / engineer combat air assaultEngineer combat air assaultEngineer525SGUCECS---------Gnd
a-.-G-U-C-E-C-TGnd / Combat / Engineer / engineer combat mechanized (track)Engineer combat mechanized (track)Engineer526SGUCECT---------Gnd
a-.-G-U-C-E-C-WGnd / Combat / Engineer / engineer combat motorizedEngineer combat motorizedEngineer527SGUCECW---------Gnd
a-.-G-U-C-E-NGnd / Combat / Engineer / engineer constructionEngineer constructionEngineer528SGUCEN---------Gnd
a-.-G-U-C-E-N-NGnd / Combat / Engineer / engineer naval constructionEngineer naval constructionEngineer529SGUCENN---------Gnd
a-.-G-U-C-FGnd / Combat / Artillery (Fixed)Artillery (Fixed)Artillery530SGUCF---------Gnd
a-.-G-U-C-F-HGnd / Combat / howitzer / gunHowitzer / gunHowitzer / gun531SGUCFH---------Gnd
a-.-G-U-C-F-H-AGnd / Combat / airborneAirborneAirborne532SGUCFHA---------Gnd
a-.-G-U-C-F-H-CGnd / Combat / arcticArcticArctic533SGUCFHC---------Gnd
a-.-G-U-C-F-H-EGnd / Combat / Artillery (Mobile)Artillery (Mobile)Howitzer / gun534SGUCFHE---------Gnd
a-.-G-U-C-F-H-HGnd / Combat / heavyHeavyHeavy535SGUCFHH---------Gnd
a-.-G-U-C-F-H-LGnd / Combat / lightLightLight536SGUCFHL---------Gnd
a-.-G-U-C-F-H-MGnd / Combat / mediumMediumMedium537SGUCFHM---------Gnd
a-.-G-U-C-F-H-OGnd / Combat / mountainMountainMountain538SGUCFHO---------Gnd
a-.-G-U-C-F-H-SGnd / Combat / air assaultAir assaultAir assault539SGUCFHS---------Gnd
a-.-G-U-C-F-H-XGnd / Combat / amphibiousAmphibiousAmphibious540SGUCFHX---------Gnd
a-.-G-U-C-F-MGnd / Combat / mortarMortarMortar541SGUCFM---------Gnd
a-.-G-U-C-F-M-LGnd / Combat / amphibious mortarAmphibious mortarMortar542SGUCFML---------Gnd
a-.-G-U-C-F-M-SGnd / Combat / self propelled (SP) tracked mortarSelf propelled (SP) tracked mortarMortar543SGUCFMS---------Gnd
a-.-G-U-C-F-M-TGnd / Combat / towed mortarTowed mortarTowed mortar544SGUCFMT---------Gnd
a-.-G-U-C-F-M-T-AGnd / Combat / towed airborne mortarTowed airborne mortarTowed mortar545SGUCFMTA---------Gnd
a-.-G-U-C-F-M-T-CGnd / Combat / towed arctic mortarTowed arctic mortarTowed mortar546SGUCFMTC---------Gnd
a-.-G-U-C-F-M-T-OGnd / Combat / towed mountain mortarTowed mountain mortarTowed mortar547SGUCFMTO---------Gnd
a-.-G-U-C-F-M-T-SGnd / Combat / towed air assault mortarTowed air assault mortarTowed mortar548SGUCFMTS---------Gnd
a-.-G-U-C-F-M-WGnd / Combat / SP wheeled mortarSP wheeled mortarMortar549SGUCFMW---------Gnd
a-.-G-U-C-F-OGnd / Combat / meteorologicalMeteorologicalCombat550SGUCFO---------Gnd
a-.-G-U-C-F-O-AGnd / Combat / airborne meteorologicalAirborne meteorologicalCombat551SGUCFOA---------Gnd
a-.-G-U-C-F-O-LGnd / Combat / light meteorologicalLight meteorologicalCombat552SGUCFOL---------Gnd
a-.-G-U-C-F-O-OGnd / Combat / mountain meteorologicalMountain meteorologicalCombat553SGUCFOO---------Gnd
a-.-G-U-C-F-O-SGnd / Combat / air assault meteorologicalAir assault meteorologicalCombat554SGUCFOS---------Gnd
a-.-G-U-C-F-RGnd / Combat / rocketRocketRocket555SGUCFR---------Gnd
a-.-G-U-C-F-R-MGnd / Combat / Rockets (Fixed)Rockets (Fixed)Rocket556SGUCFRM---------Gnd
a-.-G-U-C-F-R-M-RGnd / Combat / Rockets (Mobile)Rockets (Mobile)Rocket557SGUCFRMR---------Gnd
a-.-G-U-C-F-R-M-SGnd / Combat / multi rocket self propelledMulti rocket self propelledRocket558SGUCFRMS---------Gnd
a-.-G-U-C-F-R-M-TGnd / Combat / multi rocket towedMulti rocket towedRocket559SGUCFRMT---------Gnd
a-.-G-U-C-F-R-SGnd / Combat / single rocket launcherSingle rocket launcherRocket560SGUCFRS---------Gnd
a-.-G-U-C-F-R-S-RGnd / Combat / single rocket truckSingle rocket truckRocket561SGUCFRSR---------Gnd
a-.-G-U-C-F-R-S-SGnd / Combat / single rocket self propelledSingle rocket self propelledRocket562SGUCFRSS---------Gnd
a-.-G-U-C-F-R-S-TGnd / Combat / single rocket towedSingle rocket towedRocket563SGUCFRST---------Gnd
a-.-G-U-C-F-SGnd / Combat / artillery surveyArtillery surveyCombat564SGUCFS---------Gnd
a-.-G-U-C-F-S-AGnd / Combat / airborneAirborneAirborne565SGUCFSA---------Gnd
a-.-G-U-C-F-S-LGnd / Combat / lightLightLight566SGUCFSL---------Gnd
a-.-G-U-C-F-S-OGnd / Combat / mountainMountainMountain567SGUCFSO---------Gnd
a-.-G-U-C-F-S-SGnd / Combat / air assaultAir assaultAir assault568SGUCFSS---------Gnd
a-.-G-U-C-F-TGnd / Combat / target acquisitionTarget acquisitionCombat569SGUCFT---------Gnd
a-.-G-U-C-F-T-AGnd / Combat / anglicoAnglicoAnglico570SGUCFTA---------Gnd
a-.-G-U-C-F-T-CGnd / Combat / colt / fistColt / fistColt / fist571SGUCFTC---------Gnd
a-.-G-U-C-F-T-C-DGnd / Combat / dismounted colt / fistDismounted colt / fistColt / fist572SGUCFTCD---------Gnd
a-.-G-U-C-F-T-C-MGnd / Combat / tracked colt / fistTracked colt / fistColt / fist573SGUCFTCM---------Gnd
a-.-G-U-C-F-T-FGnd / Combat / flash (optical)Flash (optical)Combat574SGUCFTF---------Gnd
a-.-G-U-C-F-T-RGnd / Combat / radarRadarRadar575SGUCFTR---------Gnd
a-.-G-U-C-F-T-SGnd / Combat / soundSoundSound576SGUCFTS---------Gnd
a-.-G-U-C-IGnd / Combat / Infantry / Troops (Open)Troops (Open)Troops577SGUCI---------Gnd
a-.-G-U-C-I-AGnd / Combat / Infantry / AirborneInfantry airborneCombat578SGUCIA---------Gnd
a-.-G-U-C-I-CGnd / Combat / Infantry / ArcticInfantry arcticCombat579SGUCIC---------Gnd
a-.-G-U-C-I-dGnd / Combat / Infantry / DugInTroops (DugIn)Sniper580SGUCI---------Gnd
a-.-G-U-C-I-IGnd / Combat / Infantry / Fighting VehicleInfantry fighting vehicleCombat581SGUCII---------Gnd
a-.-G-U-C-I-LGnd / Combat / Infantry / LightInfantry lightCombat582SGUCIL---------Gnd
a-.-G-U-C-I-MGnd / Combat / Infantry / MotorizedInfantry motorizedCombat583SGUCIM---------Gnd
a-.-G-U-C-I-NGnd / Combat / Infantry / NavalInfantry navalCombat584SGUCIN---------Gnd
a-.-G-U-C-I-OGnd / Combat / Infantry / MountainInfantry mountainCombat585SGUCIO---------Gnd
a-.-G-U-C-I-SGnd / Combat / Infantry / Air AssaultInfantry air assaultCombat586SGUCIS---------Gnd
a-.-G-U-C-I-ZGnd / Combat / Infantry / MechanizedInfantry mechanizedCombat587SGUCIZ---------Gnd
a-.-G-U-C-MGnd / Combat / missile (surf surf)Missile (surf surf)Combat588SGUCM---------Gnd
a-.-G-U-C-M-SGnd / Combat / missile (surf surf) strategicMissile (surf surf) strategicCombat589SGUCMS---------Gnd
a-.-G-U-C-M-TGnd / Combat / missile (surf surf) tacticalMissile (surf surf) tacticalCombat590SGUCMT---------Gnd
a-.-G-U-C-RGnd / Combat / Recon /ReconnaissanceCombat591SGUCR---------Gnd
a-.-G-U-C-R-AGnd / Combat / Recon / airborneReconnaissance airborneCombat592SGUCRA---------Gnd
a-.-G-U-C-R-CGnd / Combat / Recon / arcticReconnaissance arcticCombat593SGUCRC---------Gnd
a-.-G-U-C-R-HGnd / Combat / Recon / horseReconnaissance horseCombat594SGUCRH---------Gnd
a-.-G-U-C-R-LGnd / Combat / Recon / lightReconnaissance lightCombat595SGUCRL---------Gnd
a-.-G-U-C-R-OGnd / Combat / Recon / mountainReconnaissance mountainCombat596SGUCRO---------Gnd
a-.-G-U-C-R-RGnd / Combat / Recon / marineReconnaissance marineCombat597SGUCRR---------Gnd
a-.-G-U-C-R-R-DGnd / Combat / Recon / marine divisionReconnaissance marine divisionCombat598SGUCRRD---------Gnd
a-.-G-U-C-R-R-FGnd / Combat / Recon / marine forceReconnaissance marine forceCombat599SGUCRRF---------Gnd
a-.-G-U-C-R-R-LGnd / Combat / Recon / marine light armoredReconnaissance marine light armoredCombat600SGUCRRL---------Gnd
a-.-G-U-C-R-SGnd / Combat / Recon / air assaultReconnaissance air assaultCombat601SGUCRS---------Gnd
a-.-G-U-C-R-VGnd / Combat / Recon / cavalryReconnaissance cavalryCombat602SGUCRV---------Gnd
a-.-G-U-C-R-V-AGnd / Combat / Recon / cavalry armoredReconnaissance cavalry armoredCombat603SGUCRVA---------Gnd
a-.-G-U-C-R-V-GGnd / Combat / Recon / cavalry groundReconnaissance cavalry groundCombat604SGUCRVG---------Gnd
a-.-G-U-C-R-V-MGnd / Combat / Recon / cavalry motorizedReconnaissance cavalry motorizedCombat605SGUCRVM---------Gnd
a-.-G-U-C-R-V-OGnd / Combat / Recon / cavalry airReconnaissance cavalry airCombat606SGUCRVO---------Gnd
a-.-G-U-C-R-XGnd / Combat / Recon / long range surveillanceReconnaissance long range surveillanceCombat607SGUCRX---------Gnd
a-.-G-U-C-SGnd / Combat / Security / internal security forcesInternal security forcesCombat608SGUCS---------Gnd
a-.-G-U-C-S-AGnd / Combat / Security / aviationAviationAviation609SGUCSA---------Gnd
a-.-G-U-C-S-GGnd / Combat / Security / groundGroundGround610SGUCSG---------Gnd
a-.-G-U-C-S-G-AGnd / Combat / Security / mechanized groundMechanized groundGround611SGUCSGA---------Gnd
a-.-G-U-C-S-G-DGnd / Combat / Security / dismounted groundDismounted groundGround612SGUCSGD---------Gnd
a-.-G-U-C-S-G-MGnd / Combat / Security / motorized groundMotorized groundGround613SGUCSGM---------Gnd
a-.-G-U-C-S-MGnd / Combat / Security / wheeled mechanizedWheeled mechanizedCombat614SGUCSM---------Gnd
a-.-G-U-C-S-RGnd / Combat / Security / RailRailRail615SGUCSR---------Gnd
a-.-G-U-C-S-WGnd / Combat / Security / riverineRiverineRiverine616SGUCSW---------Gnd
a-.-G-U-C-VGnd / Combat / Aviation / aviationAviationAviation617SGUCV---------Gnd
a-.-G-U-C-V-CGnd / Combat / Aviation / compositeCompositeComposite618SGUCVC---------Gnd
a-.-G-U-C-V-FGnd / Combat / Aviation / fixed wingFixed wingFixed wing619SGUCVF---------Gnd
a-.-G-U-C-V-F-AGnd / Combat / Aviation / attack fixed wingAttack fixed wingFixed wing620SGUCVFA---------Gnd
a-.-G-U-C-V-F-RGnd / Combat / Aviation / recon fixed wingRecon fixed wingFixed wing621SGUCVFR---------Gnd
a-.-G-U-C-V-F-UGnd / Combat / Aviation / utility fixed wingUtility fixed wingFixed wing622SGUCVFU---------Gnd
a-.-G-U-C-V-RGnd / Combat / Aviation / rotary wingRotary wingRotary wing623SGUCVR---------Gnd
a-.-G-U-C-V-R-AGnd / Combat / Aviation / attack rotary wingAttack rotary wingRotary wing624SGUCVRA---------Gnd
a-.-G-U-C-V-R-CGnd / Combat / Aviation / C2 Rotorary WingC2C2625SGUCVRC---------Gnd
a-.-G-U-C-V-R-dGnd / Combat / Aviation / Helo / DualHelo ground unit (Dual)Rotary wing626SGUCVR---------Gnd
a-.-G-U-C-V-R-EGnd / Combat / Aviation / rotary wing / MedevacMedevacMedevac627SGUCVRE---------Gnd
a-.-G-U-C-V-R-MGnd / Combat / Aviation / mine countermeasure rotary wingMine countermeasure rotary wingRotary wing628SGUCVRM---------Gnd
a-.-G-U-C-V-R-SGnd / Combat / Aviation / scout rotary wingScout rotary wingRotary wing629SGUCVRS---------Gnd
a-.-G-U-C-V-R-sGnd / Combat / Aviation / Helo / SingleHelo ground unit (Single)Rotary wing630SGUCVR---------Gnd
a-.-G-U-C-V-R-UGnd / Combat / Aviation / utility rotary wingUtility rotary wingRotary wing631SGUCVRU---------Gnd
a-.-G-U-C-V-R-U-CGnd / Combat / Aviation / C2 rotary wingC2 rotary wingRotary wing632SGUCVRUC---------Gnd
a-.-G-U-C-V-R-U-EGnd / Combat / Aviation / medevac rotary wingMedevac rotary wingRotary wing633SGUCVRUE---------Gnd
a-.-G-U-C-V-R-U-HGnd / Combat / Aviation / heavy utility rotary wingHeavy utility rotary wingRotary wing634SGUCVRUH---------Gnd
a-.-G-U-C-V-R-U-LGnd / Combat / Aviation / light utility rotary wingLight utility rotary wingRotary wing635SGUCVRUL---------Gnd
a-.-G-U-C-V-R-U-MGnd / Combat / Aviation / medium utility rotary wingMedium utility rotary wingRotary wing636SGUCVRUM---------Gnd
a-.-G-U-C-V-R-WGnd / Combat / Aviation / antisubmarine warfare rotary wingAntisubmarine warfare rotary wingRotary wing637SGUCVRW---------Gnd
a-.-G-U-C-V-SGnd / Combat / Aviation / search and rescueSearch and rescueAviation638SGUCVS---------Gnd
a-.-G-U-C-V-UGnd / Combat / Aviation / unmanned aerial vehicleUnmanned aerial vehicleAviation639SGUCVU---------Gnd
a-.-G-U-C-V-U-FGnd / Combat / Aviation / unmanned aerial vehicle fixed wingUnmanned aerial vehicle fixed wingAviation640SGUCVUF---------Gnd
a-.-G-U-C-V-U-RGnd / Combat / Aviation / unmanned aerial vehicle rotary wingUnmanned aerial vehicle rotary wingAviation641SGUCVUR---------Gnd
a-.-G-U-C-V-VGnd / Combat / Aviation / vertical / short takeoff and landingVertical / short takeoff and landingAviation642SGUCVV---------Gnd
a-.-G-U-HGnd / special C2 headquarters componentSpecial C2 headquarters componentUnit643SGUH---------Gnd
a-.-G-U-iGnd / IM ResourcesIncident Management ResourcesUnit644SGU---------Gnd
a-.-G-U-i-aGnd / IM Resources / Animal HealthAnimal HealthUnit645SGU---------Gnd
a-.-G-U-i-a-imtGnd / Incident Management Team Animal ProtectionIncident Management Team Animal ProtectionUnit646SGU---------Gnd
a-.-G-U-i-a-larGnd / Large Animal Rescue Strike TeamLarge Animal Rescue Strike TeamUnit647SGU---------Gnd
a-.-G-U-i-a-lasGnd / Large Animal Sheltering TeamLarge Animal Sheltering TeamUnit648SGU---------Gnd
a-.-G-U-i-a-latGnd / Large Animal Transport TeamLarge Animal Transport TeamUnit649SGU---------Gnd
a-.-G-U-i-a-SARGnd / Small Animal Rescue Strike TeamSmall Animal Rescue Strike TeamUnit650SGUSAR---------Gnd
a-.-G-U-i-a-sasGnd / Small Animal Sheltering TeamSmall Animal Sheltering TeamUnit651SGU---------Gnd
a-.-G-U-i-a-satGnd / Small Animal Transport TeamSmall Animal Transport TeamUnit652SGU---------Gnd
a-.-G-U-i-eGnd / IM Resources / Emergency ManagementEmergency ManagementUnit653SGU---------Gnd
a-.-G-U-i-e-acrcGnd / Airborne Communications Relay (cap)Airborne Communications Relay(cap)Unit654SGU---------Gnd
a-.-G-U-i-e-acrtGnd / Airborne Communications Relay TeamAirborne Communications Relay TeamUnit655SGU---------Gnd
a-.-G-U-i-e-attGnd / Airborne Transport TeamAirborne Transport TeamUnit656SGU---------Gnd
a-.-G-U-i-e-cisGnd / Critical Incident Stress Management TeamCritical Incident Stress Management TeamUnit657SGU---------Gnd
a-.-G-U-i-e-cstGnd / Communications Support TeamCommunications Support TeamUnit658SGU---------Gnd
a-.-G-U-i-e-dcGnd / Donations CoordinatorDonations CoordinatorUnit659SGU---------Gnd
a-.-G-U-i-e-dmtGnd / Donations Management Personnel TeamDonations Management Personnel TeamUnit660SGU---------Gnd
a-.-G-U-i-e-ectGnd / Evacuation Coordination TeamEvacuation Coordination TeamUnit661SGU---------Gnd
a-.-G-U-i-e-efaGnd / EOC Finance AdministrationEOC Finance AdministrationUnit662SGU---------Gnd
a-.-G-U-i-e-eltGnd / Evacuation Liaison TeamEvacuation Liaison TeamUnit663SGU---------Gnd
a-.-G-U-i-e-emsGnd / EOC Management Support TeamEOC Management Support TeamUnit664SGU---------Gnd
a-.-G-U-i-e-eosGnd / EOC Operations Section ChiefEOC Operations Section ChiefUnit665SGU---------Gnd
a-.-G-U-i-e-epsGnd / EOC Planning Section ChiefEOC Planning Section ChiefUnit666SGU---------Gnd
a-.-G-U-i-e-ialGnd / Individual Assistance Disaster Assessment Team LeaderIndividual Assistance Disaster Assessment Team LeaderUnit667SGU---------Gnd
a-.-G-U-i-e-iatGnd / Individual Assistance Disaster Assessment TeamIndividual Assistance Disaster Assessment TeamUnit668SGU---------Gnd
a-.-G-U-i-e-imtGnd / Incident Management TeamIncident Management TeamUnit669SGU---------Gnd
a-.-G-U-i-e-MCCGnd / Mobile Communications CenterMobile Communications CenterUnit670SGUMCC---------Gnd
a-.-G-U-i-e-mfkGnd / Mobile Feeding KitchenMobile Feeding KitchenUnit671SGU---------Gnd
a-.-G-U-i-e-pacGnd / Public Assistance CoordinatorPublic Assistance CoordinatorUnit672SGU---------Gnd
a-.-G-U-i-e-rnaGnd / Rapid Needs Assessment TeamRapid Needs Assessment TeamUnit673SGU---------Gnd
a-.-G-U-i-e-smtGnd / Shelter Management TeamShelter Management TeamUnit674SGU---------Gnd
a-.-G-U-i-e-valGnd / Volunteer Agency LiaisonVolunteer Agency LiaisonUnit675SGU---------Gnd
a-.-G-U-i-fGnd / IM Resources / Fire hazmatFire hazmatFire hazmat676SGU---------Gnd
a-.-G-U-i-f-actGnd / Area Command Team, FirefightingArea Command Team, FirefightingFire hazmat677SGU---------Gnd
a-.-G-U-i-f-bpGnd / Brush PatrolBrush PatrolBrush Patrol678SGU---------Gnd
a-.-G-U-i-f-ctGnd / Crew TransportCrew TransportFire hazmat679SGU---------Gnd
a-.-G-U-i-f-efpGnd / Engine, Fire (Pumper)Engine, Fire (Pumper)Fire hazmat680SGU---------Gnd
a-.-G-U-i-f-fbGnd / Fire BoatFire BoatFire Boat681SGU---------Gnd
a-.-G-U-i-f-ftGnd / Fuel TenderFuel TenderFuel Tender682SGU---------Gnd
a-.-G-U-i-f-ftaGnd / Fire TruckFire TruckFire Truck683SGU---------Gnd
a-.-G-U-i-f-ftfGnd / Foam TenderFoam TenderFoam Tender684SGU---------Gnd
a-.-G-U-i-f-hcGnd / Hand CrewHand CrewHand Crew685SGU---------Gnd
a-.-G-U-i-f-hetGnd / HazMat Entry TeamHazMat Entry TeamFire hazmat686SGU---------Gnd
a-.-G-U-i-f-hfGnd / Helicopters FirefightingHelicopters, FirefightingFire hazmat687SGU---------Gnd
a-.-G-U-i-f-htGnd / HelitankerHelitankerHelitanker688SGU---------Gnd
a-.-G-U-i-f-ibtGnd / Interagency Buying Team FirefightingInteragency Buying Team FirefightingFire hazmat689SGU---------Gnd
a-.-G-U-i-f-imtGnd / Incident Management Team FirefightingIncident Management Team FirefightingFire hazmat690SGU---------Gnd
a-.-G-U-i-f-mcuGnd / Mobile Communications UnitMobile Communications UnitFire hazmat691SGU---------Gnd
a-.-G-U-i-f-nsfGnd / USCG National Strike ForceUSCG National Strike ForceFire hazmat692SGU---------Gnd
a-.-G-U-i-f-ppGnd / Portable PumpPortable PumpFire hazmat693SGU---------Gnd
a-.-G-U-i-f-stGnd / Strike Team, Engine (Fire)Strike Team, Engine (Fire)Fire hazmat694SGU---------Gnd
a-.-G-U-i-f-wtGnd / Water Tender, Firefighting (Tanker)Water Tender, Firefighting (Tanker)Fire hazmat695SGU---------Gnd
a-.-G-U-i-hGnd / IM Resources / Health and MedicalHealth and MedicalUnit696SGU---------Gnd
a-.-G-U-i-h-dmbGnd / Disaster Medical Assistance Team - BasicDisaster Medical Assistance Team - BasicUnit697SGU---------Gnd
a-.-G-U-i-h-dmcGnd / Disaster Medical Assistance Team - Crush Injury SpecialtyDisaster Medical Assistance Team - Crush Injury SpecialtyUnit698SGU---------Gnd
a-.-G-U-i-h-dmmGnd / Disaster Medical Assistance Team - Mental HealthDisaster Medical Assistance Team - Mental HealthUnit699SGU---------Gnd
a-.-G-U-i-h-dmpGnd / Disaster Medical Assistance Team - PediatricDisaster Medical Assistance Team - PediatricUnit700SGU---------Gnd
a-.-G-U-i-h-dmsGnd / Disaster Medical Assistance Team - BurnDisaster Medical Assistance Team - BurnUnit701SGU---------Gnd
a-.-G-U-i-h-morGnd / Disaster Mortuary Operational Response TeamDisaster Mortuary Operational Response TeamUnit702SGU---------Gnd
a-.-G-U-i-h-msrGnd / International Medical Surgical Response TeamInternational Medical Surgical Response TeamUnit703SGU---------Gnd
a-.-G-U-i-h-mstGnd / NDMS Management Support TeamNDMS Management Support TeamUnit704SGU---------Gnd
a-.-G-U-i-h-vmaGnd / Veterinary Medical Assistance TeamVeterinary Medical Assistance TeamUnit705SGU---------Gnd
a-.-G-U-i-lGnd / IM Resources / Law EnforcementLaw EnforcementUnit706SGU---------Gnd
a-.-G-U-i-l-bsGnd / Bomb Squad Explosives TeamBomb Squad Explosives TeamUnit707SGU---------Gnd
a-.-G-U-i-l-cctGnd / Crowd Control TeamCrowd Control TeamUnit708SGU---------Gnd
a-.-G-U-i-l-dtGnd / Public Safety Dive TeamPublic Safety Dive TeamUnit709SGU---------Gnd
a-.-G-U-i-l-hpsGnd / Aviation-Helicopters Patrol SurveillanceAviation-Helicopters Patrol SurveillanceUnit710SGU---------Gnd
a-.-G-U-i-l-oaGnd / Observation AircraftObservation AircraftUnit711SGU---------Gnd
a-.-G-U-i-l-ttGnd / SWAT Tactical TeamSWAT Tactical TeamUnit712SGU---------Gnd
a-.-G-U-i-mGnd / IM Resources / Emergency Medical ServicesEmergency Medical ServicesUnit713SGU---------Gnd
a-.-G-U-i-m-aafGnd / Air Ambulance (Fixed-Wing)Air Ambulance (Fixed-Wing)Unit714SGU---------Gnd
a-.-G-U-i-m-aarGnd / Air Ambulance (Rotary-Wing)Air Ambulance (Rotary-Wing)Unit715SGU---------Gnd
a-.-G-U-i-m-agGnd / Ambulances (Ground)Ambulances (Ground)Unit716SGU---------Gnd
a-.-G-U-i-m-astGnd / Ambulance Strike TeamAmbulance Strike TeamUnit717SGU---------Gnd
a-.-G-U-i-m-atfGnd / Ambulance Task ForceAmbulance Task ForceUnit718SGU---------Gnd
a-.-G-U-i-m-etfGnd / Emergency Medical Task ForceEmergency Medical Task ForceUnit719SGU---------Gnd
a-.-G-U-i-oGnd / IM Resources / OtherOtherOther720SGU---------Gnd
a-.-G-U-i-pGnd / IM Resources / Public WorksPublic WorksPublic Works721SGU---------Gnd
a-.-G-U-i-p-acfGnd / Air Curtain Burners (Above Ground)Air Curtain Burners (Above Ground)Public Works722SGU---------Gnd
a-.-G-U-i-p-achGnd / Air Conditioner HeaterAir Conditioner HeaterPublic Works723SGU---------Gnd
a-.-G-U-i-p-actGnd / Air Curtain Burners (In Ground)Air Curtain Burners (In Ground)Public Works724SGU---------Gnd
a-.-G-U-i-p-atcGnd / All Terrain CranesAll Terrain CranesPublic Works725SGU---------Gnd
a-.-G-U-i-p-bhGnd / Backhoe LoaderBackhoe LoaderPublic Works726SGU---------Gnd
a-.-G-U-i-p-cahGnd / Chillers Air HandlersChillers Air HandlersPublic Works727SGU---------Gnd
a-.-G-U-i-p-ccGnd / Crawler CranesCrawler CranesPublic Works728SGU---------Gnd
a-.-G-U-i-p-cceGnd / Concrete Cutter Multi-Processor for Hydraulic ExcavatorConcrete Cutter Multi-Processor for Hydraulic ExcavatorPublic Works729SGU---------Gnd
a-.-G-U-i-p-datGnd / Disaster Assessment TeamDisaster Assessment TeamPublic Works730SGU---------Gnd
a-.-G-U-i-p-dmmGnd / Debris Management Monitoring TeamDebris Management Monitoring TeamPublic Works731SGU---------Gnd
a-.-G-U-i-p-dmrGnd / Debris Management Site Reduction TeamDebris Management Site Reduction TeamPublic Works732SGU---------Gnd
a-.-G-U-i-p-dmtGnd / Debris Management TeamDebris Management TeamPublic Works733SGU---------Gnd
a-.-G-U-i-p-drtGnd / Disaster Recovery TeamDisaster Recovery TeamPublic Works734SGU---------Gnd
a-.-G-U-i-p-dtGnd / Dump TrailerDump TrailerDump Trailer735SGU---------Gnd
a-.-G-U-i-p-dtfGnd / Dump Truck Off RoadDump Truck Off RoadPublic Works736SGU---------Gnd
a-.-G-U-i-p-dtnGnd / Dump Truck On RoadDump Truck On RoadPublic Works737SGU---------Gnd
a-.-G-U-i-p-eprGnd / Electrical Power Restoration TeamElectrical Power Restoration TeamPublic Works738SGU---------Gnd
a-.-G-U-i-p-esGnd / Engineering ServicesEngineering ServicesPublic Works739SGU---------Gnd
a-.-G-U-i-p-fbtGnd / Flat Bed Trailer TruckFlat Bed Trailer TruckPublic Works740SGU---------Gnd
a-.-G-U-i-p-genGnd / GeneratorsGeneratorsGenerators741SGU---------Gnd
a-.-G-U-i-p-helGnd / Hydraulic Excavator (Large)Hydraulic Excavator (Large)Public Works742SGU---------Gnd
a-.-G-U-i-p-hemGnd / Hydraulic Excavator (Medium)Hydraulic Excavator (Medium)Public Works743SGU---------Gnd
a-.-G-U-i-p-htcGnd / Hydraulic Truck CranesHydraulic Truck CranesPublic Works744SGU---------Gnd
a-.-G-U-i-p-ltcGnd / Lattice Truck CranesLattice Truck CranesPublic Works745SGU---------Gnd
a-.-G-U-i-p-tbGnd / Tug BoatTug BoatTug Boat746SGU---------Gnd
a-.-G-U-i-p-tdGnd / Track DozerTrack DozerTrack Dozer747SGU---------Gnd
a-.-G-U-i-p-tgGnd / Tub GrinderTub GrinderTub Grinder748SGU---------Gnd
a-.-G-U-i-p-ttGnd / Tractor TrailerTractor TrailerPublic Works749SGU---------Gnd
a-.-G-U-i-p-wdGnd / Wheel DozerWheel DozerWheel Dozer750SGU---------Gnd
a-.-G-U-i-p-wllGnd / Wheel Loaders (Large)Wheel Loaders (Large)Public Works751SGU---------Gnd
a-.-G-U-i-p-wlmGnd / Wheel Loaders (Medium)Wheel Loaders (Medium)Public Works752SGU---------Gnd
a-.-G-U-i-p-wlsGnd / Wheel Loaders (Small)Wheel Loaders (Small)Public Works753SGU---------Gnd
a-.-G-U-i-p-wptGnd / Water Purification TeamWater Purification TeamPublic Works754SGU---------Gnd
a-.-G-U-i-p-wtGnd / Water TruckWater TruckWater Truck755SGU---------Gnd
a-.-G-U-i-sGnd / IM Resources / Search and RescueSearch and RescueUnit756SGU---------Gnd
a-.-G-U-i-s-arGnd / Airborne ReconnaissanceAirborne ReconnaissanceUnit757SGU---------Gnd
a-.-G-U-i-s-astGnd / Air Search TeamAir Search TeamUnit758SGU---------Gnd
a-.-G-U-i-s-casGnd / Canine SAR Team Avalanche SnowCanine SAR Team Avalanche SnowUnit759SGU---------Gnd
a-.-G-U-i-s-cavGnd / Cave SAR TeamCave SAR TeamUnit760SGU---------Gnd
a-.-G-U-i-s-cdrGnd / Canine SAR Team Disaster ResponseCanine SAR Team Disaster ResponseUnit761SGU---------Gnd
a-.-G-U-i-s-clcGnd / Canine SAR Team Land CadaverCanine SAR Team Land CadaverUnit762SGU---------Gnd
a-.-G-U-i-s-colGnd / Collapse SAR TeamCollapse SAR TeamUnit763SGU---------Gnd
a-.-G-U-i-s-cwaGnd / Canine SAR Team WaterCanine SAR Team WaterUnit764SGU---------Gnd
a-.-G-U-i-s-cwiGnd / Canine SAR Team WildernessCanine SAR Team WildernessUnit765SGU---------Gnd
a-.-G-U-i-s-cwtGnd / Canine SAR Team Wilderness TrackingCanine SAR Team Wilderness TrackingUnit766SGU---------Gnd
a-.-G-U-i-s-mntGnd / Mountain SAR TeamMountain SAR TeamUnit767SGU---------Gnd
a-.-G-U-i-s-mtGnd / Mine Tunnel SAR TeamMine Tunnel SAR TeamUnit768SGU---------Gnd
a-.-G-U-i-s-rdfGnd / Radio Direction Finding TeamRadio Direction Finding TeamUnit769SGU---------Gnd
a-.-G-U-i-s-sfdGnd / Swiftwater Flood Search and Dive Rescue TeamSwiftwater Flood Search and Dive Rescue TeamUnit770SGU---------Gnd
a-.-G-U-i-s-uisGnd / USAR Incident Support TeamUSAR Incident Support TeamUnit771SGU---------Gnd
a-.-G-U-i-s-utfGnd / USAR Task ForceUSAR Task ForceUnit772SGU---------Gnd
a-.-G-U-i-s-wiGnd / Wilderness SAR TeamWilderness SAR TeamUnit773SGU---------Gnd
a-.-G-U-SGnd / combat service supportCombat service supportUnit774SGUS---------Gnd
a-.-G-U-S-AGnd / administrative (admin)Administrative (admin)Unit775SGUSA---------Gnd
a-.-G-U-S-A-CGnd / admin corpsAdmin corpsAdmin corps776SGUSAC---------Gnd
a-.-G-U-S-A-FGnd / financeFinanceFinance777SGUSAF---------Gnd
a-.-G-U-S-A-F-CGnd / finance corpsFinance corpsFinance778SGUSAFC---------Gnd
a-.-G-U-S-A-F-TGnd / finance theaterFinance theaterFinance779SGUSAFT---------Gnd
a-.-G-U-S-A-JGnd / judge advocate general (JAG)Judge advocate general (JAG)Unit780SGUSAJ---------Gnd
a-.-G-U-S-A-J-CGnd / JAG corpsJAG corpsJAG corps781SGUSAJC---------Gnd
a-.-G-U-S-A-J-TGnd / JAG theaterJAG theaterJAG theater782SGUSAJT---------Gnd
a-.-G-U-S-A-LGnd / laborLaborLabor783SGUSAL---------Gnd
a-.-G-U-S-A-L-CGnd / labor corpsLabor corpsLabor corps784SGUSALC---------Gnd
a-.-G-U-S-A-L-TGnd / labor theaterLabor theaterLabor785SGUSALT---------Gnd
a-.-G-U-S-A-MGnd / mortuary / graves registryMortuary / graves registryUnit786SGUSAM---------Gnd
a-.-G-U-S-A-M-CGnd / mortuary / graves registry corpsMortuary / graves registry corpsUnit787SGUSAMC---------Gnd
a-.-G-U-S-A-M-TGnd / mortuary / graves registry theaterMortuary / graves registry theaterUnit788SGUSAMT---------Gnd
a-.-G-U-S-A-OGnd / postalPostalPostal789SGUSAO---------Gnd
a-.-G-U-S-A-O-CGnd / postal corpsPostal corpsPostal corps790SGUSAOC---------Gnd
a-.-G-U-S-A-O-TGnd / postal theaterPostal theaterPostal791SGUSAOT---------Gnd
a-.-G-U-S-A-PGnd / public affairsPublic affairsUnit792SGUSAP---------Gnd
a-.-G-U-S-A-P-BGnd / public affairs broadcastPublic affairs broadcastUnit793SGUSAPB---------Gnd
a-.-G-U-S-A-P-B-CGnd / public affairs broadcast corpsPublic affairs broadcast corpsUnit794SGUSAPBC---------Gnd
a-.-G-U-S-A-P-B-TGnd / public affairs broadcast theaterPublic affairs broadcast theaterUnit795SGUSAPBT---------Gnd
a-.-G-U-S-A-P-CGnd / public affairs corpsPublic affairs corpsUnit796SGUSAPC---------Gnd
a-.-G-U-S-A-P-MGnd / public affairs joint information bureauPublic affairs joint information bureauUnit797SGUSAPM---------Gnd
a-.-G-U-S-A-P-M-CGnd / public affairs JIB corpsPublic affairs JIB corpsUnit798SGUSAPMC---------Gnd
a-.-G-U-S-A-P-M-TGnd / public affairs JIB theaterPublic affairs JIB theaterUnit799SGUSAPMT---------Gnd
a-.-G-U-S-A-P-TGnd / public affairs theaterPublic affairs theaterUnit800SGUSAPT---------Gnd
a-.-G-U-S-A-QGnd / quartermaster (supply)Quartermaster (supply)Unit801SGUSAQ---------Gnd
a-.-G-U-S-A-Q-CGnd / quartermaster (supply) corpsQuartermaster (supply) corpsUnit802SGUSAQC---------Gnd
a-.-G-U-S-A-Q-TGnd / quartermaster (supply) theaterQuartermaster (supply) theaterUnit803SGUSAQT---------Gnd
a-.-G-U-S-A-RGnd / religious / chaplainReligious / chaplainUnit804SGUSAR---------Gnd
a-.-G-U-S-A-R-CGnd / religious / chaplain corpsReligious / chaplain corpsUnit805SGUSARC---------Gnd
a-.-G-U-S-A-R-TGnd / religious / chaplain theaterReligious / chaplain theaterUnit806SGUSART---------Gnd
a-.-G-U-S-A-SGnd / personnel servicesPersonnel servicesUnit807SGUSAS---------Gnd
a-.-G-U-S-A-S-CGnd / personnel corpsPersonnel corpsUnit808SGUSASC---------Gnd
a-.-G-U-S-A-S-TGnd / personnel theaterPersonnel theaterUnit809SGUSAST---------Gnd
a-.-G-U-S-A-TGnd / admin theaterAdmin theaterUnit810SGUSAT---------Gnd
a-.-G-U-S-A-WGnd / morale, welfare, recreation (MWR)Morale, welfare, recreation (MWR)Unit811SGUSAW---------Gnd
a-.-G-U-S-A-W-CGnd / MWR corpsMWR corpsMWR corps812SGUSAWC---------Gnd
a-.-G-U-S-A-W-TGnd / MWR theaterMWR theaterMWR theater813SGUSAWT---------Gnd
a-.-G-U-S-A-XGnd / replacement holding unit (RHU)Replacement holding unit (RHU)Unit814SGUSAX---------Gnd
a-.-G-U-S-A-X-CGnd / RHU corpsRHU corpsRHU corps815SGUSAXC---------Gnd
a-.-G-U-S-A-X-TGnd / RHU theaterRHU theaterRHU theater816SGUSAXT---------Gnd
a-.-G-U-S-MGnd / medicalMedicalMedical817SGUSM---------Gnd
a-.-G-U-S-M-CGnd / medical corpsMedical corpsMedical818SGUSMC---------Gnd
a-.-G-U-S-M-DGnd / medical dentalMedical dentalMedical819SGUSMD---------Gnd
a-.-G-U-S-M-D-CGnd / medical dental corpsMedical dental corpsMedical820SGUSMDC---------Gnd
a-.-G-U-S-M-D-TGnd / medical dental theaterMedical dental theaterMedical821SGUSMDT---------Gnd
a-.-G-U-S-M-MGnd / medical treatment facilityMedical treatment facilityMedical822SGUSMM---------Gnd
a-.-G-U-S-M-M-CGnd / medical treatment facility corpsMedical treatment facility corpsMedical823SGUSMMC---------Gnd
a-.-G-U-S-M-M-TGnd / medical treatment facility theaterMedical treatment facility theaterMedical824SGUSMMT---------Gnd
a-.-G-U-S-M-PGnd / medical psychologicalMedical psychologicalMedical825SGUSMP---------Gnd
a-.-G-U-S-M-P-CGnd / medical psychological corpsMedical psychological corpsMedical826SGUSMPC---------Gnd
a-.-G-U-S-M-P-TGnd / medical psychological theaterMedical psychological theaterMedical827SGUSMPT---------Gnd
a-.-G-U-S-M-TGnd / medical theaterMedical theaterMedical828SGUSMT---------Gnd
a-.-G-U-S-M-VGnd / medical veterinaryMedical veterinaryMedical829SGUSMV---------Gnd
a-.-G-U-S-M-V-CGnd / medical veterinary corpsMedical veterinary corpsMedical830SGUSMVC---------Gnd
a-.-G-U-S-M-V-TGnd / medical veterinary theaterMedical veterinary theaterMedical831SGUSMVT---------Gnd
a-.-G-U-S-SGnd / supplySupplySupply832SGUSS---------Gnd
a-.-G-U-S-S-1Gnd / supply class ISupply class ISupply833SGUSS1---------Gnd
a-.-G-U-S-S-1-CGnd / supply class I corpsSupply class I corpsSupply834SGUSS1C---------Gnd
a-.-G-U-S-S-1-TGnd / supply class I theaterSupply class I theaterSupply835SGUSS1T---------Gnd
a-.-G-U-S-S-2Gnd / supply class IISupply class IISupply836SGUSS2---------Gnd
a-.-G-U-S-S-2-CGnd / supply class II corpsSupply class II corpsSupply837SGUSS2C---------Gnd
a-.-G-U-S-S-2-TGnd / supply class II theaterSupply class II theaterSupply838SGUSS2T---------Gnd
a-.-G-U-S-S-3Gnd / supply class IIISupply class IIISupply839SGUSS3---------Gnd
a-.-G-U-S-S-3-AGnd / supply class III aviationSupply class III aviationSupply840SGUSS3A---------Gnd
a-.-G-U-S-S-3-A-CGnd / supply class III aviation corpsSupply class III aviation corpsSupply841SGUSS3AC---------Gnd
a-.-G-U-S-S-3-A-TGnd / supply class III aviation theaterSupply class III aviation theaterSupply842SGUSS3AT---------Gnd
a-.-G-U-S-S-3-CGnd / supply class III corpsSupply class III corpsSupply843SGUSS3C---------Gnd
a-.-G-U-S-S-3-TGnd / supply class III theaterSupply class III theaterSupply844SGUSS3T---------Gnd
a-.-G-U-S-S-4Gnd / supply class IVSupply class IVSupply845SGUSS4---------Gnd
a-.-G-U-S-S-4-CGnd / supply class IV corpsSupply class IV corpsSupply846SGUSS4C---------Gnd
a-.-G-U-S-S-4-TGnd / supply class IV theaterSupply class IV theaterSupply847SGUSS4T---------Gnd
a-.-G-U-S-S-5Gnd / supply class VSupply class VSupply848SGUSS5---------Gnd
a-.-G-U-S-S-5-CGnd / supply class V corpsSupply class V corpsSupply849SGUSS5C---------Gnd
a-.-G-U-S-S-5-TGnd / supply class V theaterSupply class V theaterSupply850SGUSS5T---------Gnd
a-.-G-U-S-S-6Gnd / supply class VISupply class VISupply851SGUSS6---------Gnd
a-.-G-U-S-S-6-CGnd / supply class VI corpsSupply class VI corpsSupply852SGUSS6C---------Gnd
a-.-G-U-S-S-6-TGnd / supply class VI theaterSupply class VI theaterSupply853SGUSS6T---------Gnd
a-.-G-U-S-S-7Gnd / supply class VIISupply class VIISupply854SGUSS7---------Gnd
a-.-G-U-S-S-7-CGnd / supply class VII corpsSupply class VII corpsSupply855SGUSS7C---------Gnd
a-.-G-U-S-S-7-TGnd / supply class VII theaterSupply class VII theaterSupply856SGUSS7T---------Gnd
a-.-G-U-S-S-8Gnd / supply class VIIISupply class VIIISupply857SGUSS8---------Gnd
a-.-G-U-S-S-8-CGnd / supply class VIII corpsSupply class VIII corpsSupply858SGUSS8C---------Gnd
a-.-G-U-S-S-8-TGnd / supply class VIII theaterSupply class VIII theaterSupply859SGUSS8T---------Gnd
a-.-G-U-S-S-9Gnd / supply class IXSupply class IXSupply860SGUSS9---------Gnd
a-.-G-U-S-S-9-CGnd / supply class IX corpsSupply class IX corpsSupply861SGUSS9C---------Gnd
a-.-G-U-S-S-9-TGnd / supply class IX theaterSupply class IX theaterSupply862SGUSS9T---------Gnd
a-.-G-U-S-S-CGnd / supply corpsSupply corpsSupply corps863SGUSSC---------Gnd
a-.-G-U-S-S-dGnd / SupplyDepotSupplyDepotSupplyDepot864SGUSS---------Gnd
a-.-G-U-S-S-LGnd / supply laundry / bathbathSupply865SGUSSL---------Gnd
a-.-G-U-S-S-L-CGnd / supply laundry / bath corpsbath corpsSupply866SGUSSLC---------Gnd
a-.-G-U-S-S-L-TGnd / supply laundry / bath theaterbath theaterSupply867SGUSSLT---------Gnd
a-.-G-U-S-S-TGnd / supply theaterSupply theaterSupply868SGUSST---------Gnd
a-.-G-U-S-S-WGnd / supply waterSupply waterSupply water869SGUSSW---------Gnd
a-.-G-U-S-S-W-CGnd / supply water corpsSupply water corpsSupply water870SGUSSWC---------Gnd
a-.-G-U-S-S-W-PGnd / supply water purificationSupply water purificationSupply water871SGUSSWP---------Gnd
a-.-G-U-S-S-W-P-CGnd / supply water purification corpsSupply water purification corpsSupply water872SGUSSWPC---------Gnd
a-.-G-U-S-S-W-P-TGnd / supply water purification theaterSupply water purification theaterSupply water873SGUSSWPT---------Gnd
a-.-G-U-S-S-W-TGnd / supply water theaterSupply water theaterSupply water874SGUSSWT---------Gnd
a-.-G-U-S-S-XGnd / supply class XSupply class XSupply875SGUSSX---------Gnd
a-.-G-U-S-S-X-CGnd / supply class X corpsSupply class X corpsSupply876SGUSSXC---------Gnd
a-.-G-U-S-S-X-TGnd / supply class X theaterSupply class X theaterSupply877SGUSSXT---------Gnd
a-.-G-U-S-TGnd / transportationTransportationUnit878SGUST---------Gnd
a-.-G-U-S-T-AGnd / APOD / APOEAPOD / APOEAPOD / APOE879SGUSTA---------Gnd
a-.-G-U-S-T-A-CGnd / APOD / APOE corpsAPOD / APOE corpsAPOD / APOE880SGUSTAC---------Gnd
a-.-G-U-S-T-A-TGnd / APOD / APOE theaterAPOD / APOE theaterAPOD / APOE881SGUSTAT---------Gnd
a-.-G-U-S-T-CGnd / transportation corpsTransportation corpsUnit882SGUSTC---------Gnd
a-.-G-U-S-T-IGnd / missileMissileMissile883SGUSTI---------Gnd
a-.-G-U-S-T-I-CGnd / missile corpsMissile corpsMissile884SGUSTIC---------Gnd
a-.-G-U-S-T-I-TGnd / missile theaterMissile theaterMissile885SGUSTIT---------Gnd
a-.-G-U-S-T-MGnd / movement control center(MCC)Movement control center(MCC)Unit886SGUSTM---------Gnd
a-.-G-U-S-T-M-CGnd / MCC corpsMCC corpsMCC corps887SGUSTMC---------Gnd
a-.-G-U-S-T-M-TGnd / MCC theaterMCC theaterMCC theater888SGUSTMT---------Gnd
a-.-G-U-S-T-RGnd / railheadRailheadRailhead889SGUSTR---------Gnd
a-.-G-U-S-T-R-CGnd / railhead corpsRailhead corpsRailhead890SGUSTRC---------Gnd
a-.-G-U-S-T-R-TGnd / railhead theaterRailhead theaterRailhead891SGUSTRT---------Gnd
a-.-G-U-S-T-SGnd / SPOD / SPOESPOD / SPOESPOD / SPOE892SGUSTS---------Gnd
a-.-G-U-S-T-S-CGnd / SPOD / SPOE corpsSPOD / SPOE corpsSPOD / SPOE893SGUSTSC---------Gnd
a-.-G-U-S-T-S-TGnd / SPOD / SPOE theaterSPOD / SPOE theaterSPOD / SPOE894SGUSTST---------Gnd
a-.-G-U-S-T-TGnd / transportation theaterTransportation theaterUnit895SGUSTT---------Gnd
a-.-G-U-S-XGnd / maintenanceMaintenanceMaintenance896SGUSX---------Gnd
a-.-G-U-S-X-CGnd / maintenance corpsMaintenance corpsMaintenance897SGUSXC---------Gnd
a-.-G-U-S-X-EGnd / electro opticalElectro opticalMaintenance898SGUSXE---------Gnd
a-.-G-U-S-X-E-CGnd / electro optical corpsElectro optical corpsMaintenance899SGUSXEC---------Gnd
a-.-G-U-S-X-E-TGnd / electro optical theaterElectro optical theaterMaintenance900SGUSXET---------Gnd
a-.-G-U-S-X-HGnd / maintenance heavyMaintenance heavyMaintenance901SGUSXH---------Gnd
a-.-G-U-S-X-H-CGnd / maintenance heavy corpsMaintenance heavy corpsMaintenance902SGUSXHC---------Gnd
a-.-G-U-S-X-H-TGnd / maintenance heavy theaterMaintenance heavy theaterMaintenance903SGUSXHT---------Gnd
a-.-G-U-S-X-OGnd / ordnanceOrdnanceOrdnance904SGUSXO---------Gnd
a-.-G-U-S-X-O-CGnd / ordnance corpsOrdnance corpsOrdnance905SGUSXOC---------Gnd
a-.-G-U-S-X-O-MGnd / ordnance missileOrdnance missileOrdnance906SGUSXOM---------Gnd
a-.-G-U-S-X-O-M-CGnd / ordnance missile corpsOrdnance missile corpsOrdnance907SGUSXOMC---------Gnd
a-.-G-U-S-X-O-M-TGnd / ordnance missile theaterOrdnance missile theaterOrdnance908SGUSXOMT---------Gnd
a-.-G-U-S-X-O-TGnd / ordnance theaterOrdnance theaterOrdnance909SGUSXOT---------Gnd
a-.-G-U-S-X-RGnd / maintenance recoveryMaintenance recoveryMaintenance910SGUSXR---------Gnd
a-.-G-U-S-X-R-CGnd / maintenance recovery corpsMaintenance recovery corpsMaintenance911SGUSXRC---------Gnd
a-.-G-U-S-X-R-TGnd / maintenance recovery theaterMaintenance recovery theaterMaintenance912SGUSXRT---------Gnd
a-.-G-U-S-X-TGnd / maintenance theaterMaintenance theaterMaintenance913SGUSXT---------Gnd
a-.-G-U-UGnd / combat supportCombat supportUnit914SGUU---------Gnd
a-.-G-U-U-AGnd / combat support NBCCombat support NBCUnit915SGUUA---------Gnd
a-.-G-U-U-A-BGnd / biologicalBiologicalBiological916SGUUAB---------Gnd
a-.-G-U-U-A-B-RGnd / recon equippedRecon equippedBiological917SGUUABR---------Gnd
a-.-G-U-U-A-CGnd / chemicalChemicalChemical918SGUUAC---------Gnd
a-.-G-U-U-A-C-CGnd / smoke / deconSmoke / deconSmoke / decon919SGUUACC---------Gnd
a-.-G-U-U-A-C-C-KGnd / mechanized smoke / deconMechanized smoke / deconSmoke / decon920SGUUACCK---------Gnd
a-.-G-U-U-A-C-C-MGnd / motorized smoke / deconMotorized smoke / deconSmoke / decon921SGUUACCM---------Gnd
a-.-G-U-U-A-C-RGnd / chemical reconChemical reconChemical922SGUUACR---------Gnd
a-.-G-U-U-A-C-R-SGnd / chemical wheeled armored vehicleChemical wheeled armored vehicleChemical923SGUUACRS---------Gnd
a-.-G-U-U-A-C-R-WGnd / chemical wheeled armored vehicleChemical wheeled armored vehicleChemical924SGUUACRW---------Gnd
a-.-G-U-U-A-C-SGnd / smokeSmokeSmoke925SGUUACS---------Gnd
a-.-G-U-U-A-C-S-AGnd / armor smokeArmor smokeArmor smoke926SGUUACSA---------Gnd
a-.-G-U-U-A-C-S-MGnd / motorized smokeMotorized smokeSmoke927SGUUACSM---------Gnd
a-.-G-U-U-A-DGnd / decontaminationDecontaminationUnit928SGUUAD---------Gnd
a-.-G-U-U-A-NGnd / nuclearNuclearNuclear929SGUUAN---------Gnd
a-.-G-U-U-EGnd / explosive ordinance disposalExplosive ordinance disposalUnit930SGUUE---------Gnd
a-.-G-U-U-IGnd / information warfare unitInformation warfare unitUnit931SGUUI---------Gnd
a-.-G-U-U-LGnd / law enforcement unitLaw enforcement unitUnit932SGUUL---------Gnd
a-.-G-U-U-L-CGnd / civilian law enforcementCivilian law enforcementUnit933SGUULC---------Gnd
a-.-G-U-U-L-DGnd / central intelligence division (CID)Central intelligence division (CID)Unit934SGUULD---------Gnd
a-.-G-U-U-L-FGnd / security police (air)Security police (air)Unit935SGUULF---------Gnd
a-.-G-U-U-L-MGnd / military policeMilitary policeUnit936SGUULM---------Gnd
a-.-G-U-U-L-SGnd / shore patrolShore patrolShore patrol937SGUULS---------Gnd
a-.-G-U-U-MGnd / military intelligenceMilitary intelligenceUnit938SGUUM---------Gnd
a-.-G-U-U-M-AGnd / aerial exploitationAerial exploitationUnit939SGUUMA---------Gnd
a-.-G-U-U-M-CGnd / counter intelligenceCounter intelligenceUnit940SGUUMC---------Gnd
a-.-G-U-U-M-JGnd / joint intelligence centerJoint intelligence centerUnit941SGUUMJ---------Gnd
a-.-G-U-U-M-M-OGnd / meteorologicalMeteorologicalUnit942SGUUMMO---------Gnd
a-.-G-U-U-M-OGnd / operationsOperationsOperations943SGUUMO---------Gnd
a-.-G-U-U-M-QGnd / interrogationInterrogationUnit944SGUUMQ---------Gnd
a-.-G-U-U-M-RGnd / surveillanceSurveillanceSurveillance945SGUUMR---------Gnd
a-.-G-U-U-M-R-GGnd / ground surveillance radarGround surveillance radarSurveillance946SGUUMRG---------------Gnd
a-.-G-U-U-M-R-OGnd / MeteorologicalMeteorologicalSurveillance947SGUUMRO---------Gnd
a-.-G-U-U-M-R-SGnd / sensorSensorSensor948SGUUMRS---------Gnd
a-.-G-U-U-M-R-S-SGnd / sensor SCMSensor SCMSensor SCM949SGUUMRSS---------Gnd
a-.-G-U-U-M-R-XGnd / ground station moduleGround station moduleSurveillance950SGUUMRX---------Gnd
a-.-G-U-U-M-SGnd / signal intelligence (SIGINT)Signal intelligence (SIGINT)Unit951SGUUMS---------Gnd
a-.-G-U-U-M-S-EGnd / electronic warfareElectronic warfareUnit952SGUUMSE---------Gnd
a-.-G-U-U-M-S-E-AGnd / armored wheeled vehicleArmored wheeled vehicleUnit953SGUUMSEA---------Gnd
a-.-G-U-U-M-S-E-CGnd / corpsCorpsCorps954SGUUMSEC---------Gnd
a-.-G-U-U-M-S-E-DGnd / direction findingDirection findingUnit955SGUUMSED---------Gnd
a-.-G-U-U-M-S-E-IGnd / interceptInterceptIntercept956SGUUMSEI---------Gnd
a-.-G-U-U-M-S-E-JGnd / jammingJammingJamming957SGUUMSEJ---------Gnd
a-.-G-U-U-M-S-E-TGnd / theaterTheaterTheater958SGUUMSET---------Gnd
a-.-G-U-U-M-TGnd / tactical exploitTactical exploitUnit959SGUUMT---------Gnd
a-.-G-U-U-PGnd / landing supportLanding supportUnit960SGUUP---------Gnd
a-.-G-U-U-SGnd / signal unitSignal unitSignal unit961SGUUS---------Gnd
a-.-G-U-U-S-AGnd / areaAreaArea962SGUUSA---------Gnd
a-.-G-U-U-S-CGnd / communication configured packageCommunication configured packageSignal unit963SGUUSC---------Gnd
a-.-G-U-U-S-C-LGnd / large communication configured packageLarge communication configured packageSignal unit964SGUUSCL---------Gnd
a-.-G-U-U-S-FGnd / forward communicationsForward communicationsSignal unit965SGUUSF---------Gnd
a-.-G-U-U-S-MGnd / multiple subscriber elementMultiple subscriber elementSignal unit966SGUUSM---------Gnd
a-.-G-U-U-S-M-LGnd / large extension nodeLarge extension nodeSignal unit967SGUUSML---------Gnd
a-.-G-U-U-S-M-NGnd / node centerNode centerNode center968SGUUSMN---------Gnd
a-.-G-U-U-S-M-SGnd / small extension nodeSmall extension nodeSignal unit969SGUUSMS---------Gnd
a-.-G-U-U-S-OGnd / command operationsCommand operationsSignal unit970SGUUSO---------Gnd
a-.-G-U-U-S-RGnd / radio unitRadio unitRadio unit971SGUUSR---------Gnd
a-.-G-U-U-S-R-SGnd / tactical satelliteTactical satelliteRadio unit972SGUUSRS---------Gnd
a-.-G-U-U-S-R-TGnd / teletype centerTeletype centerRadio unit973SGUUSRT---------Gnd
a-.-G-U-U-S-R-WGnd / relayRelayRelay974SGUUSRW---------Gnd
a-.-G-U-U-S-SGnd / signal supportSignal supportSignal unit975SGUUSS---------Gnd
a-.-G-U-U-S-WGnd / telephone switchTelephone switchSignal unit976SGUUSW---------Gnd
a-.-G-U-U-S-XGnd / electronic rangingElectronic rangingSignal unit977SGUUSX---------Gnd
a-.-PWAR / SPCSpace trackSpace track978SP--------------------WAR
a-.-P-LWAR / SPC / SLVSpace launch vehicleSpace track979SPL---------WAR
a-.-P-SWAR / SPC / SATSatelliteSatellite980SPS---------WAR
a-.-P-TWAR / SPC / SSTSpace stationSpace track981SPT---------WAR
a-.-P-VWAR / SPC / CSVCrewed space vehicleSpace track982SPV---------WAR
a-.-SSurface / sea surface trackSea surface trackWatercraft983SS---------Surface
a-.-S-CSurface / combatantCombatantWarship984SSC---------Surface
a-.-S-C-ASurface / amphibious warfare shipAmphibious warfare shipAmphibious985SSCA---------Surface
a-.-S-C-A-L-ASurface / assault vesselAssault vesselAmphibious986SSCALA---------Surface
a-.-S-C-A-L-CSurface / landing craftLanding craftAmphibious987SSCALC---------Surface
a-.-S-C-A-L-SSurface / landing shipLanding shipLanding ship988SSCALS---------Surface
a-.-S-C-A-L-S-MSurface / landing ship / MDMMediumMedium989SSCALSM---------Surface
a-.-S-C-A-L-S-TSurface / landing ship / TankTankTank990SSCALST---------Surface
a-.-S-C-DWAR / SSUF / CBTT / SUFDCYSurface decoyDecoy991SSCD------------------WAR
a-.-S-C-GSurface / Navy groupNavy groupNavy group992SSG---------Surface
a-.-S-C-HSurface / hovercraftHovercraftHovercraft993SSCH---------Surface
a-.-S-C-LSurface / lineLineLine994SSCLSurface
a-.-S-C-L-B-BSurface / battleshipBattleshipBattleship995SSCLBBSurface
a-.-S-C-L-C-CSurface / cruiserCruiserCruiser996SSCLCCSurface
a-.-S-C-L-C-VSurface / carrierCarrierCarrier997SSCLCVSurface
a-.-S-C-L-D-DSurface / destroyerDestroyerDestroyer998SSCLDDSurface
a-.-S-C-L-F-FSurface / frigate / corvetteFrigate / corvetteFrigate999SSCLFFSurface
a-.-S-C-L-L-LSurface / Line / Littoral combatantLittoral combatantLine1000SSCLLLSurface
a-.-S-C-L-L-L-A-SSurface / Line / Littoral combatant / AntisubmarineAntisubmarine warfare mission packageLine1001SSCLLLASSurface
a-.-S-C-L-L-L-M-ISurface / Line / Littoral combatant / Mine warfareMine warfare mission packageLine1002SSCLLLMISurface
a-.-S-C-L-L-L-S-USurface / Line / Littoral combatant / Surface warfareSurface warfare (SUW) mission packageLine1003SSCLLLSUSurface
a-.-S-C-MSurface / mine warfare vesselMine warfare vesselWarship1004SSCMSurface
a-.-S-C-M-M-ASurface / MCM supportMCM supportMCM support1005SSCMMASurface
a-.-S-C-M-M-DSurface / MCM droneMCM droneMCM drone1006SSCMMDSurface
a-.-S-C-M-M-HSurface / minehunterMinehunterMinehunter1007SSCMMHSurface
a-.-S-C-M-M-LSurface / minelayerMinelayerMinelayer1008SSCMMLSurface
a-.-S-C-M-M-SSurface / minesweeperMinesweeperMinesweeper1009SSCMMSSurface
a-.-S-C-PSurface / patrolPatrolPatrol1010SSCPSurface
a-.-S-C-P-S-BSurface / antisubmarine warfareAntisubmarine warfarePatrol1011SSCPSBSurface
a-.-S-C-P-S-USurface / antisurface warfareAntisurface warfarePatrol1012SSCPSUSurface
a-.-S-C-P-S-U-GSurface / antisurface warfare / gunGunGun1013SSCPSUGSurface
a-.-S-C-P-S-U-MSurface / antisurface warfare / Anti-ship missileAnti-ship missilePatrol1014SSCPSUMSurface
a-.-S-C-P-S-U-TSurface / antisurface warfare / TorpedoTorpedoTorpedo1015SSCPSUTSurface
a-.-S-C-SSurface / Unmanned Surface Vehicle Control StationUnmanned Surface Vehicle (Usv) Control StationStation1016SSCSSurface
a-.-S-C-USurface / Unmanned Surface Vehicle / Unmanned surface vehicleUnmanned surface vehicleUSV1017SSCUSurface
a-.-S-C-U-MSurface / Unmanned Surface Vehicle / Mine Countermeasures Surface DroneMine Countermeasures Surface DroneUSV1018SSCUMSurface
a-.-S-C-U-NSurface / Unmanned Surface Vehicle / Antisurface warfareAntisurface warfareUSV1019SSCUNSurface
a-.-S-C-U-SSurface / Unmanned Surface Vehicle / Antisubmarine warfareAntisubmarine warfareUSV1020SSCUSSurface
a-.-S-GSurface / navy groupNavy groupNavy group1021SSGSurface
a-.-S-G-CSurface / convoyConvoyConvoy1022SSGCSurface
a-.-S-G-GSurface / navy task groupNavy task groupTask group1023SSGGSurface
a-.-S-G-TSurface / navy task forceNavy task forceTask force1024SSGTSurface
a-.-S-G-USurface / navy task unitNavy task unitTask unit1025SSGUSurface
a-.-S-NSurface / noncombatantNoncombatantNoncombatant1026SSNSurface
a-.-S-N-FSurface / fleet supportFleet supportNoncombatant1027SSNFSurface
a-.-S-N-HSurface / hovercraftHovercraftHovercraft1028SSNHSurface
a-.-S-N-ISurface / intelligenceIntelligenceIntelligence1029SSNISurface
a-.-S-N-MSurface / hospital shipHospital shipHospital1030SSNMSurface
a-.-S-N-NSurface / stationStationStation1031SSNNSurface
a-.-S-N-N-RSurface / rescueRescueRescue1032SSNNRSurface
a-.-S-N-RSurface / underway replenishmentUnderway replenishmentNoncombatant1033SSNRSurface
a-.-S-N-SSurface / service / support harborService / support harborNoncombatant1034SSNSSurface
a-.-S-OSurface / own trackOwn trackOwn track1035SSOSurface
a-.-S-SSurface / stationStationStation1036SSSSurface
a-.-S-S-ASurface / ASW shipASW shipASW ship1037SSSASurface
a-.-S-S-PSurface / picketPicketPicket1038SSSPSurface
a-.-S-XSurface / non militaryNon militaryNon military1039SSXSurface
a-.-S-X-FSurface / fishingFishingFishing1040SSXFSurface
a-.-S-X-F-D-FSurface / drifterDrifterDrifter1041SSXFDFSurface
a-.-S-X-F-D-RSurface / dredgeDredgeDredge1042SSXFDRSurface
a-.-S-X-F-T-RSurface / trawlerTrawlerTrawler1043SSXFTRSurface
a-.-S-X-HSurface / hovercraftHovercraftHovercraft1044SSXHSurface
a-.-S-X-LSurface / law enforcement vesselLaw enforcement vesselPolice1045SSXLSurface
a-.-S-X-MSurface / merchantMerchantMerchant1046SSXMSurface
a-.-S-X-M-CSurface / cargoCargoCargo1047SSXMCSurface
a-.-S-X-M-FSurface / ferryFerryFerry1048SSXMFSurface
a-.-S-X-M-HSurface / hazardous materials (hazmat)Hazardous materials (hazmat)HAZMAT1049SSXMHSurface
a-.-S-X-M-OSurface / oiler / tankerOiler / tankerOiler / tanker1050SSXMOSurface
a-.-S-X-M-PSurface / passengerPassengerPassenger1051SSXMPSurface
a-.-S-X-M-RSurface / roll on / roll offRoll on / roll offMerchant1052SSXMRSurface
a-.-S-X-M-T-OSurface / towing vesselTowing vesselTowing1053SSXMTOSurface
a-.-S-X-M-T-USurface / tugTugTug1054SSXMTUSurface
a-.-S-X-RSurface / leisure craftLeisure craftLeisure1055SSXRSurface
a-.-USubSurf / subsurface trackSubsurface trackSubsurface1056SUSubSurf
a-.-U-NSubSurf / non submarineNon submarineNon-submarine1057SUNSubSurf
a-.-U-N-DSubSurf / diverDiverDiver1058SUNDSubSurf
a-.-U-SSubSurf / submarineSubmarineSubmarine1059SUSSubSurf
a-.-U-S-CSubSurf / submarine conventional propulsionSubmarine conventional propulsionSubmarine1060SUSCSubSurf
a-.-U-S-C-ASubSurf / submarine conventional propulsion / Attack Submarine (Ss)Attack (SS)Attack (SS)1061SUSCASubSurf
a-.-U-S-C-BSubSurf / submarine conventional propulsion / Ballistic missile (SSB)Ballistic missile (SSB)SSB1062SUSCBSubSurf
a-.-U-S-C-FSubSurf / submarine conventional propulsion / Surfaced Conventional Propulsion SubmarineSurfaced Conventional Propulsion SubmarineSurfaced1063SUSCFSubSurf
a-.-U-S-C-GSubSurf / submarine conventional propulsion / Guided Missile Submarine (Ssg)Guided Missile Submarine (Ssg)SSG1064SUSCGSubSurf
a-.-U-S-C-MSubSurf / submarine conventional propulsion / Missile Submarine (Type Unknown)Missile Submarine (Type Unknown)Missile1065SUSCMSubSurf
a-.-U-S-FSubSurf / submarine conventional propulsion / Surfaced SubmarineSurfacedSurfaced1066SUSFSubSurf
a-.-U-S-NSubSurf / submarine nuclear propulsionSubmarine nuclear propulsionSubmarine1067SUSNSubSurf
a-.-U-S-N-ASubSurf / submarine nuclear propulsion /Attack (ssn)Attack (ssn)1068SUSNASubSurf
a-.-U-S-N-BSubSurf / submarine nuclear propulsion / Ballistic missile (SSBN)Ballistic missile (SSBN)SSBN1069SUSNBSubSurf
a-.-U-S-N-FSubSurf / submarine nuclear propulsion / Surfaced Nuclear Propulsion SubmarineSurfaced Nuclear Propulsion SubmarineSurfaced1070SUSNFSubSurf
a-.-U-S-N-GSubSurf / submarine nuclear propulsion / Guided missile (SSGN)Guided missile (SSGN)SSGN1071SUSNGSubSurf
a-.-U-S-N-MSubSurf / submarine nuclear propulsion / Missile (type unknown)Missile (type unknown)Missile1072SUSNMSubSurf
a-.-U-S-OSubSurf / other submersibleOther submersibleSubmarine1073SUSOSubSurf
a-.-U-S-O-FSubSurf / other submersible / Surfaced Other SubmersibleSurfaced Other SubmersibleSurfaced1074SUSOFSubSurf
a-.-U-S-SSubSurf / stationStationStation1075SUSSSubSurf
a-.-U-S-S-ASubSurf / ASW submarineASW submarineStation1076SUSSASubSurf
a-.-U-S-USubSurf / unmanned underwater vehicle (UUV)Unmanned underwater vehicle (UUV)Submarine1077SUSUSubSurf
a-.-U-S-U-MSubSurf / Mine Warfare Subsurface DroneMine Warfare Subsurface DroneMine warfare1078SUSUMSubSurf
a-.-U-S-U-NSubSurf / Antisurface Warfare Subsurface DroneAntisurface warfareSubmarine1079SUSUNSubSurf
a-.-U-S-U-SSubSurf / Antisubmarine Warfare Subsurface DroneAntisubmarine warfareSubmarine1080SUSUSSubSurf
a-.-U-WSubSurf / underwater weaponUnderwater weaponWeapon1081SUWSubSurf
a-.-U-W-DSubSurf / underwater decoyUnderwater decoyDecoy1082SUWDSubSurf
a-.-U-W-D-MSubSurf / sea mine decoySea mine decoyMine decoy1083SUWDMSubSurf
a-.-U-W-MSubSurf / sea mineSea mineSea mine1084SUWMSubSurf
a-.-U-W-M-DSubSurf / sea mine dealtSea mine dealtSea mine1085SUWMDSubSurf
a-.-U-W-M-FSubSurf / sea mine (floating)Sea mine (floating)Sea mine1086SUWMFSubSurf
a-.-U-W-M-F-DSubSurf / sea mine (floating) dealtSea mine (floating) dealtSea mine1087SUWMFDSubSurf
a-.-U-W-M-GSubSurf / sea mine (ground)Sea mine (ground)Sea mine1088SUWMGSubSurf
a-.-U-W-M-G-DSubSurf / sea mine (ground) dealtSea mine (ground) dealtSea mine1089SUWMGDSubSurf
a-.-U-W-M-MSubSurf / sea mine (moored)Sea mine (moored)Sea mine1090SUWMMSubSurf
a-.-U-W-M-M-DSubSurf / sea mine (moored) dealtSea mine (moored) dealtSea mine1091SUWMMDSubSurf
a-.-U-W-M-OSubSurf / sea mine (in other position)Sea mine (in other position)Sea mine1092SUWMOSubSurf
a-.-U-W-M-O-DSubSurf / sea mine (in other position) dealtSea mine (in other position) dealtSea mine1093SUWMODSubSurf
a-.-U-W-TSubSurf / torpedoTorpedoTorpedo1094SUWTSubSurf
a-.-XOtherOtherOther1095Other
a-.-X-iOther / incidentIncidentIncident1096Other
a-.-X-i-cOther / incident / CBRNECBRNECBRNE1097Other
a-.-X-i-eOther / incident / pollution environmentalPollution and other EnvironmentalIncident1098Other
a-.-X-i-fOther / incident / fireIncident FireFire1099EIC----------Other
a-.-X-i-f-hOther / incident / fire / hot spotIncident Fire Hot SpotFire1100Other
a-.-X-i-f-nOther / incident / fire / non residentialIncident Fire Non-residentialFire1101EICB---------Other
a-.-X-i-f-n-hOther / incident / fire / non residential special needIncident Fire Non-residential Special NeedFire1102Other
a-.-X-i-f-n-sOther / incident / fire / non residential schoolIncident Fire Non-residential SchoolFire1103Other
a-.-X-i-f-oOther / incident / fire / originIncident Fire OriginFire1104Other
a-.-X-i-f-pOther / incident / fire / special needsIncident Fire Special NeedsFire1105EICG---------Other
a-.-X-i-f-rOther / incident / fire / residentialIncident Fire ResidentialFire1106Other
a-.-X-i-f-sOther / incident / fire / smokeIncident Fire SmokeSmoke1107EICF---------Other
a-.-X-i-f-wOther / incident / fire / wildIncident Fire WildWildfire1108Other
a-.-X-i-gOther / incident / geoGeophysicalGeophysical1109Other
a-.-X-i-g-aOther / incident / geo / avalancheGeophysical AvalancheAvalanche1110ENAB---------Other
a-.-X-i-g-eOther / incident / geo / earthquakeGeophysical EarthquakeEarthquake1111Other
a-.-X-i-g-e-aOther / incident / geo / aftershockGeophysical Earthquake AftershockAftershock1112ENAC---------Other
a-.-X-i-g-e-eOther / incident / geo / epicenterGeophysical Earthquake EpicenterEpicenter1113ENAC---------Other
a-.-X-i-g-lOther / incident / geo / landslideGeophysical LandslideLandslide1114ENAD---------Other
a-.-X-i-g-sOther / incident / geo / subsistanceGeophysical SubsistanceSubsistance1115Other
a-.-X-i-g-vOther / incident / geo / volcanoGeophysical VolcanoVolcano1116Other
a-.-X-i-g-v-eOther / incident / geo / eruptionGeophysical Volcano EruptionEruption1117WAS-WSVE--P----Other
a-.-X-i-g-v-tOther / incident / geo / volcano threatGeophysical Volcano ThreatVolcano1118ENAG---------Other
a-.-X-i-hOther / incident / medical public healthMedical and Public HealthHealth1119Other
a-.-X-i-iOther / incident / infrastructureInfrastructureIncident1120Other
a-.-X-i-lOther / incident / securitySecuritySecurity1121Other
a-.-X-i-l-cOther / incident / security / civil disturbSecurity Civil DisturbanceSecurity1122EIA----------Other
a-.-X-i-l-c-dOther / incident / security / civil disturb / demonstrationSecurity Civil Disturbance DemonstrationDemonstration1123OOD----------Other
a-.-X-i-l-c-pOther / incident / security / civil disturb / displacedSecurity Civil Disturbance Displaced PopulationSecurity1124OGA----------Other
a-.-X-i-l-c-rOther / incident / security / civil disturb / riotingSecurity Civil Disturbance RiotingRioting1125EIAC---------Other
a-.-X-i-l-lOther / incident / security / law enforcementSecurity Law Enforcement ActivitySecurity1126EIB----------Other
a-.-X-i-l-l-bOther / incident / security / law enforcement / bombingSecurity Law Enforcement Activity BombingBombing1127Other
a-.-X-i-l-l-b-eOther / incident / security / law enforcement / bomb explosionSecurity Law Enforcement Activity Bombing ExplosionExplosion1128EIBC---------Other
a-.-X-i-l-l-b-tOther / incident / security / law enforcementbomb threatSecurity Law Enforcement Activity Bombing ThreatBomb Threat1129EIBA---------Other
a-.-X-i-l-l-lOther / incident / security / law enforcement / lootingSecurity Law Enforcement Activity LootingLooting1130EIBD---------Other
a-.-X-i-l-l-pOther / incident / security / law enforcement / poisoningSecurity Law Enforcement Activity PoisoningPoisoning1131OVP----------Other
a-.-X-i-l-l-sOther / incident / security / law enforcement / shootingSecurity Law Enforcement Activity ShootingShooting1132EIBF---------Other
a-.-X-i-mOther / incident / metHYDRO-METEOROLOGICALWeather1133Other
a-.-X-i-m-aOther / incident / met / sandstormMeteorological SandstormSandstorm1134Other
a-.-X-i-m-cOther / incident / met / cycloneMeteorological CycloneCyclone1135WAS-WSTSS-P----Other
a-.-X-i-m-dOther / incident / met / droughtMeteorological DroughtDrought1136ENBB---------Other
a-.-X-i-m-fOther / incident / met / floodMeteorological FloodFlood1137ENBC---------Other
a-.-X-i-m-gOther / incident / met / fogMeteorological FogFog1138WAS-WSFGSOP----Other
a-.-X-i-m-hOther / incident / met / hailMeteorological HailHail1139WAS-WSGRL-P----Other
a-.-X-i-m-iOther / incident / met / inversionMeteorological InversionInversion1140ENBF---------Other
a-.-X-i-m-nOther / incident / met / tsunamiMeteorological TsunamiTsunami1141ENBM---------Other
a-.-X-i-m-rOther / incident / met / rainMeteorological RainRain1142WAS-WSR-LIP----Other
a-.-X-i-m-sOther / incident / met / snowMeteorological SnowSnow1143WAS-WSS-LIP----Other
a-.-X-i-m-tOther / incident / met / tornadoMeteorological TornadoTornado1144WAS-WST-FCP----Other
a-.-X-i-m-uOther / incident / metthunderstormMeteorological ThunderstormThunderstorm1145WAS-WSTMH-P----Other
a-.-X-i-m-zOther / incident / met / drizzleMeteorological DrizzleDrizzle1146WAS-WSD-LIP----Other
a-.-X-i-oOther / incident / otherOtherOther1147OOCC---------Other
a-.-X-i-rOther / incident / rescueRescueRescue1148GGGPAR--****XOther
a-.-X-i-sOther / incident / safetySafetySafety1149Other
a-.-X-i-tOther / incident / transportation /Public and Private transportationIncident1150Other
a-.-X-i-t-aOther / incident / transportation / airPublic and Private transportation Air IncidentIncident1151EIE----------Other
a-.-X-i-t-a-aOther / incident / transportation / air accidentPublic and Private transportation Air AccidentIncident1152EIEA---------Other
a-.-X-i-t-a-hOther / incident / transportation / air hijackingPublic and Private transportation Air HijackingIncident1153OOHA---------Other
a-.-X-i-t-mOther / incident / transportation / maritimePublic and Private transportation Maritime IncidentIncident1154EIF----------Other
a-.-X-i-t-m-aOther / incident / transportation / maritime accidentPublic and Private transportation Maritime AccidentIncident1155EIFA---------Other
a-.-X-i-t-m-hOther / incident / transportation / maritime hijackingPublic and Private transportation Maritime HijackingIncident1156OOHV---------Other
a-.-X-i-t-rOther / incident / transportation / railPublic and Private transportation Rail IncidentIncident1157EIG----------Other
a-.-X-i-t-r-aOther / incident / transportation / rail accidentPublic and Private transportation Rail AccidentIncident1158EIGA---------Other
a-.-X-i-t-r-hOther / incident / transportation / rail hijackingPublic and Private transportation Rail HijackingIncident1159EIGB---------Other
a-.-X-i-t-vOther / incident / transportation / vehiclePublic and Private transportation Vehicle IncidentIncident1160EIH----------Other
a-.-X-i-t-v-aOther / incident / transportation / vehicle accidentPublic and Private transportation Vehicle AccidentIncident1161EIHA---------Other
a-.-X-i-t-v-hOther / incident / transportation / vehicle hijackingPublic and Private transportation Vehicle HijackingIncident1162OOHT---------Other
bBitsBits1163Bits
b-dDetectionDetection1164Detection
b-d-aDetection / AcousticAcoustic1165Detection
b-d-a-cDetection / Acoustic / CyclostationaryCyclostationary1166Detection
b-d-a-iDetection / Acoustic / ImpulsiveImpulsive1167Detection
b-d-a-vDetection / Acoustic / VoiceVoice1168Detection
b-d-cDetection / CBRNECBRNE1169Detection
b-d-c-bDetection / CBRNE / BioChemBioChem1170Detection
b-d-c-b-bDetection / CBRNE / BioChem / BiologicalBiological1171Detection
b-d-c-b-cDetection / CBRNE / BioChem / ChemicalChemical1172Detection
b-d-c-eDetection / CBRNE / ExplosiveExplosive1173Detection
b-d-c-e-dDetection / CBRNE / Explosive / DeviceDevice1174Detection
b-d-c-nDetection / CBRNE / NuclearRadiologicalNuclearRadiological1175Detection
b-d-c-n-nDetection / CBRNE / NuclearRadiological / NuclearNuclear1176Detection
b-d-c-n-n-bDetection / CBRNE / NuclearRadiological / Nuclear / BombBomb1177Detection
b-d-c-n-n-smDetection / CBRNE / NuclearRadiological / Nuclear / Special Nuclear MaterialSpecial Nuclear Material1178Detection
b-d-c-n-rDetection / CBRNE / NuclearRadiological / RadiationRadiation1179Detection
b-d-c-n-r-ddDetection / CBRNE / NuclearRadiological / Radiological / Dispersal Device (Dirty Bomb)Dispersal Device (Dirty Bomb)1180Detection
b-d-iDetection / ImpactImpact1181Detection
b-d-i-mDetection / Impact / MortarMortar1182Detection
b-d-lDetection / LaunchLaunch1183Detection
b-d-l-bDetection / Launch / BulletBullet1184Detection
b-d-l-mDetection / Launch / MortarMortar1185Detection
b-d-mDetection / MotionMotion1186Detection
b-d-nDetection / NuclearNuclear1187Detection
b-d-rDetection / RadiaitionRadiaition1188Detection
b-d-sDetection / SeismicSeismic1189Detection
b-g-.TACGRPTactical Graphics1190TACGRP
b-g-.-FTACGRP / FSUPPFire Support1191TACGRP
b-g-.-F-ATACGRP / C2GM / AVN / ARSAreas1192TACGRP
b-g-.-F-A-ATACGRP / FSUPP / ARS / C2ARS / FSAFire Support Area (Fsa)Circular1193GFACSC--****XTACGRP
b-g-.-F-A-BTACGRP / FSUPP / ARS / ARATGT / BMARABomb AreaCircular1194GFATB---****XTACGRP
b-g-.-F-A-CTACGRP / FSUPP / ARS / C2ARS / ACAAirspace Coordination Area (Aca)Circular1195GFACAC--****XTACGRP
b-g-.-F-A-FTACGRP / FSUPP / ARS / C2ARS / FFAFree Fire Area (Ffa)Circular1196GFACFC--****XTACGRP
b-g-.-F-A-KTACGRP / FSUPP / ARS / ARATGT / SMKSmokeCircular1197GFATS---****XTACGRP
b-g-.-F-A-NTACGRP / FSUPP / ARS / C2ARS / NFA / CIRCLRNo Fire Area (Nfa)Circular1198GFACNC--****XTACGRPCIRCLR
b-g-.-F-A-PTACGRP / FSUPP / ARS / C2ARS / PAAPosition Area For Artillery (Paa)Circular1199GFACPC--****XTACGRP
b-g-.-F-A-RTACGRP / FSUPP / ARS / C2ARS / RFA / CIRCLRRestrictive Fire Area (Rfa)Circular1200GFACRC--****XTACGRPCIRCLR
b-g-.-F-A-STACGRP / FSUPP / ARS / ARATGT / SGTGTSeries Or Group Of Targets1201GFATG---****XTACGRP
b-g-.-F-A-TTACGRP / FSUPP / ARS / ARATGTArea Target1202GFAT----****XTACGRP
b-g-.-F-LTACGRP / FSUPP / LNELines1203TACGRP
b-g-.-F-L-CTACGRP / FSUPP / LNE / C2LNE / CFLCoordinated Fire Line (Cfl)1204GFLCC---****XTACGRP
b-g-.-F-L-FTACGRP / FSUPP / LNE / C2LNE / FSCLFire Support Coordination Line (Fscl)1205GFLCF---****XTACGRP
b-g-.-F-L-LTACGRP / FSUPP / LNE / LNRTGTLinear Target1206GFLT----****XTACGRP
b-g-.-F-L-NTACGRP / FSUPP / LNE / C2LNE / NFLNo-Fire Line (Nfl)1207GFLCN---****XTACGRP
b-g-.-F-L-PTACGRP / FSUPP / LNE / LNRTGT / FPFFinal Protective Fire (Fpf)1208GFLTF---****XTACGRP
b-g-.-F-L-RTACGRP / FSUPP / LNE / C2LNE / RFLRestrictive Fire Line (Rfl)1209GFLCR---****XTACGRP
b-g-.-F-L-STACGRP / FSUPP / LNE / LNRTGT / LSTGTLinear Smoke Target1210GFLTS---****XTACGRP
b-g-.-F-PTACGRP / FSUPP / PNTPoint1211TACGRP
b-g-.-F-P-STACGRP / FSUPP / PNT / C2PNT / FSSFire Support Station1212GFPCF---****XTACGRP
b-g-.-F-P-TTACGRP / FSUPP / PNT / TGTTarget1213TACGRP
b-g-.-F-P-T-CTACGRP / FSUPP / ARS / ARATGT / CIRTGTCircular Target1214GFATC---****XTACGRP
b-g-.-F-P-T-NTACGRP / FSUPP / PNT / TGT / NUCTGTNuclear Target1215GFPTN---****XTACGRP
b-g-.-F-P-T-RTACGRP / FSUPP / ARS / ARATGT / RTGTGTRectangular Target1216GFATR---****XTACGRP
b-g-.-F-P-T-STACGRP / FSUPP / PNT / TGT / PTGTPoint / Single Target1217GFPTS---****XTACGRP
b-g-.-GTACGRP / C2GMCommand And Control And General Maneuver1218TACGRP
b-g-.-G-ATACGRP / C2GM / AVNAviation1219TACGRP
b-g-.-G-A-ATACGRP / C2GM / AVN / ARSAreas1220TACGRP
b-g-.-G-A-A-FTACGRP / C2GM / AVN / ARS / FFAADEZForward Area Air Defense Zone (Faadez)1221TACGRP
b-g-.-G-A-A-HTACGRP / C2GM / AVN / ARS / HIDACZHigh Density Airspace Control Zone (Hidacz)1222GGAAH---****XTACGRP
b-g-.-G-A-A-MTACGRP / C2GM / AVN / ARS / MEZMissile Engagement Zone (Mez)1223GGAAM---****XTACGRP
b-g-.-G-A-A-M-HTACGRP / C2GM / AVN / ARS / MEZ / HAMEZHigh Altitude Mez1224GGAAMH--****XTACGRPHAMEZ
b-g-.-G-A-A-M-LTACGRP / C2GM / AVN / ARS / MEZ / LAMEZLow Altitude Mez1225GGAAML--****XTACGRPLAMEZ
b-g-.-G-A-A-RTACGRP / C2GM / AVN / ARS / ROZRestricted Operations Zone (Roz)1226GGAAR---****XTACGRP
b-g-.-G-A-A-WTACGRP / C2GM / AVN / ARS / WFZWeapons Free Zone1227GGAAW---****XTACGRP
b-g-.-G-A-LTACGRP / C2GM / AVN / LNELines1228TACGRP
b-g-.-G-A-L-CTACGRP / C2GM / AVN / LNE / ACDRAir Corridor1229GGALC---****XTACGRP
b-g-.-G-A-L-LTACGRP / C2GM / AVN / LNE / LLTRLow Level Transit Route (Lltr)1230GGALL---****XTACGRP
b-g-.-G-A-L-MTACGRP / C2GM / AVN / LNE / MRRMinimum Risk Route (Mrr)1231GGALM---****XTACGRP
b-g-.-G-A-L-STACGRP / C2GM / AVN / LNE / SAAFRStandard-Use Army Aircraft Flight Route (Saafr)1232GGALS---****XTACGRP
b-g-.-G-A-L-UTACGRP / C2GM / AVN / LNE / UARUnmanned Aircraft (Ua) Route1233GGALU---****XTACGRP
b-g-.-G-A-PTACGRP / C2GM / AVN / PNTPoints1234TACGRP
b-g-.-G-A-P-CTACGRP / C2GM / AVN / PNT / COMMCPCommunications Checkpoint (Ccp)1235GGAPC---****XTACGRP
b-g-.-G-A-P-DTACGRP / C2GM / AVN / PNT / DAPPDowned Aircrew Pickup Point1236GGAPD---****XTACGRP
b-g-.-G-A-P-PTACGRP / C2GM / AVN / PNT / ACPAir Control Point (Acp)1237GGAPP---****XTACGRP
b-g-.-G-A-P-UTACGRP / C2GM / AVN / PNT / PUPPull-Up Point (Pup)1238GGAPU---****XTACGRP
b-g-.-G-DTACGRP / C2GM / DEFDefense1239TACGRP
b-g-.-G-D-ATACGRP / C2GM / AVN / ARSAreas1240TACGRP
b-g-.-G-D-A-BTACGRP / C2GM / DEF / ARS / BTLPSNBattle Position1241GGDAB---****XTACGRP
b-g-.-G-D-A-B-PTACGRP / C2GM / DEF / ARS / BTLPSN / PBNOPrepared But Not Occupied1242GGDABP--****XTACGRPPBNO
b-g-.-G-D-A-ETACGRP / C2GM / DEF / ARS / EMTARAEngagement Area1243GGDAE---****XTACGRP
b-g-.-G-D-LMETOC / AMPHC / PRS / LNELines1244METOC
b-g-.-G-D-L-FTACGRP / C2GM / DEF / LNE / FEBAForward Edge Of Battle Area (Feba)1245GGDLF---****XTACGRP
b-g-.-G-D-L-PTACGRP / C2GM / DEF / LNE / PDFPrincipal Direction Of Fire (Pdf)1246GGDLP---****XTACGRP
b-g-.-G-D-PTACGRP / C2GM / AVN / PNTPoints1247TACGRP
b-g-.-G-D-P-OTACGRP / C2GM / DEF / PNT / OBSPSTObservation Post / Outpost1248GGDPO---****XTACGRP
b-g-.-G-D-P-O-CTACGRP / C2GM / DEF / PNT / OBSPST / CBTPSTCombat Outpost1249GGDPOC--****XTACGRPCBTPST
b-g-.-G-D-P-O-FTACGRP / C2GM / DEF / PNT / OBSPST / FWDOPForward Observer Position1250GGDPOF--****XTACGRPFWDOP
b-g-.-G-D-P-O-NTACGRP / C2GM / DEF / PNT / OBSPST / CBRNOPCbrn Observation Post (Dismounted)1251GGDPON--****XTACGRPCBRNOP
b-g-.-G-D-P-O-RTACGRP / C2GM / DEF / PNT / OBSPST / RECONObservation Post Occupied By Dismounted Scouts Or Reconnaissance1252GGDPOR--****XTACGRPRECON
b-g-.-G-D-P-O-STACGRP / C2GM / DEF / PNT / OBSPST / SOPSensor Outpost / Listening Post (Op / Lp)1253GGDPOS--****XTACGRPSOP
b-g-.-G-D-P-TTACGRP / C2GM / DEF / PNT / TGTREFTarget Reference Point (Trp)1254GGDPT---****XTACGRP
b-g-.-G-GTACGRP / C2GM / GNLGeneral1255TACGRP
b-g-.-G-G-ATACGRP / C2GM / AVN / ARSAreas1256TACGRP
b-g-.-G-G-A-ATACGRP / C2GM / GNL / ARS / ABYARAAssembly Area1257GGGAA---****XTACGRP
b-g-.-G-G-A-DTACGRP / C2GM / GNL / ARS / DRPZDrop Zone1258GGGAD---****XTACGRP
b-g-.-G-G-A-ETACGRP / C2GM / DEF / ARS / EMTARAEngagement Area1259GGDAE---****XTACGRP
b-g-.-G-G-A-FTACGRP / C2GM / GNL / ARS / FTFDARFortified Area1260GGGAF---****XTACGRP
b-g-.-G-G-A-GTACGRP / C2GM / GNL / ARS / GENARAGeneral Area1261GGGAG---****XTACGRP
b-g-.-G-G-A-LTACGRP / C2GM / GNL / ARS / LZLanding Zone (Lz)1262GGGAL---****XTACGRP
b-g-.-G-G-A-PTACGRP / C2GM / GNL / ARS / PZPickup Zone (Pz)1263GGGAP---****XTACGRP
b-g-.-G-G-A-STACGRP / C2GM / GNL / ARS / SRHARASearch Area / Reconnaissance Area1264GGGAS---****XTACGRP
b-g-.-G-G-A-XTACGRP / C2GM / GNL / ARS / EZExtraction Zone (Ez)1265GGGAX---****XTACGRP
b-g-.-G-G-A-YTACGRP / C2GM / GNL / ARS / LAARALimited Access Area1266GGGAY---****XTACGRP
b-g-.-G-G-A-ZTACGRP / C2GM / GNL / ARS / AIRFZAirfield Zone1267GGGAZ---****XTACGRP
b-g-.-G-G-LTACGRP / C2GM / GNL / LNELines1268TACGRP
b-g-.-G-G-L-BTACGRP / C2GM / GNL / LNE / BNDSBoundaries1269GGGLB---****XTACGRP
b-g-.-G-G-L-CTACGRP / C2GM / GNL / LNE / LOCLine Of Contact1270GGGLC---****XTACGRP
b-g-.-G-G-L-FTACGRP / C2GM / GNL / LNE / FLOTForward Line Of Own Troops (Flot)1271GGGLF---****XTACGRP
b-g-.-G-G-L-LTACGRP / C2GM / GNL / LNE / LITLNELight Line1272GGGLL---****XTACGRP
b-g-.-G-G-L-PTACGRP / C2GM / GNL / LNE / PHELNEPhase Line1273GGGLP---****XTACGRP
b-g-.-G-G-PTACGRP / C2GM / AVN / PNTPoints1274TACGRP
b-g-.-G-G-P-ATACGRP / C2GM / GNL / PNT / ACTLAir Control1275GGGPA---****XTACGRP
b-g-.-G-G-P-A-ATACGRP / C2GM / GNL / PNT / ACTL / ASBWFAntisubmarine Warfare Fixed Wing1276GGGPAA--****XTACGRPASBWF
b-g-.-G-G-P-A-CTACGRP / C2GM / GNL / PNT / REFPNT / CRDRTBCorridor Tab1277GGGPRC--****XTACGRPCRDRTB
b-g-.-G-G-P-A-HTACGRP / C2GM / GNL / PNT / ACTL / ASBWRAntisubmarine Warfare Rotorary Wing1278GGGPAH--****XTACGRPASBWR
b-g-.-G-G-P-A-KTACGRP / C2GM / GNL / PNT / ACTL / TAKTanking1279GGGPAK--****XTACGRPTAK
b-g-.-G-G-P-A-LTACGRP / C2GM / GNL / PNT / ACTL / RPHReplenish1280GGGPAL--****XTACGRPRPH
b-g-.-G-G-P-A-MTACGRP / C2GM / GNL / PNT / ACTL / ORBRTOrbit - Race TrackMarshall1281GGGPAM--****XTACGRPORBRT
b-g-.-G-G-P-A-OTACGRP / C2GM / GNL / PNT / ACTL / TMCTomcat1282GGGPAO--****XTACGRPTMC
b-g-.-G-G-P-A-PTACGRP / C2GM / GNL / PNT / ACTL / CAPCombat Air Patrol (Cap)1283GGGPAP--****XTACGRPCAP
b-g-.-G-G-P-A-RTACGRP / C2GM / GNL / PNT / ACTL / RSCRescue1284GGGPAR--****XTACGRPRSC
b-g-.-G-G-P-A-STACGRP / C2GM / GNL / PNT / ACTL / SKEIPStrike Ip1285GGGPAS--****XTACGRPSKEIP
b-g-.-G-G-P-A-TTACGRP / C2GM / GNL / PNT / ACTL / TCNTacan1286GGGPAT--****XTACGRPTCN
b-g-.-G-G-P-A-WTACGRP / C2GM / GNL / PNT / ACTL / ABNEWAirborne Early Warning (Aew)1287GGGPAW--****XTACGRPABNEW
b-g-.-G-G-P-FTACGRP / C2GM / GNL / PNT / FRMNFormation1288GGGPF---****XTACGRP
b-g-.-G-G-P-HTACGRP / C2GM / GNL / PNT / HBRHarbor (General)1289GGGPH---****XTACGRP
b-g-.-G-G-P-H-ATACGRP / C2GM / GNL / PNT / HBR / PNTAPoint A1290GGGPHA--****XTACGRPPNTA
b-g-.-G-G-P-H-QTACGRP / C2GM / GNL / PNT / HBR / PNTQPoint Q1291GGGPHQ--****XTACGRPPNTQ
b-g-.-G-G-P-H-XTACGRP / C2GM / GNL / PNT / HBR / PNTXPoint X1292GGGPHX--****XTACGRPPNTX
b-g-.-G-G-P-H-YTACGRP / C2GM / GNL / PNT / HBR / PNTYPoint Y1293GGGPHY--****XTACGRPPNTY
b-g-.-G-G-P-OTACGRP / C2GM / GNL / PNT / RTERoute1294GGGPO---****XTACGRP
b-g-.-G-G-P-O-DTACGRP / C2GM / GNL / PNT / RTE / DVSNDiversions1295GGGPOD--****XTACGRPDVSN
b-g-.-G-G-P-O-PTACGRP / C2GM / GNL / PNT / RTE / PIMPim1296GGGPOP--****XTACGRPPIM
b-g-.-G-G-P-O-RTACGRP / C2GM / GNL / PNT / RTE / PNTRPoint R1297GGGPOR--****XTACGRPPNTR
b-g-.-G-G-P-O-WTACGRP / C2GM / GNL / PNT / ACTPNT / WAPWaypoint1298GGGPPW--****XTACGRPWAP
b-g-.-G-G-P-O-ZTACGRP / C2GM / GNL / PNT / RTE / RDVRendezvous1299GGGPOZ--****XTACGRPRDV
b-g-.-G-G-P-PTACGRP / C2GM / GNL / PNT / ACTPNTAction Points (General)1300GGGPP---****XTACGRP
b-g-.-G-G-P-P-CTACGRP / C2GM / GNL / PNT / ACTPNT / CONPNTContact Point1301GGGPPC--****XTACGRPCONPNT
b-g-.-G-G-P-P-DTACGRP / C2GM / GNL / PNT / ACTPNT / DCNPNTDecision Point1302GGGPPD--****XTACGRPDCNPNT
b-g-.-G-G-P-P-ETACGRP / C2GM / GNL / PNT / ACTPNT / RELPNTRelease Point1303GGGPPE--****XTACGRPRELPNT
b-g-.-G-G-P-P-KTACGRP / C2GM / GNL / PNT / ACTPNT / CHKPNTCheck Point1304GGGPPK--****XTACGRPCHKPNT
b-g-.-G-G-P-P-LTACGRP / C2GM / GNL / PNT / ACTPNT / LNKUPTLinkup Point1305GGGPPL--****XTACGRPLNKUPT
b-g-.-G-G-P-P-OTACGRP / C2GM / GNL / PNT / ACTPNT / CRDPNTCoordination Point1306GGGPPO--****XTACGRPCRDPNT
b-g-.-G-G-P-P-PTACGRP / C2GM / GNL / PNT / ACTPNT / PSSPNTPassage Point1307GGGPPP--****XTACGRPPSSPNT
b-g-.-G-G-P-P-RTACGRP / C2GM / GNL / PNT / ACTPNT / RAYPNTRally Point1308GGGPPR--****XTACGRPRAYPNT
b-g-.-G-G-P-P-STACGRP / C2GM / GNL / PNT / ACTPNT / STRPNTStart Point1309GGGPPS--****XTACGRPSTRPNT
b-g-.-G-G-P-P-WTACGRP / C2GM / GNL / PNT / ACTPNT / WAPWaypoint1310GGGPPW--****XTACGRPWAP
b-g-.-G-G-P-RTACGRP / C2GM / GNL / PNT / REFPNTReference Point1311GGGPR---****XTACGRP
b-g-.-G-G-P-R-DTACGRP / C2GM / GNL / PNT / REFPNT / DLRPDlrp1312GGGPRD--****XTACGRPDLRP
b-g-.-G-G-P-R-ITACGRP / C2GM / GNL / PNT / REFPNT / PNTINRPoint Of Interest1313GGGPRI--****XTACGRPPNTINR
b-g-.-G-G-P-R-NTACGRP / C2GM / GNL / PNT / REFPNT / NAVREFNavigational Reference Point1314GGGPRN--****XTACGRPNAVREF
b-g-.-G-G-P-R-STACGRP / C2GM / GNL / PNT / REFPNT / SPLPNTSpecial Point1315GGGPRS--****XTACGRPSPLPNT
b-g-.-G-G-P-UTACGRP / C2GM / GNL / PNT / USWUNDER SEA WARFARE1316TACGRP
b-g-.-G-G-P-U-STACGRP / C2GM / GNL / PNT / USW / SRHSearch1317GGGPUS--****XTACGRPSRH
b-g-.-G-G-P-U-S-ATACGRP / C2GM / GNL / PNT / USW / SRH / ARASearch Area1318GGGPUSA-****XTACGRPSRHARA
b-g-.-G-G-P-U-S-CTACGRP / C2GM / GNL / PNT / USW / SRH / CTRSearch Center1319GGGPUSC-****XTACGRPSRHCTR
b-g-.-G-G-P-U-S-DTACGRP / C2GM / GNL / PNT / USW / SRH / DIPPSNDip Position1320GGGPUSD-****XTACGRPSRHDIPPSN
b-g-.-G-G-P-U-UTACGRP / C2GM / GNL / PNT / USW / UH2Underwater1321TACGRPUH2
b-g-.-G-G-P-U-U-BTACGRP / C2GM / GNL / PNT / USW / UH2 / BCONBrief Contact1322GGGPUUB-****XTACGRPUH2BCON
b-g-.-G-G-P-U-U-DTACGRP / C2GM / GNL / PNT / USW / UH2 / DTMDatum1323GGGPUUD-****XTACGRPUH2DTM
b-g-.-G-G-P-U-U-LTACGRP / C2GM / GNL / PNT / USW / UH2 / LCONLost Contact1324GGGPUUL-****XTACGRPUH2LCON
b-g-.-G-G-P-U-U-STACGRP / C2GM / GNL / PNT / USW / UH2 / SNKSinker1325GGGPUUS-****XTACGRPUH2SNK
b-g-.-G-G-P-U-YTACGRP / C2GM / GNL / PNT / USW / SNBYSonobuoy1326GGGPUY--****XTACGRPSNBY
b-g-.-G-G-P-U-Y-ATACGRP / C2GM / GNL / PNT / USW / SNBY / ANMAnm1327GGGPUYA-****XTACGRPSNBYANM
b-g-.-G-G-P-U-Y-BTACGRP / C2GM / GNL / PNT / USW / SNBY / BTBathythermograph Transmitting (Bt)1328GGGPUYB-****XTACGRPSNBYBT
b-g-.-G-G-P-U-Y-CTACGRP / C2GM / GNL / PNT / USW / SNBY / CASSCommand Active Sonobuoy System (Cass)1329GGGPUYC-****XTACGRPSNBYCASS
b-g-.-G-G-P-U-Y-DTACGRP / C2GM / GNL / PNT / USW / SNBY / DIFARDirectional Frequency Analyzing And Recording (Difar)1330GGGPUYD-****XTACGRPSNBYDIFAR
b-g-.-G-G-P-U-Y-KTACGRP / C2GM / GNL / PNT / USW / SNBY / KGPKingpin1331GGGPUYK-****XTACGRPSNBYKGP
b-g-.-G-G-P-U-Y-LTACGRP / C2GM / GNL / PNT / USW / SNBY / LOFARLow Frequency Analyzing And Recording (Lofar)1332GGGPUYL-****XTACGRPSNBYLOFAR
b-g-.-G-G-P-U-Y-PTACGRP / C2GM / GNL / PNT / USW / SNBY / PTNCTRPattern Center1333GGGPUYP-****XTACGRPSNBYPTNCTR
b-g-.-G-G-P-U-Y-RTACGRP / C2GM / GNL / PNT / USW / SNBY / RORange Only (Ro)1334GGGPUYR-****XTACGRPSNBYRO
b-g-.-G-G-P-U-Y-STACGRP / C2GM / GNL / PNT / USW / SNBY / DICASSDirectional Command Active Sonobuoy System (Dicass)1335GGGPUYS-****XTACGRPSNBYDICASS
b-g-.-G-G-P-U-Y-TTACGRP / C2GM / GNL / PNT / USW / SNBY / ATACAtac1336GGGPUYT-****XTACGRPSNBYATAC
b-g-.-G-G-P-U-Y-VTACGRP / C2GM / GNL / PNT / USW / SNBY / VLADVertical Line Array Difar (Vlad)1337GGGPUYV-****XTACGRPSNBYVLAD
b-g-.-G-G-P-WTACGRP / C2GM / GNL / PNT / WPNWeapon1338TACGRP
b-g-.-G-G-P-W-ATACGRP / C2GM / GNL / PNT / WPN / AIMPNTAim Point1339GGGPWA--****XTACGRPAIMPNT
b-g-.-G-G-P-W-DTACGRP / C2GM / GNL / PNT / WPN / DRPPNTDrop Point1340GGGPWD--****XTACGRPDRPPNT
b-g-.-G-G-P-W-ETACGRP / C2GM / GNL / PNT / WPN / ENTPNTEntry Point1341GGGPWE--****XTACGRPENTPNT
b-g-.-G-G-P-W-GTACGRP / C2GM / GNL / PNT / WPN / GRDZROGround Zero1342GGGPWG--****XTACGRPGRDZRO
b-g-.-G-G-P-W-ITACGRP / C2GM / GNL / PNT / WPN / IMTPNTImpact Point1343GGGPWI--****XTACGRPIMTPNT
b-g-.-G-G-P-W-MTACGRP / C2GM / GNL / PNT / WPN / MSLPNTMsl Detect Point1344GGGPWM--****XTACGRPMSLPNT
b-g-.-G-G-P-W-PTACGRP / C2GM / GNL / PNT / WPN / PIPNTPredicted Impact Point1345GGGPWP--****XTACGRPPIPNT
b-g-.-G-OTACGRP / C2GM / OFFOffense1346TACGRP
b-g-.-G-O-ATACGRP / C2GM / OFF / ARSAreas1347TACGRP
b-g-.-G-O-A-ATACGRP / C2GM / OFF / ARS / ASTPSNAssault Position1348GGOAA---****XTACGRP
b-g-.-G-O-A-FTACGRP / C2GM / OFF / ARS / AFPAttack By Fire Position1349GGOAF---****XTACGRP
b-g-.-G-O-A-KTACGRP / C2GM / OFF / ARS / ATKPSNAttack Position1350GGOAK---****XTACGRP
b-g-.-G-O-A-OTACGRP / C2GM / OFF / ARS / OBJObjective1351GGOAO---****XTACGRP
b-g-.-G-O-A-PTACGRP / C2GM / OFF / ARS / PBXPenetration Box1352GGOAP---****XTACGRP
b-g-.-G-O-A-STACGRP / C2GM / OFF / ARS / SFPSupport By Fire Position1353GGOAS---****XTACGRP
b-g-.-G-O-LTACGRP / C2GM / OFF / LNELines1354TACGRP
b-g-.-G-O-L-ATACGRP / C2GM / OFF / LNE / AXSADVAXIS OF ADVANCE1355TACGRP
b-g-.-G-O-L-A-ATACGRP / C2GM / OFF / LNE / AXSADV / ABNAirborne1356GGOLAA--****XTACGRPABN
b-g-.-G-O-L-A-GTACGRP / C2GM / OFF / LNE / AXSADV / GRDGround1357TACGRPGRD
b-g-.-G-O-L-A-G-MTACGRP / C2GM / OFF / LNE / AXSADV / GRD / MANATKMain Attack1358GGOLAGM-****XTACGRPGRDMANATK
b-g-.-G-O-L-A-G-STACGRP / C2GM / OFF / LNE / AXSADV / GRD / SUPATKSupporting Attack1359GGOLAGS-****XTACGRPGRDSUPATK
b-g-.-G-O-L-A-RTACGRP / C2GM / OFF / LNE / AXSADV / ATKAttack Rotorary Wingv1360GGOLAR--****XTACGRPATK
b-g-.-G-O-L-A-VTACGRP / C2GM / OFF / LNE / AXSADV / AVNAviation1361GGOLAV--****XTACGRPAVN
b-g-.-G-O-L-CTACGRP / C2GM / OFF / LNE / LDLCLine Of Departure / Line Of Contact (Ld / Lc)1362GGOLC---****XTACGRP
b-g-.-G-O-L-FTACGRP / C2GM / OFF / LNE / FCLFinal Coordination Line1363GGOLF---****XTACGRP
b-g-.-G-O-L-ITACGRP / C2GM / OFF / LNE / INFNLEInfiltration Lane1364GGOLI---****XTACGRP
b-g-.-G-O-L-KTACGRP / C2GM / OFF / LNE / DIRATKDirection Of Attack1365TACGRP
b-g-.-G-O-L-K-ATACGRP / C2GM / OFF / LNE / DIRATK / AVNAviation1366GGOLKA--****XTACGRPAVN
b-g-.-G-O-L-K-GTACGRP / C2GM / OFF / LNE / AXSADV / GRDGround1367GGOLKA--****XTACGRPGRD
b-g-.-G-O-L-K-G-MTACGRP / C2GM / OFF / LNE / AXSADV / GRD / MANATKMain Attack1368GGOLKA--****XTACGRPGRDMANATK
b-g-.-G-O-L-K-G-STACGRP / C2GM / OFF / LNE / AXSADV / GRD / SUPATKSupporting Attack1369GGOLKA--****XTACGRPGRDSUPATK
b-g-.-G-O-L-LTACGRP / C2GM / OFF / LNE / LMTADVLimit Of Advance1370GGOLKA--****XTACGRP
b-g-.-G-O-L-PTACGRP / C2GM / OFF / LNE / PLDProbable Line Of Deployment (Pld)1371GGOLKA--****XTACGRP
b-g-.-G-O-L-TTACGRP / C2GM / OFF / LNE / LDLine Of Departure1372GGOLKA--****XTACGRP
b-g-.-G-O-PTACGRP / C2GM / OFF / PNTPoints1373TACGRP
b-g-.-G-O-P-PTACGRP / C2GM / OFF / PNT / PNTDPoint Of Departure1374GGOPP---****XTACGRP
b-g-.-G-PTACGRP / C2GM / DCPNDeception1375TACGRP
b-g-.-G-P-ATACGRP / C2GM / DCPN / AAFFAxis Of Advance For Feint1376GGPA----****XTACGRP
b-g-.-G-P-CTACGRP / C2GM / DCPN / DMYMDDummy Minefield (Dynamic)1377GGPC----****XTACGRP
b-g-.-G-P-DTACGRP / C2GM / DCPN / DMYDummy (Deception / Decoy)1378GGPD----****XTACGRP
b-g-.-G-P-FTACGRP / C2GM / DCPN / DAFFDirection Of Attack For Feint1379GGPF----****XTACGRP
b-g-.-G-P-MTACGRP / C2GM / DCPN / DMADecoy Mined Area1380GGPM----****XTACGRP
b-g-.-G-P-NTACGRP / C2GM / DCPN / DMYMSDummy Minefield (Static)1381GGPN----****XTACGRP
b-g-.-G-P-YTACGRP / C2GM / DCPN / DMADecoy Mined Area1382TACGRP
b-g-.-G-STACGRP / C2GM / SPLSpecial1383TACGRP
b-g-.-G-S-ATACGRP / C2GM / SPL / ARAArea1384TACGRP
b-g-.-G-S-A-ATACGRP / C2GM / SPL / ARA / AHDAirhead1385GGSAA---****XTACGRP
b-g-.-G-S-A-BTACGRP / C2GM / SPL / LNE / BRGHBridgehead1386GGSLB---****XTACGRP
b-g-.-G-S-A-ETACGRP / C2GM / SPL / ARA / ENCMTEncirclement1387GGSAE---****XTACGRP
b-g-.-G-S-A-NTACGRP / C2GM / SPL / ARA / NAINamed Area Of Interest (Nai)1388GGSAN---****XTACGRP
b-g-.-G-S-A-OTACGRP / C2GM / SPL / ARA / AOOArea Of Operations (Ao)1389GGSAO---****XTACGRP
b-g-.-G-S-A-TTACGRP / C2GM / SPL / ARA / TAITargeted Area Of Interest (Tai)1390GGSAT---****XTACGRP
b-g-.-G-S-LTACGRP / C2GM / SPL / LNELine1391TACGRP
b-g-.-G-S-L-ATACGRP / C2GM / SPL / LNE / AMBAmbush1392GGSLA---****XTACGRP
b-g-.-G-S-L-HTACGRP / C2GM / SPL / LNE / HGLHolding Line1393GGSLH---****XTACGRP
b-g-.-G-S-L-RTACGRP / C2GM / SPL / LNE / RELRelease Line1394GGSLR---****XTACGRP
b-g-.-MTACGRP / MOBSUMobility / Survivability1395TACGRP
b-g-.-M-BTACGRP / MOBSU / OBSTBPOBSTACLE BYPASS1396TACGRP
b-g-.-M-B-CTACGRP / MOBSU / OBSTBP / CSGSTECROSSING SITE / WATER CROSSING1397TACGRP
b-g-.-M-B-C-ATACGRP / MOBSU / OBSTBP / CSGSTE / ASTCAAssault Crossing Area1398GMBCA---****XTACGRP
b-g-.-M-B-C-BTACGRP / MOBSU / OBSTBP / CSGSTE / BRGBridge Or Gap1399GMBCB---****XTACGRP
b-g-.-M-B-C-DTACGRP / MOBSU / OBSTBP / CSGSTE / FRDDFTFord Difficult1400GMBCD---****XTACGRP
b-g-.-M-B-C-ETACGRP / MOBSU / OBSTBP / CSGSTE / FRDESYFord Easy1401GMBCE---****XTACGRP
b-g-.-M-B-C-FTACGRP / MOBSU / OBSTBP / CSGSTE / FRYFerry1402GMBCF---****XTACGRP
b-g-.-M-B-C-LTACGRP / MOBSU / OBSTBP / CSGSTE / LANELane1403GMBCL---****XTACGRP
b-g-.-M-B-C-PTACGRP / MOBSU / OBSTBP / CSGSTE / ERPEngineer Regulating Point1404GMBCP---****XTACGRP
b-g-.-M-B-C-RTACGRP / MOBSU / OBSTBP / CSGSTE / RFTRaft Site1405GMBCR---****XTACGRP
b-g-.-M-B-DTACGRP / MOBSU / OBSTBP / DFTYOBSTACLE BYPASS DIFFICULTY1406TACGRP
b-g-.-M-B-D-DTACGRP / MOBSU / OBSTBP / DFTY / DFTBypass Difficult1407GMBDD---****XTACGRP
b-g-.-M-B-D-ETACGRP / MOBSU / OBSTBP / DFTY / ESYBypass Easy1408GMBDE---****XTACGRP
b-g-.-M-B-D-ITACGRP / MOBSU / OBSTBP / DFTY / IMPBypass Impossible1409GMBDI---****XTACGRP
b-g-.-M-NTACGRP / MOBSU / CBRNCHEMICAL, BIOLOGICAL, RADIOLOGICAL, AND NUCLEAR1410TACGRP
b-g-.-M-N-BTACGRP / MOBSU / CBRN / BIOCABiologically Contaminated Area1411GMNB----****XTACGRP
b-g-.-M-N-CTACGRP / MOBSU / CBRN / CMLCAChemically Contaminated Area1412GMNC----****XTACGRP
b-g-.-M-N-DTACGRP / MOBSU / CBRN / DECONPDECONTAMINATION (DECON) POINTS1413TACGRP
b-g-.-M-N-D-ATACGRP / MOBSU / CBRN / DECONP / ALTUSPAlternate Decon Site / Point (Unspecified)1414GMNDA---****XTACGRP
b-g-.-M-N-D-BTACGRP / MOBSU / CBRN / DECONP / EQTTRPDecon Site / Point (Equipment And Troops)1415GMNDB---****XTACGRP
b-g-.-M-N-D-DTACGRP / MOBSU / CBRN / DECONP / TRGHDecon Site / Point (Thorough Decontamination)1416GMNDD---****XTACGRP
b-g-.-M-N-D-ETACGRP / MOBSU / CBRN / DECONP / EQTDecon Site / Point (Equipment)1417GMNDE---****XTACGRP
b-g-.-M-N-D-OTACGRP / MOBSU / CBRN / DECONP / OPDECNDecon Site / Point (Operational Decontamination)1418GMNDO---****XTACGRP
b-g-.-M-N-D-PTACGRP / MOBSU / CBRN / DECONP / USPDecon Site / Point (Unspecified)1419GMNDP---****XTACGRP
b-g-.-M-N-D-TTACGRP / MOBSU / CBRN / DECONP / TRPDecon Site / Point (Troops)1420GMNDT---****XTACGRP
b-g-.-M-N-ETACGRP / MOBSU / CBRN / REEVNTRELEASE EVENTS1421TACGRP
b-g-.-M-N-E-BTACGRP / MOBSU / CBRN / REEVNT / BIOBiological1422GMNEB---****XTACGRP
b-g-.-M-N-E-CTACGRP / MOBSU / CBRN / REEVNT / CMLChemical1423GMNEC---****XTACGRP
b-g-.-M-N-FTACGRP / MOBSU / CBRN / FAOTPFallout Producing1424GMNF----****XTACGRP
b-g-.-M-N-LTACGRP / MOBSU / CBRN / DRCLDose Rate Contour Lines1425GMNL----****XTACGRP
b-g-.-M-N-MTACGRP / MOBSU / CBRN / MSDZMinimum Safe Distance Zones1426GMNM----****XTACGRP
b-g-.-M-N-RTACGRP / MOBSU / CBRN / RADARadioactive Area1427GMNR----****XTACGRP
b-g-.-M-N-ZTACGRP / MOBSU / CBRN / NDGZNuclear Detonations Ground Zero1428GMNZ----****XTACGRP
b-g-.-M-OTACGRP / MOBSU / OBSTObstacles1429TACGRP
b-g-.-M-O-ATACGRP / MOBSU / OBST / ATOAntitank Obstacles1430TACGRP
b-g-.-M-O-A-DTACGRP / MOBSU / OBST / ATO / ATDANTITANK DITCH1431TACGRP
b-g-.-M-O-A-D-CTACGRP / MOBSU / OBST / ATO / ATD / ATDCComplete (Antitank Obstacles)1432GMOADC--****XTACGRPATDC
b-g-.-M-O-A-D-UTACGRP / MOBSU / OBST / ATO / ATD / ATDUCUnder Construction (Antitank Obstacles)1433GMOADU--****XTACGRPATDUC
b-g-.-M-O-A-OTACGRP / MOBSU / OBST / ATO / TDTSMANTITANK OBSTACLES: TETRAHEDRONS, DRAGONS TEETH, AND OTHER SIMILAR OBSTACLES1434TACGRP
b-g-.-M-O-A-O-FTACGRP / MOBSU / OBST / ATO / TDTSM / FIXPFDFixed And Prefabricated (Antitank Obstacles: Tetrahedrons Dragons Teeth And Other Similar Obstacles)1435GMOAOF--****XTACGRPFIXPFD
b-g-.-M-O-A-O-MTACGRP / MOBSU / OBST / ATO / TDTSM / MVBMoveable (Antitank Obstacles: Tetrahedrons Dragons Teeth And Other Similar Obstacles)1436GMOAOM--****XTACGRPMVB
b-g-.-M-O-A-O-PTACGRP / MOBSU / OBST / ATO / TDTSM / MVBPFDMoveable And Prefabricated (Antitank Obstacles: Tetrahedrons Dragons Teeth And Other Similar Obstacles)1437GMOAOP--****XTACGRPMVBPFD
b-g-.-M-O-A-RTACGRP / MOBSU / OBST / ATO / ATDATMAntitank Ditch Reinforced With Antitank Mines1438GMOAR---****XTACGRP
b-g-.-M-O-A-WTACGRP / MOBSU / OBST / ATO / ATWAntitank Wall1439GMOAW---****XTACGRP
b-g-.-M-O-BTACGRP / MOBSU / OBST / BBYBooby Trap1440GMOB----****XTACGRP
b-g-.-M-O-ETACGRP / MOBSU / OBST / OBSEFTOBSTACLE EFFECT1441TACGRP
b-g-.-M-O-E-BTACGRP / MOBSU / OBST / OBSEFT / BLKBlock1442GMOEB---****XTACGRP
b-g-.-M-O-E-DTACGRP / MOBSU / OBST / OBSEFT / DRTDisrupt1443GMOED---****XTACGRP
b-g-.-M-O-E-FTACGRP / MOBSU / OBST / OBSEFT / FIXFix1444GMOEF---****XTACGRP
b-g-.-M-O-E-TTACGRP / MOBSU / OBST / OBSEFT / TURTurn1445GMOET---****XTACGRP
b-g-.-M-O-FTACGRP / MOBSU / OBST / MNEFLDMINEFIELDS1446TACGRP
b-g-.-M-O-F-ATACGRP / MOBSU / OBST / MNEFLD / MNDARAMined Area1447GMOFA---****XTACGRP
b-g-.-M-O-F-DTACGRP / MOBSU / OBST / MNEFLD / DYNDynamic Depiction1448GMOFD---****XTACGRP
b-g-.-M-O-F-GTACGRP / MOBSU / OBST / MNEFLD / GAPGap1449GMOFG---****XTACGRP
b-g-.-M-O-F-STACGRP / MOBSU / OBST / MNEFLD / STCStatic Depiction1450GMOFS---****XTACGRP
b-g-.-M-O-GTACGRP / MOBSU / OBST / GNLGeneralGeneral Obstacle1451TACGRP
b-g-.-M-O-G-BTACGRP / MOBSU / OBST / GNL / BLTBelt1452GMOGB---****XTACGRP
b-g-.-M-O-G-FTACGRP / MOBSU / OBST / GNL / OFAObstacle Free Area1453GMOGF---****XTACGRP
b-g-.-M-O-G-LTACGRP / MOBSU / OBST / GNL / LNELine1454GMOGL---****XTACGRP
b-g-.-M-O-G-RTACGRP / MOBSU / OBST / GNL / ORAObstacle Restricted Area1455GMOGR---****XTACGRP
b-g-.-M-O-G-ZTACGRP / MOBSU / OBST / GNL / ZZone1456GMOGZ---****XTACGRP
b-g-.-M-O-MTACGRP / MOBSU / OBST / MNEMINES1457TACGRP
b-g-.-M-O-M-CTACGRP / MOBSU / OBST / MNE / MCLSTMine Cluster1458GMOMC---****XTACGRP
b-g-.-M-O-M-DTACGRP / MOBSU / OBST / MNE / ATMAHDAntitank Mine With Antihandling Device1459GMOMD---****XTACGRP
b-g-.-M-O-M-ETACGRP / MOBSU / OBST / MNE / ATMDIRAntitank Mine (Directional)1460GMOME---****XTACGRP
b-g-.-M-O-M-PTACGRP / MOBSU / OBST / MNE / APMNEAntipersonnel (Ap) Mines1461GMOMP---****XTACGRP
b-g-.-M-O-M-TTACGRP / MOBSU / OBST / MNE / ATMNEAntitank Mine (At)1462GMOMT---****XTACGRP
b-g-.-M-O-M-UTACGRP / MOBSU / OBST / MNE / USPMNEUnspecified Mine1463GMOMU---****XTACGRP
b-g-.-M-O-M-WTACGRP / MOBSU / OBST / MNE / WAMNEWide Area Mines1464GMOMW---****XTACGRP
b-g-.-M-O-RTACGRP / MOBSU / OBST / RCBBROADBLOCKS, CRATERS, AND BLOWN BRIDGES1465TACGRP
b-g-.-M-O-R-ATACGRP / MOBSU / OBST / RCBB / ABPExplosives State Of Readiness 2 (Armed-But Passable)1466GMORA---****XTACGRP
b-g-.-M-O-R-CTACGRP / MOBSU / OBST / RCBB / EXCDRoadblock Complete (Executed)1467GMORC---****XTACGRP
b-g-.-M-O-R-PTACGRP / MOBSU / OBST / RCBB / PLNDPlanned1468GMORP---****XTACGRP
b-g-.-M-O-R-STACGRP / MOBSU / OBST / RCBB / SAFEExplosives State Of Readiness 1 (Safe)1469GMORS---****XTACGRP
b-g-.-M-O-STACGRP / MOBSU / OBST / ABSAbatis1470GMOS----****XTACGRP
b-g-.-M-O-TTACGRP / MOBSU / OBST / TRIPWRTrip Wire1471GMOT----****XTACGRP
b-g-.-M-O-UTACGRP / MOBSU / OBST / UXOUnexploded Ordnance Area (Uxo)1472GMOU----****XTACGRP
b-g-.-M-O-WTACGRP / MOBSU / OBST / WREOBSWIRE OBSTACLE1473TACGRP
b-g-.-M-O-W-ATACGRP / MOBSU / OBST / WREOBS / DAFNCDouble Apron Fence1474GMOWA---****XTACGRP
b-g-.-M-O-W-CTACGRP / MOBSU / OBST / WREOBS / CCTAConcertina1475TACGRP
b-g-.-M-O-W-C-DTACGRP / MOBSU / OBST / WREOBS / CCTA / DBLSTDDouble Strand Concertina1476GMOWCD--****XTACGRPDBLSTD
b-g-.-M-O-W-C-STACGRP / MOBSU / OBST / WREOBS / CCTA / SNGSingle Concertina1477GMOWCS--****XTACGRPSNG
b-g-.-M-O-W-C-TTACGRP / MOBSU / OBST / WREOBS / CCTA / TRISTDTriple Strand Concertina1478GMOWCT--****XTACGRPTRISTD
b-g-.-M-O-W-DTACGRP / MOBSU / OBST / WREOBS / DBLFNCDouble Fence1479GMOWD---****XTACGRP
b-g-.-M-O-W-HTACGRP / MOBSU / OBST / WREOBS / HWFNCHigh Wire Fence1480GMOWH---****XTACGRP
b-g-.-M-O-W-LTACGRP / MOBSU / OBST / WREOBS / LWFNCLow Wire Fence1481GMOWL---****XTACGRP
b-g-.-M-O-W-STACGRP / MOBSU / OBST / WREOBS / SNGFNCSingle Fence1482GMOWS---****XTACGRP
b-g-.-M-O-W-UTACGRP / MOBSU / OBST / WREOBS / USPUnspecified1483GMOWU---****XTACGRP
b-g-.-M-STACGRP / MOBSU / SUSURVIVABILITY1484TACGRP
b-g-.-M-S-ETACGRP / MOBSU / SU / ESTOFEarthwork Small Trench Or Fortification1485GMSE----****XTACGRP
b-g-.-M-S-FTACGRP / MOBSU / SU / FRTFort1486GMSF----****XTACGRP
b-g-.-M-S-LTACGRP / MOBSU / SU / FTFDLNFortified Line1487GMSL----****XTACGRP
b-g-.-M-S-PTACGRP / MOBSU / SU / STRGPTStrong Point1488GMSP----****XTACGRP
b-g-.-M-S-STACGRP / MOBSU / SU / SUFSHLSurface Shelter1489GMSS----****XTACGRP
b-g-.-M-S-UTACGRP / MOBSU / SU / UGDSHLUnderground Shelter1490GMSU----****XTACGRP
b-g-.-M-S-WTACGRP / MOBSU / SU / FEWSFoxhole Emplacement Or Weapon Site1491GMSW----****XTACGRP
b-g-.-OTACGRP / OTHOther1492OOCC---------TACGRP
b-g-.-O-BTACGRP / OTH / BERLNEBearing Line1493GOB-----****XTACGRP
b-g-.-O-B-ATACGRP / OTH / BERLNE / ACUAcoustic1494GOBA----****XTACGRP
b-g-.-O-B-ETACGRP / OTH / BERLNE / ELCElectronic1495GOBE----****XTACGRP
b-g-.-O-B-OTACGRP / OTH / BERLNE / EOPIElectro-Optical Intercept1496GOBO----****XTACGRP
b-g-.-O-B-TTACGRP / OTH / BERLNE / TPDTorpedo1497GOBT----****XTACGRP
b-g-.-O-ETACGRP / OTH / EREmergency1498TACGRP
b-g-.-O-E-DTACGRP / OTH / ER / DTHACDitched Aircraft1499GOED----****XTACGRP
b-g-.-O-E-PTACGRP / OTH / ER / PIWPerson In Water1500GOEP----****XTACGRP
b-g-.-O-E-VTACGRP / OTH / ER / DSTVESDistressed Vessel1501GOEV----****XTACGRP
b-g-.-O-FTACGRP / OTH / FIXFIX1502GMOEF---****XTACGRP
b-g-.-O-F-ATACGRP / OTH / FIX / ACUAcoustic1503GOFA----****XTACGRP
b-g-.-O-F-ETACGRP / OTH / FIX / EMElectro-Magnetic1504GOFE----****XTACGRP
b-g-.-O-F-OTACGRP / OTH / FIX / EOPElectro-Optical1505GOFO----****XTACGRP
b-g-.-O-HTACGRP / OTH / HAZHazard1506TACGRP
b-g-.-O-H-ITACGRP / OTH / HAZ / IBIceberg1507GOHI----****XTACGRP
b-g-.-O-H-MTACGRP / OTH / HAZ / SMLSea Mine-Like1508GOHM----****XTACGRP
b-g-.-O-H-NTACGRP / OTH / HAZ / NVGLNavigational1509GOHN----****XTACGRP
b-g-.-O-H-OTACGRP / OTH / HAZ / OLRGOil Rig1510GOHO----****XTACGRP
b-g-.-O-STACGRP / OTH / SSUBSRSEA SUBSURFACE RETURNS1511TACGRP
b-g-.-O-S-BTACGRP / OTH / SSUBSR / BTMRTNBottom Return / Non-Milco1512GOSB----****XTACGRP
b-g-.-O-S-B-MTACGRP / OTH / SSUBSR / BTMRTN / INSInstallation / Manmade1513GOSBM---****XTACGRP
b-g-.-O-S-B-NTACGRP / OTH / SSUBSR / BTMRTN / SBRSOOSeabed Rock / Stone Obstacle Other1514GOSBN---****XTACGRP
b-g-.-O-S-B-WTACGRP / OTH / SSUBSR / BTMRTN / WRKDWreck Dangerous1515GOSBX---****XTACGRP
b-g-.-O-S-MTACGRP / OTH / SSUBSR / MARLFEMarine Life1516GOSM----****XTACGRP
b-g-.-O-S-STACGRP / OTH / SSUBSR / SASea Anomaly (Wake Current Knuckle)1517GOSS----****XTACGRP
b-g-.-STACGRP / CSSCOMBAT SERVICE SUPPORT1518TACGRP
b-g-.-S-ATACGRP / CSS / ARAArea1519TACGRP
b-g-.-S-A-DTACGRP / CSS / ARA / DHADetainee Holding Area1520GSAD----****XTACGRP
b-g-.-S-A-ETACGRP / CSS / ARA / EPWHAEnemy Prisoner Of War (Epw) Holding Area1521GSAE----****XTACGRP
b-g-.-S-A-HTACGRP / CSS / ARA / RHARefugee Holding Area1522GSAH----****XTACGRP
b-g-.-S-A-RTACGRP / CSS / ARA / FARPForward Arming And Refueling Area (Farp)1523GSAR----****XTACGRP
b-g-.-S-A-STACGRP / CSS / ARA / SUPARSSupport Areas1524TACGRP
b-g-.-S-A-S-BTACGRP / CSS / ARA / SUPARS / BSABrigade (Bsa)1525GSASB---****XTACGRP
b-g-.-S-A-S-DTACGRP / CSS / ARA / SUPARS / DSADivision (Dsa)1526GSASD---****XTACGRP
b-g-.-S-A-S-RTACGRP / CSS / ARA / SUPARS / RSARegimental (Rsa)1527GSASR---****XTACGRP
b-g-.-S-LTACGRP / CSS / LNELines1528TACGRP
b-g-.-S-L-CTACGRP / CSS / LNE / CNYCONVOYS1529TACGRP
b-g-.-S-L-C-HTACGRP / CSS / LNE / CNY / HCNYHalted Convoy1530GSLCH---****XTACGRP
b-g-.-S-L-C-MTACGRP / CSS / LNE / CNY / MCNYMoving Convoy1531GSLCM---****XTACGRP
b-g-.-S-L-RTACGRP / CSS / LNE / SLPRUTSUPPLY ROUTES1532TACGRP
b-g-.-S-L-R-ATACGRP / CSS / LNE / SLPRUT / ASRUTAlternate Supply Route1533GSLRA---****XTACGRP
b-g-.-S-L-R-MTACGRP / CSS / LNE / SLPRUT / MSRUTMain Supply Route1534GSLRM---****XTACGRP
b-g-.-S-L-R-OTACGRP / CSS / LNE / SLPRUT / 1WTRFFOne-Way Traffic1535GSLRO---****XTACGRP
b-g-.-S-L-R-TTACGRP / CSS / LNE / SLPRUT / ATRFFAlternating Traffic1536GSLRT---****XTACGRP
b-g-.-S-L-R-WTACGRP / CSS / LNE / SLPRUT / 2WTRFFTwo-Way Traffic1537GSLRW---****XTACGRP
b-g-.-S-PTACGRP / CSS / PNTPoints1538TACGRP
b-g-.-S-P-ATACGRP / CSS / PNT / APAMMUNITION POINTS1539TACGRP
b-g-.-S-P-A-STACGRP / CSS / PNT / AP / ASPAmmunition Supply Point (Asp)1540GSPAS---****XTACGRP
b-g-.-S-P-A-TTACGRP / CSS / PNT / AP / ATPAmmunition Transfer Point (Atp)1541GSPAT---****XTACGRP
b-g-.-S-P-CTACGRP / CSS / PNT / CBNPCannibalization Point1542GSPC----****XTACGRP
b-g-.-S-P-DTACGRP / CSS / PNT / DCPDetainee Collection Point1543GSPD----****XTACGRP
b-g-.-S-P-ETACGRP / CSS / PNT / EPWCPEnemy Prisoner Of War (Epw) Collection Point1544GSPE----****XTACGRP
b-g-.-S-P-ITACGRP / CSS / PNT / TTPTrailer Transfer Point1545GSPI----****XTACGRP
b-g-.-S-P-LTACGRP / CSS / PNT / LRPLogistics Release Point (Lrp)1546GSPL----****XTACGRP
b-g-.-S-P-MTACGRP / CSS / PNT / MCPMaintenance Collection Point1547GSPM----****XTACGRP
b-g-.-S-P-NTACGRP / CSS / PNT / UMCUnit Maintenance Collection Point1548GSPN----****XTACGRP
b-g-.-S-P-OTACGRP / CSS / PNT / TCPTraffic Control Post (Tcp)1549GSPO----****XTACGRP
b-g-.-S-P-RTACGRP / CSS / PNT / RRRPRearm Refuel And Resupply Point1550GSPR----****XTACGRP
b-g-.-S-P-STACGRP / CSS / PNT / SPTSupply Points1551TACGRP
b-g-.-S-P-S-ATACGRP / CSS / PNT / SPT / CLS1Class I1552GSPSA---****XTACGRP
b-g-.-S-P-S-BTACGRP / CSS / PNT / SPT / CLS2Class Ii1553GSPSB---****XTACGRP
b-g-.-S-P-S-CTACGRP / CSS / PNT / SPT / CLS3Class Iii1554GSPSC---****XTACGRP
b-g-.-S-P-S-DTACGRP / CSS / PNT / SPT / CLS4Class Iv1555GSPSD---****XTACGRP
b-g-.-S-P-S-ETACGRP / CSS / PNT / SPT / CLS5Class V1556GSPSE---****XTACGRP
b-g-.-S-P-S-FTACGRP / CSS / PNT / SPT / CLS6Class Vi1557GSPSF---****XTACGRP
b-g-.-S-P-S-GTACGRP / CSS / PNT / SPT / CLS7Class Vii1558GSPSG---****XTACGRP
b-g-.-S-P-S-HTACGRP / CSS / PNT / SPT / CLS8Class Viii1559GSPSH---****XTACGRP
b-g-.-S-P-S-ITACGRP / CSS / PNT / SPT / CLS9Class Ix1560GSPSI---****XTACGRP
b-g-.-S-P-S-JTACGRP / CSS / PNT / SPT / CLS10Class X1561GSPSJ---****XTACGRP
b-g-.-S-P-S-ZTACGRP / C2GM / GNLGeneral1562TACGRP
b-g-.-S-P-TTACGRP / CSS / PNT / CVPCivilian Collection Point1563GSPT----****XTACGRP
b-g-.-S-P-UTACGRP / CSS / PNT / ROMRefuel On The Move (Rom) Point1564GSPU----****XTACGRP
b-g-.-S-P-XTACGRP / CSS / PNT / AEPAmbulance Exchange Point1565GSPX----****XTACGRP
b-g-.-S-P-YTACGRP / CSS / PNT / CCPCasualty Collection Point1566GSPY----****XTACGRP
b-g-.-TTACGRP / TSKTASKS1567TACGRP
b-g-.-T-ATACGRP / TSK / FLWASSFollow And Assume1568GTA-----****XTACGRP
b-g-.-T-A-STACGRP / TSK / FLWASS / FLWSUPFollow And Support1569GTAS----****XTACGRP
b-g-.-T-BTACGRP / TSK / BLKBlock1570GTB-----****XTACGRP
b-g-.-T-CTACGRP / TSK / CNZCanalize1571GTC-----****XTACGRP
b-g-.-T-DTACGRP / TSK / DSTYDestroy1572GTD-----****XTACGRP
b-g-.-T-ETACGRP / TSK / ISLIsolate1573GTE-----****XTACGRP
b-g-.-T-FTACGRP / TSK / FIXFix1574GTF-----****XTACGRP
b-g-.-T-HTACGRP / TSK / BRHBreach1575GTH-----****XTACGRP
b-g-.-T-ITACGRP / TSK / ITDTInterdict1576GTI-----****XTACGRP
b-g-.-T-JTACGRP / TSK / CNTContain1577GTJ-----****XTACGRP
b-g-.-T-KTACGRP / TSK / CATKCounterattack (Catk)1578GTK-----****XTACGRP
b-g-.-T-K-FTACGRP / TSK / CATK / CATKFCounterattack By Fire1579GTKF----****XTACGRP
b-g-.-T-LTACGRP / TSK / DLYDelay1580GTL-----****XTACGRP
b-g-.-T-MTACGRP / TSK / RTMRetirement1581GTM-----****XTACGRP
b-g-.-T-NTACGRP / TSK / NEUTNeutralize1582GTN-----****XTACGRP
b-g-.-T-OTACGRP / TSK / OCCOccupy1583GTO-----****XTACGRP
b-g-.-T-PTACGRP / TSK / PNEPenetrate1584GTP-----****XTACGRP
b-g-.-T-QTACGRP / TSK / RTNRetain1585GTQ-----****XTACGRP
b-g-.-T-RTACGRP / TSK / RIPRelief In Place (Rip)1586GTR-----****XTACGRP
b-g-.-T-STACGRP / TSK / SCESecure1587GTS-----****XTACGRP
b-g-.-T-TTACGRP / TSK / DRTDisrupt1588GTT-----****XTACGRP
b-g-.-T-UTACGRP / TSK / SECSECURITY1589TACGRP
b-g-.-T-U-CTACGRP / TSK / SEC / COVCover1590GTUC----****XTACGRP
b-g-.-T-U-GTACGRP / TSK / SEC / GUDGuard1591GTUG----****XTACGRP
b-g-.-T-U-STACGRP / TSK / SEC / SCNScreen1592GTUS----****XTACGRP
b-g-.-T-WTACGRP / TSK / WDRWithdraw1593GTW-----****XTACGRP
b-g-.-T-W-PTACGRP / TSK / WDR / WDRUPWithdraw Under Pressure1594GTWP----****XTACGRP
b-g-.-T-XTACGRP / TSK / CLRClear1595GTX-----****XTACGRP
b-g-.-T-YTACGRP / TSK / BYSBypass1596GTY-----****XTACGRP
b-g-.-T-ZTACGRP / TSK / SZESeize1597GTZ-----****XTACGRP
b-ibits ImageImage1598Image
b-i-vbits Imagevideo15981Video
b-lAlarmAlarm1599Alarm
b-l-cAlarm / CBRNECBRNE1600Alarm
b-l-c-bAlarm / CBRNE / BioChemBioChem1601Alarm
b-l-c-b-bAlarm / CBRNE / BioChem / BiologicalBiological1602GMNEB---****XAlarm
b-l-c-b-cAlarm / CBRNE / BioChem / ChemicalChemical1603GMNEC---****XAlarm
b-l-c-eAlarm / CBRNE / ExplosiveExplosive1604EIDD---------Alarm
b-l-c-e-dAlarm / CBRNE / Explosive / DeviceDevice1605Alarm
b-l-c-nAlarm / CBRNE / NuclearRadiologicalNuclearRadiological1606Alarm
b-l-c-n-nAlarm / CBRNE / NuclearRadiological / NuclearNuclear1607SGIRNN--H****Alarm
b-l-c-n-n-bAlarm / CBRNE / NuclearRadiological / Nuclear / BombBomb1608OVB----------Alarm
b-l-c-n-n-smAlarm / CBRNE / NuclearRadiological / Nuclear / Special Nuclear MaterialSpecial Nuclear Material1609Alarm
b-l-c-n-rAlarm / CBRNE / NuclearRadiological / RadiologicalRadiological1610Alarm
b-l-c-n-r-ddAlarm / CBRNE / Radiological / Dispersal Device (Dirty Bomb)Dispersal Device (Dirty Bomb)1611Alarm
b-l-eAlarm / EnvironmentalEnvironmental1612Alarm
b-l-e-hAlarm / Environmental / HazmatHazmat1613Alarm
b-l-fAlarm / FireFire1614Alarm
b-l-f-aAlarm / Fire / AudibleAudible1615Alarm
b-l-f-a-aAlarm / Fire / Audible / Pump ActivatedPump Activated1616Alarm
b-l-f-a-cAlarm / Fire / Audible / CombustionCombustion1617Alarm
b-l-f-a-dAlarm / Fire / Audible / Duct DetectorDuct Detector1618Alarm
b-l-f-a-fAlarm / Fire / Audible / Flame DetectorFlame Detector1619Alarm
b-l-f-a-hAlarm / Fire / Audible / HeatHeat1620Alarm
b-l-f-a-pAlarm / Fire / Audible / Pull StationPull Station1621Alarm
b-l-f-a-sAlarm / Fire / Audible / SmokeSmoke1622Alarm
b-l-f-a-wAlarm / Fire / Audible / WaterflowWaterflow1623Alarm
b-l-gAlarm / GeophysicalGeophysical1624Alarm
b-l-hAlarm / Medical and Public HealthMedical and Public Health1625Alarm
b-l-h-aAlarm / Medical and Public Health / AudibleAudible1626Alarm
b-l-h-amAlarm / Medical and Public Health / AmbulanceAmbulance1627EOAE---------Alarm
b-l-h-am-sAlarm / Medical and Public Health / Ambulance / SilentSilent1628Alarm
b-l-iAlarm / InfrastructureInfrastructure1629Alarm
b-l-lAlarm / SecuritySecurity1630Alarm
b-l-l-lAlarm / Security / Law EnforcementLaw Enforcement1631Alarm
b-l-l-l-adAlarm / Security / Law Enforcement / Armed and DangerousArmed and Dangerous1632Alarm
b-l-l-l-anAlarm / Security / Law Enforcement / AnimalAnimal1633Alarm
b-l-l-l-an-orAlarm / Security / Law Enforcement / Animal / On RoadwayOn Roadway1634Alarm
b-l-l-l-asAlarm / Security / Law Enforcement / AssualtAssualt1635Alarm
b-l-l-l-avAlarm / Security / Law Enforcement / Abandoned VehicleAbandoned Vehicle1636Alarm
b-l-l-l-baAlarm / Security / Law Enforcement / BatteryBattery1637Alarm
b-l-l-l-btAlarm / Security / Law Enforcement / Bomb ThreatBomb Threat1638EIBA---------Alarm
b-l-l-l-burAlarm / Security / Law Enforcement / BurglaryBurglary1639Alarm
b-l-l-l-bur-aAlarm / Security / Law Enforcement / Burglary / AudibleAudible1640Alarm
b-l-l-l-bur-a-dAlarm / Security / Law Enforcement / Burglary / Audible / Day / Night ZoneNight Zone1641AlarmDayNight Zone
b-l-l-l-bur-a-eAlarm / Security / Law Enforcement / Burglary / Audible / Entry / ExitExit1642AlarmEntryExit
b-l-l-l-bur-a-iAlarm / Security / Law Enforcement / Burglary / Audible / InteriorInterior1643AlarmInterior
b-l-l-l-bur-a-oAlarm / Security / Law Enforcement / Burglary / Audible / OutdoorOutdoor1644AlarmOutdoor
b-l-l-l-bur-a-pAlarm / Security / Law Enforcement / Burglary / Audible / PerimeterPerimeter1645AlarmPerimeter
b-l-l-l-bur-a-tAlarm / Security / Law Enforcement / Burglary / Audible / 24 Hour Zone24 Hour Zone1646Alarm24 Hour Zone
b-l-l-l-bur-a-xAlarm / Security / Law Enforcement / Burglary / Audible / Exit ErrorExit Error1647AlarmExit Error
b-l-l-l-bur-sAlarm / Security / Law Enforcement / Burglary / SilentSilent1648Alarm
b-l-l-l-bur-s-cAlarm / Security / Law Enforcement / Burglary / Silent / Recent CloseRecent Close1649AlarmRecent Close
b-l-l-l-cAlarm / Security / Law Enforcement / CrashCrash1650Alarm
b-l-l-l-c-aAlarm / Security / Law Enforcement / Crash / AircraftAircraft1651Alarm
b-l-l-l-c-pcAlarm / Security / Law Enforcement / Crash / Patrol CarPatrol Car1652Alarm
b-l-l-l-c-wfAlarm / Security / Law Enforcement / Crash / With FatalitiesWith Fatalities1653Alarm
b-l-l-l-c-wiAlarm / Security / Law Enforcement / Crash / With injuriesWith injuries1654Alarm
b-l-l-l-c-wrAlarm / Security / Law Enforcement / Crash / With RoadblockWith Roadblock1655Alarm
b-l-l-l-caAlarm / Security / Law Enforcement / Child AbuseChild Abuse1656Alarm
b-l-l-l-cdAlarm / Security / Law Enforcement / Civil Disturbance or DisorderCivil Disturbance or Disorder1657Alarm
b-l-l-l-crAlarm / Security / Law Enforcement / Callbox RequestCallbox Request1658Alarm
b-l-l-l-dcAlarm / Security / Law Enforcement / Drug or ContrabandDrug or Contraband1659Alarm
b-l-l-l-dovAlarm / Security / Law Enforcement / Domestic ViolenceDomestic Violence1660Alarm
b-l-l-l-dpAlarm / Security / Law Enforcement / Dead PersonDead Person1661Alarm
b-l-l-l-drpAlarm / Security / Law Enforcement / Drunk PedestrianDrunk Pedestrian1662Alarm
b-l-l-l-duiAlarm / Security / Law Enforcement / DUIDUI1663Alarm
b-l-l-l-dui-jAlarm / Security / Law Enforcement / DUI / JuvenileJuvenile1664Alarm
b-l-l-l-dvAlarm / Security / Law Enforcement / Disabled VehicleDisabled Vehicle1665Alarm
b-l-l-l-epAlarm / Security / Law Enforcement / Escaped PrisonerEscaped Prisoner1666Alarm
b-l-l-l-hrAlarm / Security / Law Enforcement / Hit and RunHit and Run1667Alarm
b-l-l-l-hr-wiAlarm / Security / Law Enforcement / Hit and Run / With InjuriesWith Injuries1668Alarm
b-l-l-l-hr-wrAlarm / Security / Law Enforcement / Hit and Run / With RoadblockWith Roadblock1669Alarm
b-l-l-l-hupAlarm / Security / Law Enforcement / Hold UpHold Up1670Alarm
b-l-l-l-hup-aAlarm / Security / Law Enforcement / Hold Up / AudibleAudible1671Alarm
b-l-l-l-hup-sAlarm / Security / Law Enforcement / Hold Up / SilentSilent1672Alarm
b-l-l-l-iiAlarm / Security / Law Enforcement / Information or Intelligence - calls to take witness infoInformation or Intelligence - calls to take witness info1673Alarm
b-l-l-l-ioAlarm / Security / Law Enforcement / Impersonating an OfficerImpersonating an Officer1674Alarm
b-l-l-l-joAlarm / Security / Law Enforcement / Juvenile OffenseJuvenile Offense1675Alarm
b-l-l-l-kAlarm / Security / Law Enforcement / KidnappingKidnapping1676OOK----------Alarm
b-l-l-l-lAlarm / Security / Law Enforcement / LarcenyLarceny1677Alarm
b-l-l-l-mAlarm / Security / Law Enforcement / MurderMurder1678OVMA---------Alarm
b-l-l-l-miAlarm / Security / Law Enforcement / Mentally Ill PersonMentally Ill Person1679Alarm
b-l-l-l-mmAlarm / Security / Law Enforcement / Malacious MischiefMalacious Mischief1680Alarm
b-l-l-l-mpAlarm / Security / Law Enforcement / Missing PersonMissing Person1681Alarm
b-l-l-l-odAlarm / Security / Law Enforcement / Officer DownOfficer Down1682Alarm
b-l-l-l-phAlarm / Security / Law Enforcement / Pedestrian or HitchhikerPedestrian or Hitchhiker1683Alarm
b-l-l-l-rAlarm / Security / Law Enforcement / RobberyRobbery1684Alarm
b-l-l-l-r-saAlarm / Security / Law Enforcement / Robbery / StrongarmStrongarm1685Alarm
b-l-l-l-rdAlarm / Security / Law Enforcement / Reckless DrivingReckless Driving1686Alarm
b-l-l-l-rtAlarm / Security / Law Enforcement / Rock ThrowingRock Throwing1687Alarm
b-l-l-l-sAlarm / Security / Law Enforcement / ShootingShooting1688Alarm
b-l-l-l-scAlarm / Security / Law Enforcement / Suspicious CircumstancesSuspicious Circumstances1689Alarm
b-l-l-l-sdAlarm / Security / Law Enforcement / Special DetailSpecial Detail1690Alarm
b-l-l-l-sgAlarm / Security / Law Enforcement / SmugglingSmuggling1691Alarm
b-l-l-l-siAlarm / Security / Law Enforcement / Sick or Injured PersonSick or Injured Person1692Alarm
b-l-l-l-soAlarm / Security / Law Enforcement / Sex OffenseSex Offense1693Alarm
b-l-l-l-spAlarm / Security / Law Enforcement / Suspicious PersonSuspicious Person1694Alarm
b-l-l-l-suAlarm / Security / Law Enforcement / SuicideSuicide1695Alarm
b-l-l-l-svAlarm / Security / Law Enforcement / Suspicious VehcleSuspicious Vehcle1696Alarm
b-l-l-l-teAlarm / Security / Law Enforcement / Toll EvasionToll Evasion1697Alarm
b-l-l-l-vtAlarm / Security / Law Enforcement / Lost or Stolen Vehicle TagLost or Stolen Vehicle Tag1698Alarm
b-l-mAlarm / MeteorologicalMeteorological1699SGUCFO-------Alarm
b-l-oAlarm / OtherOther1700OOCC---------Alarm
b-l-o-bypAlarm / Other / BypassBypass1701GTY-----****XAlarm
b-l-o-byp-sAlarm / Other / Bypass / SilentSilent1702Alarm
b-l-o-byp-s-24Alarm / Other / Bypass / Silent / 24 Hour zone24 Hour zone1703Alarm
b-l-o-byp-s-bAlarm / Other / Bypass / Silent / BurglaryBurglary1704Alarm
b-l-o-byp-s-fAlarm / Other / Bypass / Silent / FireFire1705Alarm
b-l-o-byp-s-gAlarm / Other / Bypass / Silent / GroupGroup1706Alarm
b-l-o-byp-s-sbAlarm / Other / Bypass / Silent / Swinger BypassedSwinger Bypassed1707Alarm
b-l-o-byp-s-zsAlarm / Other / Bypass / Silent / Zone or SensorZone or Sensor1708Alarm
b-l-o-canAlarm / Other / CancelCancel1709Alarm
b-l-o-can-sAlarm / Other / Cancel / SilentSilent1710Alarm
b-l-o-cloAlarm / Other / CloseClose1711Alarm
b-l-o-clo-sAlarm / Other / Close / SilentSilent1712Alarm
b-l-o-clo-s-smAlarm / Other / Close / Silent / Stay ModeStay Mode1713Alarm
b-l-o-farAlarm / Other / Forced ArmingForced Arming1714Alarm
b-l-o-far-sAlarm / Other / Forced Arming / SilentSilent1715Alarm
b-l-o-far-s-paAlarm / Other / Forced Arming / Silent / Partial ArmPartial Arm1716Alarm
b-l-o-fttAlarm / Other / Failure to TestFailure to Test1717Alarm
b-l-o-ftt-sAlarm / Other / Failure to Test / SilentSilent1718Alarm
b-l-o-ftt-s-pnAlarm / Other / Failure to Test / Silent / Point not TestedPoint not Tested1719Alarm
b-l-o-logAlarm / Other / LogLog1720Alarm
b-l-o-log-sAlarm / Other / Log / SilentSilent1721Alarm
b-l-o-log-s-adAlarm / Other / Log / Silent / Access DeniedAccess Denied1722Alarm
b-l-o-log-s-apAlarm / Other / Log / Silent / Access PermittedAccess Permitted1723Alarm
b-l-o-log-s-asAlarm / Other / Log / Silent / Access Schedule ChangeAccess Schedule Change1724Alarm
b-l-o-log-s-crAlarm / Other / Log / Silent / Callback RequestedCallback Requested1725Alarm
b-l-o-log-s-dsAlarm / Other / Log / Silent / Dialer ShutdownDialer Shutdown1726Alarm
b-l-o-log-s-erAlarm / Other / Log / Silent / Event Log ResetEvent Log Reset1727Alarm
b-l-o-log-s-esAlarm / Other / Log / Silent / Exception Schedule ChangeException Schedule Change1728Alarm
b-l-o-log-s-peAlarm / Other / Log / Silent / Program Mode EntryProgram Mode Entry1729Alarm
b-l-o-log-s-pxAlarm / Other / Log / Silent / Program Mode ExitProgram Mode Exit1730Alarm
b-l-o-log-s-saAlarm / Other / Log / Silent / Successful AccessSuccessful Access1731Alarm
b-l-o-log-s-srAlarm / Other / Log / Silent / Status Report to FollowStatus Report to Follow1732Alarm
b-l-o-log-s-ssAlarm / Other / Log / Silent / System shutdownSystem shutdown1733Alarm
b-l-o-log-s-trAlarm / Other / Log / Silent / Time / Date ResetDate Reset1734AlarmDate Reset
b-l-o-log-s-uaAlarm / Other / Log / Silent / Unsuccessful AccessUnsuccessful Access1735Alarm
b-l-o-log-s-vxAlarm / Other / Log / Silent / Video Transmitter ActiveVideo Transmitter Active1736Alarm
b-l-o-ltcAlarm / Other / Late to CloseLate to Close1737Alarm
b-l-o-ltc-sAlarm / Other / Late to Close / SilentSilent1738Alarm
b-l-o-ltc-s-afAlarm / Other / Late to Close / Silent / Auto Armed FailedAuto Armed Failed1739Alarm
b-l-o-ltoAlarm / Other / Late to OpenLate to Open1740Alarm
b-l-o-lto-sAlarm / Other / Late to Open / SilentSilent1741Alarm
b-l-o-nulAlarm / Other / NullNull1742Alarm
b-l-o-nul-sAlarm / Other / Null / SilentSilent1743Alarm
b-l-o-nul-s-pAlarm / Other / Null / Silent / PeriodicPeriodic1744Alarm
b-l-o-nul-s-prAlarm / Other / Null / Silent / Periodic RadioPeriodic Radio1745Alarm
b-l-o-opnAlarm / Other / OpenOpen1746Alarm
b-l-o-opn-sAlarm / Other / Open / SilentSilent1747Alarm
b-l-o-opn-s-aAlarm / Other / Open / Silent / AutomaticAutomatic1748Alarm
b-l-o-opn-s-dAlarm / Other / Open / Silent / DeferredDeferred1749Alarm
b-l-o-opn-s-eAlarm / Other / Open / Silent / EarlyEarly1750Alarm
b-l-o-opn-s-exAlarm / Other / Open / Silent / ExceptionException1751Alarm
b-l-o-opn-s-gAlarm / Other / Open / Silent / GroupGroup1752Alarm
b-l-o-opn-s-kAlarm / Other / Open / Silent / KeyswitchKeyswitch1753Alarm
b-l-o-opn-s-lAlarm / Other / Open / Silent / LateLate1754Alarm
b-l-o-opn-s-qaAlarm / Other / Open / Silent / Quick ArmQuick Arm1755Alarm
b-l-o-opn-s-rAlarm / Other / Open / Silent / RemoteRemote1756Alarm
b-l-o-opn-s-uAlarm / Other / Open / Silent / By UserBy User1757Alarm
b-l-o-opn-s-upAlarm / Other / Open / Silent / User on PremisesUser on Premises1758Alarm
b-l-o-panAlarm / Other / PanicPanic1759Alarm
b-l-o-resAlarm / Other / ResetReset1760Alarm
b-l-o-res-sAlarm / Other / Reset / SilentSilent1761Alarm
b-l-o-res-s-erAlarm / Other / Reset / Silent / Exp Mod ResetExp Mod Reset1762Alarm
b-l-o-spcAlarm / Other / SpecialSpecial1763Alarm
b-l-o-spc-aAlarm / Other / Special / AudibleAudible1764Alarm
b-l-o-spc-a-aAlarm / Other / Special / Audible / General AlarmGeneral Alarm1765Alarm
b-l-o-spc-a-eAlarm / Other / Special / Audible / Personal EmergencyPersonal Emergency1766Alarm
b-l-o-spc-a-fAlarm / Other / Special / Audible / Air Flow LossAir Flow Loss1767Alarm
b-l-o-spc-a-gAlarm / Other / Special / Audible / Gas DetectedGas Detected1768Alarm
b-l-o-spc-a-lAlarm / Other / Special / Audible / Low Gas LevelLow Gas Level1769Alarm
b-l-o-spc-a-wAlarm / Other / Special / Audible / Water LeakageWater Leakage1770Alarm
b-l-o-spc-sAlarm / Other / Special / SilentSilent1771Alarm
b-l-o-spc-s-fAlarm / Other / Special / Silent / Fail to ReportFail to Report1772Alarm
b-l-o-spc-s-liAlarm / Other / Special / Silent / Listen in to FollowListen in to Follow1773Alarm
b-l-o-spsAlarm / Other / SupressSupress1774Alarm
b-l-o-sps-aAlarm / Other / Supress / AudibleAudible1775Alarm
b-l-o-sps-a-gAlarm / Other / Supress / Audible / Gate Valve TamperGate Valve Tamper1776Alarm
b-l-o-sps-sAlarm / Other / Supress / SilentSilent1777Alarm
b-l-o-sps-s-arAlarm / Other / Supress / Silent / Alarm Relay DisabledAlarm Relay Disabled1778Alarm
b-l-o-sps-s-b1Alarm / Other / Supress / Silent / Bell 1 DisabledBell 1 Disabled1779Alarm
b-l-o-sps-s-b2Alarm / Other / Supress / Silent / Bell 2 DisabledBell 2 Disabled1780Alarm
b-l-o-sps-s-ddAlarm / Other / Supress / Silent / Dialer DisabledDialer Disabled1781Alarm
b-l-o-sps-s-rrAlarm / Other / Supress / Silent / Reversing Relay DisabledReversing Relay Disabled1782Alarm
b-l-o-sps-s-rxAlarm / Other / Supress / Silent / Radio Transmitter DisabledRadio Transmitter Disabled1783Alarm
b-l-o-sps-s-srAlarm / Other / Supress / Silent / Sounder relay DisabledSounder relay Disabled1784Alarm
b-l-o-sps-s-trAlarm / Other / Supress / Silent / Trouble Relay DisabledTrouble Relay Disabled1785Alarm
b-l-o-tamAlarm / Other / TamperTamper1786Alarm
b-l-o-tam-aAlarm / Other / Tamper / AudibleAudible1787Alarm
b-l-o-tam-sAlarm / Other / Tamper / SilentSilent1788Alarm
b-l-o-tam-s-eAlarm / Other / Tamper / Silent / Expansion ModuleExpansion Module1789Alarm
b-l-o-tam-s-pAlarm / Other / Tamper / Silent / Panel Program ChangePanel Program Change1790Alarm
b-l-o-tam-s-sAlarm / Other / Tamper / Silent / SensorSensor1791SGES---------Alarm
b-l-o-tam-s-vAlarm / Other / Tamper / Silent / VerifyVerify1792Alarm
b-l-o-tblAlarm / Other / TroubleTrouble1793Alarm
b-l-o-tbl-aAlarm / Other / Trouble / AudibleAudible1794Alarm
b-l-o-tbl-a-bAlarm / Other / Trouble / Audible / Foil BreakFoil Break1795Alarm
b-l-o-tbl-a-cAlarm / Other / Trouble / Audible / Low CO2Low CO21796Alarm
b-l-o-tbl-a-dAlarm / Other / Trouble / Audible / Day TroubleDay Trouble1797Alarm
b-l-o-tbl-a-eeAlarm / Other / Trouble / Audible / Exit errorExit error1798Alarm
b-l-o-tbl-a-lAlarm / Other / Trouble / Audible / Low Water LevelLow Water Level1799Alarm
b-l-o-tbl-a-pAlarm / Other / Trouble / Audible / Low Water PressureLow Water Pressure1800Alarm
b-l-o-tbl-a-uAlarm / Other / Trouble / Audible / Pump FailurePump Failure1801Alarm
b-l-o-tbl-sAlarm / Other / Trouble / SilentSilent1802Alarm
b-l-o-tbl-s-aAlarm / Other / Trouble / Silent / SensorSensor1803SGES---------Alarm
b-l-o-tbl-s-arAlarm / Other / Trouble / Silent / Alarm RelayAlarm Relay1804Alarm
b-l-o-tbl-s-bAlarm / Other / Trouble / Silent / Low System BatteryLow System Battery1805Alarm
b-l-o-tbl-s-b1Alarm / Other / Trouble / Silent / Bell 1Bell 11806Alarm
b-l-o-tbl-s-b2Alarm / Other / Trouble / Silent / Bell 2Bell 21807Alarm
b-l-o-tbl-s-btAlarm / Other / Trouble / Silent / Battery Test FailBattery Test Fail1808Alarm
b-l-o-tbl-s-cAlarm / Other / Trouble / Silent / Polling Loop ClosePolling Loop Close1809Alarm
b-l-o-tbl-s-cfAlarm / Other / Trouble / Silent / Communication FailCommunication Fail1810Alarm
b-l-o-tbl-s-dcAlarm / Other / Trouble / Silent / Exp Mod DC LossExp Mod DC Loss1811Alarm
b-l-o-tbl-s-dhAlarm / Other / Trouble / Silent / Detector Hi SensDetector Hi Sens1812Alarm
b-l-o-tbl-s-dlAlarm / Other / Trouble / Silent / Detector Low SensDetector Low Sens1813Alarm
b-l-o-tbl-s-eAlarm / Other / Trouble / Silent / Expansion Mod FailExpansion Mod Fail1814Alarm
b-l-o-tbl-s-e50Alarm / Other / Trouble / Silent / Event Log 50% FullEvent Log 50% Full1815Alarm
b-l-o-tbl-s-e90Alarm / Other / Trouble / Silent / Event Log 90% FullEvent Log 90% Full1816Alarm
b-l-o-tbl-s-emAlarm / Other / Trouble / Silent / Expansion Module FailExpansion Module Fail1817Alarm
b-l-o-tbl-s-eoAlarm / Other / Trouble / Silent / Event Log OverflowEvent Log Overflow1818Alarm
b-l-o-tbl-s-ftAlarm / Other / Trouble / Silent / Fire TroubleFire Trouble1819Alarm
b-l-o-tbl-s-gfAlarm / Other / Trouble / Silent / Ground FaultGround Fault1820Alarm
b-l-o-tbl-s-lbAlarm / Other / Trouble / Silent / Exp Mod Low BatteryExp Mod Low Battery1821Alarm
b-l-o-tbl-s-loAlarm / Other / Trouble / Silent / Protection Loop OpenProtection Loop Open1822Alarm
b-l-o-tbl-s-lpAlarm / Other / Trouble / Silent / Lost PollingLost Polling1823Alarm
b-l-o-tbl-s-lrAlarm / Other / Trouble / Silent / Long Range RadioLong Range Radio1824Alarm
b-l-o-tbl-s-lsAlarm / Other / Trouble / Silent / Protection Loop ShortProtection Loop Short1825Alarm
b-l-o-tbl-s-msAlarm / Other / Trouble / Silent / RPM SupervisionRPM Supervision1826Alarm
b-l-o-tbl-s-nAlarm / Other / Trouble / Silent / Near AlarmNear Alarm1827Alarm
b-l-o-tbl-s-oAlarm / Other / Trouble / Silent / Polling Loop OpenPolling Loop Open1828Alarm
b-l-o-tbl-s-pAlarm / Other / Trouble / Silent / AC Power LostAC Power Lost1829Alarm
b-l-o-tbl-s-pfAlarm / Other / Trouble / Silent / Printer FailurePrinter Failure1830Alarm
b-l-o-tbl-s-plAlarm / Other / Trouble / Silent / Protection LoopProtection Loop1831Alarm
b-l-o-tbl-s-ppAlarm / Other / Trouble / Silent / Printer Paper OutPrinter Paper Out1832Alarm
b-l-o-tbl-s-psAlarm / Other / Trouble / Silent / Polling Loop ShortPolling Loop Short1833Alarm
b-l-o-tbl-s-raAlarm / Other / Trouble / Silent / Radio Antenna VswrRadio Antenna Vswr1834Alarm
b-l-o-tbl-s-rfAlarm / Other / Trouble / Silent / Repeater FailureRepeater Failure1835Alarm
b-l-o-tbl-s-rfbAlarm / Other / Trouble / Silent / RF Low BatteryRF Low Battery1836Alarm
b-l-o-tbl-s-rrAlarm / Other / Trouble / Silent / Reversing RelayReversing Relay1837Alarm
b-l-o-tbl-s-rsAlarm / Other / Trouble / Silent / RF SupervisionRF Supervision1838Alarm
b-l-o-tbl-s-shAlarm / Other / Trouble / Silent / Smoke Det Hi SensSmoke Det Hi Sens1839Alarm
b-l-o-tbl-s-slAlarm / Other / Trouble / Silent / Smoke Det Low SensSmoke Det Low Sens1840Alarm
b-l-o-tbl-s-spAlarm / Other / Trouble / Silent / System PeripheralSystem Peripheral1841Alarm
b-l-o-tbl-s-srAlarm / Other / Trouble / Silent / Sounder / RelayRelay1842SGUUSRW------AlarmRelay
b-l-o-tbl-s-ssAlarm / Other / Trouble / Silent / System ShutdownSystem Shutdown1843Alarm
b-l-o-tbl-s-stAlarm / Other / Trouble / Silent / Self Test FailureSelf Test Failure1844Alarm
b-l-o-tbl-s-t1Alarm / Other / Trouble / Silent / Telco Line 1Telco Line 11845Alarm
b-l-o-tbl-s-t2Alarm / Other / Trouble / Silent / Telco Line 2Telco Line 21846Alarm
b-l-o-tbl-s-tiAlarm / Other / Trouble / Silent / Time / Date InaccurateDate Inaccurate1847AlarmDate Inaccurate
b-l-o-tbl-s-trAlarm / Other / Trouble / Silent / Trouble RelayTrouble Relay1848Alarm
b-l-o-tbl-s-xAlarm / Other / Trouble / Silent / RAM Checksum BadRAM Checksum Bad1849Alarm
b-l-o-tbl-s-yAlarm / Other / Trouble / Silent / ROM Checksum BadROM Checksum Bad1850Alarm
b-l-o-temAlarm / Other / TemperatureTemperature1851Alarm
b-l-o-tem-aAlarm / Other / Temperature / AudibleAudible1852Alarm
b-l-o-tem-a-hAlarm / Other / Temperature / Audible / High TemperatureHigh Temperature1853Alarm
b-l-o-tem-a-lAlarm / Other / Temperature / Audible / Low TemperatureLow Temperature1854Alarm
b-l-o-tem-a-lhAlarm / Other / Temperature / Audible / Loss of HeatLoss of Heat1855Alarm
b-l-o-tem-a-rAlarm / Other / Temperature / Audible / RefrigerationRefrigeration1856Alarm
b-l-o-tstAlarm / Other / TestTest1857Alarm
b-l-o-tst-sAlarm / Other / Test / SIlentSIlent1858Alarm
b-l-o-tst-s-faAlarm / Other / Test / SIlent / Fire AlarmFire Alarm1859Alarm
b-l-o-tst-s-mAlarm / Other / Test / SIlent / ManualManual1860Alarm
b-l-o-tst-s-ptAlarm / Other / Test / SIlent / Point Tested OKPoint Tested OK1861Alarm
b-l-o-tst-s-stAlarm / Other / Test / SIlent / System Remains in TroubleSystem Remains in Trouble1862Alarm
b-l-o-tst-s-wmAlarm / Other / Test / SIlent / Walk Test Mode EnteredWalk Test Mode Entered1863Alarm
b-l-rAlarm / RescueRescue1864GGGPAR--****XAlarm
b-l-sAlarm / SafetySafety1865Alarm
b-l-tAlarm / TransportationTransportation1866SGUST--------Alarm
b-l-t-vAlarm / Transportation / VehicleVehicle1867Alarm
b-l-t-v-aAlarm / Transportation / Vehicle / AccidentAccident1868OOCB---------Alarm
b-l-t-v-a-cAlarm / Transportation / Vehicle / Accident / CollisionCollision1869Alarm
b-l-t-v-a-c-fAlarm / Transportation / Vehicle / Accident / Collision / Fixed ObjectFixed Object1870AlarmFixed Object
b-l-t-v-a-c-nAlarm / Transportation / Vehicle / Accident / Collision / Non-Fixed ObjectNon-Fixed Object1871AlarmNon-Fixed Object
b-l-t-v-a-eAlarm / Transportation / Vehicle / Accident / Equipment / Cargo Loss / ShiftShift1872AlarmCargo LossShift
b-l-t-v-a-fAlarm / Transportation / Vehicle / Accident / Fire_ExplosionFire_Explosion1873Alarm
b-l-t-v-a-iAlarm / Transportation / Vehicle / Accident / ImmersionImmersion1874Alarm
b-l-t-v-a-jAlarm / Transportation / Vehicle / Accident / JacknifeJacknife1875Alarm
b-l-t-v-a-oAlarm / Transportation / Vehicle / Accident / Object Thrown / FallenFallen1876AlarmFallen
b-l-t-v-a-orAlarm / Transportation / Vehicle / Accident / Overturn_RolloverOverturn_Rollover1877Alarm
b-l-t-v-a-pAlarm / Transportation / Vehicle / Accident / Person Fell or JumpedPerson Fell or Jumped1878Alarm
b-l-t-v-oAlarm / Transportation / Vehicle / Other (Non Collision)Other (Non Collision)1879Alarm
b-m-g-oMap / point / gridgrid1880Map
b-m-pMap / point / map pointmap point1881Map
b-m-p-c-cpMap / point / contact pointcontact point1882GGGPPC--****XMap
b-m-p-c-ipMap / point / initial pointinitial point1883Map
b-m-p-m-cMap / point / clickclick1884Map
b-m-p-s-mMap / point / Marker – SpotMarker – Spot1885Map
b-m-p-s-p-iMap / point / spispi1886Map
b-m-p-s-p-locMap / point / sensor pointsensor point1887Map
b-m-p-s-p-opMap / point / observation pointobservation point1888Map
b-m-p-tMap / point / targetedtargeted1889Map
b-m-p-v-p-iMap / point / vpoivpoi1890Map
b-m-p-wMap / point / waypointwaypoint1891GGGPPW--****XMap
b-m-rMap / Route / routeroute1892GGGPO---****XMap
b-m-rMap / Route / routeroute1893GGGPO---****XMap
b-r-.-h-cMap / Health / CasualtyHealth / Casualty1894Map
b-r-.-ISIGINTSignals Intelligence1895SIGINT
b-r-.-I-ASIGINT / AIRTRKAir Track1896SIGINT
b-r-.-I-A-SSIGINT / AIRTRK / SIGINCAIR SIGNAL INTERCEPT1897SIGINT
b-r-.-I-A-S-CSIGINT / AIRTRK / SIGINC / COMMCOMMUNICATIONS1898SIGINT
b-r-.-I-A-S-C-CSIGINT / AIRTRK / SIGINC / COMM / CELLCellular / Mobile1899IASCC-----***SIGINT
b-r-.-I-A-S-C-OSIGINT / AIRTRK / SIGINC / COMM / OLOSOmni-Line Of Sight (Los)1900IASCO-----***SIGINT
b-r-.-I-A-S-C-PSIGINT / AIRTRK / SIGINC / COMM / PTPLOSPoint-To-Point Line Of Sight (Los)1901IASCP-----***SIGINT
b-r-.-I-A-S-C-SSIGINT / AIRTRK / SIGINC / COMM / SATULSatellite Uplink1902IASCS-----***SIGINT
b-r-.-I-A-S-RSIGINT / AIRTRK / SIGINC / RADRadar1903SIGINT
b-r-.-I-A-S-R-A-ISIGINT / AIRTRK / SIGINC / RAD / ABNINCAirborne Intercept1904IASRAI----***SIGINT
b-r-.-I-A-S-R-A-SSIGINT / AIRTRK / SIGINC / RAD / ABNSBAirborne Search & Bombing1905IASRAS----***SIGINT
b-r-.-I-A-S-R-CSIGINT / AIRTRK / SIGINC / RAD / CTDINCControlled Intercept1906IASRC-----***SIGINT
b-r-.-I-A-S-R-DSIGINT / AIRTRK / SIGINC / RAD / DATTMNData Transmission1907IASRD-----***SIGINT
b-r-.-I-A-S-R-ESIGINT / AIRTRK / SIGINC / RAD / EWEarly Warning1908IASRE-----***SIGINT
b-r-.-I-A-S-R-FSIGINT / AIRTRK / SIGINC / RAD / FIRCTLFire Control1909IASRF-----***SIGINT
b-r-.-I-A-S-R-ISIGINT / AIRTRK / SIGINC / RAD / IFFIff (Transponder)1910IASRI-----***SIGINT
b-r-.-I-A-S-R-M-ASIGINT / AIRTRK / SIGINC / RAD / MSLAQMissile Acquisition1911IASRMA----***SIGINT
b-r-.-I-A-S-R-M-DSIGINT / AIRTRK / SIGINC / RAD / MSLDLMissile Downlink1912IASRMD----***SIGINT
b-r-.-I-A-S-R-M-FSIGINT / AIRTRK / SIGINC / RAD / MFNMultifunction1913SIGINT
b-r-.-I-A-S-R-M-GSIGINT / AIRTRK / SIGINC / RAD / MSLGDNMissile Guidance1914IASRMG----***SIGINT
b-r-.-I-A-S-R-M-TSIGINT / AIRTRK / SIGINC / RAD / MSLTRKMissile Tracking1915IASRMT----***SIGINT
b-r-.-I-A-S-R-T-ASIGINT / AIRTRK / SIGINC / RAD / TGTAQTarget Acquisition1916IASRTA----***SIGINT
b-r-.-I-A-S-R-T-ISIGINT / AIRTRK / SIGINC / RAD / TGTILLTarget Illuminator1917IASRTI----***SIGINT
b-r-.-I-A-S-R-T-TSIGINT / AIRTRK / SIGINC / RAD / TGTTRKTarget Tracking1918IASRTT----***SIGINT
b-r-.-I-A-S-R-USIGINT / AIRTRK / SIGINC / RAD / UNKUnknown1919IASRU-----***SIGINT
b-r-.-I-GSIGINT / GRDTRKGround Track1920SG-----------SIGINT
b-r-.-I-G-SSIGINT / GRDTRK / SIGINCGround SIGNAL INTERCEPT1921SIGINT
b-r-.-I-G-S-CSIGINT / GRDTRK / SIGINC / COMMCOMMUNICATIONS1922SIGINT
b-r-.-I-G-S-C-CSIGINT / GRDTRK / SIGINC / COMM / CELLCellular / Mobile1923IGSCC-----***SIGINT
b-r-.-I-G-S-C-OSIGINT / GRDTRK / SIGINC / COMM / OLOSOmni-Line Of Sight (Los)1924IGSCO-----***SIGINT
b-r-.-I-G-S-C-PSIGINT / GRDTRK / SIGINC / COMM / PTPLOSPoint To Point Line Of Sight (Los)1925IGSCP-----***SIGINT
b-r-.-I-G-S-C-SSIGINT / GRDTRK / SIGINC / COMM / SATULSatellite Uplink1926IGSCS-----***SIGINT
b-r-.-I-G-S-C-TSIGINT / GRDTRK / SIGINC / COMM / TPSSCTTropospheric Scatter1927IGSCT-----***SIGINT
b-r-.-I-G-S-RSIGINT / GRDTRK / SIGINC / RADRadar1928SIGINT
b-r-.-I-G-S-R-A-ASIGINT / GRDTRK / SIGINC / RAD / AAAnti Aircraft1929SIGINT
b-r-.-I-G-S-R-A-TSIGINT / GRDTRK / SIGINC / RAD / ATCTLAir Traffic Control1930IGSRAT----***SIGINT
b-r-.-I-G-S-R-BSIGINT / GRDTRK / SIGINC / RAD / BTFSVLBattlefield Surveillance1931IGSRB-----***SIGINT
b-r-.-I-G-S-R-C-ASIGINT / GRDTRK / SIGINC / RAD / CTDAPPControlled Approach1932IGSRCA----***SIGINT
b-r-.-I-G-S-R-C-SSIGINT / GRDTRK / SIGINC / RAD / CSTSVLCoastal Surveillance1933IGSRCS----***SIGINT
b-r-.-I-G-S-R-DSIGINT / GRDTRK / SIGINC / RAD / DATTMNData Transmission1934IGSRD-----***SIGINT
b-r-.-I-G-S-R-ESIGINT / GRDTRK / SIGINC / RAD / EWEarly Warning1935IGSRE-----***SIGINT
b-r-.-I-G-S-R-FSIGINT / GRDTRK / SIGINC / RAD / FIRCTLFire Control1936IGSRF-----***SIGINT
b-r-.-I-G-S-R-HSIGINT / GRDTRK / SIGINC / RAD / HGTFDGHeight Finding1937IGSRH-----***SIGINT
b-r-.-I-G-S-R-ISIGINT / GRDTRK / SIGINC / RAD / IDFFIdentification Friend / Foe (Interrogator)1938IGSRI-----***SIGINT
b-r-.-I-G-S-R-M-ASIGINT / GRDTRK / SIGINC / RAD / MSLAQMissile Acquisition1939IGSRMA----***SIGINT
b-r-.-I-G-S-R-M-FSIGINT / GRDTRK / SIGINC / RAD / MFNMultifunction1940IGSRMF----***SIGINT
b-r-.-I-G-S-R-M-GSIGINT / GRDTRK / SIGINC / RAD / MSLGDNMissile Guidance1941IGSRMG----***SIGINT
b-r-.-I-G-S-R-M-MSIGINT / GRDTRK / SIGINC / RAD / METOMeteorological (Military)1942IGSRMM----***SIGINT
b-r-.-I-G-S-R-M-TSIGINT / GRDTRK / SIGINC / RAD / MSLTRKMissile Tracking1943IGSRMT----***SIGINT
b-r-.-I-G-S-R-SSIGINT / GRDTRK / SIGINC / RAD / SHETKGShell Tracking1944IGSRS-----***SIGINT
b-r-.-I-G-S-R-T-ASIGINT / GRDTRK / SIGINC / RAD / TGTAQTarget Acquisition1945IGSRTA----***SIGINT
b-r-.-I-G-S-R-T-ISIGINT / GRDTRK / SIGINC / RAD / TGTILLTarget Illuminator1946IGSRTT----***SIGINT
b-r-.-I-G-S-R-T-TSIGINT / GRDTRK / SIGINC / RAD / TGTTRKTarget Tracking1947IGSRTT----***SIGINT
b-r-.-I-G-S-R-USIGINT / GRDTRK / SIGINC / RAD / UNKUnknown1948IGSRU-----***SIGINT
b-r-.-I-PSIGINT / SPCSpace Track1949SP-----------SIGINT
b-r-.-I-P-SSIGINT / SPC / SIGINCSignal Intercept1950SIGINT
b-r-.-I-P-S-CSIGINT / SPC / SIGINC / COMMCommunications1951SIGINT
b-r-.-I-P-S-C-DSIGINT / SPC / SIGINC / COMM / SATDLSatellite Downlink1952IPSCD-----***SIGINT
b-r-.-I-P-S-RSIGINT / SPC / SIGINC / RADRadar1953SIGINT
b-r-.-I-P-S-R-DSIGINT / SPC / SIGINC / RAD / DATTMNData Transmission1954IPSRD-----***SIGINT
b-r-.-I-P-S-R-ESIGINT / SPC / SIGINC / RAD / ERHSVLEarth Surveillance1955IPSRI-----***SIGINT
b-r-.-I-P-S-R-ISIGINT / SPC / SIGINC / RAD / IFFIff (Transponder)1956IASRI-----***SIGINT
b-r-.-I-P-S-R-MSIGINT / SPC / SIGINC / RAD / MFNMultifunction1957IPSRM-----***SIGINT
b-r-.-I-P-S-R-SSIGINT / SPC / SIGINC / RAD / SPCSpace1958IPSRS-----***SIGINT
b-r-.-I-P-S-R-TSIGINT / SPC / SIGINC / RAD / TGTAQTarget Acquisition1959IPSRU-----***SIGINT
b-r-.-I-P-S-R-USIGINT / SPC / SIGINC / RAD / UNKUnknown1960IASRU-----***SIGINT
b-r-.-I-SSIGINT / SSUFSea Surface Track1961SIGINT
b-r-.-I-S-SSIGINT / SSUF / SIGINCSignal Intercept1962SIGINT
b-r-.-I-S-S-CSIGINT / SSUF / SIGINC / COMMCommunications1963SIGINT
b-r-.-I-S-S-C-CSIGINT / SSUF / SIGINC / COMM / CELLCellular / Mobile1964ISSCC-----***SIGINT
b-r-.-I-S-S-C-OSIGINT / SSUF / SIGINC / COMM / OLOSOmni Line Of Sight (Los)1965ISSCO-----***SIGINT
b-r-.-I-S-S-C-PSIGINT / SSUF / SIGINC / COMM / PTPLOSPoint To Point Line Of Sight (Los)1966ISSCP-----***SIGINT
b-r-.-I-S-S-C-SSIGINT / SSUF / SIGINC / COMM / SATULSatellite Up Link1967ISSCS-----***SIGINT
b-r-.-I-S-S-RSIGINT / SSUF / SIGINC / RADRadar1968SIGINT
b-r-.-I-S-S-R-A-ASIGINT / SSUF / SIGINC / RAD / AA-CAntiAircraft1969ISSRAA----***SIGINT
b-r-.-I-S-S-R-A-TSIGINT / SSUF / SIGINC / RAD / ATCTLAir Traffic Control1970ISSRAT----***SIGINT
b-r-.-I-S-S-R-C-ASIGINT / SSUF / SIGINC / RAD / CTDAPPControlled Approach1971ISSRCA----***SIGINT
b-r-.-I-S-S-R-C-ISIGINT / SSUF / SIGINC / RAD / CTDINCControlled Intercept1972ISSRCI----***SIGINT
b-r-.-I-S-S-R-DSIGINT / SSUF / SIGINC / RAD / DATTMNData Transmission1973ISSRD-----***SIGINT
b-r-.-I-S-S-R-ESIGINT / SSUF / SIGINC / RAD / EWEarly Warning1974ISSRE-----***SIGINT
b-r-.-I-S-S-R-FSIGINT / SSUF / SIGINC / RAD / FIRCTLFire Control1975ISSRF-----***SIGINT
b-r-.-I-S-S-R-HSIGINT / SSUF / SIGINC / RAD / HGTFDGHeight Finding1976ISSRH-----***SIGINT
b-r-.-I-S-S-R-ISIGINT / SSUF / SIGINC / RAD / IDFFIdentification Friend / Foe (Interrogator)1977ISSRI-----***SIGINT
b-r-.-I-S-S-R-M-ASIGINT / SSUF / SIGINC / RAD / MSLAQMissile Acquisition1978ISSRMA----***SIGINT
b-r-.-I-S-S-R-M-FSIGINT / SSUF / SIGINC / RAD / MFNMultifunction1979ISSRMF----***SIGINT
b-r-.-I-S-S-R-M-GSIGINT / SSUF / SIGINC / RAD / MSLGDNMissile Guidance1980ISSRMG----***SIGINT
b-r-.-I-S-S-R-M-MSIGINT / SSUF / SIGINC / RAD / METOMeteorological (Military)1981ISSRMM----***SIGINT
b-r-.-I-S-S-R-M-TSIGINT / SSUF / SIGINC / RAD / MSLTRKMissile Tracking1982IASRMT----***SIGINT
b-r-.-I-S-S-R-SSIGINT / SSUF / SIGINC / RAD / SUFSRHSurface Search1983ISSRS-----***SIGINT
b-r-.-I-S-S-R-T-ASIGINT / SSUF / SIGINC / RAD / TGTAQTarget Acquisition1984ISSRTA----***SIGINT
b-r-.-I-S-S-R-T-ISIGINT / SSUF / SIGINC / RAD / TGTILLTarget Illuminator1985ISSRTI----***SIGINT
b-r-.-I-S-S-R-T-TSIGINT / SSUF / SIGINC / RAD / TGTTRKTarget Tracking1986ISSRTT----***SIGINT
b-r-.-I-S-S-R-USIGINT / SSUF / SIGINC / RAD / UNKUnknown1987ISSRU-----***SIGINT
b-r-.-I-USIGINT / SBSUFSubsurface Track1988SU-----------SIGINT
b-r-.-I-U-SSIGINT / SBSUF / SIGINCSignal Intercept1989SIGINT
b-r-.-I-U-S-CSIGINT / SBSUF / SIGINC / COMMCommunications1990SIGINT
b-r-.-I-U-S-C-OSIGINT / SBSUF / SIGINC / COMM / CELLOmni Line Of Sight (Los)1991SIGINT
b-r-.-I-U-S-C-PSIGINT / SBSUF / SIGINC / COMM / OLOSPoint To Point Line Of Sight (Los)1992IUSCO-----***SIGINT
b-r-.-I-U-S-C-SSIGINT / SBSUF / SIGINC / COMM / PTPLOSSatellite Up Link1993IUSCP-----***SIGINT
b-r-.-I-U-S-RSIGINT / SBSUF / SIGINC / COMM / SATULRadar1994IUSCS-----***SIGINT
b-r-.-I-U-S-R-DSIGINT / SBSUF / SIGINC / RADData Transmission1995SIGINT
b-r-.-I-U-S-R-ESIGINT / SBSUF / SIGINC / RAD / EWEarly Warning1996IUSRE-----***SIGINT
b-r-.-I-U-S-R-MSIGINT / SBSUF / SIGINC / RAD / ATCTLMulti Function1997SIGINT
b-r-.-I-U-S-R-SSIGINT / SBSUF / SIGINC / RAD / CTDAPPSurface Search1998SIGINT
b-r-.-I-U-S-R-TSIGINT / SBSUF / SIGINC / RAD / CTDINCTarget Acquisition1999SIGINT
b-r-.-I-U-S-R-USIGINT / SBSUF / SIGINC / RAD / DATTMNUnknown2000IUSRD-----***SIGINT
b-r-.-OSTBOPSMilitary Operations Other Than War (Mootw)2001STBOPS
b-r-.-O-ISTBOPS / ITMItems2002STBOPS
b-r-.-O-I-DSTBOPS / ITM / DGVEHDrug Vehicle2003OID----------STBOPS
b-r-.-O-I-FSTBOPS / ITM / ISFInternal Security Force2004OIF----------STBOPS
b-r-.-O-I-GSTBOPS / ITM / GRFGraffiti2005OIG----------STBOPS
b-r-.-O-I-ISTBOPS / ITM / KNIVEHKnown Insurgent Vehicle2006OII----------STBOPS
b-r-.-O-I-RSTBOPS / ITM / RFGRefugees2007OIR----------STBOPS
b-r-.-O-I-SSTBOPS / ITM / SAFHSESafe House2008OIS----------STBOPS
b-r-.-O-I-VSTBOPS / ITM / VRLRPSVandalism / Loot / Ransack / Plunder / Sack2009OIV----------STBOPS
b-r-.-O-LSTBOPS / LOCATLocations2010STBOPS
b-r-.-O-L-BSTBOPS / LOCAT / BLSTBlack List Location2011OLB----------STBOPS
b-r-.-O-L-GSTBOPS / LOCAT / GLSTGray List Location2012OLG----------STBOPS
b-r-.-O-L-WSTBOPS / LOCAT / WLSTWhite List Location2013OLW----------STBOPS
b-r-.-O-OSTBOPS / OPNOperations2014STBOPS
b-r-.-O-O-ASTBOPS / OPN / ARRArrest2015OOA----------STBOPS
b-r-.-O-O-DSTBOPS / OPN / DEMODemonstration2016OOD----------STBOPS
b-r-.-O-O-ESTBOPS / OPN / EXTNExtortion2017OOE----------STBOPS
b-r-.-O-O-FSTBOPS / OPN / FRGSRHForaging / Searching2018OOF----------STBOPS
b-r-.-O-O-HSTBOPS / OPN / HJKGHijacking2019STBOPS
b-r-.-O-O-H-ASTBOPS / OPN / HJKG / APLHijacking (Airplane)2020OOHA---------STBOPS
b-r-.-O-O-H-TSTBOPS / OPN / HJKG / VEHHijacking (Vehicle)2021OOHT---------STBOPS
b-r-.-O-O-H-VSTBOPS / OPN / HJKG / BOATHijacking (Boat)2022OOHV---------STBOPS
b-r-.-O-O-KSTBOPS / OPN / KDNGKidnapping2023OOK----------STBOPS
b-r-.-O-O-MSTBOPS / OPN / MLMine Laying2024OOM----------STBOPS
b-r-.-O-O-OSTBOPS / OPN / FDDISTFood Distribution2025OOO----------STBOPS
b-r-.-O-O-PSTBOPS / OPN / PATGPatrolling2026OOP----------STBOPS
b-r-.-O-O-RSTBOPS / OPN / RCMTRECRUITMENT2027STBOPS
b-r-.-O-O-R-CSTBOPS / OPN / RCMT / CRCDRecruitment (Coerced / Impressed)2028OORC---------STBOPS
b-r-.-O-O-R-WSTBOPS / OPN / RCMT / WLGRecruitment (Willing)2029OORW---------STBOPS
b-r-.-O-O-SSTBOPS / OPN / SPYSpy2030OOS----------STBOPS
b-r-.-O-O-USTBOPS / OPN / DGOPNDrug Operation2031OOU----------STBOPS
b-r-.-O-O-YSTBOPS / OPN / PSYOPPsychological Operations (Psyop)2032OOY----------STBOPS
b-r-.-O-O-Y-HSTBOPS / OPN / PSYOP / HTHPHouse-To-House Propaganda2033OOYH---------STBOPS
b-r-.-O-O-Y-TSTBOPS / OPN / PSYOP / TARPPsyop (Tv And Radio Propaganda)2034OOYT---------STBOPS
b-r-.-O-O-Y-WSTBOPS / OPN / PSYOP / WPPsyop (Written Propaganda)2035OOYW---------STBOPS
b-r-.-O-VSTBOPS / VIOATYViolent Activities (Death Causing)2036STBOPS
b-r-.-O-V-ASTBOPS / VIOATY / ASNArson / Fire2037OVA----------STBOPS
b-r-.-O-V-BSTBOPS / VIOATY / BMBomb / Bombing2038OVB----------STBOPS
b-r-.-O-V-DSTBOPS / VIOATY / DBSDrive-By Shooting2039OVD----------STBOPS
b-r-.-O-V-MSTBOPS / VIOATY / KILLAssassination / Murder / Execution2040OVM----------STBOPS
b-r-.-O-V-PSTBOPS / VIOATY / PSNGPoisoning2041OVP----------STBOPS
b-r-.-O-V-SSTBOPS / VIOATY / SPGSniping2042OVS----------STBOPS
b-r-.-O-V-YSTBOPS / VIOATY / BBYBooby Trap2043OVY----------STBOPS
b-t-fnoneGeo-Chat20431
b-wMETOCMetoc2044METOC
b-w-AMETOC / AMPHCAtmospheric2045METOC
b-w-A-CMETOC / AMPHC / CUDCOV / SYMCoverage Symbols2046METOC
b-w-A-C-aMETOC / AMPHC / CUDCOV / SYM / Total Cloud CoverageTotal Cloud Coverage2047METOC
b-w-A-C-bMETOC / AMPHC / CUDCOV / SYM / Cloud BaseCloud Base2048METOC
b-w-A-C-BMETOC / AMPHC / CUDCOV / SYM / BKNBroken Coverage2049WAS-CCCSBCP----METOC
b-w-A-C-cMETOC / AMPHC / CUDCOV / SYM / Cloud CeilingCloud Ceiling2050METOC
b-w-A-C-CMETOC / AMPHC / CUDCOV / SYM / SKCClear Sky2051WAS-CCCSCSP----METOC
b-w-A-C-OMETOC / AMPHC / CUDCOV / SYM / OVCOvercast Coverage2052WAS-CCCSOCP----METOC
b-w-A-C-PMETOC / AMPHC / CUDCOV / SYM / STOPOSky Totally Or Partially Obscured2053WAS-CCCSOBP----METOC
b-w-A-C-SMETOC / AMPHC / CUDCOV / SYM / SCTScattered Coverage2054WAS-CCCSSCP----METOC
b-w-A-C-tMETOC / AMPHC / CUDCOV / SYM / Cloud TopsCloud Tops2055METOC
b-w-A-C-WMETOC / AMPHC / CUDCOV / SYM / OVCOvercast Coverage2056WAS-CCCSOCP----METOC
b-w-A-FMETOC / AMPHC / BDAWTHFlight Rules2057METOC
b-w-A-F-IMETOC / AMPHC / BDAWTH / IFRInstrument Flight Rule (Ifr)2058WA-DBAIF----A--METOC
b-w-A-F-VMETOC / AMPHC / BDAWTH / MVFRMarginal Visual Flight Rule (Mvfr)2059WA-DBAMV----A--METOC
b-w-A-IMETOC / AMPHC / BDAWTH / ICGIcing2060WA-DBAI-----A--METOC
b-w-A-I-CMETOC / AMPHC / ICG / CLR / LITClear Icing – Light2061WAS-ICL---P----METOC
b-w-A-I-C-LMETOC / AMPHC / ICG / CLR / LITClear Icing - Light2062WAS-ICL---P----METOC
b-w-A-I-C-MMETOC / AMPHC / ICG / CLR / MODClear Icing - Moderate2063WAS-ICM---P----METOC
b-w-A-I-C-SMETOC / AMPHC / ICG / CLR / SVRClear Icing - Severe2064WAS-ICS---P----METOC
b-w-A-I-MMETOC / AMPHC / ICG / MIXMIXED ICING2065METOC
b-w-A-I-M-LMETOC / AMPHC / ICG / MIX / LITMixed Icing - Light2066WAS-IML---P----METOC
b-w-A-I-M-MMETOC / AMPHC / ICG / MIX / MODMixed Icing - Moderate2067WAS-IMM---P----METOC
b-w-A-I-M-SMETOC / AMPHC / ICG / MIX / SVRMixed Icing - Severe2068WAS-IMS---P----METOC
b-w-A-I-RMETOC / AMPHC / ICG / RIMERIME ICING2069METOC
b-w-A-I-R-LMETOC / AMPHC / ICG / RIME / LITRime Icing - Light2070WAS-IRL---P----METOC
b-w-A-I-R-MMETOC / AMPHC / ICG / RIME / MODRime Icing - Moderate2071WAS-IRM---P----METOC
b-w-A-I-R-SMETOC / AMPHC / ICG / RIME / SVRRime Icing - Severe2072WAS-IRS---P----METOC
b-w-A-OMETOC / AMPHC / WTHObstructions To Visibility2073METOC
b-w-A-O-BMETOC / AMPHC / WTH / DT-SD / BLDTSDBlowing Dust Or Sand2074WAS-WSDB--P----METOC
b-w-A-O-DMETOC / AMPHC / WTH / DT-SD / DTDVLDust Devil2075WAS-WSDD--P----METOC
b-w-A-O-FMETOC / AMPHC / WTH / FGFog (Fg)2076METOC
b-w-A-O-F-FMETOC / AMPHC / WTH / FG / FZSNVFog - Freezing Sky Not Visible2077WAS-WSFGFOP----METOC
b-w-A-O-HMETOC / AMPHC / WTH / HZHaze2078WAS-WSHZ--P----METOC
b-w-A-O-KMETOC / AMPHC / WTH / FUSmoke2079WAS-WSFU--P----METOC
b-w-A-O-SMETOC / AMPHC / WTH / SN / BLSNHYBlowing Snow – Heavy2080WAS-WSSBH-P----METOC
b-w-A-O-TMETOC / AMPHC / WTH / DT-SD / LITMODDust-Sand Storm - Light To Moderate2081WAS-WSDSLMP----METOC
b-w-A-PMETOC / AMPHC / PRSPRESSURE SYSTEMS2082METOC
b-w-A-P-FMETOC / AMPHC / PRS / FRNSYSFRONTAL SYSTEMS2083METOC
b-w-A-P-F-CMETOC / AMPHC / PRS / FRNSYS / CLDFRNCold Front2084WA-DPFC----L---METOC
b-w-A-P-F-C-UMETOC / AMPHC / PRS / FRNSYS / CLDFRN / UPPUpper Cold Front2085WA-DPFCU---L---METOCUPP
b-w-A-P-F-OMETOC / AMPHC / PRS / FRNSYS / OCDOccluded Front2086WA-DPFO----L---METOC
b-w-A-P-F-SMETOC / AMPHC / PRS / FRNSYS / STATStationary Front2087WA-DPFS----L---METOC
b-w-A-P-F-WMETOC / AMPHC / PRS / FRNSYS / WRMFRNWarm Front2088WA-DPFW----L---METOC
b-w-A-P-F-W-UMETOC / AMPHC / PRS / FRNSYS / WRMFRN / UPPUpper Warm Front2089WA-DPFWU---L---METOCUPP
b-w-A-P-HMETOC / AMPHC / PRS / HGHCTRHigh Pressure Center2090WAS-PH----P----METOC
b-w-A-P-LMETOC / AMPHC / PRS / LOWCTRLow Pressure Center2091WAS-PL----P----METOC
b-w-A-P-XMETOC / AMPHC / PRS / LNELINES2092METOC
b-w-A-P-X-RMETOC / AMPHC / PRS / LNE / RDGAXSRidge Axis2093WA-DPXR----L---METOC
b-w-A-P-X-SMETOC / AMPHC / PRS / LNE / SSLSevere Squall Line2094WA-DPXSQ---L---METOC
b-w-A-P-X-TMETOC / AMPHC / PRS / LNE / TRUAXSTrough Axis2095WA-DPXT----L---METOC
b-w-A-RPrecipitation2096
b-w-A-R-CMETOC / AMPHC / WTH / ICIce Crystals (Diamond Dust)Ice Crystals2097WAS-WSIC--P----METOC
b-w-A-R-HMETOC / AMPHC / WTH / HLHail2098WAS-WSGRL-P----METOC
b-w-A-R-IMETOC / AMPHC / WTH / PE / LITIce Pellets - Light2099WAS-WSPLL-P----METOC
b-w-A-R-RMETOC / AMPHC / WTH / RARain (Ra)2100METOC
b-w-A-R-R-DMETOC / AMPHC / WTH / DZ / INMLITDrizzle - Intermittent Light2101WAS-WSD-LIP----METOC
b-w-A-R-R-D-FMETOC / AMPHC / WTH / FZDZ / LITFreezing Drizzle - Light2102WAS-WSDFL-P----METOC
b-w-A-R-R-FMETOC / AMPHC / WTH / FZRA / LITFreezing Rain - Light2103WAS-WSRFL-P----METOC
b-w-A-R-R-SMETOC / AMPHC / WTH / RASWR / LITRain Showers - Light2104WAS-WSRSL-P----METOC
b-w-A-R-SMETOC / AMPHC / WTH / SNSnow(Sn)2105METOC
b-w-A-R-S-GMETOC / AMPHC / WTH / SGSnow Grains2106WAS-WSSG--P----METOC
b-w-A-R-S-SMETOC / AMPHC / WTH / SSWRSNOW SHOWERS2107METOC
b-w-A-SMETOC / AMPHC / WTH / STMSSTORMS2108METOC
b-w-A-S-SMETOC / AMPHC / WTH / TPLSYSTROPICAL STORM SYSTEMS2109METOC
b-w-A-S-S-HMETOC / AMPHC / WTH / TPLSYS / HCHurricane-Typhoon2110WAS-WSTSH-P----METOC
b-w-A-S-S-TMETOC / AMPHC / WTH / TPLSYS / TROPSMTropical Storm2111WAS-WSTSS-P----METOC
b-w-A-S-TMETOC / AMPHC / WTH / STMS / TSThunderstorm - No Precipitation2112WAS-WST-NPP----METOC
b-w-A-S-T-FMETOC / AMPHC / WTH / STMS / FCFunnel Cloud (Tornado-Waterspout)2113WAS-WST-FCP----METOC
b-w-A-S-T-LMETOC / AMPHC / WTH / STMS / LTGLightning2114WAS-WST-LGP----METOC
b-w-A-S-T-RMETOC / AMPHC / WTH / STMS / TSHVNHThunderstorm Heavy With Rain-Snow - No Hail2115WAS-WSTHR-P----METOC
b-w-A-tTemperature2116
b-w-A-TMETOC / AMPHC / BDAWTH / TRBTURBULENCE2117WA-DBATB----A--METOC
b-w-A-T-EMETOC / AMPHC / TRB / EXTTurbulence - Extreme2118WAS-TE----P----METOC
b-w-A-T-LMETOC / AMPHC / TRB / LITTurbulence - Light2119WAS-TL----P----METOC
b-w-A-T-MMETOC / AMPHC / TRB / MODTurbulence - Moderate2120WAS-TM----P----METOC
b-w-A-T-SMETOC / AMPHC / TRB / SVRTurbulence - Severe2121WAS-TS----P----METOC
b-w-A-WMETOC / AMPHC / WND / PLTWind PlotWind Barb2122WAS-WP----P----METOC
b-w-A-W-JMETOC / AMPHC / WND / JTSMJet Stream2123WA-DWJ-----L---METOC
b-w-OMETOC / OCAOceanic2124METOC
b-w-SSIGINT / SPC / SIGINC / RAD / SPCSpace2125IPSRS-----***SIGINT
b-x.*Non COTNon-Cot Object2126Non COT
cCapabilityCapability2127Capability
c-ccapability / CAP: CommunicationsCAP: Communications2128capability
c-fcapability / CAP: FiresCAP: Fires2129capability
c-f-dcapability / CAP: Direct firesCAP: Direct fires2130capability
c-f-icapability / CAP: Indirect firesCAP: Indirect fires2131capability
c-lcapability / CAP: Logistics (supply)CAP: Logistics (supply)2132capability
c-l-fcapability / CAP: FuelCAP: Fuel2133capability
c-rcapability / CAP: RescueCAP: Rescue2134capability
c-scapability / CAP: SurveillanceCAP: Surveillance2135capability
r-c-x-bBiological AttackBiological attack2136Biological Attack
r-c-x-b-bBiological Attack / Bacterial biological agentsBacterial biological agents2137Biological Attack
r-c-x-b-b-aBiological Attack / anthraxanthrax2138Biological Attack
r-c-x-b-b-a-nBiological Attack / N anthraxN anthrax2139Biological Attack
r-c-x-b-b-a-tBiological Attack / TR anthraxTR anthrax2140Biological Attack
r-c-x-b-b-bBiological Attack / brucellosisbrucellosis2141Biological Attack
r-c-x-b-b-b-bBiological Attack / AB, bovine brucellosisAB, bovine brucellosis2142Biological Attack
r-c-x-b-b-b-cBiological Attack / caprine brucellosiscaprine brucellosis2143Biological Attack
r-c-x-b-b-b-c-aBiological Attack / AM, caprine brucellosisAM, caprine brucellosis2144Biological Attack
r-c-x-b-b-b-c-bBiological Attack / BX, caprine brucellosisBX, caprine brucellosis2145Biological Attack
r-c-x-b-b-b-pBiological Attack / porcine brucellosisporcine brucellosis2146Biological Attack
r-c-x-b-b-b-p-nBiological Attack / NX, porcine brucellosisNX, porcine brucellosis2147Biological Attack
r-c-x-b-b-b-p-uBiological Attack / US, porcine brucellosisUS, porcine brucellosis2148Biological Attack
r-c-x-b-b-cBiological Attack / HO, choleraHO, cholera2149Biological Attack
r-c-x-b-b-dBiological Attack / DK, diphtheriaDK, diphtheria2150Biological Attack
r-c-x-b-b-gBiological Attack / LA, GlandersLA, Glanders2151Biological Attack
r-c-x-b-b-lBiological Attack / TQ, listeriosisTQ, listeriosis2152Biological Attack
r-c-x-b-b-mBiological Attack / HI, MelioidosisHI, Melioidosis2153Biological Attack
r-c-x-b-b-pBiological Attack / LE, plagueLE, plague2154Biological Attack
r-c-x-b-b-tBiological Attack / tularemiatularemia2155Biological Attack
r-c-x-b-b-t-dBiological Attack / ZZ, dry-type ULZZ, dry-type UL2156Biological Attack
r-c-x-b-b-t-jBiological Attack / JT, tularemia (425)JT, tularemia (425)2157Biological Attack
r-c-x-b-b-t-sBiological Attack / SR, tularemiaSR, tularemia2158Biological Attack
r-c-x-b-b-t-uBiological Attack / UL, tularemia (schu S4)UL, tularemia (schu S4)2159Biological Attack
r-c-x-b-b-t-wBiological Attack / TT, wet-type ULTT, wet-type UL2160Biological Attack
r-c-x-b-b-yBiological Attack / Y, bacterial dysenteryY, bacterial dysentery2161Biological Attack
r-c-x-b-cBiological Attack / Chlamydial biological agentsChlamydial biological agents2162Biological Attack
r-c-x-b-c-sBiological Attack / SI - psittacosisSI - psittacosis2163Biological Attack
r-c-x-b-mBiological Attack / Mycotic biological agentsMycotic biological agents2164Biological Attack
r-c-x-b-m-cBiological Attack / OC, Coccidioides mycosisOC, Coccidioides mycosis2165Biological Attack
r-c-x-b-rBiological Attack / Rickettsial biological agentsRickettsial biological agents2166Biological Attack
r-c-x-b-r-qBiological Attack / OU, Q feverOU, Q fever2167Biological Attack
r-c-x-b-r-q-dBiological Attack / NT, dry-type OUNT, dry-type OU2168Biological Attack
r-c-x-b-r-q-wBiological Attack / MN, wet-type OUMN, wet-type OU2169Biological Attack
r-c-x-b-r-rBiological Attack / rocky mountain spotted feverrocky mountain spotted fever2170Biological Attack
r-c-x-b-r-r-rBiological Attack / RI, rocky mountain spotted feverRI, rocky mountain spotted fever2171Biological Attack
r-c-x-b-r-r-uBiological Attack / UY, rocky mountain spotted feverUY, rocky mountain spotted fever2172Biological Attack
r-c-x-b-r-tBiological Attack / typhustyphus2173Biological Attack
r-c-x-b-r-t-hBiological Attack / YE, human typhusYE, human typhus2174Biological Attack
r-c-x-b-r-t-mBiological Attack / AV, murine typhusAV, murine typhus2175Biological Attack
r-c-x-b-sBiological Attack / SimuantsSimuants2176Biological Attack
r-c-x-b-s-aBiological Attack / AF, Aspergillus fumigatus mutant C-2AF, Aspergillus fumigatus mutant C-22177Biological Attack
r-c-x-b-s-eBiological Attack / EC, E / coliEC, E. coli2178Biological Attack
r-c-x-b-s-fBiological Attack / FP, fluorescent particleFP, fluorescent particle2179Biological Attack
r-c-x-b-s-gBiological Attack / Bacillus globigiiBacillus globigii2180Biological Attack
r-c-x-b-s-g-bgBiological Attack / BG, Bacillus globigiiBG, Bacillus globigii2181Biological Attack
r-c-x-b-s-g-bsBiological Attack / BS, Bacillus globigiiBS, Bacillus globigii2182Biological Attack
r-c-x-b-s-g-uBiological Attack / U, Bacillus globigiiU, Bacillus globigii2183Biological Attack
r-c-x-b-s-mBiological Attack / MR, molasis residiumMR, molasis residium2184Biological Attack
r-c-x-b-s-sBiological Attack / Serratia marescensSerratia marescens2185Biological Attack
r-c-x-b-s-s-pBiological Attack / P, Serratia marescensP, Serratia marescens2186Biological Attack
r-c-x-b-s-s-sBiological Attack / SM, Serratia marescensSM, Serratia marescens2187Biological Attack
r-c-x-b-s-tBiological Attack / BT, Bacillus thursidiusBT, Bacillus thursidius2188Biological Attack
r-c-x-b-s-wBiological Attack / EH, Erwinia hebicolaEH, Erwinia hebicola2189Biological Attack
r-c-x-b-tBiological Attack / Biological ToxinsBiological Toxins2190Biological Attack
r-c-x-b-t-3Biological Attack / TrichotheceneTrichothecene2191Biological Attack
r-c-x-b-t-aBiological Attack / AbrinAbrin2192Biological Attack
r-c-x-b-t-bBiological Attack / botulinum toxin Abotulinum toxin A2193Biological Attack
r-c-x-b-t-b-xBiological Attack / X, botulinum toxin AX, botulinum toxin A2194Biological Attack
r-c-x-b-t-b-xrBiological Attack / XR, partially purified botulinum toxin AXR, partially purified botulinum toxin A2195Biological Attack
r-c-x-b-t-cBiological Attack / ColchicineColchicine2196Biological Attack
r-c-x-b-t-dBiological Attack / DigitalisDigitalis2197Biological Attack
r-c-x-b-t-eBiological Attack / staphylococcal enterotoxin Bstaphylococcal enterotoxin B2198Biological Attack
r-c-x-b-t-e-pgBiological Attack / PG, staphylococcal enterotoxin BPG, staphylococcal enterotoxin B2199Biological Attack
r-c-x-b-t-e-ucBiological Attack / UC, staphylococcal enterotoxin BUC, staphylococcal enterotoxin B2200Biological Attack
r-c-x-b-t-nBiological Attack / NicotineNicotine2201Biological Attack
r-c-x-b-t-rBiological Attack / ricinricin2202Biological Attack
r-c-x-b-t-r-wBiological Attack / W, ricinW, ricin2203Biological Attack
r-c-x-b-t-r-waBiological Attack / WA, ricinWA, ricin2204Biological Attack
r-c-x-b-t-sBiological Attack / saxitoxinsaxitoxin2205Biological Attack
r-c-x-b-t-s-sBiological Attack / SS, saxitoxinSS, saxitoxin2206Biological Attack
r-c-x-b-t-s-tBiological Attack / TZ, saxitoxinTZ, saxitoxin2207Biological Attack
r-c-x-b-t-tBiological Attack / PP, tetrodotoxinPP, tetrodotoxin2208Biological Attack
r-c-x-b-t-vBiological Attack / BrevetoxinBrevetoxin2209Biological Attack
r-c-x-b-t-yBiological Attack / StrychnineStrychnine2210Biological Attack
r-c-x-b-vBiological Attack / Viral biological agentsViral biological agents2211Biological Attack
r-c-x-b-v-eBiological Attack / EncephalitisEncephalitis2212Biological Attack
r-c-x-b-v-e-eBiological Attack / Equine EncephalitisEquine Encephalitis2213Biological Attack
r-c-x-b-v-e-e-eBiological Attack / ZX, Eastern Equine EncephalitisZX, Eastern Equine Encephalitis2214Biological Attack
r-c-x-b-v-e-e-vBiological Attack / Venezuelan Equine EncephalitisVenezuelan Equine Encephalitis2215Biological Attack
r-c-x-b-v-e-e-v-fBiological Attack / FX, Venezuelan Equine EncephalitisFX, Venezuelan Equine Encephalitis2216Biological Attack
r-c-x-b-v-e-e-v-nBiological Attack / NU, Venezuelan Equine EncephalitisNU, Venezuelan Equine Encephalitis2217Biological Attack
r-c-x-b-v-e-e-v-tBiological Attack / TD, Venezuelan Equine EncephalitisTD, Venezuelan Equine Encephalitis2218Biological Attack
r-c-x-b-v-e-jBiological Attack / AN, Japanese B EncephalitisAN, Japanese B Encephalitis2219Biological Attack
r-c-x-b-v-rBiological Attack / FA, rift valley feverFA, rift valley fever2220Biological Attack
r-c-x-b-v-sBiological Attack / ZL, smallpoxZL, smallpox2221Biological Attack
r-c-x-b-v-yBiological Attack / yellow feveryellow fever2222Biological Attack
r-c-x-b-v-y-lBiological Attack / LU, yellow feverLU, yellow fever2223Biological Attack
r-c-x-b-v-y-oBiological Attack / OJ, yellow feverOJ, yellow fever2224Biological Attack
r-c-x-b-v-y-uBiological Attack / UT, yellow feverUT, yellow fever2225Biological Attack
r-c-x-cBiological Attack / Chemical attackChemical attack2226Biological Attack
r-c-x-c-aBiological Attack / Long-Acting Anticoagulants: Poisons that prevent blood from clotting properly, which can lead to uncontrolled bleedingLong-Acting Anticoagulants: Poisons that prevent blood from clotting properly, which can lead to uncontrolled bleeding2227Biological Attack
r-c-x-c-a-wBiological Attack / Super warfarinSuper warfarin2228Biological Attack
r-c-x-c-bBiological Attack / blood: Poisons that affect the body by being absorbed into the bloodblood: Poisons that affect the body by being absorbed into the blood2229Biological Attack
r-c-x-c-b-aBiological Attack / Arsine (SA)Arsine (SA)2230Biological Attack
r-c-x-c-b-cBiological Attack / CyanideCyanide2231Biological Attack
r-c-x-c-b-c-cBiological Attack / Cyanogen chloride (CK)Cyanogen chloride (CK)2232Biological Attack
r-c-x-c-b-c-hBiological Attack / Hydrogen cyanide (AC)Hydrogen cyanide (AC)2233Biological Attack
r-c-x-c-b-c-pBiological Attack / Potassium cyanide (KCN)Potassium cyanide (KCN)2234Biological Attack
r-c-x-c-b-c-sBiological Attack / Sodium cyanide (NaCN)Sodium cyanide (NaCN)2235Biological Attack
r-c-x-c-b-mBiological Attack / Carbon MonoxideCarbon Monoxide2236Biological Attack
r-c-x-c-b-sBiological Attack / Sodium monofluoroacetate (compound 1080)Sodium monofluoroacetate (compound 1080)2237Biological Attack
r-c-x-c-cBiological Attack / caustics (Acids): Chemicals that burn or corrode people's skin, eyes, and mucus membranes (lining of the nose, mouth, throat, and lungs) on contactcaustics (Acids): Chemicals that burn or corrode people's skin, eyes, and mucus membranes (lining of the nose, mouth, throat, and lungs) on contact2238Biological Attack
r-c-x-c-c-hBiological Attack / Hydrofluoric acid (hydrogen fluoride)Hydrofluoric acid (hydrogen fluoride)2239Biological Attack
r-c-x-c-gBiological Attack / Riot Control Agents / Tear Gas: Highly irritating agents normally used by law enforcement for crowd control or by individuals for protection (for example, mace)Riot Control Agents / Tear Gas: Highly irritating agents normally used by law enforcement for crowd control or by individuals for protection (for example, mace)2240Biological Attack
r-c-x-c-g-bBiological Attack / Bromobenzylcyanide (CA)Bromobenzylcyanide (CA)2241Biological Attack
r-c-x-c-g-dBiological Attack / Dibenzoxazepine (CR)Dibenzoxazepine (CR)2242Biological Attack
r-c-x-c-g-nBiological Attack / Chloroacetophenone (CN)Chloroacetophenone (CN)2243Biological Attack
r-c-x-c-g-pBiological Attack / Chloropicrin (PS)Chloropicrin (PS)2244Biological Attack
r-c-x-c-g-sBiological Attack / Chlorobenzylidenemalononitrile (CS)Chlorobenzylidenemalononitrile (CS)2245Biological Attack
r-c-x-c-hBiological Attack / Toxic Alcohols: Poisonous alcohols that can damage the heart, kidneys, and nervous systemToxic Alcohols: Poisonous alcohols that can damage the heart, kidneys, and nervous system2246Biological Attack
r-c-x-c-h-eBiological Attack / Ethylene glycolEthylene glycol2247Biological Attack
r-c-x-c-iBiological Attack / Incapacitating Agents: Drugs that make people unable to think clearly or that cause an altered state of consciousness (possibly unconsciousness)Incapacitating Agents: Drugs that make people unable to think clearly or that cause an altered state of consciousness (possibly unconsciousness)2248Biological Attack
r-c-x-c-i-bBiological Attack / BZBZ2249Biological Attack
r-c-x-c-i-oBiological Attack / opioids: chemical substance that causes a morphine-like actionopioids: chemical substance that causes a morphine-like action2250Biological Attack
r-c-x-c-i-o-fBiological Attack / FentanylsFentanyls2251Biological Attack
r-c-x-c-mBiological Attack / Metals: Agents that consist of metallic poisonsMetals: Agents that consist of metallic poisons2252Biological Attack
r-c-x-c-m-aBiological Attack / ArsenicArsenic2253Biological Attack
r-c-x-c-m-bBiological Attack / BariumBarium2254Biological Attack
r-c-x-c-m-mBiological Attack / MercuryMercury2255Biological Attack
r-c-x-c-m-tBiological Attack / ThalliumThallium2256Biological Attack
r-c-x-c-nBiological Attack / Nerve Agents: Highly poisonous chemicals that work by preventing the nervous system from working properlyNerve Agents: Highly poisonous chemicals that work by preventing the nervous system from working properly2257Biological Attack
r-c-x-c-n-gBiological Attack / G agentsG agents2258Biological Attack
r-c-x-c-n-g-aBiological Attack / Tabun (GA)Tabun (GA)2259Biological Attack
r-c-x-c-n-g-bBiological Attack / Sarin (GB)Sarin (GB)2260Biological Attack
r-c-x-c-n-g-dBiological Attack / Soman (GD)Soman (GD)2261Biological Attack
r-c-x-c-n-vBiological Attack / V agentsV agents2262Biological Attack
r-c-x-c-n-v-xBiological Attack / VXVX2263Biological Attack
r-c-x-c-oBiological Attack / Organic Solvents: Agents that damage the tissues of living things by dissolving fats and oilsOrganic Solvents: Agents that damage the tissues of living things by dissolving fats and oils2264Biological Attack
r-c-x-c-o-bBiological Attack / BenzeneBenzene2265Biological Attack
r-c-x-c-pBiological Attack / Choking / Lung / Pulmonary Agents: Chemicals that cause severe irritation or swelling of the respiratory tract (lining of the nose, throat, and lungs)Choking / Lung / Pulmonary Agents: Chemicals that cause severe irritation or swelling of the respiratory tract (lining of the nose, throat, and lungs)2266Biological Attack
r-c-x-c-p-aBiological Attack / AmmoniaAmmonia2267Biological Attack
r-c-x-c-p-bBiological Attack / Bromine (CA)Bromine (CA)2268Biological Attack
r-c-x-c-p-cBiological Attack / Chlorine (CL)Chlorine (CL)2269Biological Attack
r-c-x-c-p-hBiological Attack / Hydrogen chlorideHydrogen chloride2270Biological Attack
r-c-x-c-p-iBiological Attack / Methyl isocyanateMethyl isocyanate2271Biological Attack
r-c-x-c-p-mBiological Attack / Methyl bromideMethyl bromide2272Biological Attack
r-c-x-c-p-oBiological Attack / PhosphinePhosphine2273Biological Attack
r-c-x-c-p-pBiological Attack / PhosgenePhosgene2274Biological Attack
r-c-x-c-p-p-cBiological Attack / Phosgene (CG)Phosgene (CG)2275Biological Attack
r-c-x-c-p-p-dBiological Attack / Diphosgene (DP)Diphosgene (DP)2276Biological Attack
r-c-x-c-p-rBiological Attack / Phosphorus, elementalPhosphorus, elemental2277Biological Attack
r-c-x-c-p-r-wBiological Attack / whitewhite2278Biological Attack
r-c-x-c-p-r-yBiological Attack / yellowyellow2279Biological Attack
r-c-x-c-p-sBiological Attack / Sulfuryl fluorideSulfuryl fluoride2280Biological Attack
r-c-x-c-p-tBiological Attack / Osmium tetroxideOsmium tetroxide2281Biological Attack
r-c-x-c-sBiological Attack / blister: aka vesicants / Chemicals that severely blister the eyes, respiratory tract, and skin on contactblister: aka vesicants. Chemicals that severely blister the eyes, respiratory tract, and skin on contact2282Biological Attack
r-c-x-c-s-cxBiological Attack / hosgene oxime (CX)hosgene oxime (CX)2283Biological Attack
r-c-x-c-s-lBiological Attack / Lewisites / chloroarsine agentsLewisites / chloroarsine agents2284Biological Attack
r-c-x-c-s-l-hlBiological Attack / ustard / lewisite (HL)ustard / lewisite (HL)2285Biological Attack
r-c-x-c-s-l-lBiological Attack / Lewisite (L, L-1, L-2, L-3)Lewisite (L, L-1, L-2, L-3)2286Biological Attack
r-c-x-c-s-mBiological Attack / mustardsmustards2287Biological Attack
r-c-x-c-s-m-hBiological Attack / Mustard gas (H) (sulfur mustard)Mustard gas (H) (sulfur mustard)2288Biological Attack
r-c-x-c-s-m-hdBiological Attack / istilled mustard (HD)istilled mustard (HD)2289Biological Attack
r-c-x-c-s-m-hlBiological Attack / ustard / lewisite (HL)ustard / lewisite (HL)2290Biological Attack
r-c-x-c-s-m-nBiological Attack / Nitrogen mustard (HN-1, HN-2, HN-3)Nitrogen mustard (HN-1, HN-2, HN-3)2291Biological Attack
r-c-x-c-s-m-qBiological Attack / Sesqui mustardSesqui mustard2292Biological Attack
r-c-x-c-s-m-sBiological Attack / Sulfur mustard (H) (mustard gas)Sulfur mustard (H) (mustard gas)2293Biological Attack
r-c-x-c-s-m-tBiological Attack / Mustard / TMustard / T2294Biological Attack
r-c-x-c-vBiological Attack / Vomiting Agents: Chemicals that cause nausea and vomitingVomiting Agents: Chemicals that cause nausea and vomiting2295Biological Attack
r-c-x-c-v-aBiological Attack / Adamsite (DM)Adamsite (DM)2296Biological Attack
tTaskingTasking2297Tasking
t-aTasking / airair2298Tasking
t-a-cTasking / close air supportclose air support2299Tasking
t-a-dTasking / air dropair drop2300Tasking
t-a-eTasking / electronic warfareelectronic warfare2301Tasking
t-a-kTasking / strikestrike2302Tasking
t-a-rTasking / recoveryrecovery2303Tasking
t-a-sTasking / SEADSEAD2304Tasking
t-kTasking / StrikeStrike2305Tasking
t-k-dTasking / DestroyDestroy2306Tasking
t-k-iTasking / InvestigateInvestigate2307Tasking
t-k-tTasking / TargetTarget2308Tasking
t-mTasking / MensurateMensurate2309Tasking
t-pTasking / Weapon Target Pairing- pairingWeapon Target Pairing- pairing2310Tasking
t-p-aTasking / Weapon Target Pairing- airWeapon Target Pairing- air2311Tasking
t-p-a-cTasking / Weapon Target Pairing- CASWeapon Target Pairing- CAS2312Tasking
t-p-a-fTasking / Weapon Target Pairing- refuelingWeapon Target Pairing- refueling2313Tasking
t-p-a-kTasking / Weapon Target Pairing- strikeWeapon Target Pairing- strike2314Tasking
t-p-kTasking / Weapon Target Pairing- StrikeWeapon Target Pairing- Strike2315Tasking
t-p-k-dTasking / Weapon Target Pairing- DestroyWeapon Target Pairing- Destroy2316Tasking
t-p-k-iTasking / Weapon Target Pairing- InvestigateWeapon Target Pairing- Investigate2317Tasking
t-p-k-tTasking / Weapon Target Pairing- TargetWeapon Target Pairing- Target2318Tasking
t-p-rTasking / Weapon Target Pairing- Recovery (personnel)Weapon Target Pairing- Recovery (personnel)2319Tasking
t-p-sTasking / Weapon Target Pairing- ISRWeapon Target Pairing- ISR2320Tasking
t-p-s-iTasking / Weapon Target Pairing- imageryWeapon Target Pairing- imagery2321Tasking
t-qTasking / Tasking Query CapableTasking Query Capable2322Tasking
t-rTasking / Tasking RelocateTasking Relocate2323Tasking
t-sTasking / ISRISR2324Tasking
t-s-bTasking / Tasking BFT infoTasking BFT info2325Tasking
t-s-iTasking / imagery desiredimagery desired2326Tasking
t-s-i-eTasking / ISR EOISR EO2327Tasking
t-s-i-iTasking / ISR IRISR IR2328Tasking
t-s-rTasking / ISR RadarISR Radar2329Tasking
t-s-vTasking / ISR VideoISR Video2330Tasking
t-s-v-eTasking / ISR Video EOISR Video EO2331Tasking
t-s-v-iTasking / ISR Video IRISR Video IR2332Tasking
t-uTasking / Tasking UpdateTasking Update2333Tasking
t-u-qTasking / Tasking Status QueryTasking Status Query2334Tasking
t-u-zTasking / Tasking CancelTasking Cancel2335Tasking
t-xTasking / Tasking (Experimental)Tasking (Experimental)2336Tasking
t-x-a-fTasking / FilterFilter2337Tasking
t-x-a-oTasking / OpenOpen2338Tasking
t-x-a-sTasking / App control- Sync (with peer)App control- Sync (with peer)2339Tasking
t-x-a-s-cTasking / App control- Sync (subscribe)App control- Sync (subscribe)2340Tasking
t-x-iTasking / Tasking Data RetrievalTasking Data Retrieval2341Tasking
t-x-i-lTasking / Link DereferenceLink Dereference2342Tasking
t-x-m-cTasking / MissionMission add CONTENT23431Tasking
t-x-m-c-lTasking / MissionMission LOG234310Tasking
t-x-m-c-kTasking / MissionMission keyword234311Tasking
t-x-m-c-k-uTasking / MissionMission UID KEYWORD234312Tasking
t-x-m-c-k-cTasking / MissionMission RESOURCE_KEYWORD234313Tasking
t-x-m-c-mTasking / MissionMission METADATA234314Tasking
t-x-m-c-nTasking / MissionMission new234315Tasking
t-x-m-c-eTasking / MissionMission EXTERNAL_DATA234316Tasking
t-x-m-c-eTasking / MissionMission Layer2343161Tasking
t-x-m-iTasking / MissionMission invite2343161Tasking
t-x-v-mTasking / MedevacMedevac2343Tasking
u-d-c-cDrawing Shapes / Drawing Shapes – CircleDrawing Shapes – Circle2344Drawing Shapes
u-d-c-cDrawing Shapes / Geo FenceGeo Fence2345Drawing Shapes
u-d-fDrawing Shapes / Drawing Shapes - Free FormDrawing Shapes - Free Form2346Drawing Shapes
u-d-f-mDrawing Shapes / Drawing Shapes – TelestrationDrawing Shapes – Telestration2347Drawing Shapes
u-d-rDrawing Shapes / Drawing Shapes – RectangleDrawing Shapes – Rectangle2348Drawing Shapes
u-r-b-bullseyeRange & Bearing / Range & Bearing – BullseyeRange & Bearing – Bullseye2349Range & Bearing
u-r-b-c-cRange & Bearing / Range & Bearing – CircleRange & Bearing – Circle2350Range & Bearing
u-rb-aRange & Bearing / Range & Bearing – LineRange & Bearing – Line2351Range & Bearing
yReplyReply2352Reply
y-aReply / AckAck2353Reply
y-a-rReply / RcvdRcvd2354Reply
y-a-wReply / WilcoWilco2355Reply
y-cReply / Tasking CompleteTasking Complete2356Reply
y-c-fFailFail2357Fail
y-c-f-aFail / Fail: No AssetsFail: No Assets2358Fail
y-c-f-bFail / Fail: Bad Reqest (CANTPRO)Fail: Bad Reqest (CANTPRO)2359Fail
y-c-f-dFail / Fail: DeniedFail: Denied2360Fail
y-c-f-iFail / Fail: Insufficient InfoFail: Insufficient Info2361Fail
y-c-f-rFail / Fail: RejectedFail: Rejected2362Fail
y-c-f-r-cFail / Fail: C2 elementFail: C2 element2363Fail
y-c-f-r-pFail / Fail: Platform (CANTCO)Fail: Platform (CANTCO)2364Fail
y-c-f-sFail / Fail: StaleFail: Stale2365Fail
y-c-f-xFail / Fail: CancelledFail: Cancelled2366Fail
y-c-sComplete / Complete: SuccessComplete: Success2367Complete
y-sStatus / Status: StatusStatus: Status2368Status
y-s-cStatus / Status: CancelingStatus: Canceling2369Status
y-s-eStatus / Status: ExecutingStatus: Executing2370Status
y-s-e-aStatus / Status: ApprovedStatus: Approved2371Status
y-s-e-dStatus / Status: DisseminatingStatus: Disseminating2372Status
y-s-e-d-cStatus / Status: DisseminatedStatus: Disseminated2373Status
y-s-iStatus / Status: Imagery AvailableStatus: Imagery Available2374Status
y-s-mStatus / Status: MISREP availableStatus: MISREP available2375Status
y-s-pStatus / Status: PlanningStatus: Planning2376Status
y-s-rStatus / Status: ReviewingStatus: Reviewing2377Status
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/architecture/mil_std_2525/index.html b/About/architecture/mil_std_2525/index.html new file mode 100644 index 000000000..497dd17d2 --- /dev/null +++ b/About/architecture/mil_std_2525/index.html @@ -0,0 +1,4454 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

About MIL-STD-2525 and CoT

+

The Center on Target (CoT) is a data exchange format primarily used in military and emergency response applications such as the TAK ecosystem. +It is designed to facilitate real-time sharing of geospatial information among various systems and users. +The CoT protocol enables efficient communication of location, status, and other relevant situational data, +enhancing operational awareness and coordination. +MIL-STD-2525 is a military standard that specifies symbols for use on maps, charts, and other graphical displays +in military command, control, communications, computers, and intelligence (C4I) system. +The original 'NATO symbol' are expressed as a set of Military Symbols for Land Based Systems (MIL-STD-2525). +The CoT system is only partially overlapping with 2525. +On a list of 3000+ CoT's , 1000 are directly traceable to MIL-STD-2525.

+

The MIL_STD-2525 has had several versions:

+ +

The standard make use of 'Symbol Identification Code' (SIDC).

+

In MIL-STD-2525C/B, +"An alphanumeric code based on a database structure that +provides the minimum elements required to construct +the basic icon and/or a complete symbol."

+

MIL-STD-2525C further specifies that +A SIDC is a 15-character alphanumeric +identifier that provides the information necessary to display or transmit +a tactical symbol between MIL-STD-2525 compliant systems."

+

In MIL-STD-2525D this changed substantially, +"A.5.2 Elements of the symbol identification codes. +The symbol identification code is composed of eleven elements of information +which are presented in two sets of ten digits. +An additional set of ten digits composed of three elements must be used +when a symbology originator version extension flag is used."

+

As the SIDC does not require that all positions be used +the vacant positions are conventionally occupied by a '-'. +When used with CoT this introduces an ambiguity which is addressed below.

+

Event.type

+

Defines what the event is about. +An event may describe a physical object, a set of raw, unprocessed bits, or a tasking.

+

See the Cursor on Target Message Router User's Guide for details.

+

section 2.3 'CoT Type Field Details'

+

Duplicated (with edits) herein:

+

The Cursor-on-Target Message Router often uses the CoT type string as a test for publication. +For this reason, the type field is briefly explained here.

+

The set of possible CoT types is defined by a tree structure. +The type attribute, as defined in Event.xsd, identifies a specific node in the type tree. +It is a hyphen delimited set of alphanumeric characters. +For example, a-f-G represents a type tree of "atoms-friendly-ground". +The root element (first character in the type field) of the tree +has several values to include atoms, bits, reservations, capability descriptions, etc.

+

The atoms branch of the tree leverages the MIL-STD-2525B specification for defining the detailed type. +The string is broken out as atoms-affiliation-battle dimension-from 2525 function code. +For example, the type string a-h-A-MFA represents "atoms-hostile-Airborne-Military-Attack/Strike". +The lower case a-h prefix is defined in Event.xsd.

+

In the discussion found below, the "atoms" branch of the type +string will be described by the term's affiliation, battle dimension, and 2525 function code +per the description in this paragraph.

+

The following tree diagrams the valid atomic event combinations.

+

Level 1 : atoms

+
    +
  • a (atom)
  • +
+

Level 2 : affiliation

+
    +
  • p (pending)
  • +
  • u (unknown)
  • +
  • a (assumed friend)
  • +
  • f (friend)
  • +
  • n (neutral)
  • +
  • s (suspect)
  • +
  • h (hostile)
  • +
  • j (joker)
  • +
  • k (faker)
  • +
  • o (none specified)
  • +
  • x (other)
  • +
+

Level 3 : battle dimension

+
    +
  • P (space)
  • +
  • A (air)
  • +
  • G (ground)
  • +
  • S (sea surface)
  • +
  • U (sea subsurface)
  • +
  • X (other)
  • +
+

The first -A- is the MIL-STD-2525 battle dimension (air, ground, surface, etc). +It is derived from the battle-dimension portion of the SIDC (position 3).

+

Level 4 : function code

+

The remaining characters are the MIL-STD-2525B function code. +In this example, MFA represents "Military-Attack/Strike" which +corresponds with the SIDC / function-code (positions 5-10) MFA---.

+

Hierarchically organized hint about event type

+

The "type" attribute is a composite of components delimited by the semicolon character +(e.g. a-f-G-I for "Friendly Ground infrastructure"). +The first component of this composite attribute is defined below.

+

Future versions of this schema will define other components which we expect will aid in machine filtering. +Despite the exclusion of definitions for additional components in this version of the schema, +users of this schema should expect and design an optional trailing field +delimited by the semicolon character.

+

This field can be ignored. +

component1;optional field
+

+

The first component (component1) is a hierarchically organized hint about type. +The intention is that this hierarchy be flexible and extensible and +facilitate simple filtering, translation and display.

+

To facilitate filtering, the hierarchy needs to present key fields in an easily parsed and logical order. +To facilitate this, this component is a composite of fields separated by the "-" punctuation character, +so a valid type would be:

+
x-x-X-X-x. 
+
+

Using a punctuation for field separation allows arbitrary expansion of the type space. +

e.g., a-fzp-mlk-gm-...
+

+

Field meanings are type specific. +That is, the third field of an "atom" type may represent air vs. ground +while the same field for a "reservation" type may represent purpose.

+

MEANING of 'a' in the first position

+

The "Atoms" portion of the type tree requires some additional explanation past the taxonomy defined below. +The "Atoms" portion of the type tree contains CoT defined fields +and part of the MIL-STD-2525 type definition. +To distinguish MIL-STD-2525 type strings from CoT defined fields, +the MIL-STD-2525 types must be represented in all upper case. +Differentiation of type namespace with upper/lower case +facilitates extension of CoT types and MIL-STD-2525 types without name space conflict. +An example: +

 a-f-A-B-C-x
+

+
    +
  • a = Atom
  • +
  • f = attitude or disposition (friendly in this case)
  • +
  • A-B-C = the symbol identification coding (SIDC) scheme for 2525 – a strings of 15 characters used to transmit symbols.
  • +
  • x = non capital CoT specific extension
  • +
+

The organization of CoT and MIL-STD-2525 types can be determined from the taxonomy, + but additional details are provided here. + The "Atoms" portion of the "type" tree contains + the "Battle Dimension" and "Function ID" fields taken from MIL-STD-2525 (see below). + "Battle Dimension" is a single character taken from MIL-STD-2525 and is located in the position 5. +

a-.- **G** -I-M-N-B
+

+

The typical 2525 representation for "Function ID" is three groups of two characters separated by a space (e.g. "12 34 56"). +The CoT schema maps this to a "-" delimited list of characters. (e.g. "1-2-3-4-5-6"). + The concatenation of the "Battle Dimension" and "Function ID" fields + from the MIL-STD-2525 specification represented in the CoT schema will be as follows:

+

battle dimension-func id char1-func id char2- ... -func id char6
+
+ When an appropriate MIL-STD-2525 type exists, it should be used. + If there is a MIL-STD-2525 representation which is close, but may be refined, + a CoT extension to the 2525 type can be appended.

+

For example: +a-h-X-X-X-X-X-i might represent hostile MIL-STD-2525 type X-X-X-X-X of Israeli (the 'i') manufacture. +Again, the CoT extension uses lower case. +Conceptually, this extension defines further branching from the nearest MIL-STD-2525 tree point. +If no appropriate 2525 representation exists, +a type definition can be added to the CoT tree defined here. +The resulting definition would be represented in all lower case. +For example, a-h-G-p-i +might define atoms-hostile-Ground-photon cannon-infrared. +The taxonomy currently looks like this: +(Note that the coding of the sub-fields are determined entirely by the preceding fields!) +The current type tree is defined here.

+

First position, this event describes a - Atoms

+
    +
  • a - Atoms - this event describes an actual "thing"
  • +
+
2nd CoT affiliation of these atoms
+
    +
  • p - Pending
  • +
  • u - Unknown
  • +
  • a - Assumed friend
  • +
  • f - Friend
  • +
  • n - Neutral
  • +
  • s - Suspect
  • +
  • h - Hostile
  • +
  • j - Joker
  • +
  • k - Faker
  • +
  • o - None specified
  • +
  • x - Other
  • +
+
Battle dimension
+

Taken from MIL-STD-2525 "Battle Dimension" (upper case) + * P - Space + * A - Air + * G - Ground + * S - Sea Surface + * U - Sea Subsurface + * SF - Special Operations Forces

+
Function (dimension specific!)
+

See MIL-STD-2525B specification for function fields (must be upper case). +Any number of characters before the first "dash", +it also expresses a hierarchy (Hundreds of options).

+

The event describes: b - Bits ...

+

the first position can also contain a b.

+

b - Bits - Events in the "Bit" group (pos 1163++ ) carry meta information about raw data sources. For example, range-doppler radar returns or SAR imagery represent classes of information that are "bits". However, tracks derived from such sources represent objects on the battlespace and this have event type "A-..." +The intention with the "Bit" type is to facilitate the identification of germane information products. +This hierarchy is not intended to replace more detailed domain-specific meta information (such as that contained in NITF image headers or the GMTI data formats), rather it is intended to provide a domain-neutral mechanism for rapid filtering of information products.

+

Dimension

+

second position, like battle dimension but for 'b' types

+
i - Imagery
+
    +
  • e - Electro-optical
  • +
  • i - Infra red
  • +
  • s - SAR
  • +
  • v - video
  • +
  • ...
  • +
+
r - Radar
+
    +
  • m - MTI data
  • +
  • ...
  • +
+
d - Sensor detection events
+
    +
  • s - Seismic
  • +
  • d - Doppler
  • +
  • a - Acoustic
  • +
  • m - Motion (e.g., IR)
  • +
  • ...
  • +
+
m - Mapping
+
    +
  • p - Designated point (rally point, etc.)
  • +
  • i - initial points
  • +
  • r - rally points
  • +
  • ...
  • +
+

The event describes: r - Reservation/Restriction/References

+

Events in this category are generally "notices" about specific areas. + These events are used for deconfliction and conveyance of significant "area" conditions. + Generally, the "point" entity will describe a conical region that completely encloses the affected area. + The details entity will provide more specific bounds on precisely the region affected.

+
    +
  • u - Unsafe (hostile capability)
  • +
  • o - Occupied (e.g., SOF forces on ground)
  • +
  • c - Contaminated (NBC event)
  • +
  • c - chemical
  • +
  • x - agents, direction,
  • +
  • y
  • +
  • z
  • +
  • f - Flight restrictions
  • +
+

The event describes: t - Tasking (requests/orders)

+

Events in this category are generalized requests for service. +These may be used to request for data collection, request mensuration of a specific object, order an asset to take action against a specific point. +Generally, the "details" entity will identify the general or specific entity being tasked. + * s - Surveillance + * r - Relocate + * e - Engage + * m - Mensurate + * x - experimental, new tasking + ### The event describes: u - drawing (applied to an area) + * d - drawing + * r - range + * ... + ### The event describes: c - Capability (applied to an area) + * s - Surveillance + * r - Rescue + * f - Fires + * d - Direct fires + * i - Indirect fires + * l - Logistics (supply) + * f - Fuel + ...

+

c - Communications

+
    +
  • TBD
  • +
+

The event describes: y - reply to a task

+
    +
  • c - task completed
  • +
  • s - task status
  • +
  • a - acknowledge
  • +
+

mil2525 structure

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PosTypeValue
1en: Coding scheme

S - Warfighting
I - Intelligence
O - Stability Operations
E – Emergency Management
WO – Weather

G – Tactical Group

2en: AffiliationP - Pending
U - Unknown
A - Assumed Friend
F - Friend
N - Neutral
S - Suspect
H - Hostile
G - Exercise Pending
W - Exercise Unknown
D - Exercise Friend
L - Exercise Neutral
M - Exercise Assumed Friend
J - Joker
K - Faker
O - None Specified
3en: Battle DimensionIf Coding scheme is S or I:
P - Space
A - Air
G - Ground
S - Sea Surface
U - Sea Subsurface
SF - Special Operations Forces

If Coding scheme is O:
V - Violent Activities
L - Locations
O – Operations
I - Items
P - Individual
G - Nonmilitary Group or Organization
R – Rape

If Coding scheme is E:
I - Incident
N - Natural Events
O - Operations
F - Infrastructure
4en: StatusA - Anticipated/Planned
P - Present
C - Present/Fully Capable
D - Present/Damaged
X - Present/Destroyed
F - Present/Full to Capacity
5-10en: Function ID

Any number of char before the first "dash", it express also the hierarchy

(Hundreds of options)

11en: Symbol Modifier 1

A - Headquarters
B - Task Force HQ
C - Feint Dummy HQ
D - Feint Dummy/Task Force HQ
E - Task Force
F - Feint Dummy
G - Feint Dummy/Task Force
H – Installation

M - Mobility
N - Towed Array

12en: Symbol Modifier 2A - Team/Crew
B - Squad
C - Section
D - Platoon/Detachment
E - Company/Battery/Troop
F - Battalion/Squadron
G - Regiment/Group
H - Brigade
I - Division
J - Corps/Mef
K - Army
L - Army Group/Front
M - Region
N – Command

If Symbol Modifier 1 is M:
O - Wheeled/Limited
P - Wheeled
Q - Tracked
R - Wheeled and Tracked
S - Towed
T - Rail
U - Over the Snow
V - Sled
W - Pack Animals
Y - Barge
Z – Amphibious

If Symbol Modifier 1 is N:
S - Towed Array (Short)
L - Towed Array (Long)
+

Example 2525

+

Equipment Manufacture is part of ‘WAR.GRDTRK.INS.EQTMNF’ code is

+

S*G*IE----H**** +image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
S*G*IEH
WarAffiliationGroundBattle DimensionFunction IDinstallation
+

Test code here:

+

Example CoT

+

Equipment Manufacture Building is part of Gnd/Structure/Factory

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Atom** **Affiliation** **** Ground **** **** Infrastructure **** **** Equipment **
a-.-G-I-E
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/About/why_fts/index.html b/About/why_fts/index.html new file mode 100644 index 000000000..ebf8a1c41 --- /dev/null +++ b/About/why_fts/index.html @@ -0,0 +1,3853 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Why a Free TAK Server

+ +

I want to emphasize a key principle: +"Before you ask, ask yourself what you can give." +Now, you might wonder, why should you give? +As the authors of FTS, here are our top 10 reasons for creating this software for you:

+

WHY FTS IS BETTER

+
    +
  1. Since 2020, FreeTAKServer (FTS) has been a labor of love, +supported by dozens of volunteers dedicating their free time, including Sundays.
  2. +
  3. FTS boasts a modern, scalable architecture, completely revamped for the 2.X series.
  4. +
  5. It's nurtured by a dedicated community that stands up to giants.
  6. +
  7. Extensive documentation supports users at every step.
  8. +
  9. FTS is incredibly versatile, capable of running on a wide range of platforms (and no, this don't mean that ANYBOBY can run FTS on everything!) .
  10. +
  11. It intelligently "understands" COT messages, paving the way for innovative developments.
  12. +
  13. Our public roadmap invites community involvement and contribution towards a shared vision.
  14. +
  15. FTS embodies true open-source principles, welcoming everyone to contribute and benefit. we are not hiding behind secrecy and limited access
  16. +
  17. Installation is straightforward compared to the convoluted process for TAK Server.
  18. +
  19. We believe in the power of community and open-source development. FTS is not just "our software"; it's a collaborative effort that benefits all users.
  20. +
+

WHY WE DO NOT LIKE TAK Server

+
    +
  1. TAK Server OG is based on ancient (20+ years) J2EE architecture with a lot of spaghetti code.
  2. +
  3. It's notoriously difficult to install—historically requiring specialized personnel funded by the USG.
  4. +
  5. The user interface is far from user-friendly.
  6. +
  7. It's maintained by a mega-corporation charging exorbitant fees for minimal service.
  8. +
  9. The documentation is either sparse or non-existent.
  10. +
  11. It demands significant machine resources to operate.
  12. +
  13. It acts merely as a "broker" without any understanding of the messages it handles.
  14. +
  15. There's no public roadmap.
  16. +
  17. Though recently open-sourced, TAK Server lacks a true open-source spirit, focusing mainly on military applications without community engagement.
  18. +
  19. Pressure from our project contributed to making TAK server publicly available, highlighting its previous exclusivity.
  20. +
+

Join us in supporting and contributing to FTS, and let's continue to make it even better together. You can start by giving FTS a star in GitHub: +On https://github.com/FreeTAKTeam/FreeTakServer, in the top-right corner of the page, click Star.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/HowToHelp/DevSetupMambaPyCharm/index.html b/HowToHelp/DevSetupMambaPyCharm/index.html new file mode 100644 index 000000000..4f9875474 --- /dev/null +++ b/HowToHelp/DevSetupMambaPyCharm/index.html @@ -0,0 +1,3957 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Setup a development environment for FTS

+

introduction

+

this tutorial assumes that you are working under windows (tested under 11)

+

Tools Installation

+

Get the IDE: PyCharm

+

As an integrated Development Environment (IDE) some people use PyCharm.

+

Download PyCharm from here

+

Clone the Project Repositories

+

Clone from the FreeTAKTeam/repositories group +FreeTakServer and DigitalPy repositories locally. +This can be done from within PyCharm.

+

It can also be done from the command line.

+
git clone https://github.com/FreeTAKTeam/FreeTakServer.git fts
+git clone https://github.com/FreeTAKTeam/DigitalPy dipy
+
+

Some other optional repositories: +

git clone https://github.com/FreeTAKTeam/FreeTAKServer-User-Docs fts-docs
+git clone https://github.com/FreeTAKTeam/UI.git fts-ui
+

+

Create a virtual Environment

+

Here we use a conda variant, micromamba.

+

Detailed installation instructions can be found here.

+

With micromamba installed we can set up a virtual environment:

+
mamba env create -y -f fts_user/docs/HowToHelp/fts-dev-env.yml
+
+

This environment definition is not seminal. +The dependencies used here are copied from the following sources:

+

FreeTakServer

+ +

DigitalPy

+ +
name: fts-dev
+channels:
+- conda-forge
+dependencies:
+- coverage>=7.3.2
+- coveralls>=1.8.0
+- email-validator>=2.1.0.post1
+- flake8>=6.1.0
+- flake8-print>=5.0.0
+- flask>=3.0.0
+- flask-login>=0.6.3
+- flask-migrate>=4.0.5
+- flask-wtf>=1.2.1
+- flask-testing>=0.8.0
+- lxml>=4.9.3
+- nose>=1.3.7
+- pluggy>=1.3.0
+- pathlib>=1.0.1
+- pep8-naming>=0.13.3
+- platformdirs>=4.0.0
+- pycairo>=1.25.1
+- python=3.11
+- selenium>=4.15.2
+- setuptools>=68.2.2
+- tabulate>=0.9.0
+- tox>=4.11.4
+- vim>=9.0.2059
+- waitress>=2.1.2
+- pytest>=7.4.3
+- pytest-pep8>=1.0.6
+- pytest-cov>=4.1.0
+- pip>=23.3.1
+- pip:
+    - pytak>=6.2.0
+    - randomize>=0.14
+
+

Activate the virtual environment +

mamba activate fts-dev
+

+

Install FTS Locally

+

Install dependencies and DigitalPy as package +

pushd dipy
+pip install -e .
+popd
+

+

Configure PyCharm

+

FTS YAML File

+

In the folder containing the FreeTakServer working repository create a file.

+

Populate that file, FTSConfig.yaml, with the following: +

System:
+  #FTS_DATABASE_TYPE: SQLite
+  FTS_CONNECTION_MESSAGE: Welcome to FreeTAKServer FreeTAKServer-2.X alpha. 
+    The Parrot is not dead. It’s just resting
+  #FTS_OPTIMIZE_API: True
+  #FTS_MAINLOOP_DELAY: 1
+Addresses:
+  #FTS_COT_PORT: 8087
+  #FTS_SSLCOT_PORT: 8089
+  FTS_DP_ADDRESS: 192.168.100.105
+  FTS_USER_ADDRESS: 192.168.100.105
+  #FTS_API_PORT: 19023
+  #FTS_FED_PORT: 9000
+  #FTS_API_ADDRESS: 0.0.0.0
+  FTS_FIRST_START: false
+Filesystem:
+  FTS_DB_PATH: [PATH]\\FreeTakServer\\FreeTAKServer.db
+  #FTS_COT_TO_DB: True
+  FTS_MAINPATH:  [PATH]\\FreeTakServer\\FreeTAKServer
+  FTS_CERTS_PATH: [PATH]\\FreeTakServer\\FreeTAKServerCerts
+  FTS_EXCHECK_PATH: [PATH]\\FreeTakServer\\ExCheck
+  FTS_EXCHECK_TEMPLATE_PATH: [PATH]\\FreeTakServer\\ExCheck\\template
+  FTS_EXCHECK_CHECKLIST_PATH: [PATH]\\FreeTakServer\\ExCheck\\checklist
+  FTS_DATAPACKAGE_PATH: [PATH]\\FreeTakServer\\FreeTAKServerDataPackageFolder
+  FTS_LOGFILE_PATH: [PATH]\\FreeTakServer\\FreeTakServerLogs
+  FTS_CORE_COMPONENTS_PATH: \\home\\ariel\\Workspace\\FTAK\\FreeTakServer\\FreeTAKServer\\components\\core
+  FTS_EXTERNAL_COMPONENTS_PATH: [PATH]\\FreeTakServer\\components\\extended
+  FTS_CLIENT_PACKAGES: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\clientPackages
+Certs:
+  FTS_SERVER_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key
+  FTS_SERVER_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem
+  FTS_TESTCLIENT_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.pem
+  FTS_TESTCLIENT_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.key
+  FTS_UNENCRYPTED_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key.unencrypted
+  FTS_SERVER_P12DIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.p12
+  FTS_CADIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.pem
+  FTS_CAKEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.key
+  FTS_FEDERATION_CERTDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem
+  FTS_FEDERATION_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key
+  FTS_CRLDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\FTS_CRL.json
+  FTS_FEDERATION_KEYPASS: demopassfed
+  FTS_CLIENT_CERT_PASSWORD: demopasscert
+  FTS_WEBSOCKET_KEY: YourWebsocketKey
+

+
    +
  1. Adjust paths to point to point to dir structure
  2. +
  3. Create a certs folder at the same level
  4. +
  5. Adjust FTS_CERTS_PATH to point to the newly created dir
  6. +
  7. Create new directory for the FreeTakServerLogs
  8. +
  9. Adjust FTS_LOGFILE_PATH to point to the newly created dir
  10. +
+

you're Ready to Help!

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/HowToHelp/DevSetupPipVScode/index.html b/HowToHelp/DevSetupPipVScode/index.html new file mode 100644 index 000000000..b16b3abdc --- /dev/null +++ b/HowToHelp/DevSetupPipVScode/index.html @@ -0,0 +1,3987 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Setup a development environment for FTS

+

introduction

+

this tutorial assumes that you are working under windows (tested under 11)

+

Tools Installation

+

Install Python

+

Download python-3.11.1-amd64.exe from the source

+

Get the IDE: VisualStudio Code

+

As an integrated Development Environment (IDE) we use VisualStudio Code. +Visual Studio Code is integrated with GitHub, in fact you can start editing any file directly in the browser for committing lightweight code changes.

+

For a more serious collaboration you should install the desktop version: +https://code.visualstudio.com/Download +with the following plugins:

+

image

+

we use the Setting Sync plugin to keep the team setting aligned, +ask us for the coordinates of the settings.

+

Install visual-cpp-build-tools

+

Get Microsoft C++ Build Tools +image

+

ensure that you have "Desktop development with C++" installed +image

+

Install a source code manager: TortoiseGit

+

install a source code manager like TortoiseGit

+

Clone from the https://github.com/orgs/FreeTAKTeam/repositories group +FreeTakServer and DigitalPy repositories locally. +image +

git clone https://github.com/FreeTAKTeam/FreeTakServer.git fts
+git clone https://github.com/FreeTAKTeam/DigitalPy dipy
+

+

Some other optional repositories: +

git clone https://github.com/FreeTAKTeam/FreeTAKServer-User-Docs fts-docs
+git clone https://github.com/FreeTAKTeam/UI.git fts-ui
+

+

Configuration

+

create a virtual Environment

+
    +
  • open a command prompt and navigate to the FreeTakServer repo
  • +
  • Type: +
    py -m venv venv
    +
  • +
+

Having set up a virtual environment +you now take a look inside the directory of your venv. +You will see something like this (on Windows): +

.
+├── Include
+├── Lib
+│   └── site-packages
+├── pyvenv.cfg
+└── Scripts
+    ├── activate
+    ├── activate.bat
+    ├── Activate.ps1
+    ├── deactivate.bat
+    ├── pip3.10.exe
+    ├── pip3.exe
+    ├── pip.exe
+    ├── python.exe
+    └── pythonw.exe
+
+Activate the virtual environment +
# In cmd.exe
+venv\Scripts\activate.bat
+# In PowerShell
+venv\Scripts\Activate.ps1
+

+

Install FTS locally

+

show installed packages
+

pip list
+
+output

+

image

+
    +
  • now install dependencies and FreeTAKServer as package +
    pip install -e .
    +
  • +
+

change directory to DigitalPy dir +

cd .../DigitalPy
+
+install dependencies and DigitalPy as package +
pip install -e .
+

+

Configure VS Code

+

open VS Code Explorer to the location of the FreeTAKServer project

+

image

+
    +
  • change the VSCODE Python Interpreter (ctrl + shift + p).
  • +
  • Look for "Python: Select Interpreter".
  • +
  • Select the one in your venv/scripts/python.exe
  • +
  • Go to "Run and Debug"
  • +
  • Select "Create launch.json" file
  • +
  • copy this configuration over the created file and configure [YOURPATH] with your actual path +
    {
    +    "version": "0.2.0",
    +    "configurations": [
    +      {
    +        "name": "FTS",
    +        "type": "python",
    +        "request": "launch",
    +        "program": "C:\\[YOURPATH]\\src\\FreeTakServer\\FreeTAKServer\\controllers\\services\\FTS.py",
    +        "console": "integratedTerminal",
    +        "justMyCode": false,
    +        "env": {
    +          "FTS_CONFIG_PATH": "C:\\[YOURPATH]\\src\\FreeTakServer\\FreeTAKServer\\FTSConfig.yaml",
    +          "FTS_FIRST_START": "false",
    +          "PYTHONTRACEMALLOC": "25"
    +        }
    +      }
    +    ]
    +}  
    +
  • +
+

image

+

FTS YAML File

+

In the folder containing FreeTakServer repo create a file: + FTSConfig.yaml

+

Copy the example FTSConfig.yaml into the file just created +

System:
+  #FTS_DATABASE_TYPE: SQLite
+  FTS_CONNECTION_MESSAGE: Welcome to FreeTAKServer FreeTAKServer-2.X alpha. 
+    The Parrot is not dead. It’s just resting
+  #FTS_OPTIMIZE_API: True
+  #FTS_MAINLOOP_DELAY: 1
+Addresses:
+  #FTS_COT_PORT: 8087
+  #FTS_SSLCOT_PORT: 8089
+  FTS_DP_ADDRESS: 192.168.100.105
+  FTS_USER_ADDRESS: 192.168.100.105
+  #FTS_API_PORT: 19023
+  #FTS_FED_PORT: 9000
+  #FTS_API_ADDRESS: 0.0.0.0
+  FTS_FIRST_START: false
+Filesystem:
+  FTS_DB_PATH: [PATH]\\FreeTakServer\\FreeTAKServer.db
+  #FTS_COT_TO_DB: True
+  FTS_MAINPATH:  [PATH]\\FreeTakServer\\FreeTAKServer
+  FTS_CERTS_PATH: [PATH]\\FreeTakServer\\FreeTAKServerCerts
+  FTS_EXCHECK_PATH: [PATH]\\FreeTakServer\\ExCheck
+  FTS_EXCHECK_TEMPLATE_PATH: [PATH]\\FreeTakServer\\ExCheck\\template
+  FTS_EXCHECK_CHECKLIST_PATH: [PATH]\\FreeTakServer\\ExCheck\\checklist
+  FTS_DATAPACKAGE_PATH: [PATH]\\FreeTakServer\\FreeTAKServerDataPackageFolder
+  FTS_LOGFILE_PATH: [PATH]\\FreeTakServer\\FreeTakServerLogs
+  FTS_CORE_COMPONENTS_PATH: \\home\\ariel\\Workspace\\FTAK\\FreeTakServer\\FreeTAKServer\\components\\core
+  FTS_EXTERNAL_COMPONENTS_PATH: [PATH]\\FreeTakServer\\components\\extended
+  FTS_CLIENT_PACKAGES: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\clientPackages
+Certs:
+  FTS_SERVER_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key
+  FTS_SERVER_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem
+  FTS_TESTCLIENT_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.pem
+  FTS_TESTCLIENT_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.key
+  FTS_UNENCRYPTED_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key.unencrypted
+  FTS_SERVER_P12DIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.p12
+  FTS_CADIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.pem
+  FTS_CAKEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.key
+  FTS_FEDERATION_CERTDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem
+  FTS_FEDERATION_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key
+  FTS_CRLDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\FTS_CRL.json
+  FTS_FEDERATION_KEYPASS: demopassfed
+  FTS_CLIENT_CERT_PASSWORD: demopasscert
+  FTS_WEBSOCKET_KEY: YourWebsocketKey
+

+
    +
  1. Adjust paths to point to point to dir structure
  2. +
  3. Create a certs folder at the same level
  4. +
  5. Adjust FTS_CERTS_PATH to point to the newly created dir
  6. +
  7. Create new directory for the FreeTakServerLogs
  8. +
  9. Adjust FTS_LOGFILE_PATH to point to the newly created dir
  10. +
+

you're Done!

+

Hit [F5] to run debug

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/HowToHelp/FTSConfig.yaml b/HowToHelp/FTSConfig.yaml new file mode 100644 index 000000000..4efdb88d7 --- /dev/null +++ b/HowToHelp/FTSConfig.yaml @@ -0,0 +1,43 @@ +System: + #FTS_DATABASE_TYPE: SQLite + FTS_CONNECTION_MESSAGE: Welcome to FreeTAKServer FreeTAKServer-2.X alpha. + The Parrot is not dead. It’s just resting + #FTS_OPTIMIZE_API: True + #FTS_MAINLOOP_DELAY: 1 +Addresses: + #FTS_COT_PORT: 8087 + #FTS_SSLCOT_PORT: 8089 + FTS_DP_ADDRESS: 192.168.100.105 + FTS_USER_ADDRESS: 192.168.100.105 + #FTS_API_PORT: 19023 + #FTS_FED_PORT: 9000 + #FTS_API_ADDRESS: 0.0.0.0 + FTS_FIRST_START: false +Filesystem: + FTS_DB_PATH: [PATH]\\FreeTakServer\\FreeTAKServer.db + #FTS_COT_TO_DB: True + FTS_MAINPATH: [PATH]\\FreeTakServer\\FreeTAKServer + FTS_CERTS_PATH: [PATH]\\FreeTakServer\\FreeTAKServerCerts + FTS_EXCHECK_PATH: [PATH]\\FreeTakServer\\ExCheck + FTS_EXCHECK_TEMPLATE_PATH: [PATH]\\FreeTakServer\\ExCheck\\template + FTS_EXCHECK_CHECKLIST_PATH: [PATH]\\FreeTakServer\\ExCheck\\checklist + FTS_DATAPACKAGE_PATH: [PATH]\\FreeTakServer\\FreeTAKServerDataPackageFolder + FTS_LOGFILE_PATH: [PATH]\\FreeTakServer\\FreeTakServerLogs + FTS_CORE_COMPONENTS_PATH: \\home\\ariel\\Workspace\\FTAK\\FreeTakServer\\FreeTAKServer\\components\\core + FTS_EXTERNAL_COMPONENTS_PATH: [PATH]\\FreeTakServer\\components\\extended + FTS_CLIENT_PACKAGES: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\clientPackages +Certs: + FTS_SERVER_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key + FTS_SERVER_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem + FTS_TESTCLIENT_PEMDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.pem + FTS_TESTCLIENT_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\Client.key + FTS_UNENCRYPTED_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key.unencrypted + FTS_SERVER_P12DIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.p12 + FTS_CADIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.pem + FTS_CAKEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\ca.key + FTS_FEDERATION_CERTDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.pem + FTS_FEDERATION_KEYDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\server.key + FTS_CRLDIR: [PATH]\\FreeTakServer\\FreeTAKServerCerts\\FTS_CRL.json + FTS_FEDERATION_KEYPASS: demopassfed + FTS_CLIENT_CERT_PASSWORD: demopasscert + FTS_WEBSOCKET_KEY: YourWebsocketKey \ No newline at end of file diff --git a/HowToHelp/GettingStartedAsHelper/index.html b/HowToHelp/GettingStartedAsHelper/index.html new file mode 100644 index 000000000..a7481b80c --- /dev/null +++ b/HowToHelp/GettingStartedAsHelper/index.html @@ -0,0 +1,4000 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

How to help

+

Depending on your skill-set and passion you can participate in the project in different ways. +Jump to the proper Section to get the instructions, +this page is structured so that the basic instructions applies to more advanced roles.

+
    +
  • Hobby User
  • +
  • Professional User / SME
  • +
  • Unix Admin / DevOps
  • +
  • Developer
  • +
  • Modeler / Digital Engineer
  • +
+

Hobby User

+

As a Hobby user you want to install and use the FTS-TAK platform.

+

getting started as a Hobby User

+
    +
  • Connect to our Public server to familiarize your self
  • +
  • Read the user manual in GitHub, if you find inconsistencies submit a change request
  • +
  • Install FTS on your environment
  • +
  • give us a Star in GitHub
  • +
  • Donate to the project
  • +
+

Professional User / SME

+

getting started as Professional User / SME

+
    +
  • Create a GitHub user
  • +
  • Submit issues to GitHub
  • +
+

Unix Admin / DevOps

+

You are familiar with installing and configuring complex applications using the console, +you understand network configuration

+

getting started as an Admin / DevOps

+
    +
  • Help Other users on our Discord and Discourse with installation and configuration issues
  • +
  • Submit tutorials on how to deploy FTS in different environments (different clouds, different OS and so on)
  • +
+

Developer

+

As a developer you have code experience in one or many of the languages we use (Python, JavaScript).

+

getting started as a Developer

+

A good way to start helping is to pick a task.

+
    +
  • Select a candidate task
      +
    • from the current issues that we have open
    • +
    • look in the planned features
    • +
    +
  • +
  • Fork the appropriate repository
  • +
  • Try to perform the task
      +
    • to set up your machine for "VisualStudio Code" and "Pip" use this tutorial
    • +
    • to set up your machine for "PyCharm" and "Mamba" use this tutorial
    • +
    +
  • +
  • Make a GutHub pull request (PR)
      +
    • work with an FTS committer to get the PR accepted
    • +
    +
  • +
+

While selecting or working on a task you can get guidance at the

+ +

writing documentation

+

Improve the documentation

+

Modeler / Digital Engineer

+

You are an architect or a very experienced developer with +deep understanding of Object-Oriented thinking, patterns and Models.

+

get the digital environment

+

we use Sparx ™ Enterprise Architect as modeling tool.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/HowToHelp/WriteDocumentation/index.html b/HowToHelp/WriteDocumentation/index.html new file mode 100644 index 000000000..9677d0290 --- /dev/null +++ b/HowToHelp/WriteDocumentation/index.html @@ -0,0 +1,1637 @@ + + + + + + + + + + + + +FTS Documentation + + + + + + + + + + + +
+ + Skip to content + +
+
+
+ +
+ + +
+
+
+
+
+
+
+ +
+
+
+
+
+

Write Documentation

+

This project houses the FreeTakServer (FTS) documentation. +It is written in Markdown and mkdirs.

+

Procedure

+

Fork the Main Repository

+

You will need a github account.

+

Fork https://github.com/FreeTAKTeam/FreeTAKServer-User-Docs into your own account. +Clone your forked repository onto your development environment.

+

It will probably be useful to have two remotes, +one (upstream) for merging in upstream commits, +and one (origin) for your forked repository.

+

Discuss on the FreeTAK Forum

+

FTS provides a Discord server where we can provide a consistent experience, +free from kindergarten dramas and with a lot of sense of humor +(keep in mind our tagline – "The parrot's not dead! It’s just resting"). +You can join the FTS Discord Server here: https://discord.gg/m8cBzQM2te. +While Discord is cool for live interaction, it can be very inconsistent. +The forum is organized thematically, where it’s easier to stay on topic. +This will include a knowledge library of problems and solutions. +While other places may exist were enthusiast discuss our software, +the new platform is what we, the developers, will actively support.

+

Make Changes

+

See Documentation Patterns below.

+

Verify Processing

+

The following description is only partially correct.

+

GitHub Pages

+

GitHub provides the ability to publish generated documentation. +FTS makes use of this capability.

+

You should generate the documentation with your changes to make sure nothing was inadvertently broken. +The following shows you an example of how to set up gh-pages for your project repository.

+

+

The important thing here is to select [GitHub Actions].

+

GitHub Action

+

The documentation is built via GitHub actions. +Here is the .github/workflows/main.yml action: +

# https://squidfunk.github.io/mkdocs-material/publishing-your-site/#github-pages
+
+name: Build and Publish User Docs
+on:
+  push:
+    branches:
+      - main
+      - mkdocs
+permissions:
+  contents: write
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - name: Configure Git Credentials
+        run: |
+          git config user.name github-actions[bot]
+          git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+      - uses: actions/setup-python@v5
+        with:
+          python-version: 3.x
+      - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+      - uses: actions/cache@v4
+        # https://github.com/actions/cache
+        with:
+          key: mkdocs-material-${{ env.cache_id }}
+          path: .cache
+          restore-keys: |
+            mkdocs-material-
+      - run: >-
+          pip install mkdocs-material mkdocs-awesome-pages-plugin 
+          mkdocs-section-index mkdocs-toc-sidebar-plugin mike 
+          markdown-include mkdocs-pdf-export-plugin
+          mkdocs-mermaid2-plugin
+          httplib2
+          mkdocs_build_plantuml_plugin
+          mkdocs-exclude mkdocs-minify-plugin mkdocs-versioning
+      # https://www.mkdocs.org/user-guide/cli/#mkdocs-gh-deploy
+      - run: mkdocs gh-deploy --force
+
+name +: The name of the workflow

+

on push branches main +: The event and branch which triggers this workflow

+

jobs deploy steps run +: Install dependencies and build the target

+

If the GitHub Page does not show up after a few minutes, +go to the settings of your repository and ensure that the publishing source branch for your GitHub Page is set to gh-pages.

+

Make a Pull Request (PR)

+

Once you are satisfied with your changes make a GitHub pull request.

+

Announce your PR on the discord Development / doc-dev channel. +(You have been discussing your changes there, right?)

+

Any changes you make to the branch associated with +the PR will be included until it is approved and merged.

+

Working Locally

+

While you will ultimately verify your work as outlined above, +it will probably be useful to work locally.

+

Dependencies

+

Here are the packages it uses: +These packages are available for conda.

+

mamba env create -y -f docs/docs/HowToHelp/fts-doc-env.yml
+
+This environment includes the packages needed to construct the document products. +
name: fts-doc
+channels:
+  - conda-forge
+dependencies:
+    - python=3.11
+    - mkdocs
+    - mkdocs-material
+    - mkdocs-material-extensions
+    - mike
+    # - mkdocs-jupyter
+    - markdown-include
+    - pip
+    - pip:
+        - mkdocs-awesome-pages-plugin
+        - mkdocs-section-index
+        - mkdocs-pdf-export-plugin
+        - mkdocs-mermaid2-plugin
+        - mkdocs_puml
+

+

Preview Document

+

Start a service to view the resulting document. +

mkdocs serve
+

+

Documentation Patterns

+

Mkdocs and Material Theme

+

The markdown files are coordinated and supplemented by mkdocs and its plugins. +Some of the more important features of those plugins are presented here.

+

mkdocs is configured via the mkdocs.yml file.

+

Awesome Pages

+

Each document directory should contain a .pages. +These .pages distribute the nav: element across the document +rather than collecting them in the mkdocs.yml file. +This implies that mkdocs.yml should not contain a nav: element.

+

Markdown Includes

+

This file contains a typical example. +The fts-doc-env.yml file mentioned above is itself included using this facility.

+

i.e.
+```yml
+{!HowToHelp/fts-doc-env.yml!}
+```

+

Mike (multi-version support)

+

The fts_user/docs/versions.json is used to define the versions.

+

TODO: Explain how this is to be used.

+

Mermaid

+

For simple diagrams we use Mermaid.

+

https://mermaid.js.org/

+

PlantUML

+

There are some cases where Mermaid is not sufficient such as making Network Deployment Diagrams. +When that happens we use PlantUML.

+

https://github.com/plantuml-stdlib/C4-PlantUML/blob/master/README.md

+

Writing Good Markdown

+
    +
  • https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
  • +
  • https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md
  • +
+

Ventilated Prose

+

Prefer ventilated prose in composition.

+
    +
  • https://writetheasciidocs.netlify.app/ventilated-prose
  • +
  • https://vanemden.wordpress.com/2009/01/01/ventilated-prose/
  • +
  • https://mattwidmann.net/notes/using-markdown-effectively/
  • +
+

Ventilated prose dates back to the 1930s, +when Buckminster Fuller first coined the term.

+

The main benefit in using ventilated prose is +that it works well with tools like git. +git defaults to using diff which compares lines of text. +(This git default is seldom changed.) +This implies that ideas should be confined to lines of text, +which is precisely what ventilated code.

+

Apply Style Judiciously

+

It may be that a captured image is too large. +It may be tempting to resize the image. +However, if a reader wants to see the detail in the image this will lose that detail. +Instead, apply a style to the image to make it smaller. +

  ![](rpi-imager-ssh-settings.png){: style="height:200px;width:150px" }
+

+
+
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/HowToHelp/fts-dev-env.yml b/HowToHelp/fts-dev-env.yml new file mode 100644 index 000000000..175e938b9 --- /dev/null +++ b/HowToHelp/fts-dev-env.yml @@ -0,0 +1,35 @@ +name: fts-dev +channels: +- conda-forge +dependencies: +- coverage>=7.3.2 +- coveralls>=1.8.0 +- email-validator>=2.1.0.post1 +- flake8>=6.1.0 +- flake8-print>=5.0.0 +- flask>=3.0.0 +- flask-login>=0.6.3 +- flask-migrate>=4.0.5 +- flask-wtf>=1.2.1 +- flask-testing>=0.8.0 +- lxml>=4.9.3 +- nose>=1.3.7 +- pluggy>=1.3.0 +- pathlib>=1.0.1 +- pep8-naming>=0.13.3 +- platformdirs>=4.0.0 +- pycairo>=1.25.1 +- python=3.11 +- selenium>=4.15.2 +- setuptools>=68.2.2 +- tabulate>=0.9.0 +- tox>=4.11.4 +- vim>=9.0.2059 +- waitress>=2.1.2 +- pytest>=7.4.3 +- pytest-pep8>=1.0.6 +- pytest-cov>=4.1.0 +- pip>=23.3.1 +- pip: + - pytak>=6.2.0 + - randomize>=0.14 \ No newline at end of file diff --git a/HowToHelp/fts-doc-env.yml b/HowToHelp/fts-doc-env.yml new file mode 100644 index 000000000..13fe11323 --- /dev/null +++ b/HowToHelp/fts-doc-env.yml @@ -0,0 +1,18 @@ +name: fts-doc +channels: + - conda-forge +dependencies: + - python=3.11 + - mkdocs + - mkdocs-material + - mkdocs-material-extensions + - mike + # - mkdocs-jupyter + - markdown-include + - pip + - pip: + - mkdocs-awesome-pages-plugin + - mkdocs-section-index + - mkdocs-pdf-export-plugin + - mkdocs-mermaid2-plugin + - mkdocs_puml \ No newline at end of file diff --git a/HowToHelp/images/github-pages-actions.png b/HowToHelp/images/github-pages-actions.png new file mode 100644 index 000000000..eff3a5880 Binary files /dev/null and b/HowToHelp/images/github-pages-actions.png differ diff --git a/HowToHelp/images/github-pages-branch.png b/HowToHelp/images/github-pages-branch.png new file mode 100644 index 000000000..5f62f560c Binary files /dev/null and b/HowToHelp/images/github-pages-branch.png differ diff --git a/Installation/InfrastructurePlanning/index.html b/Installation/InfrastructurePlanning/index.html new file mode 100644 index 000000000..62ffb55a6 --- /dev/null +++ b/Installation/InfrastructurePlanning/index.html @@ -0,0 +1,4317 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Infrastructure Planning

+ +

FTS has been installed on several platforms using different mechanisms.

+

FTS Infrastructure

+

image

+

TAK Infrastructure thoughts: Give some thought to how you are going to deploy FTS server.

+
+

DISCLAIMER

+

It is impossible to cover all the combinations, +so this is not to be blindly applied, +rather to provide some background.

+
+
    +
  1. Cloud - A virtually hosted server allowing the quickest deployment + and scalability to as many users as you may wish
  2. +
  3. LAN - An local server located on your home/office LAN. + It may introduce additional complexities for non-LAN TAK clients to access your server, + e.g. dynamic DNS services (https://noip.com) and NAT port forwarding.
  4. +
  5. VPN - An dedicated server running as a ZeroTier (or other SD-WAN) client + will mostly circumvent the need for the complexities listed above and + allow any TAK client on the ZeroTier network to access the dedicated server + regardless of internet connection method (broadband, cellular data, etc.)
  6. +
  7. Edge – Can be setup completely off-grid and without reliance on a functioning internet, + but will suffer significant limitations in range for TAK clients to connect. + Running on an ad hoc or local infrastructure LAN configuration
  8. +
  9. Hybrid off-grid – A collection of devices each one having + one or more of the TAK clients connected as a "bridge" + to an off-grid mesh network. + This configuration will allow any off-grid mesh clients + to have their communications reach all "internet-connected" TAK clients via a + TAK client who is simultaneously connected to both the internet and mesh sides of the network.
  10. +
  11. Compute Cluster – A collection services running in Linux containers.
  12. +
+

While these are all valid configurations, +it is recommended that you first deploy one of the following standard configurations +before developing one fitting your specific situation and needs.

+

The following deployment diagrams augmented with network information +are the configurations supported by the core team and are where you should start. +Notice that in these diagrams, +the data-link layer hardware, +such as switches and wireless-access-points, +are intentionally omitted.

+

Realize that these configurations are examples and can be modified endlessly. +Indeed, the ZeroTouch installer deviates slightly in what it installs by default.

+

As you will see, configuration can be complex. +To that end we have created tooling to reduce the amount of manual configuration to a minimum.

+

Cloud Installation with Video Server

+

image

+

This configuration supports communication between a Spotter and the Team. +Each member of the Team and the Spotter have +Android phones running ATAK. +If ATAK provides all the capabilities needed by the Team, +and they were on the same local-area-network (LAN) then no TAK-server would be needed. +However, in this scenario they are not on the same LAN and the Team +wants to use TAK as a broker to gain access to a video-server.

+

In general, a cloud installation will expose FTS on public internet with a public IP address.

+

Cloud Installation with Drone

+

image

+

This configuration is similar to the previous configuration but now +the video stream originates from a remotely controlled 'drone'. +This capability is enabled via an ATAK plugin.

+

Private Installation on Raspberry Pi on a LAN

+

image

+

This configuration does not expose FTS on the public internet. +It does not broker a video-server, instead it provides a voice-chat-server, +Mumble. +The focus here is on how the LAN IP addresses are assigned. +Specifically, there is a Router on the LAN which +acts as a bridge (or gateway) to the internet. +The socket to services in the LAN has an IP address that is typically (but not always) +assigned to the "RaspberryPi" via DHCP by the "Router". +Somehow the configuration of FTS on the "RaspberryPi" needs to refer to that IP address is. +In other words you MUST supply that IP address in order for the installation to work properly.

+
+

Note

+

The IP addresses in the diagram are notional and the addresses your devices will be different.

+
+

The ATAK device is connected to the internet and +has been assigned the wide-area-network (WAN) IP address 129.224.211.12. +The Router has a public IP address of 229.24.11.24 to which the ATAK devices connects. +The Router / Gateway also faces the LAN where it is known by IP address 192.168.10.1. +The Router does a network-address-translation (NAT) converting each socket on the WAN to a socket on the LAN.

+
+

Note

+

The Router is acting as a proxy for the services on the LAN and must be carefully configured. +In particular, care must be taken to ensure that the ports on the Raspberry Pi services are unique.

+
+

The WinTAK device lives on the LAN, so, while its address is assigned by the Router +it avoids the issues associated with NAT, and communicates directly with the Raspberry Pi services. +That said WinTAK must still connect to the Raspberry Pi and so it needs to be configured +with the IP address assigned to the Raspberry Pi by the Router.

+

In addition, the services on the Raspberry Pi need to connect to each other. +In many cases, the services can use the localhost address 127.0.0.1 but occasionally that can cause issues, +so it is better to configure them with the IP address provided to the Raspberry Pi by the Router.

+

Custom Configuration

+

Once you have a configuration that gives you a working system, +you are encouraged to construct a similar diagram for your specific situation. +Such a diagram will be essential when communicating about your system. +For uniformity, we recommend C4Model. +The specific tool PlantUML, +which you can use to develop your network model.

+
+C4 References + +
+

The following example is for a Raspberry Pi deployment using the Zero-Touch installer. +It assumes the Router assigns IP addresses via DHCP. +Further, the Router reliably assigns the same IP address +to the Raspberry Pi by using its network-interface MAC.

+

Deployment Diagram

+

file

+

For reference here are PlantUML designs

+
+Network Deployment Diagram for FTS via Zero Touch Installer + +
+

FTS Sample Configurations

+

The distinction between platforms and infrastructure can get fuzzy +as platforms are commonly created to address specific infrastructure requirements. +Furthermore, the installation mechanisms may need to be tailored to each platform.

+
    +
  1. Digital Ocean (DO) - The preferred Cloud platform.
  2. +
  3. Digital Ocean Kubernetes
  4. +
  5. Orchestrates a set of micro-service PODs.
  6. +
  7. RaspberryPi server - The preferred Edge platform. + Running on an ad-hoc or local infrastructure LAN configuration.
  8. +
  9. RaspberryPi Kubernetes Cluster
  10. +
  11. Orchestrates a set of micro-service PODs.
  12. +
  13. ZeroTier
  14. +
  15. A commercial VPN which unifies the complexities of networking across physical network boundaries.
  16. +
  17. Android Mobile - Likely running to support ATAK.
  18. +
  19. Windows Desktop / WSL - Commonly used during development or troubleshooting.
  20. +
  21. Linux Desktop - Commonly used during development or troubleshooting.
  22. +
  23. Meshtastic LoRa - An ad-hoc mesh using long range radios.
  24. +
+

FTS Installation Mechanisms

+

The primary installation mechanisms are:

+
    +
  1. "Zero Touch Install" (ZTI) this is a set of Ansible roles and playbooks driven by a bash script.
  2. +
  3. Manual installation, where each service is installed separately.
  4. +
  5. Orchestrated Linux containers
  6. +
  7. by Kubernetes
  8. +
  9. with docker-compose
  10. +
  11. by docker swarm.
  12. +
+

Each of these approaches has their pros and cons. +For most beginners, the ZTI is the easiest place to start.

+

Network 101

+

FreeTAKServer is a server application designed for use for Tactical Assault Kit (TAK) clients. +Like many server applications, +FreeTAKServer requires a public IP address in order to be accessible from the public internet.

+

A public IP address is a globally unique IP address that is assigned to a device by an internet service provider (ISP). +Devices on the internet use public IP addresses to communicate with each other, +and public IP addresses are necessary for devices to be accessible from outside the local network.

+

Without a public IP address, FreeTAKServer would only be visible within the local network. +This means that devices outside the local network, +such as those on the internet, would not be able to access or communicate with the server. +In order for FreeTAKServer to be accessible from outside the local network, +it must have a public IP address that is routable on the internet.

+

One way to make FreeTAKServer accessible from outside the local network is +to configure port forwarding on the router that connects the local network to the internet. +This allows incoming traffic on a specific port to be forwarded to the FreeTAKServer, +making it accessible from the internet using the public IP address of the router. +Another option is to use a Virtual Private Network (VPN) to connect to the local network, +which can allow remote devices to access FreeTAKServer as if they were on the local network with a private IP address.

+ + + + + + + + + + + + + + + + + + + + + +
Private IP Address BlockCIDR Notation
10.0.0.0 - 10.255.255.25510.0.0.0/8
172.16.0.0 - 172.31.255.255172.16.0.0/12
192.168.0.0 - 192.168.255.255192.168.0.0/16
+

A 192.168.X.X IP address is part of the range of IP addresses that have been reserved +for private networks according to the Internet Assigned Numbers Authority (IANA) standard. +The 192.168.X.X range falls within the private IP address space defined by the RFC 1918.

+

Private IP addresses are used for local area networks (LANs) and are +not routable over the public internet. +They can be used by anyone without the need to register or pay for them. +Private IP addresses are typically assigned by your home router using Network Address Translation (NAT), +which allows multiple devices on a LAN to share a single public IP address.

+

In the case of a 192.168.X.X address, +it would typically be assigned to a device on a private network, +such as a home or office LAN. +This device would not be directly accessible from the internet, +as the 192.168.X.X address is not publicly routable.

+

Using private IP addresses like 192.168.X.X may help improve network security +by keeping internal devices hidden from external networks, +while still allowing them to communicate with each other within the private network.

+

When you connect to the internet, +your device is assigned a public IP address that can be seen by other devices on the internet. +This public IP address is used to route traffic between your device and other devices on the internet. +However, devices on the internet cannot directly access or see the private IP addresses used on your local network, +such as a 19.X.X.X address.

+

Ports

+

image

+

A complete FTS installation includes several components that need to have access to the 'internet'. +They will typically share the same IP but have different ports that need to be open on the firewall.

+

FTS Web UI (fts-ui.service)

+

Listening Port:

+
    +
  • 5000: Required for the browser based Web UI
  • +
+

FTS (fts.service)

+

DigitalPy Services

+

Listening Port:

+
    +
  • 8080: Required for HTTP
  • +
  • 8443: Required for HTTPS
  • +
+

Processes:

+
    +
  • DigitalPy Routing Worker Service [N instances]
  • +
  • Service Manager
  • +
  • Subject Service
  • +
  • Integration Manager Service
  • +
+

Cursor On Target Service

+

Listening Port:

+
    +
  • 8087: required for TCP COTS
  • +
  • 8089: required for SSL COTS
  • +
+

Processes: +* TCP CoT Service +* SSL CoT Service

+

Federation Service

+

Listening Port:

+
    +
  • 9000: Required for Federation
  • +
+

Processes:

+
    +
  • Federation Client Service
  • +
  • Federation Server Service
  • +
  • FTS Core Service
  • +
+

API Service

+

Listening Port:

+
    +
  • 19023: REST / websocket API for FTS
  • +
+

Processes:

+
    +
  • HTTP TAK Service
  • +
  • HTTPS TAK Service
  • +
  • Rest API Service
  • +
+

Integration Server NodeRed (nodered.service)

+

Listening Port:

+
    +
  • 1880: required for the Integration server (NodeRed)
  • +
  • 8000: WebUI communication with the Integration server
  • +
+

Processes:

+
    +
  • Video Sender
  • +
  • Other Misc Node Red Projects
  • +
+

Brokered Services

+

Video Server MediaMTX (mediamtx.service)

+

Listening Port:

+
    +
  • 9997: required for the Video Server (MediaMTX)
  • +
+

Voice Server Mumble (mumble.service)

+

Listening Port:

+
    +
  • 64738: required for the Voice Server (Mumble)
  • +
+

Web Map (webmap.service)

+

Processes:

+
    +
  • WebMap
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/QuickstartGuide/index.html b/Installation/QuickstartGuide/index.html new file mode 100644 index 000000000..88f4449c9 --- /dev/null +++ b/Installation/QuickstartGuide/index.html @@ -0,0 +1,3773 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Quickstart Guide

+ +

Want to jump straight into the deep end?

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/Tools/index.html b/Installation/Tools/index.html new file mode 100644 index 000000000..22f2ff962 --- /dev/null +++ b/Installation/Tools/index.html @@ -0,0 +1,3921 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Tools you need

+ +

Helpful Tools

+

Secure Shell

+

Allows you to remotely connect and manage your Linux devices (e.g. RaspPi). +Helpful for being able to copy/paste from the documentation into the Terminal CLI.

+

OpenSSH

+

Best used from the command line. +OpenSSH is available on many platforms:

+
    +
  • Windows 11
  • +
  • Ubuntu sudo apt install openssh-client
  • +
+

PuTTy

+

PuTTy has a GUI that some people prefer.

+
    +
  1. Download PuTTY +
  2. +
  3. To set up: Under Host Name, enter your RaspPi IP address and select SSH for the Connection type
  4. +
+

WinSCP

+

A GUI-type file manager. +Helpful for basic file management and understanding the RaspPi’s file structure. +You can also start Putty from a WinSCP

+
    +
  1. Download WinSCP +
  2. +
  3. To set up:
  4. +
  5. Click New Site
  6. +
  7. Select SCP for File protocol
  8. +
  9. Enter RaspPi’s IP address for Host name
  10. +
  11. Click Advanced button
  12. +
  13. Select Shell under environment, + changing shell setting from Default to sudo su - + (this will allow your changes to have Root privileges)
  14. +
  15. Click OK and then Save (if desired)
  16. +
+

ZeroTier

+

A software-defined wide area networking infrastructure that +allows you to create a virtual network that is relatively secure and under your control. +Allows clients to have static IPs that can be accessed +regardless of location on the internet and can be toggled on/off instantly.

+
    +
  1. Download ZeroTier +
  2. +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/Video_Guides/index.html b/Installation/Video_Guides/index.html new file mode 100644 index 000000000..663852ce8 --- /dev/null +++ b/Installation/Video_Guides/index.html @@ -0,0 +1,3829 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Video Guides

+ +

Official FreeTAKTeam channel

+

FreeTAKTeam youtube channel

+

RPiFTS Series

+

GHOST_DA-B6 has created a set of videos on youtube detailing how to install and set up 1.5 FTS on raspberry pi single board computers. +This is not updated to the current version of FTS +You can view his RPiFTS video series on his channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/images/configure_fts.png b/Installation/images/configure_fts.png new file mode 100644 index 000000000..bc3dea351 Binary files /dev/null and b/Installation/images/configure_fts.png differ diff --git a/Installation/images/std_deploy.png b/Installation/images/std_deploy.png new file mode 100644 index 000000000..bdf287ca9 Binary files /dev/null and b/Installation/images/std_deploy.png differ diff --git a/Installation/images/std_deploy_rpi.png b/Installation/images/std_deploy_rpi.png new file mode 100644 index 000000000..5255f12f2 Binary files /dev/null and b/Installation/images/std_deploy_rpi.png differ diff --git a/Installation/images/std_deploy_uas.png b/Installation/images/std_deploy_uas.png new file mode 100644 index 000000000..6ac2c598e Binary files /dev/null and b/Installation/images/std_deploy_uas.png differ diff --git a/Installation/images/std_deploy_video.png b/Installation/images/std_deploy_video.png new file mode 100644 index 000000000..c2022431a Binary files /dev/null and b/Installation/images/std_deploy_video.png differ diff --git a/Installation/images/zero-touch-deply-default.png b/Installation/images/zero-touch-deply-default.png new file mode 100644 index 000000000..8bb1ac3c0 Binary files /dev/null and b/Installation/images/zero-touch-deply-default.png differ diff --git a/Installation/images/zero-touch-summary.png b/Installation/images/zero-touch-summary.png new file mode 100644 index 000000000..c83587776 Binary files /dev/null and b/Installation/images/zero-touch-summary.png differ diff --git a/Installation/mechanism/Ansible/ZeroTouchInstall/index.html b/Installation/mechanism/Ansible/ZeroTouchInstall/index.html new file mode 100644 index 000000000..3ab657b69 --- /dev/null +++ b/Installation/mechanism/Ansible/ZeroTouchInstall/index.html @@ -0,0 +1,4221 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Zero Touch Installation (ZTI)

+

The ZeroTouch (ZT or ZTI) installation is the easiest way to install FTS. +Has been tested on the cloud and +on the RasberryPi; +however, only on Digital Ocean cloud (by virtue of appropriate defaults) you will have the optimal experience, +where all is installed and configured.

+

The ZTI can be run on different platforms, +make sure you have chosen the platform correctly, +or you will need to update configuration files later.

+

ZTI Usage

+

The ZTI provides usage documentation. +This information is the most current. +

wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --help
+

+

The following instructions provide examples where +these options are demonstrated.

+

Zero Touch Deployment Diagram

+

This ZTI installs and configures FreeTAKHub components on a single device.

+
+

Note

+

The following list and diagram are not exhaustive.

+
+
    +
  1. FreeTAKServer (FTS): The core server that interfaces with TAK-enabled clients
  2. +
  3. FreeTAKServer User Interface (FTS-UI): A web-based user interface.
  4. +
  5. Video Server: based on RTSP Simple Server. Handles video streaming.
  6. +
  7. Server: Handle integration services (see below)
  8. +
  9. FreeTAKHub Integration Server: Based on Node Red. Handles FTS integrations like SALUTE reports & video checking services (checks if videos are running and notifies FTS).
  10. +
  11. FreeTAKHub Voice Server: Uses Murmur or Mumble VOIP Server for voice chatting.
  12. +
  13. FreeTAKHub Webmap: A mapping component on the web interface.
  14. +
+

FreeTAK 2.1 ZTI deployment

+

Services Status

+

This command will output the status of these services +

sudo systemctl status fts.service fts-ui.service mumble-server.service nodered.service mediamtx.service
+

+

how to start / stop / enable a service?

+

Platform Specific Instructions

+

The ZTI only works on Linux systems.

+

Cloud Server (with automatic IP address discovery)

+

In this mode, ZTI guesses your IP address using +curl ifconfig.me/ip. +If this does not give the appropriate IP address you will need to provide it. +Run one of the following (equivalent) commands to start the ZeroTouch installer. +

wget -qO - bit.ly/freetakhub2 | sudo bash
+

+
+Alternate, full path. +
wget -qO - https://raw.githubusercontent.com/FreeTAKTeam/FreeTAKHub-Installation/main/scripts/easy_install.sh | sudo bash
+
+
+

Explicit IP Address

+

Implicitly, the ZTI guesses your IP address using https://ifconfig.me/ip. +When installing on the devices not on the public internet +it is unlikely that this is what you want. +There are several ways to discover a candidate IP address, here are some.

+
+

Warning

+

The IP address should be stable; on reboot you may get a different IP address. +You should take steps to ensure the IP address does not change without your knowledge.

+
+

Show the assigned IPv4 LAN addresses: +

ip -4 addr
+

+
+Extract specific LAN addresses +

Wired, ethernet, RJ45 +

ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
+
+WiFi +
ip -4 addr show wlan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
+

+
+

On the public internet: +

curl ifconfig.me/ip
+

+

It will be helpful to create an environment parameter +to remember the IP address (MY_IPA) you have selected. +

export MY_IPA=<the appropriate IP address>
+

+
+Here is an example capturing the wired LAN address: +
export MY_IPA=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
+
+
+

Run the Zero Touch Installer (ZTI)

+

With an appropriate IP address in hand you can run the ZTI. +

wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr ${MY_IPA}
+

+
+Alternate, full path. +
wget -qO - https://raw.githubusercontent.com/FreeTAKTeam/FreeTAKHub-Installation/main/scripts/easy_install.sh | sudo bash -s -- --ip-addr ${MY_IPA}
+
+
+

How ZT works

+

The command wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr ${MY_IPA} +is a combination of several commands and options used together to perform a specific task. +Here's a breakdown of what each part of the command does:

+

wget +: This is the command for a popular network downloader utility.

+

-q +: This option tells wget to operate in quiet mode, which suppresses the usual output.

+

O - +: as the capital letter 'o'. +The -O - option tells wget to redirect the downloaded content to standard output (stdout) +instead of saving it to a file. The - character is used here to denote stdout.

+

bit.ly/freetakhub2 +: This is a shortened URL using the bit.ly service. +It redirects to a longer URL from which wget will download content.

+

| +: This is a pipe. +It takes the output of the command on its left (wget in this case) +and uses it as the input for the command on its right.

+

sudo +: This command is used to execute the following command (bash) with superuser (root) privileges. +It's required for commands that need higher permissions to run, +typically for installing software or modifying system files.

+

bash +: This is the command to invoke the Bash shell. When used without a filename, +bash will read and execute commands from its standard input (which, in this case, is the output of wget).

+

-s +: If this option is present, or if no arguments remain after option processing, +then commands are read from the standard input. +This option allows the positional parameters to be set when invoking an interactive shell +or when reading input through a pipe.

+

-- +: End of options. +Anything further on the command line is an argument, not an option.

+

--ip-addr ${MY_IPA} +: Provide an argument to configure FTS with a specific, MY_IPA, IP address.

+
+Variable Expansion +

The command wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr ${MY_IPA} presumes that the variable MY_IPA has been set. +If export MY_IPA=192.168.1.100 then, the statement expands to +wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr 192.168.1.100, +and NOT to wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr $192.168.1.100

+
+

Putting it all together, wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --ip-addr ${MY_IPA} +downloads the content from the URL shortened as bit.ly/freetakhub2, +then immediately executes that content as a bash script with superuser privileges. +A specific IP address (stored in the variable MY_IPA, expanded) is provided as an argument to configure FTS.

+

Atypical Optional Behavior

+

As mentioned previously you can see several atypical behaviors are available. +They are documented here.

+

ZTI --help Argument

+
+show usage. +
wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --help
+
+
+

ZTI --verbose Argument

+
+Verbose output. +

wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --verbose
+
+Print script debugging information.

+
+

ZTI --pypi Argument

+
+Explicitly set the URL for the PYPI repository +

wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --pypi https://test.pypi.org
+
+Generally, pip acquires python packages from https://pypi.org, +this option makes it possible to use an alternate repository.

+
+

ZTI Legacy Argument

+

If you are still wanting to use the previous "legacy" version, +use this option.

+

Note:: the legacy version only works with Ubuntu 20.04

+
wget -qO - bit.ly/freetakhub2 | sudo bash -s -- --legacy
+
+
+Alternate, environment variable. +
wget -qO - bit.ly/freetakhub2 | sudo INSTALL_TYPE=legacy bash
+
+
+

ZTI --repo Argument

+
+testing a forked repository. +
export MY_IPA=10.2.118.124
+export MY_REPO=babeloff
+wget -qO - https://raw.githubusercontent.com/${MY_REPO}/FreeTAKHub-Installation/main/scripts/easy_install.sh | sudo bash -s -- --ip-addr ${MY_IPA} --repo https://github.com/${MY_REPO}/FreeTAKHub-Installation.git 
+
+
+

Operation

+

Now that your shiny new FTS system has been installed, +it is time to make sure it is nominally working.

+

FTS User Interface

+
    +
  • http://[use MY_IPA here]:5000/index
  • +
  • username: admin
  • +
  • password: password
  • +
+

FTS Hub : Node-Red

+
    +
  • http://[use MY_IPA here]:1880
  • +
  • username: admin
  • +
  • password: password
  • +
+

Reconfiguration

+

ZeroTouch will have configured the system and started the services for you. +However, there are many corner cases which ZeroTouch may miss. +Many (if not all) of the choices made by ZeroTouch are written to stdout. +I recommend that you validate the properties in that output. +You should stop the fts services prior to reconfiguration, +and you must start (restart) the fts services after reconfiguration.

+ +

Try out the TAK Clients

+

Now try out TAK clients after connecting them to the shiny new FTS server.

+ + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/CLI/index.html b/Installation/mechanism/Docker/CLI/index.html new file mode 100644 index 000000000..cc2183dd8 --- /dev/null +++ b/Installation/mechanism/Docker/CLI/index.html @@ -0,0 +1,3827 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

CLI Access

+

Accessing the CLI

+

With the docker container isolating the running instance you also need to use docker to access the cli. +

docker exec -it fts python3 -m FreeTAKServer.views.CLI
+
+This will open a CLI instance attached to the process running in the container.

+

With the CLI open in your terminal you can view supported commands by running help.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/Debian/index.html b/Installation/mechanism/Docker/Debian/index.html new file mode 100644 index 000000000..2a41d015c --- /dev/null +++ b/Installation/mechanism/Docker/Debian/index.html @@ -0,0 +1,3847 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Debian

+

This is assuming a fresh installation of Debian 10.

+

Install Docker

+

sudo apt-get install curl
+curl https://releases.rancher.com/install-docker/19.03.sh | sh
+
+Or follow the docker installation guide. +https://docs.docker.com/engine/install/debian/

+

Run the Container

+
docker volume create fts_data
+
+docker run -d -p 8080:8080/tcp -p 8087:8087/tcp -e FTS_CONNECTION_MESSAGE="Server Connection Message" -e FTS_SAVE_COT_TO_DB="True" -v fts_data:/host/system/folder --name fts --restart unless-stopped freetakteam/freetakserver:1.1.2
+
+

Alternatively, you can use the example docker-compose.yml available here +by copying docker-compose.yml into a directory and +then doing docker-compose up or docker-compose up -d to bring the container up, +and in the background, respectively. +The docker-compose.yml uses a bind mount to ./data.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/Multiple_Servers/multiple/index.html b/Installation/mechanism/Docker/Multiple_Servers/multiple/index.html new file mode 100644 index 000000000..bd70c082b --- /dev/null +++ b/Installation/mechanism/Docker/Multiple_Servers/multiple/index.html @@ -0,0 +1,3849 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Multiple Servers on Single Host

+

It is possible to run FreeTakServer multiple times on a single host by changing the port numbers.

+

If you follow an installation guide for your target platform +and have a container running named fts using the default ports, +this will explain how to run a second server on non default ports.

+

Limitations

+

Currently due to a bug in the ATAK client you will need to share packages +across all FTS servers on the same host. +The additional servers will use the first server, +using the default port of 8080 for data packages.

+

Running an additional container

+
docker volume create fts_data2
+
+docker run -d -p 8088:8087/tcp -e FTS_CONNECTION_MESSAGE="Server 2" -e FTS_SAVE_COT_TO_DB="True" -v fts_data2:/host/system/folder --name fts2 --restart unless-stopped freetakteam/freetakserver:1.1.2
+
+

We can use this command as a template to run as many FTS server instances +as we would like on a single host +by changing the name of the container and the ports FTS is running on. +So long as we avoid collisions on ports and names, +if we have the resources we can run multiple servers with ease.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/Quick_Start/index.html b/Installation/mechanism/Docker/Quick_Start/index.html new file mode 100644 index 000000000..d9084b8ee --- /dev/null +++ b/Installation/mechanism/Docker/Quick_Start/index.html @@ -0,0 +1,3932 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Container Quick-Start

+

Runtimes

+

Compatible with Podman or docker runtimes.

+

Host expectations

+

FreeTAKServer is server software, and should be treated as such. Installation onto a desktop environment will require +additional configuration that is usually only helpful if you want to do development.

+

The use of Linux is highly encouraged, as this is the industry standard host OS for containers.

+

YOU CANNOT USE DOCKER DESKTOP ON YOUR WINDOWS PC. Docker Desktop does not provide the ability to use bind-mounted +volumes, which are required in this iteration to allow the server operator to easily change the configuration files.

+

Container Repository

+

Please find all of our container images on the GitHub Container Repository.

+

You can obtain the latest images of the server and web UI by running the following commands. +Please note the use of GHCR instead of dockerhub, and adjust accordingly.

+

Setup

+

Installation Directory

+

A directory in which to store configuration and database files is required. Please ensure the permissions for this directory +allow container runtimes full RWX access recursively, and if using a selinux enabled OS, ensure the context is set for containers. +For more information on this process, visit your OS provided documentation.

+

Compose

+

A sample compose file +is provided to speed up your setup. If you do not have any other compose files, then this can be placed in the same directory +created earlier, and renamed to compose.yaml. Ensure that if you do not place the compose file in the same directory that +you update the volume path to the correct directory.

+

If you expect to run these images as part of a larger file, then you can use the sample compose file as +sensible defaults and append to your pre-existing compose file.

+

Once all the directories and files are set, both components can be activated by running +

podman-compose up -d
+

+

Or for docker runtime users

+
docker compose up -d
+
+

Configuration

+

On first run, the appropriate configuration files will be created in the indicated directory.

+

From this point, you should stop the containers before editing the configuration files.

+

podman-compose down
+
+or +
docker compose down
+

+

From this point, please follow the Linux installation guide for information regarding the configuration files.

+

Persistent Data

+

All persistent data is stored to /data and may be volume mounted. +The host volume needs to be owned by user and group 1000.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/Raspberry_Pi/index.html b/Installation/mechanism/Docker/Raspberry_Pi/index.html new file mode 100644 index 000000000..e361f822d --- /dev/null +++ b/Installation/mechanism/Docker/Raspberry_Pi/index.html @@ -0,0 +1,3851 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Raspberry Pi 4/Raspberry Pi 3

+

It is recommended to use a Raspberry Pi 4 with 4GB or 8GB of ram.

+

This guide assumes that you have a clean installation of Raspberry Pi OS or Raspbian. +You may also use the 64 bit Ubuntu 22.04 server prepared for the Raspberry Pi 4.

+

Install Docker

+
sudo apt-get update && sudo apt-get upgrade
+sudo apt-get install curl 
+curl -fsSL https://get.docker.com -o get-docker.sh
+sudo sh get-docker.sh
+
+

Run the Container

+
docker volume create fts_data
+
+docker run -d -p 8080:8080/tcp -p 8087:8087/tcp -e FTS_CONNECTION_MESSAGE="Server Connection Message" -e FTS_SAVE_COT_TO_DB="True" -v fts_data:/host/system/folder --name fts --restart unless-stopped freetakteam/freetakserver:1.1.2
+
+

Alternatively, you can use the example docker-compose.yml available here +by copying docker-compose.yml into a directory and +then doing docker-compose up or docker-compose up -d to bring the container up, +and in the background, respectively. +The docker-compose.yml uses a bind mount to ./data.

+

Older Pi's

+

Raspberry Pi's prior to the Pi3 have not been tested, and would not be recommended for use.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/Upgrade/Upgrade/index.html b/Installation/mechanism/Docker/Upgrade/Upgrade/index.html new file mode 100644 index 000000000..04ca5b310 --- /dev/null +++ b/Installation/mechanism/Docker/Upgrade/Upgrade/index.html @@ -0,0 +1,3796 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Upgrading Existing Container

+

To upgrade the container to a new version you simply +stop the container running the version you wish to upgrade from, +and start a container running the version you want to upgrade to. +To have data transferred between versions you need to have used a volume during the initial set up.

+
docker stop fts
+docker rm fts
+docker run -d -p 8080:8080/tcp -p 8087:8087/tcp -e FTS_CONNECTION_MESSAGE="Server Connection Message" -e FTS_SAVE_COT_TO_DB="True" -v fts_data:/data --name fts --restart unless-stopped freetakteam/freetakserver:{New FTS version}
+
+

If using the docker-compose.yml file, perform the following:

+
docker-compose pull
+docker-compose down
+docker-compose up
+# alternatively, use docker-compose up -d to run in the background
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Docker/overview/index.html b/Installation/mechanism/Docker/overview/index.html new file mode 100644 index 000000000..c9cc90783 --- /dev/null +++ b/Installation/mechanism/Docker/overview/index.html @@ -0,0 +1,3952 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Install

+

The official Docker image for FreeTAKServer.

+

Usage

+

When using this docker container we suggest +that you use the --restart unless-stopped flag as shown in the examples. +This will ensure that the service automatically starts with the host +and will restart if it encounters an error and crashes. +The port mappings in the examples are required to make the service accessible to hosts. +All environment variables are optional. +All data is stored in a single directory for ease of persistent data between container versions.

+

Container Quick-Start

+

Runtimes

+

Compatible with Podman or docker runtimes.

+

Host expectations

+

FreeTAKServer is server software, and should be treated as such. Installation onto a desktop environment will require +additional configuration that is usually only helpful if you want to do development.

+

The use of Linux is highly encouraged, as this is the industry standard host OS for containers.

+

YOU CANNOT USE DOCKER DESKTOP ON YOUR WINDOWS PC. Docker Desktop does not provide the ability to use bind-mounted +volumes, which are required in this iteration to allow the server operator to easily change the configuration files.

+

Container Repository

+

Please find all of our container images on the GitHub Container Repository.

+

You can obtain the latest images of the server and web UI by running the following commands. +Please note the use of GHCR instead of dockerhub, and adjust accordingly.

+

Setup

+

Installation Directory

+

A directory in which to store configuration and database files is required. Please ensure the permissions for this directory +allow container runtimes full RWX access recursively, and if using a selinux enabled OS, ensure the context is set for containers. +For more information on this process, visit your OS provided documentation.

+

Compose

+

A sample compose file +is provided to speed up your setup. If you do not have any other compose files, then this can be placed in the same directory +created earlier, and renamed to compose.yaml. Ensure that if you do not place the compose file in the same directory that +you update the volume path to the correct directory.

+

If you expect to run these images as part of a larger file, then you can use the sample compose file as +sensible defaults and append to your pre-existing compose file.

+

Once all the directories and files are set, both components can be activated by running +

podman-compose up -d
+

+

Or for docker runtime users

+
docker compose up -d
+
+

Configuration

+

On first run, the appropriate configuration files will be created in the indicated directory.

+

From this point, you should stop the containers before editing the configuration files.

+

podman-compose down
+
+or +
docker compose down
+

+

From this point, please follow the Linux installation guide for information regarding the configuration files.

+

Persistent Data

+

All persistent data is stored to /data and may be volume mounted. +The host volume needs to be owned by user and group 1000.

+

Ports

+

The docker image runs the ports on the same defaults as FreeTAKServer. +You can use the -e flag to map these ports to different ports +or to run multiple FreeTAKServer's concurrently on the same host.

+

Environment Variables

+

All environment variables will apply to FTS. +However, these are some additional ones specific to this docker image.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameDefinition
FTS_CONNECTION_MESSAGEThe text of the message sent upon connection
FTS_COT_TO_DBA boolean indicating ?
APPPORTAllows hosting FTS UI from a different port
APIIPAllows the FTS UI to specify a different API port. Defaults the IP environment variable
APIPORTAllows the FTS UI to specify a different API port
APIPROTOCOLAllows the FTS UI to specify a different API protocol
WEBMAPIPAllows the FTS UI to specify a different webmap IP
WEBMAPPORTAllows the FTS UI to specify a different webmap port
WEBMAPPROTOCOLAllows the FTS UI to specify a different webmap protocol
+

Storage

+

All data in this container is stored in /data. +This directory will need to be stored to a volume if you wish to persist data between updates.

+

If you use a storage volume you may need to inspect the docker volume to find where it saved the data.
+

docker inspect fts_data
+````
+It will return something similar to this:
+```json
+[
+    {
+        "CreatedAt": "2020-11-12T03:32:53Z",
+        "Driver": "local",
+        "Labels": {},
+        "Mountpoint": "/var/lib/docker/volumes/fts_data/_data",
+        "Name": "fts_data",
+        "Options": {},
+        "Scope": "local"
+    }
+]
+

+

The docker-compose.yml example utilizes a bind mount to ./data in the same directory.

+

Additional Architectures

+

Currently, the container is being cross compiled for linux/amd64, linux/arm64 and linux/arm/v7. +If additional processor architectures are needed please open an issue and request a new one.

+

Docker Hub Page

+

https://hub.docker.com/r/freetakteam/freetakserver

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Manual/Installation/index.html b/Installation/mechanism/Manual/Installation/index.html new file mode 100644 index 000000000..5882d9747 --- /dev/null +++ b/Installation/mechanism/Manual/Installation/index.html @@ -0,0 +1,4180 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAK Server Installation

+

This guide will walk you through installing FreeTAKServer 2.x

+

0. Document Goals

+
    +
  • Prepare host OS
  • +
  • Install FreeTAKServer
  • +
  • Configure and Run FreeTAKServer
  • +
  • Configure Web UI
  • +
  • TBD ~~Install NodeRed for FreeTAKHub~~
  • +
  • TBD ~~Install the Web Map~~
  • +
  • TBD ~~Install the Video Service~~
  • +
+
+

Note: Linux Distributions

+

The main supported OS is Ubuntu 22.04. +Due to cross-compatibility, Debian 10 and the latest Raspbian also work.

+

Centos/RHEL/Fedora installation instructions are provided on a best-effort volunteer basis.

+
+

1. Update OS Packages

+

Update OS Packages before proceeding with the installation

+
+ +Ubuntu + + +
sudo apt update && sudo apt upgrade -y
+
+
+ +
+ +Centos/RHEL/Fedora + + +
sudo dnf update
+
+
+ +
+

2. Pre-requisite Software

+

Install packages from the distro repo

+
+ +Ubuntu + + + + +
sudo apt update && sudo apt install -y python3 && sudo apt install -y python3-pip
+sudo apt install -y python3-dev python3-setuptools build-essential python3-gevent python3-lxml libcairo2-dev
+
+
+ +
+ +RHEL/Centos + + +
sudo dnf group install "Development Tools"
+sudo dnf install python3 pip virtualenv virtualenvwrapper cairo cairo-devel python3-gevent python3-lxml bzip2-devel libffi-devel
+
+ +Create and activate a virtualenv for the next steps + +
virtualenv venv
+source venv/bin/activate
+
+
+ +
+ +Fedora + + +
sudo dnf group install "Development Tools" "C Development Tools and Libraries"
+sudo dnf install python3 python3-pip cairo cairo-devel python3-cairo python3-cairo-devel python3-gevent python3-lxml python3-virtualenv
+
+ +Create and activate a virtualenv for the next steps + +
virtualenv venv
+source venv/bin/activate
+
+
+ +
+

3. Install Python Libraries

+
+ +Ubuntu + + +
sudo pip3 install wheel pycairo
+
+ +!!! note + Use of pip with sudo is not recommended, and you will be warned about this! +
+ +
+ +Centos/RHEL/Fedora + + + +
pip install wheel pycairo
+
+
+ +
+

4. Remove Old Installation

+

YOU MUST DO THIS IF:

+
    +
  • Free TAK Server has been installed before
  • +
  • An upgrade fails
  • +
  • A previous installation was not completed
  • +
+
+ +Ubuntu + + +
sudo pip3 uninstall FreeTAKServer
+sudo pip3 uninstall FreeTAKServer-UI
+
+ +Delete the database and log folders + +
sudo rm /opt/FTSDataBase.db
+sudo rm -r /usr/local/lib/<your-python-version>/<dist or site>-packages/FreeTAKServer
+
+
+ +
+ +Centos/RHEL/Fedora + + +
deactivate
+rm -rf venv/
+pip uninstall FreeTAKServer FreeTAKServer-UI
+
+ +Delete the database and log folders + +
sudo rm /opt/FTS/FTSDataBase.db
+
+
+ +
+

5. Install FreeTAKServer

+

Install the FreeTAKServer and the associated Web UI

+
+ +Ubuntu + + +
sudo python3 -m pip install FreeTAKServer[ui]
+
+
+ +
+ +Centos/RHEL/Fedora + + +
pip install FreeTAKServer[ui]
+
+
+ +

The FreeTAKServer can be installed without the UI, however this makes the +server much more difficult to use and is probably not what you want. This can be done using the FreeTAKServer pip package only.

+

Advanced Installations:

+
+ +Install a specific version + +To install a special version of a FreeTAKServer pip package by appending `==version-number` to the installation command. + +
python3 -m pip install FreeTAKServer[ui]==version-number
+
+ +For example, if you want to install version Alpha of the requests package, you can run the following command: + +
python3 -m pip install FreeTAKServer[ui]==0.2.0.13
+
+ +Old installations can be installed in the same way, if desired. + +This will download and install version 0.2.0.13 of FreeTAKServer. If no version number is specified, then the latest normal release will be installed. +
+ +
+

6. Check Installation

+

The pip utility allows the user to check the installation and dependency status of a package.

+
pip check FreeTakServer 
+
+

You should see No broken requirements found. displayed, in which case you can proceed. +Otherwise, there was an issue with the pip installation, +and you should investigate the pip-generated installation logs for more information.

+
+

7. Configure and Run FreeTAKServer

+

FTS versions older than 1.9 are not configured this way. For versions <1.9 you +will need to locate older versions of this document in the repo history.

+

Start the FreeTAKServer

+
+ +Ubuntu + + +
sudo python3 -m FreeTAKServer.controllers.services.FTS 
+
+
+ +
+ +Centos/RHEL/Fedora + + +
python -m FreeTAKServer.controllers.services.FTS 
+
+
+ +
+

:memo: Note: Warnings about failed to register component are OK. +Your system will run fine with these warnings. Starting with FTS 2.0 some future +functionality is declared but not fully implemented.

+
+

On the first run, a configuration wizard will help set up the config file.

+
+

:memo: Note: If the wizard does not appear, +see troubleshooting.

+
+

Using the Wizard

+

The default configuration option is presented in [brackets]. +If the default is acceptable you can simply press enter without entering any text +to automatically use the default.

+

An example is provided below, your exact configuration will differ.

+
would you like to use a yaml config file, 
+ if yes you will be prompted for further configuration options [yes]:
+where would you like to save the yaml config [/opt/fts/FTSConfig.yaml]: 
+enter ip [127.0.0.1]: 
+enter the preferred database type (MySQL is highly experimental if you're not sure leave default) [SQLite]: 
+enter the preferred database path [/opt/fts/FTSDataBase.db]: 
+enter the preferred main path [/usr/local/lib/python3.11/site-packages/FreeTAKServer]: 
+enter the preferred log file path [/opt/fts/Logs]: 
+
+
+

:memo: Note: The IP in this configuration wizard is the FTS_MAIN_IP. +This must be your EXTERNAL IP.

+
+

MySQL usage is beyond the scope of this guide, if you wish to use MySQL, +it is assumed you know how to configure database servers already. +Some additional information for MySQL installations is available +in the FTS-UI configuration section.

+

The database and log filepaths can be anywhere that the server's host user can access.

+

The main path should be the directory where pip installed FreeTAKServer. +This can be found under your python packages directory. +In virtualenv installations, +it is inside the virtualenv directory.

+

The wizard creates the YAML configuration file under the location you selected, +the default location is /opt/FTSConfig.yaml.

+

FreeTAKServer will then proceed start all the services.

+
+

7. FTS Configuration

+

Manual FTSConfig.yaml

+
+

Warning

+

Before modifying the YAML file, FreeTAKServer must be stopped!

+
+

Use the keyboard chord CTRL + C twice in the console running FTS to stop +FreeTAKServer.

+

A separate guide is maintained for +manual configuration of your FTS install.

+

MainConfig.py

+

FTS sends a welcome message on client connection which is configurable. +See the FreeTAKServer/core/configuration/MainConfig.py file to change it.

+
ConnectionMessage = f'Welcome to FreeTAKServer {version}. The Parrot is not dead. It’s just resting'
+
+
+

9. FTS-UI Configuration

+

Edit the config.py file in the FreeTAKServer-UI directory where it was installed by pip

+
+Where is that? + +> The FreeTAKServer-UI directory lives at the same level as the FreeTAKServer +directory that was set in the initial configuration of FTS. + +>Usually that means it's inside your python packages directory. +In virtualenv installations, it is inside the python installation in side the +virtualenv directory. +
+ +

Standard UI Config

+

Edit the IP value to your external IP, for example:

+
# this IP will be used to connect with the FTS API
+IP = '192.168.1.100'
+
+

Set the web map IP address, for example:

+
# the public IP your server is exposing
+APPIP = '0.0.0.0'
+# webmap IP
+WEBMAPIP = "192.168.1.100"
+
+

In a default installation, the port should be 19023. +Advanced users may wish to use a different port.

+
# Port the  UI uses to communicate with the API
+PORT = '19023'
+
+

Custom Secrets Configuration

+

The following items can be updated to use your own secrets, however the values +must be updated in both the FreeTAKServer-UI/config.py and the +FreeTAKServer/core/configuration/MainConfig.py files.

+

The API key used by the UI to communicate with FTS. +Generate a new system user and then set it.

+
app.config['APIKEY'] = 'Bearer [API_TOKEN]'
+app.config['WEBSOCKETKEY'] = '[Your_Web_socket_Key]'
+
+

MySQL Configuration

+

To use a MySQL database, update the URI to point to your database.

+

Database setup is beyond the scope of this document.

+
SQLALCHEMY_DATABASE_URI = 'mysql://' + 'user:pass@localhost/dbname'
+
+

Miscellaneous Parameters

+

Some additional parameters can be found in the __init__.py file +in the FreeTAKServer-UI/app/__init__.py directory.

+

These configure dashboard update frequency, ~~health pings?~~, +~~status messages?~~, and the file size limit for data packages.

+
app.config['USERINTERVAL'] = '180000';
+app.config['SERVERHEALTHINTERVAL'] = '180000';
+app.config['SYSSTATUSINTERVAL'] = '600000';
+app.config['DATAPACKAGESIZELIMIT'] = '15360000';
+
+

10. Start UI

+

In the terminal, navigate to the FreeTAKServer-UI directory wherever it was +installed by the pip utility.

+

Start the UI from the terminal using python:

+
+ +Ubuntu + + +
sudo python3 run.py
+
+
+ +
+ +Centos/RHEL/Fedora + + +
python run.py
+
+
+ +

You will see the UI server start up in your terminal, which should look similar +to that shown below.

+
(55501) wsgi starting up on http://0.0.0.0:5000
+(55501) accepted ('192.168.1.100', 49842)
+
+
+

11. Next Steps

+

Create a service

+

To run the server without keeping the console open, a service can be created.

+

See: Service

+

Installation on a Separate machine

+

Typically, the web UI is installed on the same machine as FTS; +however, you can install it on a separate machine and even use it to manage several instances.

+

If you're installing FTS-UI on a separate server the following commands may help:

+
sudo pip install WTForms==2.3.3
+sudo pip install SQLAlchemy==1.3.20
+sudo pip install eventlet
+
+

The config file will also need to be updated.

+
IP = '[FTS external IP]'
+APPIP = '[FTS-UI internal IP]'
+
+

12. Check Installation

+

After finishing all the steps, make sure your configuration is acceptable and +server running properly.

+
sudo python3 -m FreeTAKServer.controllers.services.FTS
+
+

If you see FTS start without error you may hit ctrl+c twice and move onto running FTS.

+

your FTS is now configured

+

If you have set up the UI, from the Admin console send a message hello world to the client

+

Troubleshooting

+

Default Login

+

The default credentials for the UI are admin and password.

+

You are encouraged to update these quickly.

+

WTForms Error Troubleshooting

+

In the event of a wtforms error, install it using pip:

+
pip3 install WTForms==2.3.3 
+
+

Failed to Register Components

+

Warnings about failed to register component are OK. +Your system will run fine with these warnings. Starting with FTS 2.0 some future +functionality is declared but not fully implemented.

+

UI Can't See Server

+

Usually this happens when you are using an OS that has a strong default firewall.

+

Ensure all the ports you have set in your config files are open on the firewall +for TCP traffic.

+
+ +Centos/RHEL/Fedora + + +
firewall-cmd --add-port=19023/tcp
+
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/mechanism/Manual/Manual/index.html b/Installation/mechanism/Manual/Manual/index.html new file mode 100644 index 000000000..edf3869cb --- /dev/null +++ b/Installation/mechanism/Manual/Manual/index.html @@ -0,0 +1,3885 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Manual Configuration

+

Configure FreeTAKServer

+

Depending on the linux distro your config file for FTS will be in a python version dependant location. +You can use pip to discover the location. Type: +

 sudo python3 -m pip show FreeTAKServer
+

+

If you are running python 3.11

+
/usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/MainConfig.py
+
+

You can edit the file via nano with the following command

+
sudo nano /usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/MainConfig.py
+
+

To exit nano ctrl+x and then enter y to save and hit enter.

+

DBFilePath

+

OPTIONAL this should not be necessary since FTS 1.5 +you need to change the DBFilePath value to something valid, +if you are running as root, /root is a good choice.

+

Original Value +

# this should be set before startup
+DBFilePath = str(r'/opt/FTSDataBase.db')
+

+

As roots Home Folder

+
# this should be set before startup
+DBFilePath = str(r'/root/FTSDataBase.db')
+
+

MySQL database

+

FTS supports an abstraction layer, so it's easy to use a different database like MySQL. +MYSQL is still experimental support, so use at your own risk. +To switch to a MySQL database +

# this should be set before startup
+DBFilePath = str('user:pass@localhost/dbname')
+

+

And then under +

sudo nano /usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/DatabaseConfiguration.py
+

+

Change +

DataBaseType = str('sqlite:///')
+
+To +
DataBaseType = str('mysql://')
+

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Android/Android/index.html b/Installation/platform/Android/Android/index.html new file mode 100644 index 000000000..3e7b9c817 --- /dev/null +++ b/Installation/platform/Android/Android/index.html @@ -0,0 +1,3880 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FTS Installation with Android

+

FTS 1.6 supports Android deployment. +The following instructions refers to an initial version (1.6.6), +you install it at your own risk. +This has been tested with Android 9, 10, 11 and Samsung S7, S8 and S9.

+
    +
  • download the APK installation package from GitHub to your phone
  • +
  • start the installation using Android
  • +
  • open the configuration of the APP and allow storage rights: in the app icon, click on the info, scroll down to "permission", and allow storage. Failure to do so will stop the APP to work!!!!
  • +
  • Start the FTS app
  • +
  • set your devices IP in the text box
  • +
  • Set the slider to "ON"
  • +
  • In the notifications you will see that FTS is running as a service in background
  • +
  • Open your network connection and note your IP (e.g. 192.168.1.25)
  • +
  • On a separate phone, open ATAK and create a new connection
  • +
  • Set connection to TCP, to the previously noted IP and port 15777
  • +
+

UI Setup

+

FTS Android Edition has a minimal user interface, +allowing to start and stop the FTS (including all the services). +For advanced management you will need to install the web UI. +since 1.6 you can now run the UI independently of the backend. +This allows you to install your web UI centrally and to manage several instances of FTS.

+
    +
  • install the UI with this command +
    sudo python3 -m pip install FreeTAKServer-UI=0.1.6.5
    +
  • +
  • to find where your UI is installed you run +pip show FreeTAKServer-UI
  • +
  • in [INSTALLPATH]/config.py set line 29 IP as device IP. e.g. REMEMBER THAT THIS IP MUST BE VISIBLE TO THE UI MACHINE +
        # this IP will be used to connect with the FTS API
    +    IP = '192.168.1.25'
    +
  • +
  • start UI server +sudo FLASK_APP=/usr/local/lib/python3.11/dist-packages/FreeTAKServer-UI/run.py python3 /usr/local/lib/python3.11/dist-packages/FreeTAKServer-UI/run.py
  • +
  • Open a browser to [UIIP]:5000
  • +
  • login with default creds(admin, password)
  • +
  • you can now control your FTS Android Edition from this UI
  • +
+

Troubleshooting

+

if FTS crashes at the start, please check out the following

+
    +
  1. ensure you have the following paths on your phone + /FreeTAKServer/certs/ClientPackages + /FreeTAKServer/logs
  2. +
  3. ensure once again that storage permissions are enabled
  4. +
+

Notes

+
    +
  • Dynamic DP IP changing in UI currently isn't functional
  • +
  • Federation as the server isn't functional, + you can still connect your Android Edition instance as a client to another regular FTS.
  • +
+

changes:

+
    +
  • runs now as a service
  • +
  • UI improved with sliders and spy
  • +
  • Icon added
  • +
  • Splashscreen added
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Android/installUIOnAndroid/index.html b/Installation/platform/Android/installUIOnAndroid/index.html new file mode 100644 index 000000000..50b05c8fa --- /dev/null +++ b/Installation/platform/Android/installUIOnAndroid/index.html @@ -0,0 +1,3852 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FTS-UI Installation with Android

+

FTS-UI is installed with python's pip. +One way to get pip on Android is with Pydroid3, +available here: https://play.google.com/store/apps/details?id=ru.iiec.pydroid3.

+

If you've installed Pydroid3 open the App and navigate to the terminal: +- In the upper right corner of Pydroid3, touch the 3 horizontal bars. +- Select "Terminal" +- Enter the following commands: +

pip3 install FreeTAKServer-UI==0.1.6.5
+pip3 install SQLAlchemy==1.3.23
+pip3 install requests
+pip3 install eventlet
+pip3 show eventlet
+

+

After eventlet installs we need to update a file to hardcode +the tcp/udp protocol numbers due to incompatibilities with Android +- The output of pip3 show eventlet Location should be similar to /data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.11/site-packages +- The file we need to update with the tcp/udp protocol numbers is located in dns/rdtypes/IN/WKS.py +- The full path of the file to edit using the eventlet Location output: +/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.11/site-packages/dns/rdtypes/IN/WKS.py

+

Now edit WKS.py and update as indicated below:

+

BEFORE: +

_proto_tcp = socket.getprotobyname('tcp')
+_proto_udp = socket.getprotobyname('udp')
+

+

AFTER: +

_proto_tcp = 6
+_proto_udp = 17
+

+

FTS-UI config.py assumes a Linux environment, +we need to update this for Android by replacing the appropriate paths with /sdcard for the following: +- SQLALCHEMY_DATABASE_URI +- certpath +- If you are not running FTS and FTS-UI on the same device you will need to update IP +- The config file is located here: /data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.11/site-packages/FreeTAKServer-UI/config.py

+

Now edit config.py and update as indicated below:

+

BEFORE: +

# This will connect to the FTS db
+SQLALCHEMY_DATABASE_URI = 'sqlite:///' + '/root/FTSDataBase.db'
+
+# certificates path
+certpath = "/usr/local/lib/python3.11/dist-packages/FreeTAKServer/certs/"
+

+

AFTER: +

# This will connect to the FTS db
+SQLALCHEMY_DATABASE_URI = 'sqlite:///' + r'/sdcard/FTSDataBase.db'
+
+# certificates path
+certpath = "/sdcard/FreeTAKServer/certs/"
+

+

Run FTS-UI

+
    +
  • Make sure your FTS is already up and running.
  • +
  • From the pydroid3 terminal +
    FLASK_APP=/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.11/site-packages/FreeTAKServer-UI/run.py nohup python3 /data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.8/site-packages/FreeTAKServer-UI/run.py
    +
  • +
+

Now open your web browser and navigate to http://127.0.0.1:5000 +and login with the default creds (admin/password).

+

Troubleshooting

+

Error: ImportError: cannot import name '_ColumnEntity' from 'sqlalchemy.orm.query'
+Solution: You didn't downgrade SQLAlchemy correctly

+

Error: Protocol not found
+Solution: You didn't update WKS.py correctly

+

Notes

+
    +
  • All testing was performed with a RaspPi4 8GB running LineageOS 18.1 32bit and Pydroid3
  • +
  • These instructions assume you are running FTS and FTS-UI on the same device
  • +
  • We downgrade SQLAlchemy because versions 1.4+ were not compatible with SQLAlchemy-utils
  • +
  • You need root access to update the tcp/udp protocol numbers (if you are using a RaspPi4 and LineageOS it is trivial to enable)
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Cloud/AWS/index.html b/Installation/platform/Cloud/AWS/index.html new file mode 100644 index 000000000..2e33fe153 --- /dev/null +++ b/Installation/platform/Cloud/AWS/index.html @@ -0,0 +1,3948 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

AWS

+
    +
  • Select EC2 as the service from the AWS Console
  • +
  • Click "Launch Instance"
  • +
  • Enter a name for your instance, e.g., "FreeTAK-AWS-001".
  • +
  • Under the Application and OS Images menu, select Ubuntu, then from the dropdown select Ubuntu Server 22.04 LTS (HVM) SSD Volume Type
  • +
+

image

+
    +
  • Under instance type, select the instance type appropriate for your deployment size. For testing servers a t2.micro is sufficient.
  • +
  • Under Key Pair, select a key pair in your account. If you do not have one, create one.
  • +
  • Under Network Settings, select a security group that has the necessary ports configured inbound for both SSH and FreeTAK server operations.
  • +
+

FTS Ports (FTSConfig.yaml)

+
    +
  • 8087 - TCP CoT (FTS_COT_PORT)
  • +
  • 8089 - SSL CoT (FTS_SSLCOT_PORT)
  • +
  • 19023 - API (FTS_API_PORT)
  • +
+

FTS UI Ports (config.py)

+
    +
  • 5000 - Web UI (APPPort)
  • +
  • 1880 - Webmap (WEBMAPPORT)
  • +
+

MediaMTX - Video Server

+
    +
  • 9997 - REST API
  • +
  • 9998 - Metrics Listener
  • +
+

image

+
    +
  • Under storage configuration, for testing an 8GiB GP2 volume will be sufficient.
  • +
  • Once complete, select launch instance.
  • +
  • Once ready to connect to the instance, use powershell / ssh client +
    sudo apt-get update && sudo apt-get upgrade -y 
    +
  • +
  • now
  • +
+
sudo reboot
+
+
    +
  • +

    reconnect via ssh +

    ip a 
    +

    +
  • +
  • +

    confirm ethernet adapter name (i.e. ens33) +

    grab $[publicip] from your instance details page 
    +

    +
  • +
  • +

    add the Public IP to ethernet adapter by using the following command +

    sudo ip addr add $publicip dev $ethernetadapter
    +

    +
  • +
  • +

    run zero touch installer +

    wget -qO - bit.ly/ftszerotouch | sudo bash
    +

    +
  • +
+

Troubleshooting

+

If anything fails, check IP values in the following files:

+

config.py

+

ZTI installs this file in /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py

+
    +
  • APPIP: Internal IP
  • +
  • IP: Public IP
  • +
  • WEBMAPIP: Public IP
  • +
+

FTSConfig.yaml

+
    +
  • FTS_DP_ADDRESS: Public IP
  • +
  • FTS_USER_ADDRESS: Public IP
  • +
  • FTS_API_ADDRESS: 0.0.0.0
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Cloud/DigitalOcean/index.html b/Installation/platform/Cloud/DigitalOcean/index.html new file mode 100644 index 000000000..ee01bfbcc --- /dev/null +++ b/Installation/platform/Cloud/DigitalOcean/index.html @@ -0,0 +1,3939 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

DigitalOcean

+

This installation has only been tested on Ubuntu 22.04.

+

Other operating systems may work, but are untested.

+

Step 1. Create admin user

+

The later executions will require admin privileges.

+

Create an adminuser first:

+
sudo adduser adminuser
+
+

Add passwordless to adminuser.

+

First type:

+
sudo visudo
+
+

Then add at the bottom:

+
adminuser ALL=(ALL) NOPASSWD: ALL
+
+

To save and quit in the nano editor:

+
    +
  1. Press CTRL + O then ENTER to save.
  2. +
  3. Then press CTRL + X to exit.
  4. +
+

Step 2. Download Ansible

+

In the Ubuntu console:

+
sudo apt update
+
+
sudo apt install -y software-properties-common gnupg curl git
+
+
sudo add-apt-repository -y --update ppa:ansible/ansible
+
+
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
+
+
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
+
+
sudo apt install -y ansible
+
+

Step 3. Clone the FreeTAKHub-Installation Git repository

+

Go to the home directory:

+
cd ~
+
+
git clone https://github.com/FreeTAKTeam/FreeTAKHub-Installation.git
+
+

Go to the FreeTAKTeam/FreeTAKHub-Installation directory:

+
cd FreeTAKTeam/FreeTAKHub-Installation
+
+

Step 4. Generate a public/private key pair

+

For the default, enter (and keep pressing enter):

+
ssh-keygen
+
+

Print out the public key for the next step.

+

If you did the default, the command will be:

+
cat ~/.ssh/id_rsa.pub
+
+

Step 5. Add your public key to your Digital Ocean project

+

See: https://docs.digitalocean.com/products/droplets/how-to/add-ssh-keys/to-account/

+

Step 6. Generate a Digital Ocean Personal Access Token

+

See: https://docs.digitalocean.com/reference/api/create-personal-access-token/

+

Step 7. Execute

+

You will then be prompted for your DigitalOcean Token and private key path:

+
var.digitalocean_token
+  Enter a value: <DIGITALOCEAN_TOKEN_HERE>
+
+var.private_key_path
+  ABSOLUTE path to private key, for example: /home/adminuser/.ssh/id_rsa
+
+  Enter a value: /home/adminuser/.ssh/id_rsa
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Cloud/overview/index.html b/Installation/platform/Cloud/overview/index.html new file mode 100644 index 000000000..117d0b762 --- /dev/null +++ b/Installation/platform/Cloud/overview/index.html @@ -0,0 +1,3982 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Configure and Connect to your cloud server

+

In this example we will use the provider Digital Ocean

+

Creates target machines

+

in this example we will use Digital ocean.

+
    +
  1. +

    create a DO account + image

    +
  2. +
  3. +

    create a new droplet +image

    +
  4. +
  5. +

    Select Ubuntu 22.04 (LTS) x64

    +
  6. +
  7. Plan basic
  8. +
  9. Recommended the $15 / mo plan (it would work with the $5 / mo plan but very slow).
  10. +
  11. +

    For heavy production (50-100 Concurrent users) you may want to use 8 CPUS and 32 MB RAM +image

    +
  12. +
  13. +

    Select the region that is the closest to you +image

    +
  14. +
  15. +

    Generate a new SSH key and download it. + It will download 2 files 1 with PEM extension and the second without extension

    +
  16. +
  17. Select project (FTYS)
  18. +
  19. Press "create droplet"
  20. +
+

Setup you access to the VM

+ +

Web

+
    +
  • you can use a console directly in your web browser.
  • +
  • this is not the best approach for long term management, but it works
  • +
  • press the button +image
  • +
  • run any command
  • +
+

SSH (Mac/Linux)

+
    +
  • Copy .PEM file to the machine from which you are going to connect.
  • +
  • Make sure permissions on .PEM file are appropriate (chmod 600 file.pem)
  • +
  • Connect with ssh command: + ssh vcloud@ipaddress –i privkey.pem
  • +
+

Putty (Windows)

+
    +
  • Download Putty and puttygen
  • +
  • Use puttygen to convert file without extension to .PPK file.
  • +
  • Start puttygen and select "Load"
  • +
  • Select your file without extension
  • +
  • Putty will convert format to .PPK format. enter image description here
  • +
  • Select "Save Private Key" A passphrase is not required but can be used if additional security is required.
  • +
  • Connect with Putty.
  • +
  • Launch Putty and enter the host IP address. If connecting to the 10.X private address you must first establish an SSL VPN connection.
  • +
  • Navigate to Connection/SSH/Auth
  • +
  • Click "Browse" and select the .PPK file you exported from puttygen. enter image description here
  • +
+

WinSCP (Windows)

+

WinSCP can be used on the top of Putty to make browsing and editing of files more conformable.

+
    +
  • Download WInSCP
  • +
  • Open WinSCP and create a new site
  • +
+

image

+

image

+

Install FTS on the Cloud

+

You should now have an active SSH terminal on the cloud.

+

You can now install FTS using the ZeroTouch-Installer.

+
+

Tip

+

You can probably accept the implicit IP address. +However, setting the --ip-addr will not be wrong.

+
+

Installation can also be done manually, +but it is best to leave that until you have some experience.

+

Getting Support

+

Support is provided on the FTS Discord server by volunteers.

+

Use the Discord #installation-support-cloud Support channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Linux/installation_native/index.html b/Installation/platform/Linux/installation_native/index.html new file mode 100644 index 000000000..bd01559b2 --- /dev/null +++ b/Installation/platform/Linux/installation_native/index.html @@ -0,0 +1,3830 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAK Server Installation on Native Ubuntu

+
+

Warning

+

Before installing FTS natively you should install it in a virtual machine as an exercise.

+
+

This guide will walk you through installing FreeTAKServer 2.x in a python virtual environment. +These instructions are on preparing an Ubuntu OS suitable for using the FTS Zero Touch Installer.

+

Install FTS on Native Ubuntu

+

Yow will probably need to install with an explicit IP address.

+

The complete ZTI instructions are here.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Linux/installation_vm/index.html b/Installation/platform/Linux/installation_vm/index.html new file mode 100644 index 000000000..7281eb348 --- /dev/null +++ b/Installation/platform/Linux/installation_vm/index.html @@ -0,0 +1,3873 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAK Server Installation on an Ubuntu Virtual Machine

+

This guide will walk you through installing FreeTAKServer 2.x on an Ubuntu virtual machine. +These instructions are on preparing an Ubuntu VM suitable for using the FTS Zero Touch Installer.

+

Obviously, the ZTI can be installed in a clean native Ubuntu environment. +However, cleanly setting up such an environment can consume time. +So, while running FTS on dedicated hardware may be a more performant choice +in a production environment it is more convenient with a virtual machine.

+

Setting up the Virtual Machine

+

Thankfully, Canonical has provided tooling to make setting up an Ubuntu VM easy.

+

Multipass Tutorials

+ +

Any of these are suitable for testing.

+

We will want to specify a specific Ubuntu version. +

multipass find
+
+Of the choices available we want v22.04. +
multipass launch 22.04 --name fts-test --memory 4G --disk 10G --cpus 2
+
+We can verify the image. +
multipass exec fts-test -- lsb_release -a
+

+

Open a shell on the new VM. +

multipass shell fts-test
+

+

Install FTS on the VM

+

Yow will probably need to install with an explicit IP address.

+

The complete ZTI instructions are here.

+

Getting Support

+

Support is provided on the FTS Discord server by volunteers.

+

Use the Discord #development-support Support channel. +The Linux support is primarily for developers.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/RaspberryPi/Installation/index.html b/Installation/platform/RaspberryPi/Installation/index.html new file mode 100644 index 000000000..2ae213142 --- /dev/null +++ b/Installation/platform/RaspberryPi/Installation/index.html @@ -0,0 +1,3983 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Raspberry Pi

+

this procedure Installs FTS + UI + video Server onto a Raspberry Pi

+

Hardware requirements

+

you need a RaspPi with at least 4 GB RAM

+

Procedure

+

Prepare an SD Card

+

Start with new installation of ubuntu 22.04 server for RaspPi 64. +FTS 2.x expects Ubuntu 22.04 (64 bit).

+

You will need an imager.

+ +

Follow the instructions to prepare an SD card with the appropriate image.

+

+

The rpi-imager provides a means for setting an ssh authorized key +and default username and password.

+

+

+

I construct an ssh key-pair specifically for working with compute nodes. +Construction of such key-pairs is done with ssh keygen. +Presume that the key-pair thus generated is ~/.ssh/fts_rsa and ~/.ssh/fts_rsa.pub.

+

Setup Hardware

+
    +
  • insert the prepared SD card into the Raspberry Pi.
  • +
  • connect a keyboard
  • +
  • connect a monitor
  • +
  • connect to an ethernet network
  • +
+

Update the OS

+

The initial setup takes ~5 minutes on a RaspPi 4 +Login with fts / ubuntu (or whichever user you selected)

+

If the RaspPi is connected to your router, +when it boots it will display the IP grabbed from DHCP server. +Write down the IP address, we will need it later.

+

sudo apt update -y 
+sudo apt upgrade -y
+
+You may be prompted during the upgrade. +Generally, accepting the defaults is appropriate.

+

In some cases you need to run: +sudo apt full-upgrade or sudo apt-get dist-upgrade.

+

It is generally easier to communicate with your server via ssh. +You will need the IP address (you should write the address down for later reference). +

sudo apt install -y net-tools
+
+
ip addr show
+
+Here is representative fragment from an output. +
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
+    link/ether d8:3a:dd:5f:27:24 brd ff:ff:ff:ff:ff:ff
+    inet 10.2.118.237/24 metric 100 brd 10.2.118.255 scope global dynamic eth0
+       valid_lft 53818sec preferred_lft 53818sec
+    inet6 fe80::da3a:ddff:fe5f:2724/64 scope link
+       valid_lft forever preferred_lft forever
+
+The IP address in this case is 10.2.118.237. +This is the same address you may have captured earlier during initial boot.

+

Multiple reboot may be required to get the OS fully updated. +

sudo reboot 
+

+

From here on it should be possible to connect via ssh. +Here is an example with the IP address obtained previously and fts user. +

ssh fts@10.2.118.237
+
+I generally update the ~/.ssh/config file with this information: +
Host fts-rp1
+    HostName 10.2.118.237
+    User fts
+    IdentityFile ~/.ssh/fts_rsa
+

+

Update Prerequisites

+

Verify the following packages are installed. +

sudo apt install -y wget curl
+

+

Install FTS on the Raspberry Pi

+

Yow will probably need to install with an explicit IP address.

+

The complete ZTI instructions are here.

+

Getting Support

+

Support is provided on the FTS Discord server by volunteers.

+

Use the Discord #installation-support-pi Support channel.

+

RPiFTS Series

+

GHOST_DA-B6 has created a set of videos on youtube detailing how to install +and set up FTS on raspberry pi SBC's.

+

You can view his RPiFTS video series on +his channel.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/RaspberryPi/belena-etcher-flashing.png b/Installation/platform/RaspberryPi/belena-etcher-flashing.png new file mode 100644 index 000000000..a47518eb5 Binary files /dev/null and b/Installation/platform/RaspberryPi/belena-etcher-flashing.png differ diff --git a/Installation/platform/RaspberryPi/rpi-imager-general-settings.png b/Installation/platform/RaspberryPi/rpi-imager-general-settings.png new file mode 100644 index 000000000..a9106cb5b Binary files /dev/null and b/Installation/platform/RaspberryPi/rpi-imager-general-settings.png differ diff --git a/Installation/platform/RaspberryPi/rpi-imager-ssh-settings.png b/Installation/platform/RaspberryPi/rpi-imager-ssh-settings.png new file mode 100644 index 000000000..36068dec9 Binary files /dev/null and b/Installation/platform/RaspberryPi/rpi-imager-ssh-settings.png differ diff --git a/Installation/platform/RaspberryPi/rpi-imager.png b/Installation/platform/RaspberryPi/rpi-imager.png new file mode 100644 index 000000000..55b9e1c24 Binary files /dev/null and b/Installation/platform/RaspberryPi/rpi-imager.png differ diff --git a/Installation/platform/Windows/COT_error_Wireshark.jpg b/Installation/platform/Windows/COT_error_Wireshark.jpg new file mode 100644 index 000000000..e57e5a0db Binary files /dev/null and b/Installation/platform/Windows/COT_error_Wireshark.jpg differ diff --git a/Installation/platform/Windows/CotError.png b/Installation/platform/Windows/CotError.png new file mode 100644 index 000000000..2e207819e Binary files /dev/null and b/Installation/platform/Windows/CotError.png differ diff --git a/Installation/platform/Windows/FTS_windows.gif b/Installation/platform/Windows/FTS_windows.gif new file mode 100644 index 000000000..a9013dd26 Binary files /dev/null and b/Installation/platform/Windows/FTS_windows.gif differ diff --git a/Installation/platform/Windows/MainConfig.py b/Installation/platform/Windows/MainConfig.py new file mode 100644 index 000000000..c07b4b4d7 --- /dev/null +++ b/Installation/platform/Windows/MainConfig.py @@ -0,0 +1,92 @@ +# -*- encoding: utf-8 -*- + +import os +from pathlib import Path + +currentPath = os.path.dirname(os.path.abspath(__file__)) + + +class MainConfig: + """ + this is the main configuration file and is the only one which + should need to be changed + """ + # this is the port to which clients will connect + CoTServicePort = int(8087) + + SSLCoTServicePort = int(8089) + + # this needs to be changed for private data packages to work + DataPackageServiceDefaultIP = str("0.0.0.0") + + # User Connection package IP needs to be set to the IP which is used when creating the connection in your tak device + UserConnectionIP = str("0.0.0.0") + + # python_version = 'python3.8' + + # userpath = '/usr/local/lib/' + + # api port + APIPort = 19023 + + # Federation port + FederationPort = 9000 + + # api IP + APIIP = '0.0.0.0' + + # allowed ip's to access CLI commands + AllowedCLIIPs = ['127.0.0.1'] + + # IP for CLI to access + CLIIP = '127.0.0.1' + + # whether to save CoT's to the DB + SaveCoTToDB = bool(True) + + # this should be set before startup + DBFilePath = str(r'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\FTSDataBase.db') + + # the version information of the server (recommended to leave as default) + version = 'FreeTAKServer-1.5.12 RC1' + + MainPath = str(Path(fr'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer')) + + ExCheckMainPath = str(Path(fr'{MainPath}\\ExCheck')) + + ExCheckFilePath = str(Path(fr'{MainPath}\\ExCheck\\template')) + + ExCheckChecklistFilePath = str(Path(fr'{MainPath}\\ExCheck\\checklist')) + + DataPackageFilePath = str(Path(fr'{MainPath}\\FreeTAKServerDataPackageFolder')) + + # format of API message header should be {Authentication: Bearer 'TOKEN'} + from uuid import uuid4 + id = str(uuid4()) + + nodeID = f"FreeTAKServer-{id}" + + # set to None if you don't want a message sent + ConnectionMessage = f'Welcome to FreeTAKServer {version}. The Parrot is not dead. It’s just resting' + + keyDir = str(Path(fr'{MainPath}\\certs\\pubserver.key')) + + pemDir = str(Path(fr'{MainPath}\\certs\\pubserver.pem')) # or crt + + unencryptedKey = str(Path(fr'{MainPath}\\certs\\pubserver.key.unencrypted')) + + p12Dir = str(Path(fr'{MainPath}\\certs\\pubserver.p12')) + + CA = str(Path(fr'{MainPath}\\certs\\ca.pem')) + CAkey = str(Path(fr'{MainPath}\\certs\\ca.key')) + + federationCert = str(Path(fr'{MainPath}\\certs\\pubserver.pem')) + federationKey = str(Path(fr'{MainPath}\\certs\\pubserver.key')) + federationKeyPassword = str('defaultpass') + + # location to back up client packages + clientPackages = str(Path(fr'{MainPath}\\certs\\ClientPackages')) + + password = str('defaultpass') + + websocketkey = "YourWebsocketKey" diff --git a/Installation/platform/Windows/StartFreeTAKServer.bat b/Installation/platform/Windows/StartFreeTAKServer.bat new file mode 100644 index 000000000..35a009624 --- /dev/null +++ b/Installation/platform/Windows/StartFreeTAKServer.bat @@ -0,0 +1,8 @@ +::START THE SERVER +ECHO ON +start cmd /k python -m FreeTAKServer.controllers.services.FTS +::WHEN RUNNING THE SCRIPT FROM A DIFFERENT DRIVE ADD THE `/D` SWITCH TO YOUR CD COMMAND +CD C:\Software\python\Lib\site-packages\FreeTAKServer-UI +set FLASK_APP=run.py +flask run +pause \ No newline at end of file diff --git a/Installation/platform/Windows/Windows_Ansible_Install/index.html b/Installation/platform/Windows/Windows_Ansible_Install/index.html new file mode 100644 index 000000000..8135facfd --- /dev/null +++ b/Installation/platform/Windows/Windows_Ansible_Install/index.html @@ -0,0 +1,3958 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Install FreeTAKHub with Ansible

+

Ansible is an Infrastructure-As-Code (IAC) tool used for managing and monitoring local or remote FTS servers.

+

This repository includes Ansible roles to:

+
    +
  • create the target nodes.
  • +
  • install FTS and additional modules.
  • +
  • configure FTS.
  • +
+

Windows Prerequisites

+

Below is required for Windows machines.

+

The machine must be running: +Windows 10 Version 2004 or higher (Build 19041 or higher) or Windows 11.

+

For Windows installations:

+
    +
  1. +

    Install WSL2.

    +

    See: https://docs.microsoft.com/en-us/windows/wsl/install

    +

    See also: https://www.omgubuntu.co.uk/how-to-install-wsl2-on-windows-10

    +

    See also: https://www.sitepoint.com/wsl2/

    +
  2. +
  3. +

    Install the WSL Ubuntu 22.04 distribution.

    +

    See: https://www.microsoft.com/en-us/p/ubuntu-2004-lts/9n6svws3rx71

    +
  4. +
+

Step 1. Clone the FreeTAKHub-Installation repository

+

In the console:

+
sudo apt update
+
+

Make sure you have git installed:

+
sudo apt install -y git
+
+

Go to the home directory:

+
cd ~
+
+

Clone the FreeTAKHub-Installation repository:

+
git clone https://github.com/FreeTAKTeam/FreeTAKHub-Installation.git
+
+

Go to the top-level directory of the FreeTAKHub-Installation repository:

+
cd FreeTAKHub-Installation
+
+

If you have previously cloned the repository, update the repository:

+
git pull
+
+

Step 2. Install Ansible

+

Automated Ansible Installation

+

At the top-level directory of the FreeTAKHub-Installation repository, enter:

+
./scripts/init.sh
+
+

Optional (But Recommended!): Activate the Python virtual environment:

+
activate
+
+

To deactivate the Python virtual environment:

+
deactivate
+
+

To learn more about Python virtual environments and why they are a good idea, see:

+

https://realpython.com/python-virtual-environments-a-primer/

+

Manual Ansible Installation

+

The manual installation allows more control.

+

In the console, enter:

+
sudo apt update
+
+
sudo apt -y install software-properties-common
+
+
sudo add-apt-repository --y --update ppa:ansible/ansible
+
+
sudo apt install -y ansible
+
+

See: https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu

+

Step 3. Install FreeTAKServer and Components

+

Go to the top-level directory of the FreeTAKHub-Installation repository:

+
cd ~/FreeTAKHub-Installation
+
+

Run the Ansible playbook to install FreeTAKServer and components:

+
sudo ansible-playbook install_all.yml
+
+

Step 4. Check Installation

+

Directions to check installation here.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Windows/Windows_Manual_Install/index.html b/Installation/platform/Windows/Windows_Manual_Install/index.html new file mode 100644 index 000000000..c745468f8 --- /dev/null +++ b/Installation/platform/Windows/Windows_Manual_Install/index.html @@ -0,0 +1,4440 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAKServer Install On Windows Computer

+

Below is the installation commands and comments for the installation of FreeTAKServer on a Windows computer. +Please notice, the FTS team is not supporting Windows as an official OS for FTS. +Please contact the original authors.

+

FreeTAKServer Manager For Windows

+

FreeTAKServer Manager has the ability to +Start, Stop, Restart, Install, and Uninstall the FreeTAKServer & FreeTAKServer-UI.

+

release version 1.5.12

+

FreeTAKServer provides Situational Awareness and other capabilities such as:

+
    +
  • sci-fi themed Web Administration
  • +
  • SSL Encryption Management
  • +
  • Health Monitor
  • +
  • Dynamically change IP / ports, start, stop FTS services from web UI
  • +
  • Service management
  • +
  • Federation Service (Connecting two or more FTS or TAK server instances)
  • +
  • Data Package upload and retrieval
  • +
  • Private data package (user to user)
  • +
  • Image transfer and storage
  • +
  • CoT recording in a database
  • +
  • Execution of common task list (using the ExCheck plugin for WinTAK; ATAK plugin only available to users with takmaps.com access)
  • +
  • User Management
  • +
  • Command Line Interface
  • +
  • REST API for creation of information such as emergency, Enemy units and so on
  • +
+

The preferred way to install FTS is by using Pip, that would solve all the required dependencies. +The offline release requires additional manual work and has to be used +only in the cases where internet connection is not available.

+
+

Install Instructions

+

Install python 3.11 from python.org

+

Download and run the installer. +The current version is 3.12, but it makes use of Cython 3.x +which is incompatible with several of the libraries used by FTS.

+

Choose the installer option.

+

+

Check pip, tcl/tk and IDLE and the Python test suite.

+

+

Make sure you add Python to environment variables for easy use.

+

+

Verify python environment

+

Check that python and pip are installed and working correctly. +You should be able to open cmd anywhere and do this check:

+

python -V
+pip --version
+
+It should look something like this. +
E:\>python -V
+Python 3.11.0
+
+E:\>pip --version
+pip 24.0 from c:\software\python\lib\site-package\pip (python 3.11)
+
+E:\>
+

+

Install Python packages

+

Having checked that Python and pip are working install the requirements:

+

pip: Perform install one by one

+
pip install flask
+pip install flask_login
+pip install flask_migrate
+pip install flask_wtf
+pip install flask_sqlalchemy
+pip install email_validator
+pip install waitress
+
+pip install coveralls
+pip install coverage
+pip install pytest
+pip install flake8
+pip install flake8-print
+pip install pep8-naming
+pip install selenium
+
+

pip: (alternate) Perform install from a file

+

From a file Paste these requirements into a .txt file requirements.txt for example: +

flask
+flask_login
+flask_migrate
+flask_wtf
+flask_sqlalchemy
+email_validator
+waitress
+coveralls
+coverage
+pytest
+flake8
+flake8-print
+pep8-naming
+selenium
+

+

Change into the directory (cd) containing said requirements.txt file and run the command: +

pip install -r requirements.txt
+

+

conda/mamba (alternate) Perform install from a file

+

I recommend micromamba as it does not require that Python be installed a priori. +* micromamba install

+

Create an environment. +

mamba create --name tak
+mamba activate tak
+

+

Install the packages into that environment.
+

mamba install lxml pathlib tabulate setuptools
+mamba install flask flask-login flask-migrate flask-wtf
+mamba install sqlalchemy flask-sqlalchemy 
+mamba install flake8 flake8-print 
+mamba install email-validator
+mamba install pytest coveralls coverage
+mamba install pep8-naming selenium
+mamba install waitress
+

+

Install FreeTAKServer

+

When all the requirements have been satisfied install the FreeTAKServer and FreeTAKServerUI. +

pip install FreeTAKServer
+pip install FreeTAKServer-UI
+

+
    +
  • https://pypi.org/project/FreeTAKServer/
  • +
  • https://pypi.org/project/FreeTAKServer-UI/
  • +
+

Configure the FTS

+

After the installation has finished the server and UI may need some configuration.

+

The FTS server is configured with MainConfig.py.

+

After the installation has finished the services need to be configured.

+

Configure the FreeTakServer by editing the <site-packages>\FreeTAKServer\core\configuration\MainConfig.py file.

+

Path examples: +* native Windows install: C:\Software\python\Lib\site-packages\FreeTAKServer\core\configuration\MainConfig.py +* ZTI python virtual environment: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/core/configuration/MainConfig.py +* conda env named tak: C:\Users\user\micromamba\envs\tak\Lib\site-packages\FreeTAKServer\core\configuration\MainConfig.py

+

Configure the FreeTAKServer-UI by editing the <site-packages>\FreeTAKServer-UI\config.py file.

+

Path examples: +* native Windows install: C:\Software\python\Lib\site-packages\FreeTAKServer-UI\config.py +* ZTI python virtual environment: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py +* conda env named tak: C:\Users\user\micromamba\envs\tak\Lib\site-packages\FreeTAKServer-UI\config.py

+
MY PATH EXAMPLE
+C:\Software\python\Lib\site-packages\FreeTAKServer\controllers\configuration\MainConfig.py
+
+
# -*- encoding: utf-8 -*-
+
+import os
+from pathlib import Path
+
+currentPath = os.path.dirname(os.path.abspath(__file__))
+
+
+class MainConfig:
+    """
+    this is the main configuration file and is the only one which
+    should need to be changed
+    """
+    # this is the port to which clients will connect
+    CoTServicePort = int(8087)
+
+    SSLCoTServicePort = int(8089)
+
+    # this needs to be changed for private data packages to work
+    DataPackageServiceDefaultIP = str("0.0.0.0")
+
+    # User Connection package IP needs to be set to the IP which is used when creating the connection in your tak device
+    UserConnectionIP = str("0.0.0.0")
+
+    # python_version = 'python3.8'
+
+    # userpath = '/usr/local/lib/'
+
+    # api port
+    APIPort = 19023
+
+    # Federation port
+    FederationPort = 9000
+
+    # api IP
+    APIIP = '0.0.0.0'
+
+    # allowed ip's to access CLI commands
+    AllowedCLIIPs = ['127.0.0.1']
+
+    # IP for CLI to access
+    CLIIP = '127.0.0.1'
+
+    # whether to save CoT's to the DB
+    SaveCoTToDB = bool(True)
+
+    # this should be set before startup
+    DBFilePath = str(r'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\FTSDataBase.db')
+
+    # the version information of the server (recommended to leave as default)
+    version = 'FreeTAKServer-1.5.12 RC1'
+
+    MainPath = str(Path(fr'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer'))
+
+    ExCheckMainPath = str(Path(fr'{MainPath}\\ExCheck'))
+
+    ExCheckFilePath = str(Path(fr'{MainPath}\\ExCheck\\template'))
+
+    ExCheckChecklistFilePath = str(Path(fr'{MainPath}\\ExCheck\\checklist'))
+
+    DataPackageFilePath = str(Path(fr'{MainPath}\\FreeTAKServerDataPackageFolder'))
+
+    # format of API message header should be {Authentication: Bearer 'TOKEN'}
+    from uuid import uuid4
+    id = str(uuid4())
+
+    nodeID = f"FreeTAKServer-{id}"
+
+    # set to None if you don't want a message sent
+    ConnectionMessage = f'Welcome to FreeTAKServer {version}. The Parrot is not dead. It’s just resting'
+
+    keyDir = str(Path(fr'{MainPath}\\certs\\pubserver.key'))
+
+    pemDir = str(Path(fr'{MainPath}\\certs\\pubserver.pem'))  # or crt
+
+    unencryptedKey = str(Path(fr'{MainPath}\\certs\\pubserver.key.unencrypted'))
+
+    p12Dir = str(Path(fr'{MainPath}\\certs\\pubserver.p12'))
+
+    CA = str(Path(fr'{MainPath}\\certs\\ca.pem'))
+    CAkey = str(Path(fr'{MainPath}\\certs\\ca.key'))
+
+    federationCert = str(Path(fr'{MainPath}\\certs\\pubserver.pem'))
+    federationKey = str(Path(fr'{MainPath}\\certs\\pubserver.key'))
+    federationKeyPassword = str('defaultpass')
+
+    # location to back up client packages
+    clientPackages = str(Path(fr'{MainPath}\\certs\\ClientPackages'))
+
+    password = str('defaultpass')
+
+    websocketkey = "YourWebsocketKey"   
+
+

The FTS server UI is configured with config.py.

+
MY PATH EXAMPLE
+C:\Software\python\Lib\site-packages\FreeTAKServer-UI\config.py
+
+
# -*- encoding: utf-8 -*-
+"""
+License: MIT
+Copyright (c) 2019 - present AppSeed.us
+"""
+
+import os
+from os import environ
+
+
+class Config(object):
+    basedir = os.path.abspath(os.path.dirname(__file__))
+
+    SECRET_KEY = 'key'
+
+    # This will connect to the FTS db
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + 'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\FTSDataBase.db'
+
+    # certificates path
+    certpath = "C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\certs\\"
+
+    # crt file path
+    crtfilepath = f"{certpath}pubserver.pem"
+
+    # key file path
+    keyfilepath = f"{certpath}pubserver.key.unencrypted"
+
+    # this IP will be used to connect with the FTS API
+    IP = '127.0.0.1'
+
+    # Port the  UI uses to communicate with the API
+    PORT = '19023'
+
+    # the public IP your server is exposing
+    APPIP = '127.0.0.1'
+
+    # this port will be used to listen
+    APPPort = 5000
+
+    # the webSocket  key used by the UI to communicate with FTS.
+    WEBSOCKETKEY = 'YourWebsocketKey'
+
+    # the API key used by the UI to communicate with FTS. generate a new system user and then set it
+    APIKEY = 'Bearer token'
+
+    # For 'in memory' database, please use:
+    # SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
+
+    SQLALCHEMY_TRACK_MODIFICATIONS = False
+
+    # THEME SUPPORT
+    #  if set then url_for('static', filename='', theme='')
+    #  will add the theme name to the static URL:
+    #    /static/<DEFAULT_THEME>/filename
+    # DEFAULT_THEME = "themes/dark"
+    DEFAULT_THEME = None
+
+
+class ProductionConfig(Config):
+    DEBUG = False
+
+    # Security
+    SESSION_COOKIE_HTTPONLY = True
+    REMEMBER_COOKIE_HTTPONLY = True
+    REMEMBER_COOKIE_DURATION = 3600
+
+    # PostgreSQL database
+    SQLALCHEMY_DATABASE_URI = 'postgresql://{}:{}@{}:{}/{}'.format(
+        environ.get('APPSEED_DATABASE_USER', 'appseed'),
+        environ.get('APPSEED_DATABASE_PASSWORD', 'appseed'),
+        environ.get('APPSEED_DATABASE_HOST', 'db'),
+        environ.get('APPSEED_DATABASE_PORT', 5432),
+        environ.get('APPSEED_DATABASE_NAME', 'appseed')
+    )
+
+
+class DebugConfig(Config):
+    DEBUG = True
+
+
+config_dict = {
+    'Production': ProductionConfig,
+    'Debug': DebugConfig
+}   
+
+

Start the Server

+

In order to run the server and the GUI two terminal windows must be opened +and the commands below must be run:

+

SERVER START COMMAND +

python -m FreeTAKServer.controllers.services.FTS
+

+

UI START COMMAND +

cd C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer-UI
+set FLASK_APP=run.py
+flask run
+

+

Connect to the Server

+

Now your server should be running. +User = admin, Password = password and GUI link http://localhost:5000/

+

+

Uninstall FTS

+

To uninstall do: +

pip uninstall FreeTAKServer
+pip uninstall FreeTAKServer-UI
+

+

Then in the C:\Software\python\Lib\site-packages\FreeTAKServer\ delete the FTSDataBase.db file.

+

In the C:\Software\python\Lib\site-packages\ path delete the FreeTAKServer & FreeTAKServer-UI folders.

+

Notes

+

Start FTS During System Start

+

If you would like to set up a Batch file (to run the server on a double click) +use the commands below:

+

Create a .bat file to run the server on double click and on startup:

+

StartFreeTAKServer.bat

+

::START THE SERVER
+ECHO ON
+start cmd /k python -m FreeTAKServer.controllers.services.FTS
+::WHEN RUNNING THE SCRIPT FROM A DIFFERENT DRIVE ADD THE `/D` SWITCH TO YOUR CD COMMAND
+CD C:\Software\python\Lib\site-packages\FreeTAKServer-UI
+set FLASK_APP=run.py
+flask run
+pause 
+
+To run this script at startup: Go to Run (WINDOWS + R) and Type shell:startup, +and paste a copy of your StartFreeTAKServer.bat file there.

+

ERRORS

+

CoT error v1.5.13

+

+

More Info

+

FreeTAKServer documentation for end users

+ + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionLink
User Docs:https://freetakteam.github.io/FreeTAKServer-User-Docs/
PyPi Install Docs:https://freetakteam.github.io/FreeTAKServer-User-Docs/Installation/PyPi/Linux/Install/
Server Download:https://github.com/FreeTAKTeam/FreeTakServer
Server Releases:https://github.com/FreeTAKTeam/FreeTakServer/releases
+

Helper tasks

+

To check python version python -V

+

To quickly check your IP ipconfig

+

Platform Concerns

+

gunicorn not available on Windows

+

gunicorn +is not supported on Windows and is replaced by +waitress.

+

Replace standard gunicorn command with waitress-serve. +For example: +

gunicorn --listen=*:8000 myapp.wsgi:application
+
+...becomes... +
waitress-serve --listen=*:8000 myapp.wsgi:application
+

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Installation/platform/Windows/advanced.jpg b/Installation/platform/Windows/advanced.jpg new file mode 100644 index 000000000..fed993338 Binary files /dev/null and b/Installation/platform/Windows/advanced.jpg differ diff --git a/Installation/platform/Windows/config.py b/Installation/platform/Windows/config.py new file mode 100644 index 000000000..20c7e564d --- /dev/null +++ b/Installation/platform/Windows/config.py @@ -0,0 +1,84 @@ +# -*- encoding: utf-8 -*- +""" +License: MIT +Copyright (c) 2019 - present AppSeed.us +""" + +import os +from os import environ + + +class Config(object): + basedir = os.path.abspath(os.path.dirname(__file__)) + + SECRET_KEY = 'key' + + # This will connect to the FTS db + SQLALCHEMY_DATABASE_URI = 'sqlite:///' + 'C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\FTSDataBase.db' + + # certificates path + certpath = "C:\\Software\\python\\Lib\\site-packages\\FreeTAKServer\\certs\\" + + # crt file path + crtfilepath = f"{certpath}pubserver.pem" + + # key file path + keyfilepath = f"{certpath}pubserver.key.unencrypted" + + # this IP will be used to connect with the FTS API + IP = '127.0.0.1' + + # Port the UI uses to communicate with the API + PORT = '19023' + + # the public IP your server is exposing + APPIP = '127.0.0.1' + + # this port will be used to listen + APPPort = 5000 + + # the webSocket key used by the UI to communicate with FTS. + WEBSOCKETKEY = 'YourWebsocketKey' + + # the API key used by the UI to communicate with FTS. generate a new system user and then set it + APIKEY = 'Bearer token' + + # For 'in memory' database, please use: + # SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' + + SQLALCHEMY_TRACK_MODIFICATIONS = False + + # THEME SUPPORT + # if set then url_for('static', filename='', theme='') + # will add the theme name to the static URL: + # /static//filename + # DEFAULT_THEME = "themes/dark" + DEFAULT_THEME = None + + +class ProductionConfig(Config): + DEBUG = False + + # Security + SESSION_COOKIE_HTTPONLY = True + REMEMBER_COOKIE_HTTPONLY = True + REMEMBER_COOKIE_DURATION = 3600 + + # PostgreSQL database + SQLALCHEMY_DATABASE_URI = 'postgresql://{}:{}@{}:{}/{}'.format( + environ.get('APPSEED_DATABASE_USER', 'appseed'), + environ.get('APPSEED_DATABASE_PASSWORD', 'appseed'), + environ.get('APPSEED_DATABASE_HOST', 'db'), + environ.get('APPSEED_DATABASE_PORT', 5432), + environ.get('APPSEED_DATABASE_NAME', 'appseed') + ) + + +class DebugConfig(Config): + DEBUG = True + + +config_dict = { + 'Production': ProductionConfig, + 'Debug': DebugConfig +} diff --git a/Installation/platform/Windows/features.jpg b/Installation/platform/Windows/features.jpg new file mode 100644 index 000000000..ac455c1f6 Binary files /dev/null and b/Installation/platform/Windows/features.jpg differ diff --git a/Installation/platform/Windows/flask-run.jpg b/Installation/platform/Windows/flask-run.jpg new file mode 100644 index 000000000..f1a8304b3 Binary files /dev/null and b/Installation/platform/Windows/flask-run.jpg differ diff --git a/Installation/platform/Windows/pythoninstall.png b/Installation/platform/Windows/pythoninstall.png new file mode 100644 index 000000000..b4c1c992c Binary files /dev/null and b/Installation/platform/Windows/pythoninstall.png differ diff --git a/Installation/platform/Windows/requirements.txt b/Installation/platform/Windows/requirements.txt new file mode 100644 index 000000000..f79ca1ea3 --- /dev/null +++ b/Installation/platform/Windows/requirements.txt @@ -0,0 +1,14 @@ +flask +flask_login +flask_migrate +flask_wtf +flask_sqlalchemy +email_validator +gunicorn +coveralls +coverage +pytest +flake8 +flake8-print +pep8-naming +selenium \ No newline at end of file diff --git a/Installation/platform/Windows/start-fts.jpg b/Installation/platform/Windows/start-fts.jpg new file mode 100644 index 000000000..e083d7ae6 Binary files /dev/null and b/Installation/platform/Windows/start-fts.jpg differ diff --git a/Troubleshooting/InstallationCheck/index.html b/Troubleshooting/InstallationCheck/index.html new file mode 100644 index 000000000..d8fcefab8 --- /dev/null +++ b/Troubleshooting/InstallationCheck/index.html @@ -0,0 +1,3960 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Checking Your Installation

+

Check FreeTAKServer, FreeTAKServer-UI, and WebMap

+

Open a web browser to:

+

http://[YOUR_IP_ADDRESS]:5000/ +default http://127.0.0.1:5000/

+
    +
  • login with your credentials
  • +
  • by default is user: admin, password: password
  • +
  • you should promptly change the login credentials +
  • +
  • check whether services are OK (blue) +image
  • +
  • connect a client to the server
  • +
  • click on the WEBMAP button
  • +
  • confirm the client is connected in the WEBMAP
  • +
+

Check The Video Server

+

Open a web browser to:

+

http://[YOUR_IP_ADDRESS]:9997/v1/config/get +default http://127.0.0.1:9997/v1/config/get/

+

Confirm the configuration (which is in json format):

+
{
+  "logLevel": "info",
+  "logDestinations": [
+    "stdout"
+  ],
+  "logFile": "mediamtx-server.log",
+  "readTimeout": "10s",
+  "writeTimeout": "10s",
+  "readBufferCount": 512,
+  "api": true,
+  "apiAddress": "[YOUR_IP_ADDRESS]:9997",
+  "metrics": false,
+  "metricsAddress": "127.0.0.1:9998",
+  "pprof": false,
+  "pprofAddress": "127.0.0.1:9999",
+  "runOnConnect": "",
+  "runOnConnectRestart": false,
+  "rtspDisable": false,
+  "protocols": [
+    "multicast",
+    "tcp",
+    "udp"
+  ],
+  "encryption": "no",
+  "rtspAddress": ":8554",
+  "rtspsAddress": ":8555",
+  "rtpAddress": ":8000",
+  "rtcpAddress": ":8001",
+  "multicastIPRange": "224.1.0.0/16",
+  "multicastRTPPort": 8002,
+  "multicastRTCPPort": 8003,
+  "serverKey": "server.key",
+  "serverCert": "server.crt",
+  "authMethods": [
+    "basic",
+    "digest"
+  ],
+  "readBufferSize": 2048,
+  "rtmpDisable": false,
+  "rtmpAddress": ":1935",
+  "hlsDisable": false,
+  "hlsAddress": ":8888",
+  "hlsAlwaysRemux": false,
+  "hlsSegmentCount": 3,
+  "hlsSegmentDuration": "1s",
+  "hlsAllowOrigin": "*",
+  "paths": {
+    "~^.*$": {
+      "source": "publisher",
+      "sourceProtocol": "automatic",
+      "sourceAnyPortEnable": false,
+      "sourceFingerprint": "",
+      "sourceOnDemand": false,
+      "sourceOnDemandStartTimeout": "10s",
+      "sourceOnDemandCloseAfter": "10s",
+      "sourceRedirect": "",
+      "disablePublisherOverride": false,
+      "fallback": "",
+      "publishUser": "",
+      "publishPass": "",
+      "publishIPs": [],
+      "readUser": "",
+      "readPass": "",
+      "readIPs": [],
+      "runOnInit": "",
+      "runOnInitRestart": false,
+      "runOnDemand": "",
+      "runOnDemandRestart": false,
+      "runOnDemandStartTimeout": "10s",
+      "runOnDemandCloseAfter": "10s",
+      "runOnPublish": "",
+      "runOnPublishRestart": false,
+      "runOnRead": "",
+      "runOnReadRestart": false
+    }
+  }
+}
+
+

Check the FreeTAKHub Server (or Node-RED Server)

+

Open a web browser to:

+

http://[YOUR_IP_ADDRESS]:1880/ +default http://127.0.0.1:1880/

+
    +
  • login with your credentials
  • +
  • by default is user: admin, password: password (you should promptly change the default password)
  • +
  • these are the same credentials used previously
  • +
+

see NodeRed for more information

+

Check Voice server

+

connect a client to [YOUR_IP_ADDRESS]:64738

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/ManualConfiguration/index.html b/Troubleshooting/ManualConfiguration/index.html new file mode 100644 index 000000000..2bc08845f --- /dev/null +++ b/Troubleshooting/ManualConfiguration/index.html @@ -0,0 +1,3887 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Manual Configuration

+

Configure FreeTAKServer < 1.9

+

image

+

Depending on the linux distro your config file for FTS will be in a python version dependant location. +you can use pip to discover the location. Type: +

 sudo python3 -m pip show FreeTAKServer
+

+

If you are running python 3.11 you would get +

/usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/MainConfig.py
+

+

You can edit the file via nano with the following command

+
sudo nano /usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/MainConfig.py
+
+

To exit nano ctrl+x and then enter y to save and hit enter.

+

DBFilePath

+

OPTIONAL this should not be necessary since FTS 1.5 +you need to change the DBFilePath value to something valid, +if you are running as root, /root is a good choice.

+

Original Value +

# this should be set before startup
+DBFilePath = str(r'/opt/FTSDataBase.db')
+

+

As roots Home Folder

+
# this should be set before startup
+DBFilePath = str(r'/root/FTSDataBase.db')
+
+

MySQL database

+

FTS supports an abstraction layer, so it's easy to use a different database like MySQL. +MYSQL is still experimental support, so use at your own risk. +To switch to a MySQL database +

# this should be set before startup
+DBFilePath = str('user:pass@localhost/dbname')
+

+

And then under +

sudo nano /usr/local/lib/python3.11/dist-packages/FreeTAKServer/controllers/configuration/DatabaseConfiguration.py
+

+

Change +

DataBaseType = str('sqlite:///')
+
+To +
DataBaseType = str('mysql://')
+

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/Running/index.html b/Troubleshooting/Running/index.html new file mode 100644 index 000000000..a41bb0d0f --- /dev/null +++ b/Troubleshooting/Running/index.html @@ -0,0 +1,3892 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Running from Terminal

+ +

If you have not installed FreeTAKServer please follow the installation guide first.

+

Run FTS in the Console

+

sudo python3 -m FreeTAKServer.controllers.services.FTS
+
+If you have FTS running in the terminal how you like; +it is time to move on to running FTS as a service.

+

Legacy Parameters

+

those parameters were supported in previous version of FTS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FlagDefaultDescription
-AutoStartWeather the full server start or just the RestAPI, must be True or False
-CoTIPYour Server IP
-CoTPort8087The port you want clients to connect to
-SSLCoTIPYour SSL Server IP
-SSLCoTPort8089The port you want SSL clients to connect to
-DataPackageIP0.0.0.0The IP where data packages are served from
-DataPackagePort8080The port you want Data Packages to be sent and received on
-SSLDataPackageIP0.0.0.0The IP where data SSL packages are served from
-SSLDataPackagePort8443The port you want SSL Data Packages to be sent and received on
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/Service/index.html b/Troubleshooting/Service/index.html new file mode 100644 index 000000000..e27312aa2 --- /dev/null +++ b/Troubleshooting/Service/index.html @@ -0,0 +1,4026 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Running as a Service

+ +

Running FreeTAKServer as a service on your Linux server can be achieved in multiple ways.

+

Cron

+

Cron or Crontab is a basic scheduler that ships with most linux distributions.

+

We can use this to get a very basic service running with minimal effort.

+

Edit Crontab

+
sudo crontab -e
+
+

Add this line to the bottom of the file

+
@reboot nohup sudo python3 -m FreeTAKServer.controllers.services.FTS &
+
+

You will need to add any start parameters to the crontab file such as -DataPackageIP.

+

Systemd

+

Introduction

+

Systemd is nearly unavoidable. +It has permeated so many aspects of the Linux ecosystem +that it is necessary for any Linux admin to know at least the basics of how it works. +One of the major selling points of systemd is the ease of writing service files. +They aren't scripts. +Instead, they're basic configuration files. +While they can grow to be complex, they are usually very simple.

+

background

+

The main directive is ExecStart, which specifies the command that should be run when the service is started. The command is +

/usr/bin/python3 /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/run.py. 
+
+Here's what each part of the command does:

+

/usr/bin/python3 +: This specifies the Python interpreter that should be used to run the code.

+

-m +: This option tells Python to run a module as a script.

+

/root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/run.py +: This is the path to the Python module that should be run as a script.

+

So when the service is started, +the Python interpreter will run the run.py module +located in the /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/ directory.

+

This code above is running FreeTAKServer-UI, +which is a user interface for FreeTAKServer. +When the Systemd service is started, +it will start the FreeTAKServer-UI interface, +allowing users to interact with the FreeTAKServer software through a web browser.

+
+

Note

+

You will need create two separate systemd files, if you're using Web UI +- fts.service +- fts-ui.service

+
+

Create The File

+

Systemd services exist at +/etc/systemd/system. +or +

/usr/lib/systemd/system/
+
+Any .service file that you create in that directory can be run as a service, +if you construct it properly. +Create a file that you would like with the .service extension. +In our case, +to create a file as /etc/systemd/system/FreeTAKServer.service with the following content: +(modify the parameters as needed)

+
[Unit]
+Description=FreeTAK Server service
+After=network.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+Restart=always
+RestartSec=1
+ExecStart=/usr/bin/python3 -m FreeTAKServer.controllers.services.FTS
+
+[Install]
+WantedBy=multi-user.target
+
+

And reload systemd, so it will load new unit file: +

sudo systemctl daemon-reload
+

+

Start the fts.service

+
sudo systemctl start fts.service
+
+

Get the Status of the fts.service

+
sudo systemctl status fts.service
+
+

Stop the fts.service

+
sudo systemctl stop fts.service
+
+

Start the fts.service with the system

+
sudo systemctl enable fts.service
+
+

UI Service

+

similarly the UI service can be created with /etc/systemd/system/fts-ui.service +

[Unit]
+Description=FreeTAKServer UI service
+After=network.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+Restart=always
+RestartSec=1
+ExecStart=/usr/bin/python3 -m /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/run.py
+
+[Install]
+WantedBy=multi-user.target
+

+

started

+

see also ZeroTouchInstall Services section +to see the complete list of the services created by the installer

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/SocketIssue/index.html b/Troubleshooting/SocketIssue/index.html new file mode 100644 index 000000000..9da1b564a --- /dev/null +++ b/Troubleshooting/SocketIssue/index.html @@ -0,0 +1,3872 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

SSL Issue: Regenerate Certificate Revocation List

+

Currently, there is a known issue of a socket leak, causing SSL to stop working after a period of time. +Even restarting the server OS would not help, +documented under: https://github.com/FreeTAKTeam/FreeTakServer/issues/368

+

The cause is that Certificate Revocation List (CRL) is expired. +A Certificate Revocation List (CRL) is a type of security feature used in public key infrastructure (PKI) systems. +It is a list of digital certificates that have been revoked by the certificate authority (CA) before their scheduled expiration date. +This list contains information about the certificate serial numbers, the revocation dates, and the reason for revocation. +Since FTS version 1.9, when you delete a user that has a certificate, the certificate will be revoked. +We have now created a script that will fix the issue re-creating the CRL.

+

Please follow the steps below.

+
+

Note

+

If you are trying to use this with 2.x.y the first step is not necessary

+
+
    +
  1. Install DigitalPy>=0.3.9.1 (the version where CRL regeneration support was added) with the following command: +
    pip install DigitalPy>=0.3.9.1
    +
  2. +
  3. Now execute the CRL-Regen utility. The location of the certs would under /path/to/fts/certs/ca.pem typically would be /opt/fts/certs: +
     python3 -m digitalpy.core.security.crl_regen --ca-pem-path /opt/fts/certs/ca.pem --ca-key-path /opt/fts/certs/ca.key --crl-path /opt/fts/certs/FTS_CRL.json
    +
  4. +
  5. Now stop FTS: +
     sudo systemctl stop fts && sudo pkill python
    +
  6. +
  7. Finally, restart your system for good measure (not required but recommended to ensure CRL updates are applied) +
    sudo reboot -n
    +
  8. +
+
+

Note

+

The FTS certs directory can generally be found at +

/root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs
+

+
+

SSL issue: Change the Number of max file open

+

If you have an issue with SSL probably depends on a limited amount of socket files you can open on the machine. +in a console type

+

ulimit -n
+
+If you get 1024 or less you will need to increase the allowed file descriptors for the user.

+

The procedure on Ubuntu 20.04 and 22.04 is this:

+
sudo sed -i 's/DefaultLimitNOFILE=1024/DefaultLimitNOFILE=1048576 /g' /etc/systemd/system.conf
+
+

grep NOFILE /etc/systemd/system.conf DefaultLimitNOFILE=1048576
+
+or +open the file with an editor +
vi /etc/systemd/system.conf
+

+

open the file with an editor and edit line 61 +Uncomment DefaultLimitNOFILE and set your limit there, e.

+

Restart with:

+

shutdown -r 0
+
+Then, check the user file descriptor limit again:

+
ulimit -n
+
+

Before:

+

ulimit -n
+ulimit -Sn
+ulimit -Hn
+
+
1024
+1024
+1024
+

+

After:

+

ulimit -n
+ulimit -Sn
+ulimit -Hn
+
+
1048576
+1048576
+1048576
+

+

The limits can be controlled by systemd and this is what we do here +— instruct systemd to set it to 100k. +Note that this setting will apply to all users

+

by increasing the soft limit for no file here +/etc/security/limits.conf

+

you should be able to increase this time, +try 20000 and in theory the time should multiply 20x. +so, you should be able to run for about 40 hours uninterrupted +the file may also be under the path /etc/limits.conf +also add this line:

+

fs.file-max = 65536
+
+to this file: /etc/sysctl.conf +then restart and check file limits with this

+
ulimit -Sn
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/Update/index.html b/Troubleshooting/Update/index.html new file mode 100644 index 000000000..b01ce4a69 --- /dev/null +++ b/Troubleshooting/Update/index.html @@ -0,0 +1,3855 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Removing or Updating FTS

+

In certain cases, if you already installed FTS with ZeroTouch Installer or pip you can use +the pip upgrade command to update your FTS to the current version.

+

This is not warranted to work, so backup your data before attempting.

+

To update your FTS installation:

+
    +
  • +

    SSH to your FTS server

    +
  • +
  • +

    Run upgrade commands:

    +
  • +
+
    /opt/fts.venv/bin/pip install --upgrade freetakserver-ui
+
+
    /opt/fts.venv/bin/pip install --upgrade freetakserver
+
+
    +
  • +

    Reconfigure your config.py file: +

        sudo nano /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py
    +        - Change the IP and WEBMAPIP to the address of your FTS server
    +        - Change the APPIP to 0.0.0.0
    +

    +
  • +
  • +

    Restart Services +

        sudo systemctl stop fts
    +    sudo systemctl stop fts-ui
    +    sudo systemctl start fts
    +    sudo systemctl start fts-ui
    +

    +
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/fts-core-server/index.html b/Troubleshooting/fts-core-server/index.html new file mode 100644 index 000000000..2792b5b18 --- /dev/null +++ b/Troubleshooting/fts-core-server/index.html @@ -0,0 +1,3869 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Free TAK Server : core

+

image

+

Some of these services have a secure and a clear instance.

+

The core consists of the following logical elements (with the indicated default ports):

+
    +
  • API Service
  • +
  • REST instance (port 19023)
  • +
  • websocket instance (port 19023)
  • +
  • DP Service
  • +
  • SSL instance (port 8443)
  • +
  • Clear instance (port 8080)
  • +
  • Federation Service
  • +
  • Clear instance (port 9000)
  • +
  • CoT Service
  • +
  • SSL instance (port 8089)
  • +
  • Clear instance (port 8087)
  • +
+

API Service

+

DP Service

+

Federation Service

+

CoT Service

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/fts-hub-server/index.html b/Troubleshooting/fts-hub-server/index.html new file mode 100644 index 000000000..58b16ae73 --- /dev/null +++ b/Troubleshooting/fts-hub-server/index.html @@ -0,0 +1,3814 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Integration Server

+

image

+

The integration server is NodeRed

+
    +
  1. Instructions here: https://freetakteam.github.io/FreeTAKServer-User-Docs/administration/brokered/Integration/NodeRedinstallation/
  2. +
  3. Use command: bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
  4. +
  5. Select Y to continue and Y to install Pi specific nodes
  6. +
  7. For additional settings, you can run the command: node-red admin init
  8. +
  9. Enable Node Red service:
  10. +
  11. Use command: sudo systemctl enable nodered.service
  12. +
  13. Run Node Red service:
  14. +
  15. Use command: sudo node-red-start
  16. +
  17. Login to Node Red at <IP address>:1880
  18. +
  19. Check to see if you have tabs for Webmap and FTH Video Checker Flows in Node Red
  20. +
  21. If not, go to: https://github.com/FreeTAKTeam/FreeTAKHub-Webmap/blob/main/WebMap.json
  22. +
  23. Click the copy button on the right side of the line to copy the raw contents of WebMap.json to your clipboard
  24. +
  25. Go back to your Node Red and click the Hamburger menu icon (right upper corner) and select Import
  26. +
  27. Paste the raw contents here and click import
  28. +
  29. If you get an error about missing “world map, world map in & config”
      +
    1. Click Hamburger menu and select Manage palette
    2. +
    3. Select install and search for “node-red-contrib-web-worldmap” and click install
    4. +
    5. Click back in search field and search for “node-red-contrib-config” and click install
    6. +
    +
  30. +
  31. In Node Red WebMap flow tab:
  32. +
  33. Select the FTH Global Config node and update the FTH_FTS_URL and FTH_FTS_VIDEO_URL fields with your IP (or ZeroTier) address
  34. +
  35. Select the Post CoT to FTS node and update the “bearer authentication” Token field with ‘
  36. +
  37. Click DEPLOY in upper right corner of Node Red to save settings
  38. +
  39. You should now get green “connected” indicators under one or all these nodes: FTS Server, TAK Map, tak-map & event
  40. +
  41. Confirm that the flow is working by logging back into the FTS Web UI: <IP address>:5000 and click on the WebMap tab. + Now you should see the world map displayed
  42. +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/fts-server/index.html b/Troubleshooting/fts-server/index.html new file mode 100644 index 000000000..ec805890f --- /dev/null +++ b/Troubleshooting/fts-server/index.html @@ -0,0 +1,3799 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Free TAK Server : core

+

image

+

Zero Touch Installer

+

ZeroTouch makes assumptions configuring the system. +However, there are many corner cases which ZeroTouch may miss. +For example, ZTI acquires the IP address by, effectively using: +

curl http://ifconfig.me/ip
+
+In many environments this produces the desired result. +In cases, not on the public internet, this result will be incorrect. +The following is more likely to be what you want. +
ip addr
+

+

Validate the properties set in the fts-ui configuration file.

+

Verify and/or Edit the fts configuration file
+

/opt/FTSConfig.yaml
+
+Here is a fragment of that configuration file. +
Addresses:
+  FTS_COT_PORT: 8087
+  FTS_SSLCOT_PORT: 8089
+  FTS_DP_ADDRESS: 127.0.0.1
+  FTS_USER_ADDRESS: 127.0.0.1
+  FTS_API_PORT: 19023
+  FTS_FED_PORT: 9000
+  FTS_API_ADDRESS: 127.0.0.1
+
+Adjust FTS_DP_ADDRESS, FTS_USER_ADDRESS & FTS_API_ADDRESS +to reflect your IP (or ZeroTier IP) address.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/fts-ui-server/index.html b/Troubleshooting/fts-ui-server/index.html new file mode 100644 index 000000000..7ee855d5f --- /dev/null +++ b/Troubleshooting/fts-ui-server/index.html @@ -0,0 +1,3893 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Free TAK Server User Interface

+

The WebUI is typically under the control of systemd as fts-ui.service.

+

image

+

The FTS-UI communicates with +the FTS and +the FTH.

+

Inbound Connection (in port 5000)

+

(port 5000)

+

API Service Connection (websocket port 19023)

+

Integration Connection (websocket port 8000)

+

Zero Touch Installer (ZTI)

+

ZeroTouch makes assumptions configuring the system. +However, there are many corner cases which ZeroTouch may miss. +For example, ZTI acquires the IP address by, effectively using: +

curl http://ifconfig.me/ip
+
+In many environments this produces the desired result. +In cases, not on the public internet, this result will be incorrect. +The following is more likely to be what you want. +
ip addr
+

+

Validate the properties set in the fts-ui configuration file.

+

Verify and/or Edit the fts-ui configuration file +Use of a python virtual environment (here the ZTI location) is recommended. +

/root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py
+
+Here is a sample fragment of that file. +
class Config(object):
+
+    # this IP will be used to connect with the FTS API
+    IP = '127.0.0.1'
+
+    # the public IP your server is exposing
+    APPIP = '0.0.0.0'
+
+    # The IP the Web UI service will use to access the Webmap service
+    WEBMAPIP = '127.0.0.1'
+
+    # The TCP port the Web UI service will use to access the Webmap service
+    WEBMAPPORT = 1880
+
+ZTI sets the IP and WEBMAPIP to your externally known IP address. +If you are not on a public network this will need to be adjusted.

+

WEBMAPPORT is 1880 for a NodeRedFlow install +and 8000 for a compiled webmap.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/fts-ui.service b/Troubleshooting/fts-ui.service new file mode 100644 index 000000000..55f53243a --- /dev/null +++ b/Troubleshooting/fts-ui.service @@ -0,0 +1,13 @@ +[Unit] +Description=FreeTAKServer UI service +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +ExecStart=/usr/bin/python3 -m /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/run.py + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/Troubleshooting/fts.service b/Troubleshooting/fts.service new file mode 100644 index 000000000..e04185493 --- /dev/null +++ b/Troubleshooting/fts.service @@ -0,0 +1,13 @@ +[Unit] +Description=FreeTAK Server service +After=network.target +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +ExecStart=/usr/bin/python3 -m FreeTAKServer.controllers.services.FTS + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/Troubleshooting/mediamtx.service b/Troubleshooting/mediamtx.service new file mode 100644 index 000000000..3a5cd9325 --- /dev/null +++ b/Troubleshooting/mediamtx.service @@ -0,0 +1,10 @@ +[Unit] +After=network.target + +[Service] +StandardOutput=append:/var/log/mediamtx/mediamtx-stdout.log +StandardError=append:/var/log/mediamtx/mediamtx-stderr.log +ExecStart=/opt/mediamtx/rtsp-simple-server /opt/mediamtx/rtsp-simple-server.yml + +[Install] +WantedBy=multi-user.target diff --git a/Troubleshooting/troubleshooting_faq/index.html b/Troubleshooting/troubleshooting_faq/index.html new file mode 100644 index 000000000..a6b260d7a --- /dev/null +++ b/Troubleshooting/troubleshooting_faq/index.html @@ -0,0 +1,4098 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Troubleshooting

+

My Windows Installation is failing

+

While FTS will work with this OS, we do not support it

+

My Ubuntu 22.04 Installation is failing

+

FTS 2.0 supports 22.04 older versions require Ubuntu 20.04

+

My FTS Installation is failing

+

FTS 2.0 has been tested with Python 3.11, +should work with others version (3.10). +Older versions require 3.8

+

My Raspberry Pi installation has an issue with the WebMap

+

This has been addressed, so you should not have the issue. +The older webmap was a Nodered packaged component, compiled for AMD64, so it will not run in the Pi. +You need to: + * install Node Red + * import the flow from source + * configure the flow

+

Initial setup doesn't ask to create a YAML file, how to make one manually?

+

copy this code, adapting to your environment

+
System:
+  FTS_DATABASE_TYPE: SQLite
+  FTS_CONNECTION_MESSAGE: Connected
+  FTS_OPTIMIZE_API: True
+  FTS_MAINLOOP_DELAY: 1
+Addresses:
+  FTS_COT_PORT: 8087
+  FTS_SSLCOT_PORT: 8089
+  FTS_DP_ADDRESS: [YOUREXTERNALIP]
+  FTS_USER_ADDRESS: [YOUREXTERNALIP]
+  FTS_API_PORT: 19023
+  FTS_FED_PORT: 9000
+  FTS_API_ADDRESS: [YOUREXTERNALIP]
+FileSystem:
+  FTS_CONFIG_PATH: /opt/FTSConfig.yaml
+  FTS_DB_PATH: /opt/FreeTAKServer.db
+  FTS_COT_TO_DB: True
+  FTS_MAINPATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer
+  FTS_CERTS_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs
+  FTS_EXCHECK_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/ExCheck
+  FTS_EXCHECK_TEMPLATE_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/ExCheck/template
+  FTS_EXCHECK_CHECKLIST_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/ExCheck/checklist
+  FTS_DATAPACKAGE_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/FreeTAKServerDataPackageFolder
+  FTS_LOGFILE_PATH: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/Logs
+Certs:
+  FTS_SERVER_KEYDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.key
+  FTS_SERVER_PEMDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.pem
+  FTS_TESTCLIENT_PEMDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/Client.pem
+  FTS_TESTCLIENT_KEYDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/Client.key
+  FTS_UNENCRYPTED_KEYDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.key.unencrypted
+  FTS_SERVER_P12DIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.p12
+  FTS_CADIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/ca.pem
+  FTS_CAKEYDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/ca.key
+  FTS_FEDERATION_CERTDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.pem
+  FTS_FEDERATION_KEYDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/server.key
+  FTS_CRLDIR: /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer/certs/FTS_CRL.json
+  FTS_FEDERATION_KEYPASS: [YOURPASS]
+  FTS_CLIENT_CERT_PASSWORD: [YOURPASS]
+  FTS_WEBSOCKET_KEY: [YOURPASS]
+
+

after XXX months of use the disk is full

+
    +
  • FTS writes the output of the service to a log located here: +
    /var/log/fts/fts-stdout.log
    +
  • +
  • depending on inbound traffic, this can become very large and subsequently, need to be manually deleted
  • +
+

My XXX component is not connecting / showing

+

for fts check out +

/opt/FTSConfig.yaml
+

+

for the UI check out +

/root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py
+or
+/usr/local/lib/python3.11/dist-packages/FreeTAKServer-UI/config.py
+

+

for the webmap check out +

/opt/webMAP_config.json
+
+for the video server check out +
/opt/mediamtx.yml
+

+

SSL connection is working but in an inconsistent way

+

ISSUE: SSL certs are not working +Cause: the certs are duplicated on your machine

+

This has been observed on ATAK 4.7 + and WinTAK for functions that requires both encrypted TCP and SSL connections. +The ExCheck plugin is an example of that. +The main symptom on the client is that the connection to the server fails (for specific functions). +This is NOT a FTS issue, it's provoked by the way ATAK stores certificates.

+

Workaround ATAK

+
    +
  • clear the content using the ATAK function
    +image
  • +
  • create a new user with mobile certs
  • +
  • connect to FTS using TCP
  • +
  • download new the certs
  • +
  • de-activate tcp and activate the new certs
  • +
+

Workaround WinTAK

+
    +
  • physically delete all the certs with the name (IP) of your sever from the machine in WinTAK the certs are located in + C:\Users\[USERNAME]\AppData\Roaming\WinTAK\SslCerts
  • +
  • Proceed as above but use WinTAK certs
  • +
+

Using SSL I get frequent disconnects

+

This is a problem of the client not sending data.

+

WinTAK +: under settings/network preferences set the TCP Connection timeout higher, (e.g. 60 seconds)

+

ATAK +: under settings/network preferences/ network connection preferences / TCP connection timeout (e.g. 40 seconds)

+

package not found

+

if, trying to start FTS you get an error 'package not found' +

'package not found'
+
+navigate to the physical location where the controllers are installed and start the server from there.

+

You may also check for missing libraries and install then using pip

+

issue connecting in WinTAK

+

if you have issues connecting WinTAK to FTS, +try to deactivate the TAKChat plugin, under the plugin section

+

Issues connecting using SSL

+

If you have issue connecting to FTS using SSL, +even if you have downloaded new certs, you need to manually delete the old files from your device. +In WinTAK (tested with 4.9) you can find certs files under +

C:\Users\[USERNAME]\AppData\Roaming\WinTAK\SslCerts
+
+you should have 3 certifications files of the form:

+
    +
  • [IP]_FreeTAKServer-Hash
  • +
  • 198-199-70-185_FreeTAKServer-2-a3_wbu7kirkizulslz1pstvv0xoo5qbcrr4.p12.dat2
  • +
+

and another 3 of the form:

+
    +
  • [UserNAME]Hash
  • +
  • FreeTAKTeamSupporte4fddab2-6102-4ab6-a9ec-0fee8edf8b10.p12
  • +
+

client2client datapackages

+

If you have issues sending datapackages directly to clients via FTS, +make sure the -IP argument you specified can be reached from your device. +A quick way to test if it works is to take a picture with Quick Pic in ATAK and send it to another client. +Please also note that for that test ATAK clients needs to be on different network (ie one on mobile and one on wifi), because if you run them in same network (WiFi, VPN, etc.) they will just use same multicast group, bypassing FTS completely.
+When you post package to specific contact in ATAK, following happens:

+

1) Datapackage is uploaded to server, recorded in database and stored in FTS directory
+ 2) Client receives payload with URL pointing to datapackage so ATAK can download it

+

Assuming you want to run open-to-everyone FTS instance, and you have server hosted somewhere, +you need to specify public IP address in -IP argument. +And just in case, -IP also accepts domain names. +If you run it at home and port forward on router doesn't work, +check if you receive actual IP address and not being NATed +and ports 8080 and 8087 are not filtered - you can ask your ISP about that.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/video-server/index.html b/Troubleshooting/video-server/index.html new file mode 100644 index 000000000..1d564498f --- /dev/null +++ b/Troubleshooting/video-server/index.html @@ -0,0 +1,3944 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Video Server (third party application)

+

image

+

The video server is a third party application.

+

The video server is Media MTX (previously known as rtsp-simple-server.

+

Known Issues

+

It may be that your problem may be related to a known issue. +Please, check the known issues.

+ +

Acquire the Appropriate Version

+

Different versions exist depending on the type of RaspPi you are using. +Instructions below are for RaspPi 4, having an ARM64 v8 processor.

+

This example uses a specific version verified for use with FTS, +vis. https://github.com/bluenviron/mediamtx/releases/tag/v0.18.5.

+
wget https://github.com/bluenviron/mediamtx/releases/download/v0.18.5/rtsp-simple-server_v0.18.5_linux_arm64v8.tar.gz
+
+

Extract the application into a suitable directory, e.g. /opt. +

sudo mkdir -p /opt/mediamtx
+sudo tar -zxvf rtsp-simple-server_v0.18.5_linux_arm64v8.tar.gz -C /opt/mediamtx/
+

+

Edit the configuration file /opt/mediamtx/rtsp-simple-server.yml. +The following shows the fragments of interest, before editing. +

# Enable the HTTP API.
+api: no
+# Address of the API listener.
+apiAddress: 127.0.0.1:9997
+
+# Encrypt handshake and TCP streams with TLS (RTSPS).
+# Available values are "no", "strict", "optional".
+encryption: "no"
+# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
+rtspAddress: :8554
+# Address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional".
+rtspsAddress: :8322
+
+* Enable the HTTP API +* Set the listener's address to the RaspPi's IP address (or ZeroTier)

+

Here is an example with the relevant properties after updates (in context). +

# Enable the HTTP API.
+api: yes
+# Address of the API listener.
+apiAddress: 10.2.118.237:9997
+
+# Encrypt handshake and TCP streams with TLS (RTSPS).
+# Available values are "no", "strict", "optional".
+encryption: "no"
+# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
+rtspAddress: 10.2.118.237:8554
+# Address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional".
+rtspsAddress: :8322
+

+

Smoke Test (is it running?)

+
    +
  • https://github.com/FreeTAKTeam/FreeTAKHub-Installation/blob/main/roles/videoserver/templates/rtsp-simple-server.service.j2
  • +
+
[Unit]
+After=network.target
+
+[Service]
+StandardOutput=append:/var/log/mediamtx/mediamtx-stdout.log
+StandardError=append:/var/log/mediamtx/mediamtx-stderr.log
+ExecStart=/opt/mediamtx/rtsp-simple-server /opt/mediamtx/rtsp-simple-server.yml
+
+[Install]
+WantedBy=multi-user.target
+
+

Put the mediamtx.service file in /etc/systemd/system/mediamtx.service. +

sudo systemctl daemon-reload
+sudo systemctl enable mediamtx.service
+sudo systemctl start mediamtx.service
+

+

Integrate Media Server with Integration Server

+

This presumes the prior installation of NodeRed.

+

The integration server is configured with the video-checker via a JSON file. +NodeRed provides https://github.com/FreeTAKTeam/FreeTAKHub_VideoChecker.

+

https://github.com/FreeTAKTeam/FreeTAKHub_VideoChecker/tree/2.0

+ +

Connect a Client (ICU and/or drone) to Video Server

+
    +
  • Receive the CoT notification in TAK client (WinTAK and ATAK)
  • +
  • Use notification to start video (WinTAK and ATAK)
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/voip-server/index.html b/Troubleshooting/voip-server/index.html new file mode 100644 index 000000000..7dac7188e --- /dev/null +++ b/Troubleshooting/voip-server/index.html @@ -0,0 +1,3784 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Chat Server

+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Troubleshooting/webmap-server/index.html b/Troubleshooting/webmap-server/index.html new file mode 100644 index 000000000..bd6ee95e7 --- /dev/null +++ b/Troubleshooting/webmap-server/index.html @@ -0,0 +1,3785 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

WebMap Installation

+

image

+

Some versions of the Zero Touch Installer do not install the compiled webmap.

+

In those cases you will need to install the flow version.

+

The WebMap is similar in function to WebTAK.

+

Web Team Awareness Kit (WebTAK) +: A web-based interface which allows users to type in the website for a specific TAK server +(configured to support WebTAK) was recently developed. +The primary use of WebTAK is to provide quick access to data collected +in the TAK server to enable situational awareness to be shared and avoid having to install TAK clients +(i.e. ATAK, WinTAK, iTAK) on hardware.

+ + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/Connecting_ATAK/index.html b/Usage/Connecting_ATAK/index.html new file mode 100644 index 000000000..f4dcb4b22 --- /dev/null +++ b/Usage/Connecting_ATAK/index.html @@ -0,0 +1,3942 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Connecting ATAK to Pub Server

+

The FTS team supports a public instance of FTS with the last version installed so that you can test it.

+

Configure ATAK for FreeTakServer on the Pub server

+

In order to use ATAK with a FTS server you need to: +1. Download required files +2. Configure using import manager

+

1. Download required files

+

The easiest way is to open this article in your Android phone, so that all the files will be already available there.

+

Download and install ATAK 4.10 (updated Nov 2023)

+ +

Download configurations

+
    +
  • Configuration fts-official-pub.zip +This configuration includes fts-offical-pub.pref: +
    <?xml version='1.0' standalone='yes'?>
    +<preferences>
    +    <preference version="1" name="cot_streams">
    +        <entry key="count" class="class java.lang.Integer">1</entry>
    +        <entry key="description0" class="class java.lang.String">FTS Official (Public)</entry>
    +        <entry key="enabled0" class="class java.lang.Boolean">true</entry>
    +        <entry key="connectString0" class="class java.lang.String">137.184.101.250:8087:tcp</entry>
    +    </preference>
    +    <preference version="1" name="com.atakmap.app_preferences">
    +        <entry key="displayServerConnectionWidget" class="class java.lang.Boolean">true</entry>
    +    </preference>
    +</preferences>
    +
  • +
+

Download maps (optional)

+

There are places where you may acquire ATAK maps. +Representative place are:

+ +

2. Configure using import manager

+

Navigation:

+
    +
  • Start ATAK on android
  • +
  • Tap the menu selector, i.e. ≡, (upper left).
  • +
+

→ Tap Import manager

+

ATAK Menu Main Select Settings

+

→ Tap Local SD

+

ATAK Dialog Import Type

+

→ Go to the place where you have downloaded the files (probably /sdcard/Download/)

+

ATAK Dialog Select Import

+
    +
  • Select fts-official-pub.zip
  • +
  • +

    Click OK

    +
  • +
  • +

    A message will appear to inform you that you are connected to Pub Server

    +
  • +
  • Under servers the Pub Server is green (if connected)
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/Connecting_WinTAK/index.html b/Usage/Connecting_WinTAK/index.html new file mode 100644 index 000000000..b5ebeb10e --- /dev/null +++ b/Usage/Connecting_WinTAK/index.html @@ -0,0 +1,3890 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Connecting WinTAK to Pub Server

+

The FTS team supports a public instance of FTS with the last version installed so that you can test it.

+

Issues

+

WinTAK has a known issue with the TAK Chat Plugin. +You Must disable the plugin, +or you will have frequent disconnects from FTS.

+

Disable TAK Chat

+

Navigate to the plugin management menu.

+

WinTAK Plugin Manager

+

Then select unload on TAK Chat

+

Connect to FTS

+

Navigation:
+Settings

+

WinTAK Menu Main Select Settings

+

Network Preferences

+

WinTAK Dialog Main Settings

+

Mange Server Connections

+

WinTAK Dialog Network Prefs

+

FTS Public 2.1 +From here you can add your FTS server: +Description; IP or host name, and; port.

+

WinTAK Dialog Server Connect

+

Ok If the connection is made you will see it reflected in the TAK Network Status.

+

WinTAK Dialog Server Connected

+

Connect to FTS via Configuration File

+

WinTAK Menu Main Import

+

This will bring up a file selection dialog.

+ +
+

Note

+

This reads the file, but it does not seem to update the server connections.

+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/ExCheck/index.html b/Usage/ExCheck/index.html new file mode 100644 index 000000000..4bacc9c97 --- /dev/null +++ b/Usage/ExCheck/index.html @@ -0,0 +1,3939 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

ExCheck

+

ExCheck is a plugin for ATAK and WinTAK. +It allows users to collaborate on the execution and monitoring of tasks based on templates. +To use ExCheck, you need to have a server that supports it. +FTS supports the plugin since version 1.3. +Version 1.5 supports also ExCheck in the WebUI.

+

WinTAK

+

in WinTAK (since version 4.1) you can find the plugin as ExCheck under the plugin tab. +On the top of the window you will see two buttons. +A list of active checklists shows up below them.

+

with the buttons You can:

+
    +
  • create a new Template
  • +
  • create a new template based on an existing one
  • +
  • Join active checklist
  • +
  • Start a new checklist
  • +
+

create a new Template

+

You need to define: a name, a description, and at least a task, to be able to save the template. +Standard columns can be modified or deleted,

+
    +
  • No: sequence of the task
  • +
  • Description: name of the task
  • +
  • Req. : this step is required to complete the checklist (???)
  • +
  • CallSign: TBD
  • +
  • Net: TBD
  • +
  • From: TBD
  • +
  • To: TBD
  • +
  • Codeword: a code word for this task
  • +
  • Due relative DTG: the timing of the competition of the task required field
  • +
+

after that you have created a task you can right-click the hamburger menu (the 3 lines) to the left to:

+
    +
  • Delete the task
  • +
  • add some background color
  • +
  • Toggle linebreak: allows to create a block of tasks
  • +
+

create a new template based on an existing one

+

Works like the previous, +only you will start the template by modifying an existing one.

+

Start a new checklist

+

When you start a new checklist, +the current status is saved locally and on the server.

+

Join active checklist

+

Allow you to participate with others in completing the checklist.

+

Working with checklists

+

As soon a checklist is started, you can click on an action and set it to be completed. +You can also set back to pending a completed item. +It's also possible to add Notes (those are only visible opening the task item). +If another team member changes the status of a task, +you will get an update.

+

To delete a checklist, you need to open it and pres the delete button

+

ATAK

+

the plugin for ATAK is yet not available to the community (Dec 2020). +Functionalities are similar to the WinTAK version. +Tests indicate that FTS has the same level of functional support.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/VideoManagement/index.html b/Usage/VideoManagement/index.html new file mode 100644 index 000000000..ed8732563 --- /dev/null +++ b/Usage/VideoManagement/index.html @@ -0,0 +1,3793 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Video Management

+

Since version 1.9 FTS supports a complete video management function. +you can: +* Upload to FTS a video end point using the client (ATAK only) +* Download an existing video endpoint from FTS

+

Additionally, +FTS will automatically send to all the connected clients +video streams information coming from FreeTAK UAS or TAK ICU +using the API

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/images/atak_dialog_import_type.png b/Usage/images/atak_dialog_import_type.png new file mode 100644 index 000000000..567b568a1 Binary files /dev/null and b/Usage/images/atak_dialog_import_type.png differ diff --git a/Usage/images/atak_dialog_select_import.png b/Usage/images/atak_dialog_select_import.png new file mode 100644 index 000000000..5d90cbae2 Binary files /dev/null and b/Usage/images/atak_dialog_select_import.png differ diff --git a/Usage/images/atak_menu_main_import.png b/Usage/images/atak_menu_main_import.png new file mode 100644 index 000000000..664bcf44d Binary files /dev/null and b/Usage/images/atak_menu_main_import.png differ diff --git a/Usage/images/wintak_dialog_main_settings.png b/Usage/images/wintak_dialog_main_settings.png new file mode 100644 index 000000000..942e98951 Binary files /dev/null and b/Usage/images/wintak_dialog_main_settings.png differ diff --git a/Usage/images/wintak_dialog_network_prefs.png b/Usage/images/wintak_dialog_network_prefs.png new file mode 100644 index 000000000..9ab528027 Binary files /dev/null and b/Usage/images/wintak_dialog_network_prefs.png differ diff --git a/Usage/images/wintak_dialog_server_connect.png b/Usage/images/wintak_dialog_server_connect.png new file mode 100644 index 000000000..36bfd2c3a Binary files /dev/null and b/Usage/images/wintak_dialog_server_connect.png differ diff --git a/Usage/images/wintak_dialog_server_connected.png b/Usage/images/wintak_dialog_server_connected.png new file mode 100644 index 000000000..73591e50b Binary files /dev/null and b/Usage/images/wintak_dialog_server_connected.png differ diff --git a/Usage/images/wintak_menu_main.png b/Usage/images/wintak_menu_main.png new file mode 100644 index 000000000..f810514e4 Binary files /dev/null and b/Usage/images/wintak_menu_main.png differ diff --git a/Usage/images/wintak_menu_main_import.png b/Usage/images/wintak_menu_main_import.png new file mode 100644 index 000000000..d47654284 Binary files /dev/null and b/Usage/images/wintak_menu_main_import.png differ diff --git a/Usage/images/wintak_menu_main_select_settings.png b/Usage/images/wintak_menu_main_select_settings.png new file mode 100644 index 000000000..1a24633b6 Binary files /dev/null and b/Usage/images/wintak_menu_main_select_settings.png differ diff --git a/Usage/tools/FreeTAKMumla/index.html b/Usage/tools/FreeTAKMumla/index.html new file mode 100644 index 000000000..e8ee4f58f --- /dev/null +++ b/Usage/tools/FreeTAKMumla/index.html @@ -0,0 +1,3863 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAKMumla Plugin

+

An ATAK plugin that creates a button overlay for PPT. +Requires a Mumla android app to work.

+

Requirements

+

the FreeTAKMumla Plugin for ATAK requires that: +1. you have the murmur server installed and running +2. you have Mumla installed and running +3. you have a compatible version of ATAK installed.

+

Installation

+
    +
  • Download and install Mumla
  • +
  • Connect to your murmur server
  • +
  • set the microphone to work with Push-to-Talk
  • +
  • Download the Mumla plugin on your local Windows machine
  • +
  • start WinTAK and use the ATAK Manager to create a new device configuration
  • +
+

image

+
    +
  • connect your Android device to the PC
  • +
  • as soon the phone is recognized export the configuration to the device
  • +
+

image

+
    +
  • ATAK will ask if you want to load the plugin, at this point you will see a Microphone
  • +
+

image

+

usage

+
    +
  • tap the microphone and start to talk
  • +
  • tap again to silence yourself
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/tools/FreeTAKUAS/index.html b/Usage/tools/FreeTAKUAS/index.html new file mode 100644 index 000000000..a5ef9a49e --- /dev/null +++ b/Usage/tools/FreeTAKUAS/index.html @@ -0,0 +1,3856 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

freeTAKUAS_Logo

+

Introduction

+

FreeTAK UAS (FTUAS) is an Android application that can:

+
    +
  • Control any DJI drone supported by the current DJI SDK
  • +
  • Stream the position of the drone to all the connected TAK clients
  • +
  • Stream the video Feed to all the connected TAK clients
  • +
  • Create a "target" on the map and stream with all the connected TAK clients
  • +
+

Requirements

+
    +
  • FreeTAKUAS app
  • +
  • DJI compatible drone
  • +
  • FTS v 1.9 (or better): the application will NOT support the legacy TAK server.
  • +
  • the FTS REST API service must be activated
  • +
  • You have a valid REST Token (created in the FTS UI under System User)
  • +
  • FTH Video Service (or compatible RTMP server) if you want to stream live videos
  • +
+

Installation

+
    +
  • Assuming that you have installed and configured your FTS
  • +
  • and the video service,
  • +
  • download the APK installation file on your phone / tablet and follow the instructions.
  • +
  • if the installation is successful you should have a new Icon
  • +
+

image

+

Usage

+

Connection

+

image

+
    +
  • start your drone
  • +
  • start your controller
  • +
  • +

    connect the phone with FTUAS to the controller

    +
  • +
  • +

    a popup will ask which application you want to open

    +
  • +
  • select FTUAS and configure the following:
  • +
  • FTS IP and Port
  • +
  • Video Server IP and port
  • +
  • the Drone name
  • +
  • A series of messages will appear, indicating that the SDK is registered (requires an internet connection) and that the drone is ready
  • +
  • Now click on UAS [READY]
  • +
+

Interface

+

image +the FTUAS interface is typical of DJI the following is special:

+
    +
  • As soon you switch to it the drone will start streaming the camera
  • +
  • As soon you switch to it the drone will share his position with the FTS server, that will forward to all the connected clients
  • +
  • the "Red Dot" in the middle can be tapped to create a geoObject of type "Unknown" call target and send to all the connected clients
  • +
  • the vertical aim of the "Red Dot" can be changed by moving the gimbal
  • +
  • in some model, it's also possible to aim the gimbal independently of the position of the drone by dragging the position on screen
  • +
  • In the current version, the aim is not perfect so expect some delta
  • +
+

ATAK Interface

+

Map

+

image +In ATAK the drone shows:

+
    +
  • a white zone (field of view)
  • +
  • a Sensor Point of Interest (SPI)
  • +
  • the position and name of the drone
  • +
+ +

image +to visualize the video tap the drone's icon and then the video icon

+

Video Player

+

image +In alternative open the ATAK video player and search for the name of your drone

+

NOTICE: in the current version, every time a new video endpoint will be created, this must be manually deleted.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/tools/Manuals/ATAK_Data_Sync_User_Guide_Version_1.3_ATAK_4.8.pdf b/Usage/tools/Manuals/ATAK_Data_Sync_User_Guide_Version_1.3_ATAK_4.8.pdf new file mode 100644 index 000000000..a15cd8227 Binary files /dev/null and b/Usage/tools/Manuals/ATAK_Data_Sync_User_Guide_Version_1.3_ATAK_4.8.pdf differ diff --git a/Usage/tools/Manuals/ATAK_ExCheck_User_Guide_1.1_ATAK_4.8.pdf b/Usage/tools/Manuals/ATAK_ExCheck_User_Guide_1.1_ATAK_4.8.pdf new file mode 100644 index 000000000..e2cfcc3e0 Binary files /dev/null and b/Usage/tools/Manuals/ATAK_ExCheck_User_Guide_1.1_ATAK_4.8.pdf differ diff --git a/Usage/tools/Manuals/Mumble Server Installation Guide.pdf b/Usage/tools/Manuals/Mumble Server Installation Guide.pdf new file mode 100644 index 000000000..68946a82f Binary files /dev/null and b/Usage/tools/Manuals/Mumble Server Installation Guide.pdf differ diff --git a/Usage/tools/Manuals/TAK Voice User Guide.pdf b/Usage/tools/Manuals/TAK Voice User Guide.pdf new file mode 100644 index 000000000..683595876 Binary files /dev/null and b/Usage/tools/Manuals/TAK Voice User Guide.pdf differ diff --git a/Usage/tools/Manuals/UserGuides/index.html b/Usage/tools/Manuals/UserGuides/index.html new file mode 100644 index 000000000..e30bcaf97 --- /dev/null +++ b/Usage/tools/Manuals/UserGuides/index.html @@ -0,0 +1,3841 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+ +
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/tools/UASTool/index.html b/Usage/tools/UASTool/index.html new file mode 100644 index 000000000..2d147a4b9 --- /dev/null +++ b/Usage/tools/UASTool/index.html @@ -0,0 +1,3850 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

UAS tool

+

The UAS Tool is a plug-in that provides integration of Unmanned Aircraft Systems (UAS) +for enhanced Situational Awareness (SA) and telemetry data, Full Motion Video (FMV), and command and control (C2). +The following instructions have been updated for tool compatible with ATAK 4.8.1.

+

Connect UAS tool to FTS infrastructure

+
    +
  • Make sure all devices are connected to the FTS server on the Digital Ocean (DO) droplet.
  • +
  • Open UAS tool settings, go to "Video Broadcast preferences", click on "video broadcast destination and change it to RTSP-Push"
  • +
  • Scroll down to the "RTSP-push configuration " section, click the "video destination ip address" and enter only the ip address of the DO droplet, do not enter port or paths here. hit ok.
  • +
  • Next click on the "video destination port", enter only the port of the video server here 8554. hit ok.
  • +
  • Click on "video broadcast Identifier" and enter something like + live/CorvoUAS (no quotation marks) unless it is already filled in. hit OK
  • +
  • Scroll down and under the "other" section click on "video observer URL". If this is not already filled in, enter rtsp://[yourIPhere]:[port]/live/example (should look something like this again no quotation marks + rtsp://132.233.124.12:8554/live/corvo
  • +
  • Then on the receiving device repeat steps 5a-9a and enter the same information that you did on the UAS EUD. All devices wishing to view the stream should now have identical settings (including same ip, port, video broadcast identifier etc.).
  • +
  • +

    Start streaming the broadcast from the UAS EUD. On the receiving EUD back out to the list of UAS's and click the play button. Should start streaming the video.

    +
  • +
  • +

    in the client (e.g. WinTAK, you can use the plugin to see the position of the Drone + image

    +
  • +
  • +

    also without a plugin, if you have the [videoCheck] configured, you will receive a new video feed

    +
  • +
+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/tools/images/atak_video_listing.png b/Usage/tools/images/atak_video_listing.png new file mode 100644 index 000000000..8904dbdfe Binary files /dev/null and b/Usage/tools/images/atak_video_listing.png differ diff --git a/Usage/tools/images/atak_video_locate.png b/Usage/tools/images/atak_video_locate.png new file mode 100644 index 000000000..9b9e9aa3b Binary files /dev/null and b/Usage/tools/images/atak_video_locate.png differ diff --git a/Usage/tools/images/atak_video_notification.png b/Usage/tools/images/atak_video_notification.png new file mode 100644 index 000000000..d05ff4552 Binary files /dev/null and b/Usage/tools/images/atak_video_notification.png differ diff --git a/Usage/tools/images/atak_video_stream_play.png b/Usage/tools/images/atak_video_stream_play.png new file mode 100644 index 000000000..31ff9aadb Binary files /dev/null and b/Usage/tools/images/atak_video_stream_play.png differ diff --git a/Usage/tools/images/wintak-atak-mgr-device-profiles-menu.png b/Usage/tools/images/wintak-atak-mgr-device-profiles-menu.png new file mode 100644 index 000000000..4073bdbd2 Binary files /dev/null and b/Usage/tools/images/wintak-atak-mgr-device-profiles-menu.png differ diff --git a/Usage/tools/images/wintak-export-profile-to-atak.png b/Usage/tools/images/wintak-export-profile-to-atak.png new file mode 100644 index 000000000..3ea6b92ee Binary files /dev/null and b/Usage/tools/images/wintak-export-profile-to-atak.png differ diff --git a/Usage/tools/rtsp/index.html b/Usage/tools/rtsp/index.html new file mode 100644 index 000000000..acbf1a411 --- /dev/null +++ b/Usage/tools/rtsp/index.html @@ -0,0 +1,3930 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

RTSP

+

The Real-Time Streaming Protocol (RTSP) is an application-level network protocol designed for multiplexing and packetizing multimedia transport streams (such as interactive media, video and audio) over a suitable transport protocol. It is the primary protocol used by TAK video servers.

+

The following client applications may be used as an alternative to TAK ICU.

+

Configuration

+

Any RTSP feed will need an appropriate URL. +

rstp://<ip>:8554/<feed>
+

+

ip +: the IP address of the FTS Server.

+

feed +: any (ascii) text, e.g. foo, test.

+

TAK ICU : ATAK Plugin

+

This RTSP video generator has its own page.

+

FFMPEG

+

On Windows and Linux you can generate RTSP video feeds with the venerable ffmpeg.

+
ffmpeg -re -stream_loop -1 -i https://download.samplelib.com/mp4/sample-5s.mp4 -c copy -f rtsp rtsp://10.68.1.101:8554/mystream
+
+

This loops on the https://download.samplelib.com/mp4/sample-5s.mp4 mpeg4 file sending it as the rtsp://10.68.1.101:8554/mystream stream.

+

Larix Broadcaster

+

Larix Broadcaster is an app for mobile devices, e.g. Android and iPad.

+

Configuration

+

In Settings establish a Connections. +Use Manage Connections then use the + button. Add a Connection. +The Connection has the following properties: +* Name: <feed> +* URL: rstp://<ip>:8554/<feed> +* Mode: Video only

+

The <ip> should be set to the IP address of the FTS Server. +The <feed> can be set to any (ascii) text, e.g. foo or test.

+

Usage

+

Return to the main screen and press the play button.

+

Integration with FTS

+

The FTS integration, FreeTAKHub_VideoChecker has existed since FTS 1.9.5. +It allows for seamless streaming of videos by connecting to the video server.

+

Normally, when a device is streaming video, connected TAK end user device will be not notified, +it is necessary to manually create a new feed in the RTSP application.

+

The video stream is sent to all the connected TAK Devices

+

image

+

Now you can retrieve it in your video list

+

image

+

In the video you can open the feed and visualize it. +image

+

Touching the globe, will jump to the location of the stream, +to see its context

+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Usage/tools/takICU/index.html b/Usage/tools/takICU/index.html new file mode 100644 index 000000000..c2cdddf51 --- /dev/null +++ b/Usage/tools/takICU/index.html @@ -0,0 +1,3902 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

TAK ICU

+

TAK ICU is an Android Team Awareness Kit (ATAK) support plugin that allows a user to stream video and position to a compatible RTSP server. +An operator running TAK ICU sends video and telemetry to the RTSP server, +and the observer(s) can view the video and telemetry on any compatible end-user device (EUD) that is connected to the server. +Telemetry transmitted includes the senders position location information (PLI), +field-of-view (FOV), focal point distance, and compass heading.

+

The product is a bundled support app, and is maintained by the TAK Product Center.

+

This page describes the TAK ICU tool only.

+

Client Installation (ANDROID ONLY)

+
    +
  • Install ATAK from the TAK Product Center
  • +
  • Install/Enable the TAK ICU support plugin from Settings > Plugins
  • +
  • The install/enable creates a separate app icon to access TAK ICU, which may need to be added to your home screen
  • +
+

Client configuration

+
    +
  • Start TAK ICU
  • +
  • Tap the preferences (hamburger menu, top-right)
  • +
  • Tap Settings (gear icon)
  • +
  • Under Application Settings, select Broadcast Preferences
  • +
  • In BROADCAST PREFERENCES, select Destination Type > Wowza Server
  • +
  • In BROADCAST PREFERENCES, select Broadcast Alias and set it to your TAK ID (e.g. Corvo). It needs to be a single word, if broadcast alias contains a space it will fail.
  • +
  • Scroll down to WOWZA SERVER PREFERENCES
  • +
  • In WOWZA SERVER PREFERENCES > Wowza Server IP, specify your RTSP server IP address (e.g. 147.182.190.54)
  • +
  • In WOWZA SERVER PREFERENCES > Wowza Server Port, Set the server port to 8554
  • +
  • Tap the gear icon to close Settings
  • +
+

Usage

+
    +
  • Ensure that you have a GPS fix +image
  • +
  • Again, ensure that you have a GPS fix! Best-case, without a GPS fix, your video will not be associated to a map location and telemetry will fail. Worst-case, the video broadcast will not even start.
  • +
  • Check the Broadcast checkbox
  • +
  • Press the Broadcast/Record button to begin streaming
  • +
+

Integration with FTS

+

The FTS integration, FreeTAKHub_VideoChecker exists since FTS 1.9.5. +It allows for seamless streaming of videos by simply connecting to the video server.

+

Normally, when a device is streaming video, connected TAK EUD will be not notified, +it's necessary to manually create a new feed in the software.

+

image

+

The video stream is sent to all the connected TAK Devices

+

image

+

Now you can retrieve it in your video list

+

image

+

In the video you can open the feed and visualize it. +image

+

Touching the globe, you will jump to the location of the stream, +to see its context

+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/CLI/index.html b/administration/CLI/index.html new file mode 100644 index 000000000..eb507f31c --- /dev/null +++ b/administration/CLI/index.html @@ -0,0 +1,3910 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

CLI

+

Availability

+

The CLI has been sunset since version 1.5 of FTS, because of the new way to access the server.

+

It may be reintroduced in the future.

+

Access

+

To access the CLI open a new terminal and run the command:

+
sudo python3 -m FreeTAKServer.views.CLI
+
+

Commands

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandPurpose
helpList all commands
start_allBegin all services type
start_CoT_serviceBegin CoT service type
start_data_package_serviceBegin data package service type
stop_allTerminate all services type
stop_CoT_serviceTerminate CoT service type
stop_data_package_serviceTerminate data package service type
change_connection_infoChange the address and port of the server you're connecting to
show_usersShow connected user information type
killKill the full server type
show_DPShow all DataPackages on the server
remove_DPRemove a DataPackages on the server
add_api_useradd a user and a token for API consumption
show_api_usersshow a list of users and their tokens
remove_api_userremove a user and a token for API consumption
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/FTS_Certifications_structure.png b/administration/FTS_Certifications_structure.png new file mode 100644 index 000000000..5262d61c2 Binary files /dev/null and b/administration/FTS_Certifications_structure.png differ diff --git a/administration/FTS_UI_Documention.pdf b/administration/FTS_UI_Documention.pdf new file mode 100644 index 000000000..5f3c1fa96 Binary files /dev/null and b/administration/FTS_UI_Documention.pdf differ diff --git a/administration/Operation/fts-config/index.html b/administration/Operation/fts-config/index.html new file mode 100644 index 000000000..cdb7949e9 --- /dev/null +++ b/administration/Operation/fts-config/index.html @@ -0,0 +1,3782 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Fts config

+ +

Configuration

+

ZeroTouch will have configured the system and started the services for you. +However, there are many corner cases which ZeroTouch may miss.

+

Verify and/or Edit the fts-ui configuration file

+

/root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/config.py
+or
+/usr/local/lib/python3.11/dist-packages/FreeTAKServer-UI/config.py
+
+WEBMAPPORT is 1880 for a NodeRedFlow install and 8000 for a compiled webmap.

+

For specific instructions on validating the configuration, +see these notes.

+

Verify and/or Edit the fts configuration file

+
/opt/FTSConfig.yaml
+
+

For specific instructions on validating the configuration, +see these notes.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/Operation/fts-service-mgmt/index.html b/administration/Operation/fts-service-mgmt/index.html new file mode 100644 index 000000000..954c96463 --- /dev/null +++ b/administration/Operation/fts-service-mgmt/index.html @@ -0,0 +1,3795 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Fts service mgmt

+ +

Mange the FTS services

+

If the ZTI had run it will have attempted to start the fts services. +As you make changes to their configurations you will need to restart them. +

sudo systemctl stop fts-ui
+sudo systemctl stop fts
+
+sudo systemctl start fts
+sudo systemctl start fts-ui
+

+

Your FTS should now be running.

+

See troubleshooting for more information.

+

There are other services which ZTI will start. +They are also managed by systemd.

+
# the core FTS services
+sudo systemctl status fts.service
+sudo systemctl status fts-ui.service
+
+# a flow programming environment
+sudo systemctl status nodered.service
+# manages the webmap service
+# manages the video-service checker
+
+# a video server
+sudo systemctl status rtsp-simple-server.service
+# sudo systemctl status mediamtx.service
+
+# a voice chat server
+sudo systemctl status mumble-server.service
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/SSL/index.html b/administration/SSL/index.html new file mode 100644 index 000000000..360ce7427 --- /dev/null +++ b/administration/SSL/index.html @@ -0,0 +1,4226 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

SSL

+

Secure Sockets Layer (SSL) is a protocol for secure communication. +FTS supports SSL since version 1.3.

+

Automated SSL Generation and Deployment

+

Since version 1.5, FTS features automated SSL generation and deployment.

+

The automated generation and deployment is easier, please consider using that approach.

+

For more details, read the FTS manual here.

+

Expected File Structure

+

Expected File structure

+

Manual SSL Installation Guide

+

This method requires understanding of complex console commands.

+

We do not provide support for certificate generation or deployment issues.

+

We are currently exploring tools like YAOG to simplify the process.

+

Some of the steps below to create a server and client certificate are adopted from:

+

https://blog.devolutions.net/2020/07/tutorial-how-to-generate-secure-self-signed-server-and-client-certificates-with-openssl/

+

1. Install OpenSSL on Windows using the choco package manager

+

Go to:

+

https://docs.chocolatey.org/en-us/choco/setup#installing-chocolatey

+

and install the choco package manager.

+

Next, temporarily append the choco executable to the PATH variable.

+

After PowerShell is closed, the appended path will resort back to its original state.

+
$env:Path += ";C:\ProgramData\chocolatey\bin"
+
+

To permanently add to the PATH variable, refer to:

+

https://www.computerhope.com/issues/ch000549.htm

+

Next, install OpenSSL:

+
choco install openssl
+
+

Do not close PowerShell because you will need it for the next steps.

+

2. Add OpenSSL to the PATH

+

Most likely, you will be running a 64-bit system. For a 64-bit system, enter:

+
$env:Path += ";C:\Program Files\OpenSSL-Win64\bin"
+
+

For a 32-bit system (unlikely), enter:

+
$env:Path += ";C:\Program Files\OpenSSL-Win32\bin"
+
+

3. Set up a directory for OpenSSL outputs

+

Go to your home directory.

+
cd ~
+
+

Make an invisible folder called .certs.

+
mkdir .certs
+
+

Go into the .certs directory.

+
cd .certs
+
+

4. Generate the Certificate Authority Certificate

+

Create a private key for the CA certificate.

+
openssl ecparam -name prime256v1 -genkey -noout -out ca.key
+
+

A ca.key will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            232 ca.key
+
+

Next, create CA certificate from the newly created private key.

+
openssl req -new -x509 -sha256 -key ca.key -out ca.crt
+
+

Certificate Authority Metadata Fields

+

Creating a Certificate Authority (CA) involves generating a self-signed root certificate +with various metadata fields. +Below is a table that describes some of the common metadata fields that can be set in a CA certificate.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Metadata FieldX.509 AttributeDescription
Common NameCNThe fully qualified domain name (FQDN) or name of the CA. For root CAs, this field often contains the organization's name. e.g. https://github.com/FreeTAKTeam
OrganizationOThe legal name of the organization that is running the CA. e.g. FreeTAKTeam
Organizational UnitOUThe division or department within the organization that is responsible for managing the CA.
LocalityLThe city or locality where the organization is located.
StateSTThe state, province, or region where the organization is located.
CountryCThe two-letter ISO country code for the country where the organization is located.
Email AddressemailAddressThe email address for contacting the CA administrator.
Serial NumberN/AA unique identifier for the certificate. It is used to identify the certificate within a CA's database.
Validity PeriodN/ASpecifies the time period during which the certificate is valid. It includes a start date (NotBefore) and an end date (NotAfter).
Key UsageN/ADefines the purposes for which the certificate's public key can be used, such as digital signature, key encipherment, and certificate signing.
Extended Key UsageN/ASpecifies additional purposes for which the public key may be used, like server authentication, client authentication, code signing, etc.
Subject Alternative NameSANSpecifies additional host names or IP addresses that are protected by this certificate. Useful for multi-domain or wildcard certificates.
IssuerN/AInformation about the entity that issued the certificate. For a self-signed root CA, the issuer is the CA itself.
VersionN/AIndicates the X.509 version used. Most modern certificates use version 3.
Signature AlgorithmN/AThe algorithm used to create the certificate's signature. Common algorithms include RSA-SHA256 and ECDSA-SHA256.
+

You will be prompted to enter in certificate details. Here is an example:

+
You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+
+

A ca.crt will be outputted to the directory.

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+
+

5. Generate the Server Certificate

+

Generate the server private key.

+
openssl ecparam -name prime256v1 -genkey -noout -out server.key
+
+

A server.key will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

Next, generate the server certificate signing request.

+
openssl req -new -sha256 -key server.key -out server.csr
+
+

You will be prompted to enter in certificate details. Here is an example:

+
You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:US
+State or Province Name (full name) [Some-State]:CA
+Locality Name (eg, city) []:Los Angeles
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Acme Corporation
+Organizational Unit Name (eg, section) []:Dev
+Common Name (e.g. server FQDN or YOUR name) []:Wile E. Coyote
+Email Address []:wile@acmecorp.com
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:badpassword
+An optional company name []:Acme Corporation
+
+

A server.csr will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM            626 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

Next, generate the server certificate.

+
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1000 -sha256
+
+

Something similar to this will be outputted:

+
Signature ok
+subject=C = US, ST = CA, L = Los Angeles, O = Acme Corporation, OU = Dev, CN = Wile E. Coyote, emailAddress = wile@acmecorp.com
+Getting CA Private Key
+
+

A server.crt and ca.srl will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM             42 ca.srl
+-a----        11/10/1775   6:00 PM            820 server.crt
+-a----        11/10/1775   6:00 PM            626 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

6. Generate the Client Certificate

+

These are the same steps as above, except for the client.

+

Generate the server private key.

+
openssl ecparam -name prime256v1 -genkey -noout -out client.key
+
+

A client.key will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM             42 ca.srl
+-a----        11/10/1775   6:00 PM            232 client.key
+-a----        11/10/1775   6:00 PM            820 server.crt
+-a----        11/10/1775   6:00 PM            382 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

Next, generate the client certificate signing request.

+
openssl req -new -sha256 -key client.key -out client.csr
+
+

You will be prompted to enter in certificate details. Here is an example:

+
You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:US
+State or Province Name (full name) [Some-State]:CA
+Locality Name (eg, city) []:Los Angeles
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Acme Corporation
+Organizational Unit Name (eg, section) []:Dev
+Common Name (e.g. server FQDN or YOUR name) []:Wile E. Coyote
+Email Address []:wile@acmecorp.com
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:badpassword
+An optional company name []:Acme Corporation
+
+

A client.csr will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM             42 ca.srl
+-a----        11/10/1775   6:00 PM            626 client.csr
+-a----        11/10/1775   6:00 PM            232 client.key
+-a----        11/10/1775   6:00 PM            820 server.crt
+-a----        11/10/1775   6:00 PM            626 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

Next, generate the client certificate.

+
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 1000 -sha256
+
+

Something similar to this will be outputted:

+
Signature ok
+subject=C = US, ST = CA, L = Los Angeles, O = Acme Corporation, OU = Dev, CN = Wile E. Coyote, emailAddress = wile@acmecorp.com
+Getting CA Private Key
+
+

A client.crt will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM             42 ca.srl
+-a----        11/10/1775   6:00 PM            816 client.crt
+-a----        11/10/1775   6:00 PM            626 client.csr
+-a----        11/10/1775   6:00 PM            232 client.key
+-a----        11/10/1775   6:00 PM            820 server.crt
+-a----        11/10/1775   6:00 PM            626 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

7. Make sure you have JRE installed

+

For example, install JRE8 if you do not have it installed:

+
choco install jre8
+
+

8. Add the JRE bin folder to the PATH

+

Go into the Java folder:

+
cd "C:\Program Files\Java\"
+
+

Find the JRE folder:

+
dir
+
+

which will output something like:

+
    Directory: C:\Program Files\Java
+
+
+Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+d-----        11/10/1775   6:00 PM                jre1.8.0_311
+
+

Go into the JRE folder:

+
+

Note

+

Your JRE may be a different version**

+
+
cd jre1.8.0_311
+
+

Go into the bin directory:

+
cd bin
+
+

Output the absolute path of this directory:

+
pwd
+
+

which will output out something like:

+
Path
+----
+C:\Program Files\Java\jre1.8.0_311\bin
+
+

Add this directory to the PATH:

+
$env:Path += ";C:\Program Files\Java\jre1.8.0_311\bin"
+
+

Now go back to your .certs folder:

+
cd ~\.certs\
+
+

9. Generate the keystore

+

Enter this command to generate the keystore:

+
keytool -genkey -v -keystore fts.keystore -alias fts -storetype PKCS12 -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 10000
+
+

You will be prompted to enter in keystore details. Here is an example:

+
Enter keystore password:  badpassword
+Re-enter new password:   badpassword
+What is your first and last name?
+  [Unknown]:  Wile Coyote
+What is the name of your organizational unit?
+  [Unknown]:  Dev
+What is the name of your organization?
+  [Unknown]:  Acme Corporation
+What is the name of your City or Locality?
+  [Unknown]:  Los Angeles
+What is the name of your State or Province?
+  [Unknown]:  CA
+What is the two-letter country code for this unit?
+  [Unknown]:  US
+Is CN=test client, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=US correct?
+  [no]:  yes
+
+

Something similar to this will be outputted:

+
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
+        for: CN=Wile Coyote, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=CA
+
+

An fts.keystore will be outputted to the directory:

+
Mode                 LastWriteTime         Length Name
+----                 -------------         ------ ----
+-a----        11/10/1775   6:00 PM            944 ca.crt
+-a----        11/10/1775   6:00 PM            232 ca.key
+-a----        11/10/1775   6:00 PM             42 ca.srl
+-a----        11/10/1775   6:00 PM            816 client.crt
+-a----        11/10/1775   6:00 PM            626 client.csr
+-a----        11/10/1775   6:00 PM            232 client.key
+-a----        11/10/1775   6:00 PM           4019 fts.keystore
+-a----        11/10/1775   6:00 PM            820 server.crt
+-a----        11/10/1775   6:00 PM            626 server.csr
+-a----        11/10/1775   6:00 PM            232 server.key
+
+

10. Add server.crt and client.crt certificates to the keystore

+

Add the server.crt to the keystore:

+
keytool -import -file server.crt -alias server -keystore fts.keystore
+
+

You will be prompted to enter in details. Here is an example:

+
Enter keystore password:  badpassword
+Owner: EMAILADDRESS=wile@acmecorp.com, CN=Wile E. Coyote, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=US
+Issuer: EMAILADDRESS=wile@acmecorp.com, CN=Wile E. Coyote, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=US
+Serial number: 1667f79b550a2605c2fc04de3da4e3a63f921e99
+Valid from: Fri Jan 07 04:21:32 EST 2022 until: Thu Oct 03 05:21:32 EDT 2024
+Certificate fingerprints:
+         SHA1: 7A:2C:F4:58:6C:3E:CB:C3:C5:FA:F8:2C:74:8E:E2:9B:58:75:B2:D0
+         SHA256: 14:6F:7E:04:C6:25:69:83:55:21:9F:99:17:9C:AE:28:7C:CF:74:20:C5:60:FD:36:2F:57:68:68:30:FE:D8:EB
+Signature algorithm name: SHA256withECDSA
+Subject Public Key Algorithm: 256-bit EC key
+Version: 1
+Trust this certificate? [no]:  yes
+Certificate was added to keystore
+
+

Add the client.crt to the keystore:

+
keytool -import -file client.crt -alias client -keystore fts.keystore
+
+

You will be prompted to enter in details. Here is an example:

+
Enter keystore password:  badpassword
+Owner: EMAILADDRESS=wile@acmecorp.com, CN=Wile E. Coyote, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=US
+Issuer: EMAILADDRESS=wile@acmecorp.com, CN=Wile E. Coyote, OU=Dev, O=Acme Corporation, L=Los Angeles, ST=CA, C=US
+Serial number: 1667f79b550a2605c2fc04de3da4e3a63f921e9a
+Valid from: Fri Jan 07 04:24:30 EST 2022 until: Thu Oct 03 05:24:30 EDT 2024
+Certificate fingerprints:
+         SHA1: AA:09:6D:16:13:CD:45:AD:41:45:99:7D:39:C3:55:11:AC:BC:F5:28
+         SHA256: 46:75:A7:59:80:8D:CE:52:78:DD:7D:B9:17:90:BE:A9:6C:9E:33:F3:44:84:1C:21:74:59:54:08:D5:28:AC:92
+Signature algorithm name: SHA256withECDSA
+Subject Public Key Algorithm: 256-bit EC key
+Version: 1
+Trust this certificate? [no]:  yes
+Certificate was added to keystore
+
+

11. Install SSL on the client

+

ATAK

+
    +
  1. Tap settings
  2. +
  3. Manage server connections
  4. +
  5. Open network connections
  6. +
  7. Add a new connection
  8. +
  9. Assign a name and the IP of your server
  10. +
  11. Click on advanced options
  12. +
  13. Uncheck "use default SSL/TLS certificates"
  14. +
  15. Tap "import Truststore"
  16. +
  17. Select your truststore file
  18. +
  19. type the password provide to you
  20. +
  21. Tap "Import client certificate"
  22. +
  23. Select your client certificate
  24. +
  25. Type the password
  26. +
  27. Type "OK"
  28. +
+

WinTAK

+
    +
  1. Go to Settings
  2. +
  3. Network preferences
  4. +
  5. Manage Server Connections
  6. +
  7. Add Stream
  8. +
  9. Assign a Description, IP and port of your server
  10. +
  11. Select SSL as a protocol
  12. +
  13. Uncheck "use default SSL/TLS certificates"
  14. +
  15. Click "install Certificate Authority"
  16. +
  17. Select your Certificate Authority file
  18. +
  19. Type the password provide to you
  20. +
  21. Click "Install client certificate"
  22. +
  23. Select your client certificate
  24. +
  25. Type the password
  26. +
  27. Click "OK"
  28. +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/Web_Admin/index.html b/administration/Web_Admin/index.html new file mode 100644 index 000000000..2cf70e32d --- /dev/null +++ b/administration/Web_Admin/index.html @@ -0,0 +1,4175 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Administration Manual WebUI

+

FTS has a web UI since version 1.5.

+

Please download the web UI manual here

+

FreeTAK Server User Manual

+

FTS V. 2.x

+

Nov 2023

+

Release

+
    +
  1. +

    Introduction

    +
  2. +
+

Welcome to the user manual for the FreeTAKServer (FTS) Web User interface (webUI)!

+

FreeTAKServer, as of Release 1.9, provides Situational Awareness and other capabilities such as:

+
    +
  • Web administration
  • +
  • Federation Service (Connecting two or more FTS instances)
  • +
  • Data Package upload and retrieval
  • +
  • Private data package (user to user)
  • +
  • Image transfer and storage
  • +
  • CoT recording in a database
  • +
  • Execution of common task list (using the ExCheck plugin for WinTAK; ATAK plugin only available to users with https://takmaps.com access)
  • +
  • SSL Encryption
  • +
  • User Management
  • +
  • REST API for creation of information such as emergency, Enemy units and so on
  • +
+

About the Web UI

+

FTS webUI allows administrators to easily manage the server.

+

This video, based on a pre-production version, provides an overview of most features described in the manual
+https://www.youtube.com/watch?v=q4BpolzIDLw&ab_channel=%2aDA-B6%2a

+

WebUI is a completely separate application connecting to the FTS backend.

+

It uses an API to seamless query server functions. Depending on his deployment, may or may not be seen from remote machines.

+

+

Installation and configuration

+

This section provides an overview of the installation process. +Refer to the online documentation for details.

+

To install FTS and the UI type in a console. +

sudo python3 -m pip install FreeTAKServer\[ui]
+

+

Setup your Configuration

+

your administrator will need to configure the following files

+
    +
  • Config.py for the UI
  • +
  • MainConfig.py for FTS
  • +
+

Start FTS +

nohup sudo python3 -m FreeTAKServer.controllers.services.FTS
+

+

Start the WebUI +

nohup sudo python3 /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/run.py
+

+

Basics

+

Login

+

Open a browser and navigate to [webUIIP]:[PORT].

+

For example 127.0.0.1:5000

+

+

Insert the user and password created with the function "System User" (see 4.1).

+

Click login

+

The function "Don't have an account? Create" could be useful +to provide anyone with the link to the UI with the ability to create a System user. +For security purposes it’s disabled in the standard configuration and his activation should be avoided.

+

First login can be done using:

+
    +
  • Username: admin (all non capital)
  • +
  • Password: password (all non capital)
  • +
+

It’s strongly suggested to immediately create a new user and delete the generated one.

+
+

1.0 Navigation

+

To the Left of the main screen, there is a menu with 6 sub menus. +These are: Home, Mission, User, Connect, Configure and About.

+

+

Each of these is linked to a different screen with specific information to be seen and edited. The current section is highlighted with a blue dot

+
    +
  • Home: System status
  • +
  • WebMap: a web client displaying all is sent to your FTS server
  • +
  • Mission: Data Packages and other files
  • +
  • User: UI users and groups configuration
  • +
  • Connect: send CoTs and system messages
  • +
  • Configure: Services and federated servers
  • +
  • About: FTS and web UI version and special thanks
  • +
+

1.1 Top Navigation Bar

+

+

The Events button is currently inactive. It provides a list of the last 5 events.

+

The user button allow to log out or to edit the current user Profile

+

1.2 Profile Screen

+

+

Use this screen to change the current login user password, token and group.

+

2.0 Home

+

Here the main information about FTS can be visualized. +This information is periodically updated from the server. +You can change this period in the UI configuration [UIInstallation]/UI/app/__init__.py.

+

. Default, expressed in milliseconds are

+
    +
  • USER INTERVAL= '180000'
  • +
  • SERVER HEALTH INTERVAL = '180000'
  • +
  • SYS STATUS INTERVAL = '600000'
  • +
+

2.1 System Status

+

+

The status of FTS services is visualized as a series (6) of rotating concentric circles. +The information is color coded:

+
    +
  • Blue: Service is running and activated
  • +
  • Red: Service is activated but not running (screenshot)
  • +
  • Gray: Service is turned off (See 5.1 System Configuration)
  • +
+

2.2 Run Time & connected clients

+

+

This section shows the start and current run time of the FTS, and the number of connected clients. +The start time is provided by the server, so if you are in a different time zone you may see negative uptimes.

+

2.3 System Health

+

+

In this section the % resources required by the server +are displayed as its consumption of CPU, RAM, and Disk. +The gauge shows both numerical (RAM: 32) and visual (circle ~⅓ full) values.

+

2.4 Logs

+

+

Last Errors and other log messages will appear here

+

3.0 WebMap

+

Since FTS 1.8, the UI has a Tab to a webMap. The webmap is a separate component, +part of the FreeTAKHub concept (seehttps://github.com/FreeTAKTeam/FreeTAKHub for more details)

+

+

The webmap is a partial TAK client only. +It displays all the connected clients and the CoT sent from the moment in which it connects. +Clicking on another tab closes the webmap, no memory of past events is kept.

+

3.1 Webmap Special functions

+

Following functions are also available:

+
    +
  • Zoom in and out
  • +
  • +

    Measure distances and bearing
    +

    +
  • +
  • +

    Import KML

    +
  • +
  • +

    Drag and drop a valid KML into the map to display it (server only, not shared with clients)

    +
  • +
+

+
    +
  • +

    Add markers to the map (right click) and send to all the connected clients
    +

    +
  • +
  • +

    Attitude: the attitude of the target toward the users, reflected in the color

    +
  • +
  • Type: Basic infantry types are supported
  • +
  • Timeout: time before the markers disappears in seconds
  • +
  • +

    Name: unique name of the marker, if the same name is re-used, it will move an existing marker

    +
  • +
  • +

    Delete an existing Marker
    +

    +
  • +
  • Search CoT by name
    +
  • +
  • Search geolocation
    +
  • +
  • Select different map styles
  • +
+

+
    +
  • Filter CoT's by type (each CoT type is placed in a layer)
  • +
+

+

4.0 Mission

+

A multipurpose section with a broad role in managing data and files

+

4.1 Data Packages

+

+

From here one can see, add, download, delete and hide available data packages.

+
    +
  • Add: By pressing on the three dots in the bottom right of the menu, a dialogue will appear with your file explorer. Select the Zip file meant for upload and click on "open". The dialogue will close. Now click on "add" (next to "delete" at the bottom left) and the file will be uploaded as a data package.
  • +
+

The default maximum size for a Data Package is 15 MB. +You can change this size in the UI configuration [UIInstallation]/UI/app/__init__.py.

+
    +
  • Download to local drive: Simply click on the data package name in blue. The file will be downloaded to your "downloads" folder
  • +
  • Delete: This can be done by selecting the undesired data packages (click anywhere except the blue name), the delete button will change to indicate the # of selected rows. Click "delete" (bottom left)
  • +
  • Index: the unique index number of the Data Package in the DB
  • +
  • Hide: The fourth information column from the right is labeled as "is private". This function allows you to hide data packages from ATAK / WinTAK users simply by checking the box in this column. All private data packages, exchanged between clients, are listed as private
  • +
  • QR code:opens a special image that contains the URL of the DP package. Useful to share certifications (see System Users).Notice, the QR code will appear in a new windows, check out your Adblock or similar tools to ensure that the message is not blocked
  • +
+

4.2 Mission / Data Sync

+

+

For future development,currently non-functional. +Will allow users to share data packages, CoTs and ExCheck lists with others, organized in "missions". +Still under development as of this version of FTS (V 1.9).

+

4.3 ExCheck

+

ExCheck allows users to collaborate on the execution and monitoring of tasks based on templates. +To use ExCheck, you need to have a server that supports it. +FTS supports the plugin since version 1.3. +See this article for an example of how to use it:
+https://www.reddit.com/r/ATAK/comments/jzltvt/use_freetakserver_and_excheck_plugin_to/

+

+

Allows you to see, add and delete ExCheck templates.

+
    +
  • Add: Add: By pressing on the three dots in the bottom right of the menu, a dialogue of your file explorer will appear. Select the file meant for upload and click on "open". The dialogue will close. Now click on "add" (next to "delete" at the bottom left) and the file will be uploaded as a data package.
  • +
+

The uploaded template must be valid in an XML format.

+
    +
  • Delete: This can be done by selecting the undesired data packages, and then clicking on "delete" (bottom left)
  • +
+

4.4 Federation

+

The federation function allows FTS to connect to another server +of the TAK family and exchange information such as CoT and chats. +The current implementation (1.9) does not allow sending Data packages and Missions yet.

+

4.4.1 Federating to a legacy TAK server

+

To set up a federated connection with another server +you need to upload the certificate authority to the target server.

+

Under the certs directory there's a file called pubserver.pem containing your server public certificate. +Download this file, rename it to something easy to remember like FTS204.134.0.60.pem +and upload it to the Legacy TAK server you want to federate to.

+

4.4.2 Federating to a FTS server

+
    +
  • On the federated server: Activate the Federation service under Configure/system configuration
  • +
  • On the federated client: Simply create the connection to the federated server as described below
  • +
+

+

Here one can see the status of federated servers the current instance connects to, +as well as deleting, editing and adding news ones.

+
    +
  • Add: Pressing the "Add" button will open an extension of the window. + In the correct slots, fill out the pertinent information (Name, IP Address, and Port). + Additionally, you can add a fallback (backup) server, by enabling or disabling the option. In the current version (1.5 this is not yet active) Press submit once finished.
  • +
+

In the event the status remains disabled it is likely there was an error in the creation of your federation, + the associated error message can be found in the farthest right most column of your federation + (you may need to scroll to the right to see it).

+

+
    +
  • Editing: When selecting the desired server, a new button labeled "editing" will appear next to "delete" (bottom right of panel). + Pressing this will enter the information of the selected server in the otherwise blank fields. + Information can now be edited to desired values.
  • +
  • Delete: This can be done by selecting the undesired federation and then clicking on "delete" (bottom right)
  • +
+

5.0 User

+

Allows the user to add or delete System Users and edit user group permissions.

+

5.1 System users

+

This panel shows all the registered users of the UI and allows the user to add and delete users. +A System User, other than an anonymous one is associated with a group, a Token for API, +a password that can be used to log in into the ui and finally certificates allowing to securely connect to FTS

+

+
    +
  • +

    Add: This can be done by clicking on the "add" button (bottom right of panel). + An extension will appear, with empty fields for the new user’s name, group, token and password.

    +
  • +
  • +

    Name: name of the created user. For the certs deployment to work must be the same as a connected user (see below)

    +
  • +
  • +

    Group: group of individuals this user belong to (team a, team b, team c)

    +
  • +
  • +

    Token: gives a unique combination that this user can leverage for the FTS REST API. + NOTICE: the field token is for any alphanumeric string. the prefix 'bearer' is NOT part of the token. + The name "Bearer authentication" can be understood as "give access to the bearer of this token."

    +
  • +
  • +

    Password: unique password that can be used for interact with the FTS

    +
  • +
  • +

    Certs: true/false. If true certs will be generated (see below)
    + When creating a user In the UI, you will find a new flag. + By selecting "mobile" you will generate and push a certificate that should work with:

    +
      +
    • ATAK
    • +
    • iTAK
    • +
    • TAK Tracker
    • +
    +
  • +
+

in alternative selecting desktop will generate and push a certificate for WinTAK +Once the fields have been filled, simply press submit to add a new user.

+

+
    +
  • Delete: This can be done by selecting the undesired user and then clicking on "delete" (bottom right). + You can only delete one user each time. Since version 1.9 when you delete a user that has a certificate, + the certificate will be invalid.
  • +
+

5.1.1 Automate certificates creation and deployment

+

TAK clients can connect to a server using TCP or secure connection (SSL), +this requires the creation of valid certification on the server that needs to be deployed to each client.

+

FTS supports an advanced system to generate and distribute valid certification.

+

When creating a system user, by leaving "certs" on "true", +the user will automatically be notified of his new connection, +but only if he is connected to the same server at that moment.

+

FTS will:

+
    +
  • Create a system User (e.g. Joe)
  • +
  • Generate valid Certificates
  • +
  • Package the certs into a zip file with the same name of the user (e.g. Joe.zip)
  • +
  • Create a private Data Package. This can be seen in the Mission section, with the other Data Packages
  • +
  • Send the private DP automatically to a ATAK/WinTAK (or compatible client)
  • +
  • To the user with the same name (Joe)
    + The user will receive a notification of the reception
  • +
  • Under "manage server connection" a new entry with the nameFreeTAKServer_[SERVERIP] will appear.
  • +
  • The user needs to activate the connection (in WinTAK he may need to restart the software)
  • +
+
+

Since ATAK 4.6 the ability to use non-secured data packages has been disabled.

+
+

5.1.2 Alternate certificates distribution

+

If the user is not online at the moment of the certs creations, it’s possible to deploy the certifications by:

+
    +
  • Download the data package and use another type of secure transportation
  • +
  • As soon the user is online, set the certification Data Package to be public, allowing the user to download it and then changing it back to private
  • +
+

5.1.3 Deactivate Certification

+

Since FTS 1.9 it’s possible to deactivate a certification by deleting the associated user. +The next time the user tries to connect to the server using the certifications, will get anIO error.

+

5.2 Group Permissions

+

+

Future functionality, not currently active. +Allows to create and assign permission to groups. When activated, will filter what a user can receive from FTS.

+

6.0 Connect

+

A menu that can be used to create Center Of Target (CoTs) using a "Human API" and send system messages to FTS users. +This is a User interface to some of the FTS Public UI +(see https://freetakteam.github.io/FreeTAKServer-User-Docs/API/REST_API_Doc.html for complete description of the API)

+

6.1 Send CoT

+

Can be used to create a CoT (also called a geoObject)

+

+

fill out the fields with the desired values.

+
    +
  • Name: geoObject name that will display on map
  • +
  • Longitude/Latitude: Determines where the object will appear
  • +
  • Attitude: Sets the colour and external shape (and thus faction) of the geoObject based on MIL-STD-2525D
  • +
  • GeoObject: Changes the shape and type of the object (ex: sniper, grenadier)
  • +
  • Timeout: The length of time the object appears, measured in seconds
  • +
+

6.2 Emergency

+

Allows to see, delete and create new emergencies on the server

+

+
    +
  • Delete: This can be done by selecting the undesired data packages and then clicking on "delete" (bottom right)
  • +
  • Add: Start by clicking the "add" button at bottom right. An extension of the panel will appear. Simply fill out the pertinent information (name, location in longitude/latitude, type of emergency). Press "send" once finished
  • +
+

+

6.3 Manage Presence

+

Using this function, the user can create a custom team member (friendly Dot) on the ATAK map, +who will however appear like a real TAK user.

+

+

To create a new member simply fill out the fields with the proper information. +Once finished, press "send" (bottom right of panel).

+

6.4 Message

+

This function allows users to send system messages to all connected TAK clients.

+

+

To send a message it suffices to enter the message in the top field, +and then specify the sender name in the field marked "sender". +Once finished, press "Send".

+

7.0 Configure

+

Used to configure services and federated servers.

+

7.1 System Configuration

+

Here the services can be turned on and off and a port can be assigned to the service.

+

The Data Package IP is initially determined by the starting parameter of FTS. +

sudo python3 -m FreeTAKServer.controllers.services.FTS -DataPackageIP 204.48.30.216 -AutoStart True
+

+

FTS supports following services:

+
    +
  • TCP CoT: used when a client connects with regular TCP
  • +
  • SSL CoT: used when a client connects with an encrypted channel
  • +
  • HTTP DP: Data package function over HTTP
  • +
  • SSL DP: Data package function over an encrypted channel
  • +
  • API: the Public REST API. Allows to send data over REST for integration with other systems. If deactivated some function of the WebUI will not work
  • +
  • FED: Federation function, allow to create outgoing connections to other TAK servers
  • +
+

+

To turn a service on and off:

+
    +
  • click on the slider of the desired service
  • +
  • Click ‘apply’
  • +
+

To change a service port:

+
    +
  • Move the slider to stop the service
  • +
  • Click ‘apply’
  • +
  • Change value of the port
  • +
  • Click ‘apply’
  • +
  • Reactivate the service by moving the slider
  • +
  • Click ‘apply’
  • +
+

7.2 Outgoing Federations

+

See 4.4 Federations.

+

+

8.0 About

+

FTS and UI version notes and special thanks

+

+

7.1 About FTS

+

A description of the software

+

7.2 FTS and UI version

+

Current running version and IP, important when reporting bugs

+

7.3 Credits

+

A list of individuals and organization that have contributed to FTS

+

7.4 Open Source Note

+

A list of libraries and other projects being used

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/Integration/NodeRedInstallation/index.html b/administration/brokered/Integration/NodeRedInstallation/index.html new file mode 100644 index 000000000..5039248e5 --- /dev/null +++ b/administration/brokered/Integration/NodeRedInstallation/index.html @@ -0,0 +1,3937 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAKHub Node-RED

+

This document describes how to install and secure Node-RED.

+
    +
  • Install Using Script (simple)
  • +
  • Install using APT (advanced Users)
  • +
  • Secure Node-RED
  • +
+

Install Using Script (simple)

+

The following script will do Installing and Upgrading Node-RED +to install Node.js, npm, and Node-RED onto an Ubuntu Raspberry Pi. +The script can also be used to upgrade an existing install when a new release is available.

+

Running the following command will download and run the script. +If you want to review the contents of the script first, you can view it on Github. +

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
+

+

Enable service so that starts automagically: +

sudo systemctl enable nodered.service
+
+Run the Node-RED service: +
node-red-start
+
+Navigate to your Node-RED:

+

http://localhost:1880

+

Install Using APT (advanced users)

+

To install Node-RED with APT you will need to:

+
    +
  • Satisfy the requirements
  • +
  • Create a Non-root user
  • +
  • Install Node JS
  • +
+

Prerequisites

+

This guide assumes that you are using Ubuntu 22.04 on cloud installation (we use digital Ocean).

+

Create a Non-root user

+

First create a special user and dedicated group:

+
sudo useradd -m nodered -G nodered
+
+

Install Node JS

+

you can use the apt package manager. Refresh your local package index first by typing:

+
sudo apt update
+
+

Then install Node.js:

+
sudo apt install nodejs
+
+

Check that the installation was successful by querying node for its version number: +

node -v
+
+Output something like this +
v10.19.0
+

+

If the package in the repositories suits your needs, +this is all you need to do to get set up with Node.js. +In most cases, you’ll also want to also install npm, the Node.js package manager. +You can do this by installing the npm package with apt: +

sudo apt install npm
+
+This will allow you to install modules and packages to use with Node.js.

+

Install Node-RED

+

Use npm to install node-red and a helper utility called node-red-admin.

+
sudo npm install -g --unsafe-perm node-red node-red-admin
+
+

npm normally installs its packages into your current directory. +Here, we use the -g flag to install packages 'globally' so they’re placed in standard system locations such as /usr/local/bin. +The --unsafe-perm flag helps us avoid some errors that can pop up when npm tries to compile native modules +(modules written in a compiled language such as C or C++ vs. JavaScript).

+

After a bit of downloading and file shuffling, +you’ll be returned to the normal command line prompt. +Let’s test our installation.

+

First, we’ll need to open up a port on our firewall. +Node-RED defaults to using port 1880, so let’s allow that. +

sudo ufw allow 1880
+
+And now launch Node-RED itself. +No sudo is necessary, as port 1880 is high enough to not require root privileges.

+
node-red
+
+

Create the Service

+

In order to start Node-RED automatically on startup, +we will need to install a /etc/systemd/system/node-red.service file: +

Description=Node-RED
+After=syslog.target network.target
+
+[Service]
+ExecStart=/usr/local/bin/node-red-pi --max-old-space-size=128 -v
+Restart=on-failure
+KillSignal=SIGINT
+
+# log output to syslog as 'node-red'
+SyslogIdentifier=node-red
+StandardOutput=syslog
+
+# non-root user to run as
+WorkingDirectory=/home/nodered/
+User=nodered
+Group=nodered
+
+[Install]
+WantedBy=multi-user.target
+

+

Now that our service file is installed , we need to enable it. This will enable it to execute on startup. +

sudo systemctl enable node-red
+

+

Let’s manually start the service now to test that it’s still working. +

sudo systemctl start node-red
+
+To shut it back down you can use:

+
sudo systemctl stop node-red
+
+

Test Your Installation

+

Point a browser back at the server’s port 1880 and verify that Node-RED is back up. +e.g. if your server is installed under the IP 143.198.39.135

+

http://143.198.39.135:1880/

+

You will see the welcome screen of Node-RED with the tutorial. +Now, to install the flows, click on the hamburger menu and then import:

+

image

+

Download one of the FreeTAKHub integrations (json files). +Import into your Node-RED.

+

Resolve any conflicts by importing additional nodes into your palette.

+

You can find "Manage palette" from top right corner, "setting" > "Manage palette"

+

Image 089

+

By clicking "Manage palette" a "User setting" page will pop up.

+

go to "Palette" > "install" tab and type "node-red-contrib-config" in the search bar

+

Image 090

+

Success!!!!

+

image

+

Secure Node-RED

+

By default, Node-RED is installed with no authentication to the user interface (UI), also called the "Editor". +This means that anyone with your IP address can make changes to any of your flows, +or even add malicious flows to your Node-RED instance. +Once your Node-RED instance is up-and-running, +you should immediately secure the editor with a password, at a minimum.

+

The following will get you started on securing the Node-RED editor with a password.
+For more details on how to secure Node-RED, see the Node-RED docs here: +https://nodered.org/docs/user-guide/runtime/securing-node-red

+

Switch to the Node-RED folder: +

cd ~/.node-red
+

+

Edit the settings.js file:

+
sudo nano settings.js
+
+

Uncomment the adminAuth section to password protect Node-RED editor and admin API. +See https://nodered.org/docs/security.html for details. +

adminAuth: {
+    type: "credentials", 
+    users: [{
+        username: "admin",
+        password: ".....",
+        permissions: "*"
+    }]
+}
+
+save the file and Exit.

+
CTRL+o
+ENTER
+CRTL+X
+
+

You can now log in to your Node-RED editor [YOUR-IP-ADDRESS]:1880. +The default username is admin, and the default password is password. +This isn't enough.
+You'll want to create a unique password, which will require creating a password hash.

+

This is detailed in the Node-RED docs here: +https://nodered.org/docs/user-guide/runtime/securing-node-red#editor--admin-api-security

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/Integration/node-red.service b/administration/brokered/Integration/node-red.service new file mode 100644 index 000000000..55de55c3d --- /dev/null +++ b/administration/brokered/Integration/node-red.service @@ -0,0 +1,19 @@ +Description=Node-RED +After=syslog.target network.target + +[Service] +ExecStart=/usr/local/bin/node-red-pi --max-old-space-size=128 -v +Restart=on-failure +KillSignal=SIGINT + +# log output to syslog as 'node-red' +SyslogIdentifier=node-red +StandardOutput=syslog + +# non-root user to run as +WorkingDirectory=/home/nodered/ +User=nodered +Group=nodered + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/administration/brokered/Video/Installation/index.html b/administration/brokered/Video/Installation/index.html new file mode 100644 index 000000000..fb104db08 --- /dev/null +++ b/administration/brokered/Video/Installation/index.html @@ -0,0 +1,3822 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Video Server

+

MediaMTX is a RTSP / RTPM capable software to stream in real time from / to TAK devices. +It is used with the FreeTAK UAS and TAK ICU

+

Installation

+

Get the linux_amd64 installation package link from the release page +image

+

Download the MediaMTX release: +

wget https://github.com/aler9/mediamtx/releases/download/v0.22.2/mediamtx_v0.22.2_linux_amd64.tar.gz
+

+

Un-tar the package: +

tar -zxvf mediamtx_v0.22.2_linux_amd64.tar.gz
+

+

Edit the YAML file +image

+
    +
  • Enable API by setting yes
  • +
  • Support protocols only TCP
  • +
  • Set the API address 0.0.0.0
  • +
+

image

+

Configure to start as a service

+

To start the video server as a system daemon, we will create a systemd unit file. +The systemd framework is the service manager used by Ubuntu, Debian and many other Linux distributions. +By creating a unit file to manage the daemon, +systemd will ensure the service is started with the OS and stays healthy.

+

Move the executable:

+

sudo mv mediamtx /usr/local/bin/
+
+Move the configuration file: +
sudo mv mediamtx.yml /usr/local/etc/
+

+

Create the Unit File. +Copy this complete text to /etc/systemd/system/mediamtx.service: +

[Unit]
+Description=mediamtx
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml
+
+[Install]
+WantedBy=multi-user.target
+

+

Start the service: +

sudo systemctl start mediamtx.service
+

+

Enable the service: +

sudo systemctl enable mediamtx.service
+

+

Test your video Installation

+

in a browser resolve and use this address

+

<http://<YOURSERVERIP>:9997/v1/config/get>

+

if you see your configuration the server is up and running

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/Video/howtoStartOnPi/index.html b/administration/brokered/Video/howtoStartOnPi/index.html new file mode 100644 index 000000000..fc2abf278 --- /dev/null +++ b/administration/brokered/Video/howtoStartOnPi/index.html @@ -0,0 +1,3808 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

How to autostart the video server on the Pi

+

Hardware: Raspberry Pi 4b- 8g
+OS: Ubuntu Server 22.04 lts
+Program: mediamtx

+

When trying to accomplish Auto start on system startup/reboot,

+

Solution: +For the mediamtx.service file, you will need to add and edit the following: +

[Unit]
+Description=mediamtx
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml
+
+[Install]
+WantedBy=multi-user.target
+

+

To build the auto start file, the Solution: +The root user is needed +sudo -i

+

Build your file: +

crontab -e 
+
+(if this is new, select 1 when prompted)

+

at the end of the file add the 3 @ lines +

@reboot sudo systemctl enable mediamtx.service &
+@reboot sudo systemctl stop mediamtx.service &
+@reboot nohup sudo mediamtx.service &
+

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/Video/mediamtx.service b/administration/brokered/Video/mediamtx.service new file mode 100644 index 000000000..17af8d525 --- /dev/null +++ b/administration/brokered/Video/mediamtx.service @@ -0,0 +1,10 @@ +[Unit] +Description=mediamtx +After=network-online.target +Wants=network-online.target + +[Service] +ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/administration/brokered/VideoChecker/VideoCheck/index.html b/administration/brokered/VideoChecker/VideoCheck/index.html new file mode 100644 index 000000000..3cf5b7128 --- /dev/null +++ b/administration/brokered/VideoChecker/VideoCheck/index.html @@ -0,0 +1,3863 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Video Checker

+

The VideoChecker allows a video stream to be published to all the connected clients. +It's used with TAK ICU, but any type of client can be also used.

+

Requirements

+
    +
  • FTS 1.8+
  • +
  • Video Service
  • +
  • NodeRed
  • +
+

Installation

+
    +
  • Download the video checker NodeRed flow from GitHub
  • +
  • open your node red installation at <YOURIP>:1880
  • +
  • +

    Import into NodeRed the VideoChecker flow (you may already have it installed by the ZeroTouch ) + image

    +
  • +
  • +

    open the config node

    +
  • +
+

image

+
    +
  • Set up the EXTERNAL IP of the video server
  • +
+

image

+
    +
  • in the same node set the IP of FTS (probably the same as the video Server)
  • +
  • +

    open the "Post Video to FTS" node

    +
  • +
  • +

    image

    +
  • +
  • +

    insert a valid API token

    +
  • +
+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/Voice/VoiceServer/index.html b/administration/brokered/Voice/VoiceServer/index.html new file mode 100644 index 000000000..62e26aac1 --- /dev/null +++ b/administration/brokered/Voice/VoiceServer/index.html @@ -0,0 +1,3953 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

FreeTAKHub Voice installation

+

the FTH Voice server is based on Mumble +to install it manually: +* open a console terminal +* Do some cleaning +

sudo apt-get update
+sudo apt-get upgrade
+
+* If asked to confirm installing any packages; then, type Y and press Enter.

+
    +
  • Now Install Mumble Server. +
    sudo apt-get install mumble-server
    +
  • +
+

as soon it is started you may want to configure it +

sudo dpkg-reconfigure mumble-server
+

+

You can use your arrow keys to select your answer, then press Enter to continue.

+

image

+

you will accept the default value of Yes because we want Mumble-Server to run when the server boots.

+

image

+

Even if this will be a dedicated Mumble-Server, +now select Yes since this will ensure the lowest possible latency.

+

Mumble SuperUser Password

+

SuperUser is the highest-level administrative account for the server. +You will need to log in to Mumble with this user when you want to manage the server.

+

image

+

Type a password, press Tab to select Ok, and press Enter.

+

Configuring Certificates

+

To create a self-signed cert that is fulfils all requirements for the TAK Voice Plugin, you can run the following command: +

openssl req -x509 -sha256 -nodes -days 1080 -newkey rsa:2048 -keyout (servername).key -out (servername).cer -subj '/CN=(IP Address)' -addext extendedKeyUsage=1.3.6.1.5.5.7.3.1
+
+This OpenSSL command is used to create a self-signed X.509 certificate along with a new private key. Here's a breakdown of each part of the command:

+
    +
  • openssl req: Invokes the OpenSSL utility to generate a new X.509 certificate signing request (CSR). However, in this context, combined with -x509, it's used to create a self-signed certificate instead of just a CSR.
  • +
  • x509: This option specifies that a self-signed certificate is to be generated instead of a certificate request.
  • +
  • sha256: Specifies the hashing algorithm for signing the certificate. SHA-256 is a secure hashing algorithm, making the certificate more secure.
  • +
  • nodes: Stands for "no DES". This option specifies that the private key should not be encrypted with a passphrase, allowing applications to use the key without manual intervention.
  • +
  • days 1080: Sets the validity of the certificate to 1080 days from the issue date.
  • +
  • newkey rsa:2048: Generates a new RSA private key of 2048 bits. This is a good default for secure communications.
  • +
  • keyout ftsmurmur.key: Specifies the filename to save the newly created private key to, named ftsmurmur.key.
  • +
  • out ftsmurmur.cer: Specifies the filename to save the newly created certificate to, named ftsmurmur.cer.
  • +
  • subj '/CN=(IP Address)': Sets the subject of the certificate. In this case, it sets the Common Name (CN) to an IP address e.g. 117.154.131.250. Commonly, the CN is a domain name for SSL certificates, but an IP address can be used for specific purposes.
  • +
  • addext extendedKeyUsage=1.3.6.1.5.5.7.3.1: Adds an extension to the certificate for extended key usage. The specified Object Identifier (OID) 1.3.6.1.5.5.7.3.1 corresponds to TLS Web Server Authentication, indicating that the certificate is intended for use as a TLS/SSL server certificate.
  • +
+

for example if your IP is 117.154.131.250 and registerName is 'ftsmurmur' +

openssl req -x509 -sha256 -nodes -days 1080 -newkey rsa:2048 -keyout ftsmurmur.key -out ftsmurmur.cer -subj '/CN=117.154.131.250' -addext extendedKeyUsage=1.3.6.1.5.5.7.3.1
+

+

OPTIONAL: Use the voice Tak plugin

+

In order to ensure the security of your Mumble Server connection TLS is utilised. +The TAK Voice Plugin will only connect to Mumble Servers whose server certificate is trusted and contains the full certificate chain as the whole chain is validated. +if you want to use the plugin you must create a certificate for local CA. +On the server, where the certs were created type: +

openssl x509 -in ftsmurmur.cer -outform der -out ftsmurmur.der
+

+

Transfer the Certificate to Your Android Device

+

Connect your device to your computer via USB, email the certificate to an account accessible from your device, or use a cloud storage service to transfer the ftsmurmur.der file to your Android device.

+

Install the Certificate on your device

+

tested for For Android Nougat (7.0) and above

+
    +
  • Go to Settings > Security & location > Encryption & credentials (the exact path might vary).
  • +
  • Tap Install a certificate > CA certificate.
  • +
  • Navigate to the location where you saved the certificate file on your device.
  • +
  • Select the certificate file to be installed (e.g. ftsmurmur.der). You might need to change the file type to "All files" or similar to see the DER file.
  • +
+

Init configuration

+

you will need to edit some configuration files.

+

Using WinSCP navigate to +

/etc/mumble-server.ini
+

+

In general, you want to set the following values: +

; Port to bind TCP and UDP sockets to you can leave the standard.
+port=64738
+; Password to join server.
+serverpassword=
+;Welcome message sent to clients when they connect.
+welcometext= "<br />Welcome to this server running <b>FTH Voice</b>.<br />the Parrot is not dead!<br />"
+bandwidth=
+; the maximum users allowed on the server
+users=
+registerName=ftsmurmur
+; If you have generated a proper SSL certificate using the instructions above, you can provide the filenames here.
+; Otherwise, Murmur will create its own certificate automatically.
+sslCert=/opt/ftsmurmur.cer
+sslKey=/opt/ftsmurmur.key
+
+examine the complete file for more settings.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/WebMap/Installation/index.html b/administration/brokered/WebMap/Installation/index.html new file mode 100644 index 000000000..7ea786d9e --- /dev/null +++ b/administration/brokered/WebMap/Installation/index.html @@ -0,0 +1,3966 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

About webmap

+

The webmap provides insights of user presence and CoT's shared with everyone. +Also in his NodeRed version can create certain types of CoT.

+

There are 2 versions of the webmap:

+
    +
  1. webMap NodeRed Flow version
  2. +
  3. webMap Compiled version
  4. +
+

webMap NodeRed Flow version

+

the webmap Flow works with all systems that supports Nodered. +Advanced users should use this version.

+

Installation

+

get the webmap.json the last release:

+

https://github.com/FreeTAKTeam/FreeTAKHub-Webmap/releases

+

import the flow into node red

+

image

+

in the FTS UI edit the file config.py +changing the lines: +

# webmap IP
+WEBMAPIP = "[YOURIP]"
+
+# webmap port
+WEBMAPPORT = *1880*
+

+

manage palette

+

image

+

install/update the required nodes

+

image

+

Compiled version

+

The compiled version of the webmap work only with AMD64 CPU. +Can be installed with the ZeroTouch installer +or manually following the instructions below.

+

## NOTICE +the webmap is not a background app; +so, it needs to remain open to receive information and will not persist it; +so, to test ensure that you have connected users and do not switch to other tabs.

+

Installation

+

get the link of the last release:

+

https://github.com/FreeTAKTeam/FreeTAKHub/releases/download/v0.2.5/FTH-webmap-linux-0.2.5.zip

+

login to your server and go to the opt folder

+
cd /opt
+
+

the console type

+

wget https://github.com/FreeTAKTeam/FreeTAKHub/releases/download/v0.2.5/FTH-webmap-linux-0.2.5.zip
+
+to download the zip file

+

image

+

install Unzip +

sudo apt install unzip
+

+

unzip the package +

unzip FTH-webmap-linux-0.2.5.zip
+

+

make the file an executable +

sudo chmod +x FTH-webmap-linux-0.2.5
+
+edit the config file webMAP_config.json +set FTH_FTS_URL to the IP and port of your FTS

+
"FTH_FTS_URL": "[YOUR_FTS_IP]" 
+"FTH_FTS_TCP_Port": [YOUR_FTS_PORT]
+
+

in the console type: +

./[package_name]/[PATHTOCONFIGURATIONFILE]/webMAP_config.json
+

+

e.g. if your configuration file is under opt +

./FTH-webmap-linux-0.2.5 /opt/webMAP_config.json
+

+
    +
  • navigate to your IP:8000/tak-map
  • +
  • e.g. http://10.0.2.15:8000/tak-map
  • +
+

image

+

now connect a TAK client to see if that displays +image

+

configure to start as a service

+

Systemd is the service manager used by Ubuntu, Debian and many other Linux distributions, +and allows to launch mediamtx on boot.

+

move the executable +

sudo mv FTH-webmap-linux-0.2.5 /usr/local/bin/
+

+

and configuration in the system:

+
sudo mv webMAP_config.json /usr/local/etc/
+
+

Create the service. +Copy this complete text and paste into /etc/systemd/system/webmap.service: +

[Unit]
+After=network.target
+[Service]
+ExecStart=/usr/local/bin/FTH-webmap-linux-0.2.5  /usr/local/etc/webMAP_config.json
+[Install]
+WantedBy=multi-user.target
+

+

Enable the service: +

sudo systemctl enable webMap.service
+

+

start the service +

sudo systemctl start webMap.service
+

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/administration/brokered/WebMap/webmap.service b/administration/brokered/WebMap/webmap.service new file mode 100644 index 000000000..2c64d7a0a --- /dev/null +++ b/administration/brokered/WebMap/webmap.service @@ -0,0 +1,6 @@ +[Unit] +After=network.target +[Service] +ExecStart=/usr/local/bin/FTH-webmap-linux-0.2.5 /usr/local/etc/webMAP_config.json +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/administration/usingConsole/index.html b/administration/usingConsole/index.html new file mode 100644 index 000000000..7a6431082 --- /dev/null +++ b/administration/usingConsole/index.html @@ -0,0 +1,3829 @@ + + + + + + + + + + + + + + + + + + + + + + + + FTS Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Unix Console

+

how to edit the Config Files

+

The suggested way to edit Configuration files is by using WinSCP. +However, if you need to edit files in the console you need to use vim.

+
    +
  • Open a console
  • +
  • go to cd /root/fts.venv/lib/python3.11/site-packages/FreeTAKServer-UI/app
  • +
  • type ls to see the list of files
  • +
  • type vim __init__.py
  • +
  • To go into write mode type 'i'.
  • +
  • do your edits
  • +
  • to exit from insert mode by pressing the Esc key.
  • +
  • To write a command type semicolon + and then type the command :wq! or :x! (both do the same thing)
  • +
  • hit ENTER (to save and exit).
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/assets/FTSLOGOv2.png b/assets/FTSLOGOv2.png new file mode 100644 index 000000000..66c867ff1 Binary files /dev/null and b/assets/FTSLOGOv2.png differ diff --git a/assets/FTS_Circle.png b/assets/FTS_Circle.png new file mode 100644 index 000000000..8031e1c21 Binary files /dev/null and b/assets/FTS_Circle.png differ diff --git a/assets/FreeTAKserverIcon.ico b/assets/FreeTAKserverIcon.ico new file mode 100644 index 000000000..c68886230 Binary files /dev/null and b/assets/FreeTAKserverIcon.ico differ diff --git a/assets/favicon_original.png b/assets/favicon_original.png new file mode 100644 index 000000000..9be1eaa27 Binary files /dev/null and b/assets/favicon_original.png differ diff --git a/assets/fts-official-pub.zip b/assets/fts-official-pub.zip new file mode 100644 index 000000000..05d280fff Binary files /dev/null and b/assets/fts-official-pub.zip differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 000000000..1cf13b9f9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.081f42fc.min.js b/assets/javascripts/bundle.081f42fc.min.js new file mode 100644 index 000000000..32734cd37 --- /dev/null +++ b/assets/javascripts/bundle.081f42fc.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Fi=Object.create;var gr=Object.defineProperty;var ji=Object.getOwnPropertyDescriptor;var Wi=Object.getOwnPropertyNames,Dt=Object.getOwnPropertySymbols,Ui=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty,no=Object.prototype.propertyIsEnumerable;var oo=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,R=(e,t)=>{for(var r in t||(t={}))xr.call(t,r)&&oo(e,r,t[r]);if(Dt)for(var r of Dt(t))no.call(t,r)&&oo(e,r,t[r]);return e};var io=(e,t)=>{var r={};for(var o in e)xr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Dt)for(var o of Dt(e))t.indexOf(o)<0&&no.call(e,o)&&(r[o]=e[o]);return r};var yr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Di=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Wi(t))!xr.call(e,n)&&n!==r&&gr(e,n,{get:()=>t[n],enumerable:!(o=ji(t,n))||o.enumerable});return e};var Vt=(e,t,r)=>(r=e!=null?Fi(Ui(e)):{},Di(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var ao=(e,t,r)=>new Promise((o,n)=>{var i=p=>{try{s(r.next(p))}catch(c){n(c)}},a=p=>{try{s(r.throw(p))}catch(c){n(c)}},s=p=>p.done?o(p.value):Promise.resolve(p.value).then(i,a);s((r=r.apply(e,t)).next())});var co=yr((Er,so)=>{(function(e,t){typeof Er=="object"&&typeof so!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Er,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function p(H){var mt=H.type,ze=H.tagName;return!!(ze==="INPUT"&&a[mt]&&!H.readOnly||ze==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function c(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(H){o=!1}function h(H){s(H.target)&&(o||p(H.target))&&c(H.target)}function w(H){s(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function A(H){document.visibilityState==="hidden"&&(n&&(o=!0),te())}function te(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function ie(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ie())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),te(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var Yr=yr((Rt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Rt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Rt=="object"?Rt.ClipboardJS=r():t.ClipboardJS=r()})(Rt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Ii}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(V){try{return document.execCommand(V)}catch(_){return!1}}var h=function(_){var O=f()(_);return u("cut"),O},w=h;function A(V){var _=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[_?"right":"left"]="-9999px";var j=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(j,"px"),O.setAttribute("readonly",""),O.value=V,O}var te=function(_,O){var j=A(_);O.container.appendChild(j);var D=f()(j);return u("copy"),j.remove(),D},ie=function(_){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},j="";return typeof _=="string"?j=te(_,O):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?j=te(_.value,O):(j=f()(_),u("copy")),j},J=ie;function H(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(O){return typeof O}:H=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},H(V)}var mt=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=_.action,j=O===void 0?"copy":O,D=_.container,Y=_.target,ke=_.text;if(j!=="copy"&&j!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&H(Y)==="object"&&Y.nodeType===1){if(j==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(j==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(ke)return J(ke,{container:D});if(Y)return j==="cut"?w(Y):J(Y,{container:D})},ze=mt;function Ie(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(O){return typeof O}:Ie=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Ie(V)}function _i(V,_){if(!(V instanceof _))throw new TypeError("Cannot call a class as a function")}function ro(V,_){for(var O=0;O<_.length;O++){var j=_[O];j.enumerable=j.enumerable||!1,j.configurable=!0,"value"in j&&(j.writable=!0),Object.defineProperty(V,j.key,j)}}function Ai(V,_,O){return _&&ro(V.prototype,_),O&&ro(V,O),V}function Ci(V,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");V.prototype=Object.create(_&&_.prototype,{constructor:{value:V,writable:!0,configurable:!0}}),_&&br(V,_)}function br(V,_){return br=Object.setPrototypeOf||function(j,D){return j.__proto__=D,j},br(V,_)}function Hi(V){var _=Pi();return function(){var j=Wt(V),D;if(_){var Y=Wt(this).constructor;D=Reflect.construct(j,arguments,Y)}else D=j.apply(this,arguments);return ki(this,D)}}function ki(V,_){return _&&(Ie(_)==="object"||typeof _=="function")?_:$i(V)}function $i(V){if(V===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return V}function Pi(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(V){return!1}}function Wt(V){return Wt=Object.setPrototypeOf?Object.getPrototypeOf:function(O){return O.__proto__||Object.getPrototypeOf(O)},Wt(V)}function vr(V,_){var O="data-clipboard-".concat(V);if(_.hasAttribute(O))return _.getAttribute(O)}var Ri=function(V){Ci(O,V);var _=Hi(O);function O(j,D){var Y;return _i(this,O),Y=_.call(this),Y.resolveOptions(D),Y.listenClick(j),Y}return Ai(O,[{key:"resolveOptions",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof D.action=="function"?D.action:this.defaultAction,this.target=typeof D.target=="function"?D.target:this.defaultTarget,this.text=typeof D.text=="function"?D.text:this.defaultText,this.container=Ie(D.container)==="object"?D.container:document.body}},{key:"listenClick",value:function(D){var Y=this;this.listener=c()(D,"click",function(ke){return Y.onClick(ke)})}},{key:"onClick",value:function(D){var Y=D.delegateTarget||D.currentTarget,ke=this.action(Y)||"copy",Ut=ze({action:ke,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Ut?"success":"error",{action:ke,text:Ut,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(D){return vr("action",D)}},{key:"defaultTarget",value:function(D){var Y=vr("target",D);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(D){return vr("text",D)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(D){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(D,Y)}},{key:"cut",value:function(D){return w(D)}},{key:"isSupported",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof D=="string"?[D]:D,ke=!!document.queryCommandSupported;return Y.forEach(function(Ut){ke=ke&&!!document.queryCommandSupported(Ut)}),ke}}]),O}(s()),Ii=Ri},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,h,w){var A=c.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function p(l,f,u,h,w){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return s(A,f,u,h,w)}))}function c(l,f,u,h){return function(w){w.delegateTarget=a(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!a.string(h))throw new TypeError("Second argument must be a String");if(!a.fn(w))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,h,w);if(a.nodeList(u))return l(u,h,w);if(a.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return s(document.body,u,h,w)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ts=/["'&<>]/;ei.exports=rs;function rs(e){var t=""+e,r=ts.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,h)})})}function s(u,h){try{p(o[u](h))}catch(w){f(i[0][3],w)}}function p(u){u.value instanceof nt?Promise.resolve(u.value.v).then(c,l):f(i[0][2],u)}function c(u){s("next",u)}function l(u){s("throw",u)}function f(u,h){u(h),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof de=="function"?de(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function k(e){return typeof e=="function"}function ft(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var zt=ft(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function qe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=de(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(A){t={error:A}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof zt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=de(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{fo(w)}catch(A){i=i!=null?i:[],A instanceof zt?i=q(q([],N(i)),N(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new zt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)fo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&qe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&qe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=Fe.EMPTY;function qt(e){return e instanceof Fe||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function fo(e){k(e)?e():e.unsubscribe()}var $e={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var ut={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new Fe(function(){o.currentObservers=null,qe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,o){return new Eo(r,o)},t}(F);var Eo=function(e){re(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Tr},t}(g);var _r=function(e){re(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(g);var Lt={now:function(){return(Lt.delegate||Date).now()},delegate:void 0};var _t=function(e){re(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Lt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(vt);var So=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(gt);var Hr=new So(To);var Oo=function(e){re(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=bt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(bt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(vt);var Mo=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(gt);var me=new Mo(Oo);var M=new F(function(e){return e.complete()});function Yt(e){return e&&k(e.schedule)}function kr(e){return e[e.length-1]}function Xe(e){return k(kr(e))?e.pop():void 0}function He(e){return Yt(kr(e))?e.pop():void 0}function Bt(e,t){return typeof kr(e)=="number"?e.pop():t}var xt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Gt(e){return k(e==null?void 0:e.then)}function Jt(e){return k(e[ht])}function Xt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Zt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Gi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var er=Gi();function tr(e){return k(e==null?void 0:e[er])}function rr(e){return lo(this,arguments,function(){var r,o,n,i;return Nt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,nt(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,nt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,nt(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function or(e){return k(e==null?void 0:e.getReader)}function W(e){if(e instanceof F)return e;if(e!=null){if(Jt(e))return Ji(e);if(xt(e))return Xi(e);if(Gt(e))return Zi(e);if(Xt(e))return Lo(e);if(tr(e))return ea(e);if(or(e))return ta(e)}throw Zt(e)}function Ji(e){return new F(function(t){var r=e[ht]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Xi(e){return new F(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?v(function(n,i){return e(n,i,o)}):le,Te(1),r?Be(t):zo(function(){return new ir}))}}function Fr(e){return e<=0?function(){return M}:y(function(t,r){var o=[];t.subscribe(T(r,function(n){o.push(n),e=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,h=0,w=!1,A=!1,te=function(){f==null||f.unsubscribe(),f=void 0},ie=function(){te(),l=u=void 0,w=A=!1},J=function(){var H=l;ie(),H==null||H.unsubscribe()};return y(function(H,mt){h++,!A&&!w&&te();var ze=u=u!=null?u:r();mt.add(function(){h--,h===0&&!A&&!w&&(f=Wr(J,p))}),ze.subscribe(mt),!l&&h>0&&(l=new at({next:function(Ie){return ze.next(Ie)},error:function(Ie){A=!0,te(),f=Wr(ie,n,Ie),ze.error(Ie)},complete:function(){w=!0,te(),f=Wr(ie,a),ze.complete()}}),W(H).subscribe(l))})(c)}}function Wr(e,t){for(var r=[],o=2;oe.next(document)),e}function $(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var xa=S(d(document.body,"focusin"),d(document.body,"focusout")).pipe(_e(1),Q(void 0),m(()=>Re()||document.body),B(1));function et(e){return xa.pipe(m(t=>e.contains(t)),K())}function kt(e,t){return C(()=>S(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ht(r=>Me(+!r*t)):le,Q(e.matches(":hover"))))}function Bo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Bo(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Bo(o,n);return o}function sr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=x("script",{src:e});return C(()=>(document.head.appendChild(t),S(d(t,"load"),d(t,"error").pipe(b(()=>$r(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),Te(1))))}var Go=new g,ya=C(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill"):I(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>Go.next(t)))),b(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ya.pipe(E(r=>r.observe(t)),b(r=>Go.pipe(v(o=>o.target===t),L(()=>r.unobserve(t)))),m(()=>ce(e)),Q(ce(e)))}function Tt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function Jo(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function Xo(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function Zo(e){return S(d(window,"load"),d(window,"resize")).pipe(Le(0,me),m(()=>Ue(e)),Q(Ue(e)))}function pr(e){return{x:e.scrollLeft,y:e.scrollTop}}function De(e){return S(d(e,"scroll"),d(window,"scroll"),d(window,"resize")).pipe(Le(0,me),m(()=>pr(e)),Q(pr(e)))}var en=new g,Ea=C(()=>I(new IntersectionObserver(e=>{for(let t of e)en.next(t)},{threshold:0}))).pipe(b(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function tt(e){return Ea.pipe(E(t=>t.observe(e)),b(t=>en.pipe(v(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function tn(e,t=16){return De(e).pipe(m(({y:r})=>{let o=ce(e),n=Tt(e);return r>=n.height-o.height-t}),K())}var lr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function rn(e){return lr[e].checked}function Je(e,t){lr[e].checked!==t&&lr[e].click()}function Ve(e){let t=lr[e];return d(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function wa(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ta(){return S(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function on(){let e=d(window,"keydown").pipe(v(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:rn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),v(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!wa(o,r)}return!0}),pe());return Ta().pipe(b(t=>t?M:e))}function xe(){return new URL(location.href)}function pt(e,t=!1){if(G("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function nn(){return new g}function an(){return location.hash.slice(1)}function sn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Sa(e){return S(d(window,"hashchange"),e).pipe(m(an),Q(an()),v(t=>t.length>0),B(1))}function cn(e){return Sa(e).pipe(m(t=>fe(`[id="${t}"]`)),v(t=>typeof t!="undefined"))}function $t(e){let t=matchMedia(e);return ar(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function pn(){let e=matchMedia("print");return S(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function Nr(e,t){return e.pipe(b(r=>r?t():M))}function zr(e,t){return new F(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ne(e,t){return zr(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function ln(e,t){let r=new DOMParser;return zr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function mn(e,t){let r=new DOMParser;return zr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function fn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function un(){return S(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(fn),Q(fn()))}function dn(){return{width:innerWidth,height:innerHeight}}function hn(){return d(window,"resize",{passive:!0}).pipe(m(dn),Q(dn()))}function bn(){return z([un(),hn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function mr(e,{viewport$:t,header$:r}){let o=t.pipe(Z("size")),n=z([o,r]).pipe(m(()=>Ue(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function Oa(e){return d(e,"message",t=>t.data)}function Ma(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function vn(e,t=new Worker(e)){let r=Oa(t),o=Ma(t),n=new g;n.subscribe(o);let i=o.pipe(X(),ne(!0));return n.pipe(X(),Pe(r.pipe(U(i))),pe())}var La=P("#__config"),St=JSON.parse(La.textContent);St.base=`${new URL(St.base,xe())}`;function ye(){return St}function G(e){return St.features.includes(e)}function Ee(e,t){return typeof t!="undefined"?St.translations[e].replace("#",t.toString()):St.translations[e]}function Se(e,t=document){return P(`[data-md-component=${e}]`,t)}function ae(e,t=document){return $(`[data-md-component=${e}]`,t)}function _a(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function gn(e){if(!G("announce.dismiss")||!e.childElementCount)return M;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return C(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),_a(e).pipe(E(r=>t.next(r)),L(()=>t.complete()),m(r=>R({ref:e},r)))})}function Aa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function xn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),Aa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))}function Pt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function yn(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function En(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function wn(e){return x("button",{class:"md-clipboard md-icon",title:Ee("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function qr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,x("del",null,c)," "],[]).slice(0,-1),i=ye(),a=new URL(e.location,i.base);G("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=ye();return x("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Ee("search.result.term.missing"),": ",...n)))}function Tn(e){let t=e[0].score,r=[...e],o=ye(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreqr(l,1)),...p.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,p.length>0&&p.length===1?Ee("search.result.more.one"):Ee("search.result.more.other",p.length))),...p.map(l=>qr(l,1)))]:[]];return x("li",{class:"md-search-result__item"},c)}function Sn(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?sr(r):r)))}function Qr(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function On(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function Ca(e){var o;let t=ye(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function Mn(e,t){var o;let r=ye();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Ee("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map(Ca)))}var Ha=0;function ka(e){let t=z([et(e),kt(e)]).pipe(m(([o,n])=>o||n),K()),r=C(()=>Jo(e)).pipe(oe(De),ct(1),m(()=>Xo(e)));return t.pipe(Ae(o=>o),b(()=>z([t,r])),m(([o,n])=>({active:o,offset:n})),pe())}function $a(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Ha++}`;return C(()=>{let i=new g,a=new _r(!1);i.pipe(X(),ne(!1)).subscribe(a);let s=a.pipe(Ht(c=>Me(+!c*250,Hr)),K(),b(c=>c?r:M),E(c=>c.id=n),pe());z([i.pipe(m(({active:c})=>c)),s.pipe(b(c=>kt(c,250)),Q(!1))]).pipe(m(c=>c.some(l=>l))).subscribe(a);let p=a.pipe(v(c=>c),ee(s,o),m(([c,l,{size:f}])=>{let u=e.getBoundingClientRect(),h=u.width/2;if(l.role==="tooltip")return{x:h,y:8+u.height};if(u.y>=f.height/2){let{height:w}=ce(l);return{x:h,y:-16-w}}else return{x:h,y:16+u.height}}));return z([s,i,p]).subscribe(([c,{offset:l},f])=>{c.style.setProperty("--md-tooltip-host-x",`${l.x}px`),c.style.setProperty("--md-tooltip-host-y",`${l.y}px`),c.style.setProperty("--md-tooltip-x",`${f.x}px`),c.style.setProperty("--md-tooltip-y",`${f.y}px`),c.classList.toggle("md-tooltip2--top",f.y<0),c.classList.toggle("md-tooltip2--bottom",f.y>=0)}),a.pipe(v(c=>c),ee(s,(c,l)=>l),v(c=>c.role==="tooltip")).subscribe(c=>{let l=ce(P(":scope > *",c));c.style.setProperty("--md-tooltip-width",`${l.width}px`),c.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(K(),be(me),ee(s)).subscribe(([c,l])=>{l.classList.toggle("md-tooltip2--active",c)}),z([a.pipe(v(c=>c)),s]).subscribe(([c,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),a.pipe(v(c=>!c)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),ka(e).pipe(E(c=>i.next(c)),L(()=>i.complete()),m(c=>R({ref:e},c)))})}function lt(e,{viewport$:t},r=document.body){return $a(e,{content$:new F(o=>{let n=e.title,i=yn(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t})}function Pa(e,t){let r=C(()=>z([Zo(e),De(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ce(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return et(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),Te(+!o||1/0))))}function Ln(e,t,{target$:r}){let[o,n]=Array.from(e.children);return C(()=>{let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),tt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),S(i.pipe(v(({active:s})=>s)),i.pipe(_e(250),v(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Le(16,me)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(ct(125,me),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(a),v(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),d(n,"mousedown").pipe(U(a),ee(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Re())==null||c.blur()}}),r.pipe(U(a),v(s=>s===o),Ge(125)).subscribe(()=>e.focus()),Pa(e,t).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function Ra(e){return e.tagName==="CODE"?$(".c, .c1, .cm",e):[e]}function Ia(e){let t=[];for(let r of Ra(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function _n(e,t){t.append(...Array.from(e.childNodes))}function fr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Ia(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,En(p,i)),s.replaceWith(a.get(p)))}return a.size===0?M:C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=[];for(let[l,f]of a)c.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?_n(f,u):_n(u,f)}),S(...[...a].map(([,l])=>Ln(l,t,{target$:r}))).pipe(L(()=>s.complete()),pe())})}function An(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return An(t)}}function Cn(e,t){return C(()=>{let r=An(e);return typeof r!="undefined"?fr(r,e,t):M})}var Hn=Vt(Yr());var Fa=0;function kn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return kn(t)}}function ja(e){return ge(e).pipe(m(({width:t})=>({scrollable:Tt(e).width>t})),Z("scrollable"))}function $n(e,t){let{matches:r}=matchMedia("(hover)"),o=C(()=>{let n=new g,i=n.pipe(Fr(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Hn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${Fa++}`;let l=wn(c.id);c.insertBefore(l,e),G("content.tooltips")&&a.push(lt(l,{viewport$}))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=kn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||G("content.code.annotate"))){let l=fr(c,e,t);a.push(ge(s).pipe(U(i),m(({width:f,height:u})=>f&&u),K(),b(f=>f?l:M)))}}return $(":scope > span[id]",e).length&&e.classList.add("md-code__content"),ja(e).pipe(E(c=>n.next(c)),L(()=>n.complete()),m(c=>R({ref:e},c)),Pe(...a))});return G("content.lazy")?tt(e).pipe(v(n=>n),Te(1),b(()=>o)):o}function Wa(e,{target$:t,print$:r}){let o=!0;return S(t.pipe(m(n=>n.closest("details:not([open])")),v(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(v(n=>n||!o),E(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Pn(e,t){return C(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Wa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}var Rn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var Br,Da=0;function Va(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@10/dist/mermaid.min.js"):I(void 0)}function In(e){return e.classList.remove("mermaid"),Br||(Br=Va().pipe(E(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Rn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),Br.subscribe(()=>ao(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Da++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),Br.pipe(m(()=>({ref:e})))}var Fn=x("table");function jn(e){return e.replaceWith(Fn),Fn.replaceWith(On(e)),I({ref:e})}function Na(e){let t=e.find(r=>r.checked)||e[0];return S(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(Q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Wn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=$(":scope > input",e),i=Qr("prev");e.append(i);let a=Qr("next");return e.append(a),C(()=>{let s=new g,p=s.pipe(X(),ne(!0));z([s,ge(e)]).pipe(U(p),Le(1,me)).subscribe({next([{active:c},l]){let f=Ue(c),{width:u}=ce(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=pr(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([De(o),ge(o)]).pipe(U(p)).subscribe(([c,l])=>{let f=Tt(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),S(d(i,"click").pipe(m(()=>-1)),d(a,"click").pipe(m(()=>1))).pipe(U(p)).subscribe(c=>{let{width:l}=ce(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(U(p),v(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=P(`label[for="${c.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(p),v(f=>!(f.metaKey||f.ctrlKey)),E(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&s.pipe(Ce(1),ee(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of $("[data-tabs]"))for(let A of $(":scope > input",w)){let te=P(`label[for="${A.id}"]`);if(te!==c&&te.innerText.trim()===f){te.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),s.pipe(U(p)).subscribe(()=>{for(let c of $("audio, video",e))c.pause()}),tt(e).pipe(b(()=>Na(n)),E(c=>s.next(c)),L(()=>s.complete()),m(c=>R({ref:e},c)))}).pipe(Qe(se))}function Un(e,{viewport$:t,target$:r,print$:o}){return S(...$(".annotate:not(.highlight)",e).map(n=>Cn(n,{target$:r,print$:o})),...$("pre:not(.mermaid) > code",e).map(n=>$n(n,{target$:r,print$:o})),...$("pre.mermaid",e).map(n=>In(n)),...$("table:not([class])",e).map(n=>jn(n)),...$("details",e).map(n=>Pn(n,{target$:r,print$:o})),...$("[data-tabs]",e).map(n=>Wn(n,{viewport$:t,target$:r})),...$("[title]",e).filter(()=>G("content.tooltips")).map(n=>lt(n,{viewport$:t})))}function za(e,{alert$:t}){return t.pipe(b(r=>S(I(!0),I(!1).pipe(Ge(2e3))).pipe(m(o=>({message:r,active:o})))))}function Dn(e,t){let r=P(".md-typeset",e);return C(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),za(e,t).pipe(E(n=>o.next(n)),L(()=>o.complete()),m(n=>R({ref:e},n)))})}var qa=0;function Qa(e,t){document.body.append(e);let{width:r}=ce(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=cr(t),n=typeof o!="undefined"?De(o):I({x:0,y:0}),i=S(et(t),kt(t)).pipe(K());return z([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=Ue(t),l=ce(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function Vn(e){let t=e.title;if(!t.length)return M;let r=`__tooltip_${qa++}`,o=Pt(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,C(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),S(i.pipe(v(({active:a})=>a)),i.pipe(_e(250),v(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Le(16,me)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(ct(125,me),v(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Qa(o,e).pipe(E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))}).pipe(Qe(se))}function Ka({viewport$:e}){if(!G("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ye(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),K()),o=Ve("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),K(),b(n=>n?r:I(!1)),Q(!1))}function Nn(e,t){return C(()=>z([ge(e),Ka(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),K((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function zn(e,{header$:t,main$:r}){return C(()=>{let o=new g,n=o.pipe(X(),ne(!0));o.pipe(Z("active"),We(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=ue($("[title]",e)).pipe(v(()=>G("content.tooltips")),oe(a=>Vn(a)));return r.subscribe(o),t.pipe(U(n),m(a=>R({ref:e},a)),Pe(i.pipe(U(n))))})}function Ya(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ce(e);return{active:o>=n}}),Z("active"))}function qn(e,t){return C(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?M:Ya(o,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))})}function Qn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),K()),n=o.pipe(b(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),Z("bottom"))));return z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Ba(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return I(...e).pipe(oe(o=>d(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function Kn(e){let t=$("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=$t("(prefers-color-scheme: light)");return C(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;sa.key==="Enter"),ee(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Se("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(be(se)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Ba(t).pipe(U(n.pipe(Ce(1))),st(),E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))})}function Yn(e,{progress$:t}){return C(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(E(o=>r.next({value:o})),L(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Gr=Vt(Yr());function Ga(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Bn({alert$:e}){Gr.default.isSupported()&&new F(t=>{new Gr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Ga(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(E(t=>{t.trigger.focus()}),m(()=>Ee("clipboard.copied"))).subscribe(e)}function Gn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ja(e,t){let r=new Map;for(let o of $("url",e)){let n=P("loc",o),i=[Gn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of $("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Gn(new URL(s),t))}}return r}function ur(e){return mn(new URL("sitemap.xml",e)).pipe(m(t=>Ja(t,new URL(e))),ve(()=>I(new Map)))}function Xa(e,t){if(!(e.target instanceof Element))return M;let r=e.target.closest("a");if(r===null)return M;if(r.target||e.metaKey||e.ctrlKey)return M;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),I(new URL(r.href))):M}function Jn(e){let t=new Map;for(let r of $(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Xn(e){for(let t of $("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return I(e)}function Za(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Jn(document);for(let[o,n]of Jn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Se("container");return je($("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new F(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),M}),X(),ne(document))}function Zn({location$:e,viewport$:t,progress$:r}){let o=ye();if(location.protocol==="file:")return M;let n=ur(o.base);I(document).subscribe(Xn);let i=d(document.body,"click").pipe(We(n),b(([p,c])=>Xa(p,c)),pe()),a=d(window,"popstate").pipe(m(xe),pe());i.pipe(ee(t)).subscribe(([p,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",p)}),S(i,a).subscribe(e);let s=e.pipe(Z("pathname"),b(p=>ln(p,{progress$:r}).pipe(ve(()=>(pt(p,!0),M)))),b(Xn),b(Za),pe());return S(s.pipe(ee(e,(p,c)=>c)),s.pipe(b(()=>e),Z("pathname"),b(()=>e),Z("hash")),e.pipe(K((p,c)=>p.pathname===c.pathname&&p.hash===c.hash),b(()=>i),E(()=>history.back()))).subscribe(p=>{var c,l;history.state!==null||!p.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",sn(p.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(Z("offset"),_e(100)).subscribe(({offset:p})=>{history.replaceState(p,"")}),s}var ri=Vt(ti());function oi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,ri.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function It(e){return e.type===1}function dr(e){return e.type===3}function ni(e,t){let r=vn(e);return S(I(location.protocol!=="file:"),Ve("search")).pipe(Ae(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function ii({document$:e}){let t=ye(),r=Ne(new URL("../versions.json",t.base)).pipe(ve(()=>M)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>d(document.body,"click").pipe(v(i=>!i.metaKey&&!i.ctrlKey),ee(o),b(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?M:(i.preventDefault(),I(p))}}return M}),b(i=>ur(new URL(i)).pipe(m(a=>{let p=xe().href.replace(t.base,i);return a.has(p.split("#")[0])?new URL(p):new URL(i)})))))).subscribe(n=>pt(n,!0)),z([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(Mn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases.concat(n.version))if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ae("outdated"))s.hidden=!1})}function ns(e,{worker$:t}){let{searchParams:r}=xe();r.has("q")&&(Je("search",!0),e.value=r.get("q"),e.focus(),Ve("search").pipe(Ae(i=>!i)).subscribe(()=>{let i=xe();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=et(e),n=S(t.pipe(Ae(It)),d(e,"keyup"),o).pipe(m(()=>e.value),K());return z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),B(1))}function ai(e,{worker$:t}){let r=new g,o=r.pipe(X(),ne(!0));z([t.pipe(Ae(It)),r],(i,a)=>a).pipe(Z("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(Z("focus")).subscribe(({focus:i})=>{i&&Je("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),ns(e,{worker$:t}).pipe(E(i=>r.next(i)),L(()=>r.complete()),m(i=>R({ref:e},i)),B(1))}function si(e,{worker$:t,query$:r}){let o=new g,n=tn(e.parentElement).pipe(v(Boolean)),i=e.parentElement,a=P(":scope > :first-child",e),s=P(":scope > :last-child",e);Ve("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ee(r),Ur(t.pipe(Ae(It)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Ee("search.result.none"):Ee("search.result.placeholder");break;case 1:a.textContent=Ee("search.result.one");break;default:let u=sr(l.length);a.textContent=Ee("search.result.other",u)}});let p=o.pipe(E(()=>s.innerHTML=""),b(({items:l})=>S(I(...l.slice(0,10)),I(...l.slice(10)).pipe(Ye(4),Vr(n),b(([f])=>f)))),m(Tn),pe());return p.subscribe(l=>s.appendChild(l)),p.pipe(oe(l=>{let f=fe("details",l);return typeof f=="undefined"?M:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(v(dr),m(({data:l})=>l)).pipe(E(l=>o.next(l)),L(()=>o.complete()),m(l=>R({ref:e},l)))}function is(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=xe();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function ci(e,t){let r=new g,o=r.pipe(X(),ne(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),is(e,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))}function pi(e,{worker$:t,keyboard$:r}){let o=new g,n=Se("search-query"),i=S(d(n,"keydown"),d(n,"focus")).pipe(be(se),m(()=>n.value),K());return o.pipe(We(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(v(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(v(dr),m(({data:s})=>s)).pipe(E(s=>o.next(s)),L(()=>o.complete()),m(()=>({ref:e})))}function li(e,{index$:t,keyboard$:r}){let o=ye();try{let n=ni(o.search,t),i=Se("search-query",e),a=Se("search-result",e);d(e,"click").pipe(v(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Je("search",!1)),r.pipe(v(({mode:p})=>p==="search")).subscribe(p=>{let c=Re();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of $(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}p.claim()}break;case"Escape":case"Tab":Je("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...$(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(v(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=ai(i,{worker$:n});return S(s,si(a,{worker$:n,query$:s})).pipe(Pe(...ae("search-share",e).map(p=>ci(p,{query$:s})),...ae("search-suggest",e).map(p=>pi(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ke}}function mi(e,{index$:t,location$:r}){return z([t,r.pipe(Q(xe()),v(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>oi(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=x("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function as(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function Jr(e,o){var n=o,{header$:t}=n,r=io(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:a}=Ue(i);return C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=s.pipe(Le(0,me));return c.pipe(ee(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(Ae()).subscribe(()=>{for(let l of $(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2})}}}),ue($("label[tabindex]",e)).pipe(oe(l=>d(l,"click").pipe(be(se),m(()=>l),U(p)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),as(e,r).pipe(E(l=>s.next(l)),L(()=>s.complete()),m(l=>R({ref:e},l)))})}function fi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Ct(Ne(`${r}/releases/latest`).pipe(ve(()=>M),m(o=>({version:o.tag_name})),Be({})),Ne(r).pipe(ve(()=>M),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Be({}))).pipe(m(([o,n])=>R(R({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ne(r).pipe(m(o=>({repositories:o.public_repos})),Be({}))}}function ui(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ne(r).pipe(ve(()=>M),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Be({}))}function di(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return fi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ui(r,o)}return M}var ss;function cs(e){return ss||(ss=C(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(ae("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return M}return di(e.href).pipe(E(o=>__md_set("__source",o,sessionStorage)))}).pipe(ve(()=>M),v(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function hi(e){let t=P(":scope > :last-child",e);return C(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(Sn(o)),t.classList.add("md-source__repository--active")}),cs(e).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ps(e,{viewport$:t,header$:r}){return ge(document.body).pipe(b(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),Z("hidden"))}function bi(e,t){return C(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?I({hidden:!1}):ps(e,t)).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ls(e,{viewport$:t,header$:r}){let o=new Map,n=$(".md-nav__link",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(Z("height"),m(({height:s})=>{let p=Se("main"),c=P(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),pe());return ge(document.body).pipe(Z("height"),b(s=>C(()=>{let p=[];return I([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),We(i),b(([p,c])=>t.pipe(jr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(s.height);for(;f.length;){let[,A]=f[0];if(A-c=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),K((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),Q({prev:[],next:[]}),Ye(2,1),m(([s,p])=>s.prev.length{let i=new g,a=i.pipe(X(),ne(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),G("toc.follow")){let s=S(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(v(({prev:p})=>p.length>0),We(o.pipe(be(se))),ee(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=cr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2,behavior:c})}}})}return G("navigation.tracking")&&t.pipe(U(a),Z("offset"),_e(250),Ce(1),U(n.pipe(Ce(1))),st({delay:250}),ee(i)).subscribe(([,{prev:s}])=>{let p=xe(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),ls(e,{viewport$:t,header$:r}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function ms(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Ye(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return z([i,n]).pipe(m(([a,s])=>!(a&&s)),K(),U(o.pipe(Ce(1))),ne(!0),st({delay:250}),m(a=>({hidden:a})))}function gi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),Z("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),d(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),ms(e,{viewport$:t,main$:o,target$:n}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))}function xi({document$:e,viewport$:t}){e.pipe(b(()=>$(".md-ellipsis")),oe(r=>tt(r).pipe(U(e.pipe(Ce(1))),v(o=>o),m(()=>r),Te(1))),v(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,lt(n,{viewport$:t}).pipe(U(e.pipe(Ce(1))),L(()=>n.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>$(".md-status")),oe(r=>lt(r,{viewport$:t}))).subscribe()}function yi({document$:e,tablet$:t}){e.pipe(b(()=>$(".md-toggle--indeterminate")),E(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>d(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ee(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function fs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ei({document$:e}){e.pipe(b(()=>$("[data-md-scrollfix]")),E(t=>t.removeAttribute("data-md-scrollfix")),v(fs),oe(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function wi({viewport$:e,tablet$:t}){z([Ve("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>I(r).pipe(Ge(r?400:100))),ee(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function us(){return location.protocol==="file:"?wt(`${new URL("search/search_index.js",Xr.base)}`).pipe(m(()=>__index),B(1)):Ne(new URL("search/search_index.json",Xr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ot=Yo(),jt=nn(),Ot=cn(jt),Zr=on(),Oe=bn(),hr=$t("(min-width: 960px)"),Si=$t("(min-width: 1220px)"),Oi=pn(),Xr=ye(),Mi=document.forms.namedItem("search")?us():Ke,eo=new g;Bn({alert$:eo});var to=new g;G("navigation.instant")&&Zn({location$:jt,viewport$:Oe,progress$:to}).subscribe(ot);var Ti;((Ti=Xr.version)==null?void 0:Ti.provider)==="mike"&&ii({document$:ot});S(jt,Ot).pipe(Ge(125)).subscribe(()=>{Je("drawer",!1),Je("search",!1)});Zr.pipe(v(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&pt(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&pt(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});xi({viewport$:Oe,document$:ot});yi({document$:ot,tablet$:hr});Ei({document$:ot});wi({viewport$:Oe,tablet$:hr});var rt=Nn(Se("header"),{viewport$:Oe}),Ft=ot.pipe(m(()=>Se("main")),b(e=>Qn(e,{viewport$:Oe,header$:rt})),B(1)),ds=S(...ae("consent").map(e=>xn(e,{target$:Ot})),...ae("dialog").map(e=>Dn(e,{alert$:eo})),...ae("header").map(e=>zn(e,{viewport$:Oe,header$:rt,main$:Ft})),...ae("palette").map(e=>Kn(e)),...ae("progress").map(e=>Yn(e,{progress$:to})),...ae("search").map(e=>li(e,{index$:Mi,keyboard$:Zr})),...ae("source").map(e=>hi(e))),hs=C(()=>S(...ae("announce").map(e=>gn(e)),...ae("content").map(e=>Un(e,{viewport$:Oe,target$:Ot,print$:Oi})),...ae("content").map(e=>G("search.highlight")?mi(e,{index$:Mi,location$:jt}):M),...ae("header-title").map(e=>qn(e,{viewport$:Oe,header$:rt})),...ae("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Nr(Si,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft})):Nr(hr,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft}))),...ae("tabs").map(e=>bi(e,{viewport$:Oe,header$:rt})),...ae("toc").map(e=>vi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})),...ae("top").map(e=>gi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})))),Li=ot.pipe(b(()=>hs),Pe(ds),B(1));Li.subscribe();window.document$=ot;window.location$=jt;window.target$=Ot;window.keyboard$=Zr;window.viewport$=Oe;window.tablet$=hr;window.screen$=Si;window.print$=Oi;window.alert$=eo;window.progress$=to;window.component$=Li;})(); +//# sourceMappingURL=bundle.081f42fc.min.js.map + diff --git a/assets/javascripts/bundle.081f42fc.min.js.map b/assets/javascripts/bundle.081f42fc.min.js.map new file mode 100644 index 000000000..e055db5ac --- /dev/null +++ b/assets/javascripts/bundle.081f42fc.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an