diff --git a/.gitignore b/.gitignore index a5d61361a..357b6eac1 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ # Node.js node_modules /npm-debug.log +/log/xapi-statements.json +/public/ITDG diff --git a/CHANGELOG.md b/CHANGELOG.md index 67eedef47..9cd00e200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ VIRTUAL WORLD FRAMEWORK CHANGE LOG ================================== +---------------------------------- +0.8.0 +---------------------------------------------------------------------------------------------------- +Note: (*) indicates an API change. + +- CHG*: Handle reflector actions as they arrive, without waiting for a tick. +- CHG*: Don't record ticks in the queue. Don't tick nodes and model drivers. +- CHG*: Remove ticking function from model drivers. + + ---------------------------------- 0.7.0 ---------------------------------------------------------------------------------------------------- diff --git a/StartVWFServer.bat b/StartVWFServer.bat new file mode 100644 index 000000000..5820b7f12 --- /dev/null +++ b/StartVWFServer.bat @@ -0,0 +1,7 @@ +@echo off +set NPM_PATH=%HOMEDRIVE%%HOME_PATH%\AppData\Roaming\npm +set NODEJS_PATH=%ProgramFiles%\nodejs +set PATH=%NPM_PATH%;%NODEJS_PATH%;%PATH% +cd C:\ITDG\VWF +npm start +exit \ No newline at end of file diff --git a/StartVWFServerMinimized.bat b/StartVWFServerMinimized.bat new file mode 100644 index 000000000..1bc68eed5 --- /dev/null +++ b/StartVWFServerMinimized.bat @@ -0,0 +1,4 @@ +@echo off +cd C:\ITDG\VWF +start /min StartVWFServer.bat +exit diff --git a/config/custom-environment-variables.json b/config/custom-environment-variables.json new file mode 100644 index 000000000..52bcebe0e --- /dev/null +++ b/config/custom-environment-variables.json @@ -0,0 +1,13 @@ +{ + "session": { + "secret": "VWF_SESSION_SECRET" + }, + "tdg": { + "password": "VWF_TDG_PASSWORD" + }, + "txs": { + "amqp_host": "VWF_TXS_AMQP_HOST", + "amqp_exchange": "VWF_TXS_AMQP_EXCHANGE", + "amqp_channel": "VWF_TXS_AMQP_CHANNEL" + } +} diff --git a/config/default.json b/config/default.json new file mode 100644 index 000000000..91ba62307 --- /dev/null +++ b/config/default.json @@ -0,0 +1,24 @@ +{ + + // Secret for signed sessions. Generate a new secret with + // `node -e 'console.log( require( "crypto" ).randomBytes( 32 ).toString( "hex" ) )'` + + "session": { + "secret": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" + }, + + // TDG instructor password. + + "tdg": { + "password": "password" + }, + + // AMQP parameters for the `/sim` route to publish to TXS. + + "txs": { + "amqp_host": "localhost", + "amqp_exchange": "x_txs", + "amqp_channel": "itdg.loadMission" + } + +} diff --git a/documents/ITDG/maps/test-R400.jpg b/documents/ITDG/maps/test-R400.jpg new file mode 100644 index 000000000..72c7c13f5 Binary files /dev/null and b/documents/ITDG/maps/test-R400.jpg differ diff --git a/documents/ITDG/maps/test-R400.tif b/documents/ITDG/maps/test-R400.tif new file mode 100644 index 000000000..9531fad19 Binary files /dev/null and b/documents/ITDG/maps/test-R400.tif differ diff --git a/documents/ITDG/maps/test-R400.tms/16/11653/22630.png b/documents/ITDG/maps/test-R400.tms/16/11653/22630.png new file mode 100644 index 000000000..d46318b91 Binary files /dev/null and b/documents/ITDG/maps/test-R400.tms/16/11653/22630.png differ diff --git a/documents/ITDG/maps/test-R400.tms/16/11653/22631.png b/documents/ITDG/maps/test-R400.tms/16/11653/22631.png new file mode 100644 index 000000000..d0f938922 Binary files /dev/null and b/documents/ITDG/maps/test-R400.tms/16/11653/22631.png differ diff --git a/documents/ITDG/maps/test-R400.tms/17/23306/45262.png b/documents/ITDG/maps/test-R400.tms/17/23306/45262.png new file mode 100644 index 000000000..a2e67d1fa Binary files /dev/null and b/documents/ITDG/maps/test-R400.tms/17/23306/45262.png differ diff --git a/documents/ITDG/maps/test-R400.tms/17/23307/45260.png b/documents/ITDG/maps/test-R400.tms/17/23307/45260.png new file mode 100644 index 000000000..88f25b714 Binary files /dev/null and b/documents/ITDG/maps/test-R400.tms/17/23307/45260.png differ diff --git a/documents/ITDG/maps/test-R400.tms/tilemapresource.xml b/documents/ITDG/maps/test-R400.tms/tilemapresource.xml new file mode 100644 index 000000000..5044a5df8 --- /dev/null +++ b/documents/ITDG/maps/test-R400.tms/tilemapresource.xml @@ -0,0 +1,23 @@ + + + R400_imagery_wgs84_clipped_noalpha.tif + + EPSG:4326 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documents/ITDG/metrics/CPG_Metrics.csv b/documents/ITDG/metrics/CPG_Metrics.csv new file mode 100644 index 000000000..9309a4aa5 --- /dev/null +++ b/documents/ITDG/metrics/CPG_Metrics.csv @@ -0,0 +1,95 @@ +"title","index","type","setLayerOwned","defaultValue","options" +"Understanding of Commander’s Intent.","4","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Achievement of Commander’s Intent.","5","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Focus on mission accomplishment.","6","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of assets appropriate for the situation.","7","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of assets in accordance with their capabilities.","8","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Coordination of supporting arms.","9","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of ALL available assets relevant to the fight (including requests for assets).","10","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of non-traditional assets or creative use of assets.","11","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Control of key terrain.","12","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of terrain to constrain the enemy.","13","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of terrain for concealment.","14","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Use of terrain for protection/cover.","15","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of enemy objectives.","16","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of enemy positions.","17","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of enemy scheme of maneuver.","18","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of enemy disposition and capabilities.","19","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of how the enemy would expect his actions, and ability to stay 2 moves ahead.","20","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Operated inside the opponent’s OODA loop.","21","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Leveraged the element of surprise.","22","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Assessment of time required to maneuver assets.","23","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Appropriate orchestration and timing of asset employment.","24","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Planned for contingencies.","25","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Adapted to situation changes.","26","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Provided necessary information to subordinates.","27","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Kept Higher informed.","28","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Kept adjacent units informed.","29","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Communicated in a timely manner or at the right times.","30","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Effectively described the situation to subordinates.","31","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Effectively described the situation to Higher.","32","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Pushed through resistance with determination.","33","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Showed a will to take action despite uncertainty.","34","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Showed he knew what was going on, especially with the enemy, throughout the mission.","35","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Overall, acted decisively.","36","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"Overall, performed effectively.","37","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Highly Ineffective','2':'Ineffective','3':'Effective','4':'Highly Effective'}]" +"I understood my Commander’s Intent.","38","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I achieved my Commander’s Intent.","39","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I stayed focused on my mission even when I could’ve been distracted by other tasks or events.","40","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I brought the right assets to bear.","41","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I understood my assets’ capabilities well enough to employ them correctly.","42","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I coordinated supporting arms effectively.","43","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I used all the assets available to me.","44","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was creative with the assets I employed or how I chose to employ them.","45","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I controlled the key terrain.","46","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I forced my opponent into the terrain of my choosing.","47","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I used the terrain to conceal my movements.","48","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I used the terrain to protect my assets.","49","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was right about my opponent’s objectives.","50","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was right about where my opponent would position his forces.","51","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was right about how my opponent would maneuver.","52","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was right about the strength and capabilities of my opponent.","53","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was right about how my opponent would expect me to act, and I stayed 2 moves ahead of him.","54","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was inside my opponent’s OODA loop.","55","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I took my opponent by surprise.","56","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I was in the right place at the right time.","57","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I orchestrated and timed my use of assets effectively.","58","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My plan had built-in flexibility.","59","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I adapted my approach at the right point in time.","60","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I told my subordinates what they needed to know to be effective.","61","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I told Higher what was important for him to know.","62","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I told my adjacent units what they needed to know.","63","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I provided information in a timely manner.","64","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I described what I thought the enemy was doing to my subordinates.","65","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I described what I thought the enemy was doing to Higher.","66","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I pushed through resistance to achieve my goal.","67","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I took action even when faced with uncertainty.","68","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"I knew what was happening, especially with my opponent, throughout the mission.","69","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"Overall, I acted decisively.","70","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"Overall, my decisions and actions were effective.","71","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent was able to achieve his mission objective.","72","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent was focused on his mission even when they could’ve been distracted by other tasks or events.","73","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent employed assets that were stronger than mine.","74","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent overwhelmed me with firepower.","75","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent overwhelmed me with the number of threats to which I had to respond.","76","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent used their assets cleverly, in a way I didn’t anticipate.","77","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent controlled the key terrain.","78","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent forced me into terrain of their choosing.","79","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent used terrain to conceal their movements.","80","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent used terrain to protect their assets.","81","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent correctly anticipated my objectives.","82","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent anticipated where I would position my forces.","83","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent anticipated how I would maneuver.","84","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent anticipated my strengths and capabilities.","85","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent figured out how I expected him to act, and he stayed 2 moves ahead of me.","86","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent was inside my OODA loop.","87","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent took me by surprise.","88","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent was in the right place at the right time.","89","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent orchestrated and timed their use of assets effectively.","90","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent was prepared to be flexible.","91","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent adapted his approach at the right point in time.","92","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent showed resolve by pushing through the resistance I put in his path.","93","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent took action even when faced with uncertainty.","94","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"My opponent knew what was happening, especially my actions and intent, throughout the mission.","95","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"Overall, my opponent acted decisively.","96","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" +"Overall, my opponent’s decisions and actions were effective.","97","Range","undefined","0","[0,4,1,{'0':'N/A','1':'Strongly Disagree','2':'Disagree','3':'Agree','4':'Strongly Agree'}]" \ No newline at end of file diff --git a/documents/ITDG/metrics/TBS_BOC_Metrics.csv b/documents/ITDG/metrics/TBS_BOC_Metrics.csv new file mode 100644 index 000000000..69eb8f981 --- /dev/null +++ b/documents/ITDG/metrics/TBS_BOC_Metrics.csv @@ -0,0 +1,5 @@ +"title","index","type","setLayerOwned","defaultValue","options" +"Student Orders","0","Long Text","undefined","","null" +"Instructor Rating","1","Range","undefined","","[0,10,1,{'0':'N/A','1':'Unsat','2':'Unsat','3':'Marginal','4':'Marginal','5':'Acceptable','6':'Acceptable','7':'Capable','8':'Capable','9':'Outstanding','10':'Outstanding'}]" +"Instructor Grade","2","Text","undefined","","null" +"Instructor Observations","3","Long Text","undefined","","null" \ No newline at end of file diff --git a/documents/ITDG/scenarioTemplate/saveState.vwf.config.json b/documents/ITDG/scenarioTemplate/saveState.vwf.config.json new file mode 100644 index 000000000..a1e5cfb61 --- /dev/null +++ b/documents/ITDG/scenarioTemplate/saveState.vwf.config.json @@ -0,0 +1 @@ +{"info":{"title":"Scenario Template"},"model":{"vwf/model/javascript":"","vwf/model/kineticjs":"","vwf/model/mil-sym":"","vwf/model/object":"","nodriver":""},"view":{"vwf/view/document":"","vwf/view/touch":"","vwf/view/kineticjs":"","vwf/view/mil-sym":""}} \ No newline at end of file diff --git a/documents/ITDG/scenarioTemplate/saveState.vwf.json b/documents/ITDG/scenarioTemplate/saveState.vwf.json new file mode 100644 index 000000000..7e10514e9 --- /dev/null +++ b/documents/ITDG/scenarioTemplate/saveState.vwf.json @@ -0,0 +1 @@ +{"configuration":{"log-level":"info","random-seed":1466540519030,"randomize-ids":true,"humanize-ids":true,"preserve-script-closures":false,"load-timeout":120},"kernel":{"time":0},"nodes":[{"patches":"http://vwf.example.com/clients.vwf","sequence":7,"random":{"s0":0.24205980077385902,"s1":0.9761656543705612,"s2":0.9434323732275516,"c":11304},"children":{}},{"patches":"/ITDG/index.vwf","properties":{"unitIconDefaults":{"shadowColor":"rgba( 1, 1, 1, 0.5 )","shadowBlur":10,"shadowOffsetX":8,"shadowOffsetY":8,"shadowEnabled":false}},"children":{"scenarioController":{"patches":"/ITDG/index.vwf:3-47-scenarioController","sequence":4,"random":{"s0":0.4123580085579306,"s1":0.9537082586903125,"s2":0.22647805558517575,"c":582588},"properties":{},"children":{}},"participants":{"patches":"/ITDG/index.vwf:5-08-participants","sequence":1,"random":{"s0":0.6633416542317718,"s1":0.6727178883738816,"s2":0.3024811027571559,"c":1237838},"children":{}}}}],"annotations":{"1":"application"},"queue":{"time":0,"queue":[]}} \ No newline at end of file diff --git a/external/README.txt b/external/README.txt new file mode 100644 index 000000000..ff1e64090 --- /dev/null +++ b/external/README.txt @@ -0,0 +1 @@ +Place external applications in "external" folder. diff --git a/lib/nodejs/admin.js b/lib/nodejs/admin.js index 2b0c20c1e..8a8a9a3aa 100755 --- a/lib/nodejs/admin.js +++ b/lib/nodejs/admin.js @@ -232,7 +232,7 @@ function HandleAdminConfig( request, response, parsedRequest ) { if ( ( parsedRequest[ 'public_path' ] ) && ( parsedRequest[ 'application' ] ) && ( request.method == "GET" ) ) { var filenameRoot = helpers.JoinPath( global.applicationRoot, parsedRequest[ 'public_path' ], parsedRequest[ 'application' ] ); if ( helpers.IsFile( filenameRoot + ".config.yaml" ) ) { - serve.YAML( ( filenameRoot + ".config.yaml" ).replace( /\//g, libpath.sep ), response, url.parse( request.url, true ) ); + serve.YAML( request, ( filenameRoot + ".config.yaml" ).replace( /\//g, libpath.sep ), response, url.parse( request.url, true ) ); return true; } else if ( helpers.IsFile( filenameRoot + ".config.json" ) ) { @@ -242,6 +242,7 @@ function HandleAdminConfig( request, response, parsedRequest ) { else { // If there is no config file, return an empty string to prevent 404 errors serve.JSON("", response); + return true; } } return false; @@ -267,9 +268,9 @@ function HandleAdminChrome( request, response, parsedRequest ) { return false; } -// The Serve function in admin takes in the nodeJS request and nnodeJS response as well as +// The Serve function in admin takes in the nodeJS request and nodeJS response as well as // the parsedRequest information. -// It tests if the request is actually an admin request, and if calls an appropriate handler +// It tests if the request is actually an admin request, and if so, calls an appropriate handler // to serve the appropriate response. // If the request is succesfully served, it returns TRUE, if the request is not succesfully // served (whether due to a file not being present, the request being malformed, or simply it diff --git a/lib/nodejs/application.js b/lib/nodejs/application.js index 7f6856baa..4f0fe6b1b 100755 --- a/lib/nodejs/application.js +++ b/lib/nodejs/application.js @@ -5,7 +5,8 @@ var servehandler = require( './serve-handler' ), helpers = require( './helpers' ), persistence = require( './persistence' ), - admin = require( './admin' ); + admin = require( './admin' ), + stream = require( './stream' ); // Requests are attempted to be served as if they pertain to a specific application. // If any of these attempts succesfully serve the request, true is returned. @@ -32,11 +33,15 @@ function Serve( request, response, parsedRequest ) { if ( servehandler.Component( request, response, helpers.JoinPath( global.applicationRoot, parsedRequest[ 'public_path' ], parsedRequest[ 'private_path' ] ) ) ) { return true; } + // Test if mediaServer can server the request. + if ( stream.Serve( request, response, parsedRequest ) ) { + return true; + } // If the request was still not served, try and see if the persistence functionality will serve this request. if ( persistence.Serve( request, response, parsedRequest ) ) { return true; } - // Finally, test if the admin functionality can serve this request. + // Test if the admin functionality can serve this request. if ( admin.Serve( request, response, parsedRequest ) ) { return true; } diff --git a/lib/nodejs/authentication.js b/lib/nodejs/authentication.js new file mode 100644 index 000000000..fd3069efc --- /dev/null +++ b/lib/nodejs/authentication.js @@ -0,0 +1,150 @@ +// TDG authentication scheme. +// +// A valid login is required for all routes. Any username is accepted, but instructors must provide +// the instructor password. A VWF `client.vwf` descriptor is published to the session to describe +// the user in the VWF application. + +var passport = require( "passport" ), + passportLocal = require( "passport-local" ), + config = require( "config" ), + path = require( "path" ); + +// Passport strategy options. + +var strategyOptions = { + passReqToCallback: true, // Call the strategy callback as `cb( req, ... )` instead of `cb( ... )` + usernameField: "last_name", // A non-empty field to appease `passport-local`, but we ignore `username` + passwordField: "last_name", // A non-empty field, and we ignore `password`; the actual password may be empty +}; + +// Create and attach the Passport strategy object. + +var strategy = new passportLocal( strategyOptions, function( req, username, password, done ) { + + // Build the user object from the form properties. + + var user = { + last_name: + req.body.last_name || req.query.last_name, + first_name: + req.body.first_name || req.query.first_name, + middle_initial: + req.body.middle_initial || req.query.middle_initial, + instructor: + req.body.instructor || req.query.instructor, + }; + + // Get the actual password from the form. + + password = req.body.password || req.query.password; + + // Check the password if one is configured. Instructors must provide a password. + + var authenticated = ! config.has( "tdg.password" ) || ! config.get( "tdg.password" ) || + password === config.get( "tdg.password" ); + + // Return the result. For successful logins, return the user object. The user object will be + // attached to the request at `req.user`. + // + // For login errors, return `false` for `user` and provide an error message. If an error occurs + // while performing the lookup, return the error object. + + if ( user.instructor && ! authenticated ) { + return done( null, false, { message: 'Incorrect password' } ); + } else { + return done( null, user ); + } + +} ); + +passport.use( strategy ); + +// Convert the user object to a reference to be stored in the session. Without a user database, this +// can be the user object. With a local user database, it should be the user id in the database. +// +// Also attach a VWF `client.vwf` descriptor to the session to describe the user for the VWF +// application. + +passport.serializeUser( function( req, user, done ) { + + req.session.vwf = req.session.vwf || {}; + + req.session.vwf.client = { + properties: { + last_name: + user.last_name, + first_name: + user.first_name, + middle_initial: + user.middle_initial, + instructor: + user.instructor !== undefined ? !! user.instructor : undefined, + } + }; + + done( null, user ); + +} ); + +// Convert a user reference in the session to a user object. Without a user database, the session +// data is the user object. With a local user database, look up the user from an id in the session. + +passport.deserializeUser( function( req, id, done ) { + done( null, id ); +} ); + +// Create a router to contain the Passport middleware and login/logout routes. + +var router = require( "express" ).Router(); + +// Passport and the Passport `session` module. + +router.use( passport.initialize() ); +router.use( passport.authenticate( "session" ) ); + +// Show a login form at `/login`. + +router.get( "/login", function( req, res ) { + res.sendFile( path.join( __dirname, "../../support/lobby", "login.html" ) ); +} ); + +// Receive a login request and attempt to authenticate. +// +// The URLs would need the base URL prepended if the application is not mounted at `/`. Since the +// authentication middleware is created outside the request, we don't have access to `baseUrl` to +// do this. + +router.post( "/login", passport.authenticate( "local", { + successReturnToOrRedirect: /* req.baseUrl + */ "/", + failureRedirect: /* req.baseUrl + */ "/login", + failureFlash: true, +} ) ); + +// Receive a logout request and log out. Also remove the VWF `client.vwf` descriptor from the +// session. + +router.post( "/logout", function( req, res ) { + req.logout(); + req.session.vwf && delete req.session.vwf.client; + res.redirect( req.baseUrl + "/login" ); +} ); + +// Enforce authentication rules. This implementation requires a valid login for all routes except +// for `/login` and `/logout`. + +router.use( function( req, res, next ) { + if ( req.isUnauthenticated() ) { + if ( req.accepts( "html", "json" ) === "html" ) { + req.session.returnTo = req.baseUrl + req.url; + res.redirect( req.baseUrl + "/login" ); + } else { + res.sendStatus( 401 ); + } + } else { + next(); + } +} ); + +// Export the router. + +module.exports = router; diff --git a/lib/nodejs/authentication/passport-http.js b/lib/nodejs/authentication/passport-http.js new file mode 100644 index 000000000..3e8157724 --- /dev/null +++ b/lib/nodejs/authentication/passport-http.js @@ -0,0 +1,65 @@ +// Example authentication module implemented with Passport and HTTP Basic authentication. +// +// A valid login is required for all routes, but any username and password are accepted. Hooks for +// querying a user database are shown. A VWF `client.vwf` descriptor is published to the session to +// describe the user in the VWF application. +// +// Add the NPM modules `passport` and `passport-http` to support this method. + +var passport = require( "passport" ), + passportHTTP = require( "passport-http" ); + +// Create and attach the Passport strategy object. + +var strategy = new passportHTTP.BasicStrategy( function( username, password, done ) { + + // Given `username` and `password` from a login form, look up the user in a local database. + + var user = { username: username }; + + // Return the result. For successful logins, return the user object. The user object will be + // attached to the request at `req.user`. + // + // For login errors, return `false` for `user` and provide an error message. If an error occurs + // while performing the lookup, return the error object. + + if ( false /* lookup error */ ) { + return done( {} /* err */ ); + } else if ( false /* bad user */ ) { + return done( null, false, { message: 'Incorrect username' } ); + } else if ( false /* bad password */ ) { + return done( null, false, { message: 'Incorrect password' } ); + } else { + return done( null, user ); + } + +} ); + +passport.use( strategy ); + +// Convert the user object to a reference to be stored in the session. Without a user database, this +// can be the user object. With a local user database, it should be the user id in the database. +// +// Also attach a VWF `client.vwf` descriptor to the session to describe the user for the VWF +// application. + +passport.serializeUser( function( req, user, done ) { + req.session.vwf = req.session.vwf || {}; + req.session.vwf.client = { properties: { username: user.username } }; + done( null, user ); +} ); + +// Convert a user reference in the session to a user object. Without a user database, the session +// data is the user object. With a local user database, look up the user from an id in the session. + +passport.deserializeUser( function( req, id, done ) { + done( null, id ); +} ); + +// Export the Passport initializer, `session` module, and HTTP Basic strategy module. + +module.exports = [ + passport.initialize(), + passport.authenticate( "session" ), + passport.authenticate( "basic" ), +]; diff --git a/lib/nodejs/authentication/passport-local.js b/lib/nodejs/authentication/passport-local.js new file mode 100644 index 000000000..e14fae997 --- /dev/null +++ b/lib/nodejs/authentication/passport-local.js @@ -0,0 +1,126 @@ +// Example authentication module implemented with Passport and login forms. +// +// A valid login is required for all routes, but any username and password are accepted. Hooks for +// querying a user database are shown. A VWF `client.vwf` descriptor is published to the session to +// describe the user in the VWF application. +// +// Add the NPM modules `passport` and `passport-local` to support this method. + +var passport = require( "passport" ), + passportLocal = require( "passport-local" ); + +// Create and attach the Passport strategy object. + +var strategy = new passportLocal( function( username, password, done ) { + + // Given `username` and `password` from a login form, look up the user in a local database. + + var user = { username: username }; + + // Return the result. For successful logins, return the user object. The user object will be + // attached to the request at `req.user`. + // + // For login errors, return `false` for `user` and provide an error message. If an error occurs + // while performing the lookup, return the error object. + + if ( false /* lookup error */ ) { + return done( {} /* err */ ); + } else if ( false /* bad user */ ) { + return done( null, false, { message: 'Incorrect username' } ); + } else if ( false /* bad password */ ) { + return done( null, false, { message: 'Incorrect password' } ); + } else { + return done( null, user ); + } + +} ); + +passport.use( strategy ); + +// Convert the user object to a reference to be stored in the session. Without a user database, this +// can be the user object. With a local user database, it should be the user id in the database. +// +// Also attach a VWF `client.vwf` descriptor to the session to describe the user for the VWF +// application. + +passport.serializeUser( function( req, user, done ) { + req.session.vwf = req.session.vwf || {}; + req.session.vwf.client = { properties: { username: user.username } }; + done( null, user ); +} ); + +// Convert a user reference in the session to a user object. Without a user database, the session +// data is the user object. With a local user database, look up the user from an id in the session. + +passport.deserializeUser( function( req, id, done ) { + done( null, id ); +} ); + +// Create a router to contain the Passport middleware and login/logout routes. + +var router = require( "express" ).Router(); + +// Passport and the Passport `session` module. + +router.use( passport.initialize() ); +router.use( passport.authenticate( "session" ) ); + +// Show a login form at `/login`. + +router.get( "/login", function( req, res ) { + res.send( + "
" + + "

" + ( ( res.locals.flash.shift() || {} ).message || "" ) + "

" + + "" + "
" + + "" + "
" + + "" + + "
" + ); +} ); + +// Receive a login request and attempt to authenticate. +// +// The URLs would need the base URL prepended if the application is not mounted at `/`. Since the +// authentication middleware is created outside the request, we don't have access to `baseUrl` to +// do this. + +router.post( "/login", passport.authenticate( "local", { + successReturnToOrRedirect: /* req.baseUrl + */ "/", + failureRedirect: /* req.baseUrl + */ "/login", + failureFlash: true, +} ) ); + +// Show a logout form at `/logout`. + +router.get( "/logout", function( req, res ) { + res.send( + "
" + + "" + + "
" + ); +} ); + +// Receive a logout request and log out. Also remove the VWF `client.vwf` descriptor from the +// session. + +router.post( "/logout", function( req, res ) { + req.logout(); + req.session.vwf && delete req.session.vwf.client; + res.redirect( req.baseUrl + "/login" ); +} ); + +// Enforce authentication rules. This implementation requires a valid login for all routes except +// for `/login` and `/logout`. + +router.use( function( req, res, next ) { + if ( req.isUnauthenticated() ) { + res.redirect( req.baseUrl + "/login" ); + res.session.returnTo = req.baseUrl + req.url; + } else { + next(); + } +} ); + +// Export the router. + +module.exports = router; diff --git a/lib/nodejs/file-cache.js b/lib/nodejs/file-cache.js index 3211a6881..bc7bac054 100755 --- a/lib/nodejs/file-cache.js +++ b/lib/nodejs/file-cache.js @@ -21,9 +21,10 @@ function _FileCache( ) { // Function for determining whether to treat file as binary or text // based on file extentsion. - this.getDataType = function ( file ) { - var type = file.substr( file.lastIndexOf( '.' ) + 1 ).toLowerCase( ); - if ( type === 'js' || type === 'html' || type === 'xml' || type === 'txt' || type === 'xhtml' || type === 'css' ) { + this.getDataType = function ( fileextension ) { + if ( fileextension === 'js' || fileextension === 'html' || + fileextension === 'xml' || fileextension === 'txt' || + fileextension === 'xhtml' || fileextension === 'css' ) { return "utf8"; } else return "binary"; @@ -33,11 +34,22 @@ function _FileCache( ) { // Asynchronous, returns file to the callback function. // Passes null to the callback function if there is no such file. this.getFile = function ( path, callback ) { + function getLastModifiedTime ( path ) { + try { + var stats = fs.statSync(path); + return stats.mtime; + } + catch(err) { + console.log('Error finding file: '+err); + return null; + } + } + //First, check if we have already served this file // and have it already cached, if so, return the // already cached file. for ( var i = 0; i < this.files.length; i++ ) { - if( this.files[ i ].path == path ) { + if( this.files[ i ].path == path ) { global.log( 'serving from cache: ' + path, 2 ); callback( this.files[ i ] ); return; @@ -45,11 +57,26 @@ function _FileCache( ) { } // if got here, have no record of this file yet. - var datatype = this.getDataType( path ); - var file = fs.readFileSync( path ); + var ext = path.substr( path.lastIndexOf( '.' ) + 1 ).toLowerCase(); + var datatype = this.getDataType( ext ); + var file = ext !== 'html' ? fs.readFileSync( path) : fs.readFileSync( path, datatype ); var stats = fs.statSync( path ); if ( file ) { + // if the file is html replace all autoversion entries with + // path appended by mtime parameter before adding to cache + if ( ext === 'html' ) { + var dirPath = path.substring( 0, path.lastIndexOf( '\\' ) + 1 ); + // find script and link references that use ?mtime=timestamp format + var fileStr = file.replace(/<((?:script|link)[^>]*(?:src|href)="([^"].*?)[^?]*mtime=)timestamp([^"]*"[^>]*)>/g, function(match, pre, file, post) { + file = file.substring(0, file.length-1); + var mtime = getLastModifiedTime(dirPath+file); + var replaceStr = '<'+pre+(mtime ? mtime.getTime() : '')+post+'>'; + return replaceStr; + }); + // convert to buffer to keep socket messages small + file = new Buffer(fileStr); + } // The file was not already in the cache, but does exist. // Gzip the file, which is an async process, and callback // with the gzipped file entry when finished. diff --git a/lib/nodejs/kml-handler.js b/lib/nodejs/kml-handler.js new file mode 100644 index 000000000..4916e4c33 --- /dev/null +++ b/lib/nodejs/kml-handler.js @@ -0,0 +1,43 @@ +// kml-handler.js +// This file handles the sending/receiving of KML files between applications + + +var net = require( "net" ), + fs = require( "fs" ), + formidable = require( "formidable" ); + + + +function sendKML ( req, res, next ) { + var form = new formidable.IncomingForm(); + form.keepExtensions = true; + // parse the file and then send response + form.parse( req, function( err, fields, files ) { + if ( !err ) { + var client = new net.Socket(); + client.on( 'error', function( err ) { + console.log( err ); + } ); + //connect to the host:port + client.connect(fields[ 'port' ], fields[ 'host' ], function() { + //send a file to the server + var fileStream = fs.createReadStream( files[ 'file' ].path ); + fileStream.on('error', function( err ){ + console.log( "Error on file stream: " + err ); + } ); + + fileStream.on( 'open',function() { + fileStream.pipe( client ); + } ); + res.writeHead( 200, {'content-type': 'text/plain'} ); + res.end(); + } ); + } else { + console.log("Error parsing file: " + err); + res.writeHead(500); + res.end(); + } + }); +} + +exports.sendKML = sendKML; diff --git a/lib/nodejs/lobby.js b/lib/nodejs/lobby.js new file mode 100644 index 000000000..209ab3395 --- /dev/null +++ b/lib/nodejs/lobby.js @@ -0,0 +1,348 @@ +var app = module.exports = require( "express" )(); + +var bodyParser = require( "body-parser" ), + cookieParser = require( "cookie-parser" ), + cookieSession = require( "cookie-session" ), + crypto = require( "crypto" ), + config = require( "config" ), + flash = require( "flash" ), + express = require( "express" ), + Promise = require( "bluebird" ), + fs = Promise.promisifyAll( require( "fs-extra" ) ), + mkdirp = Promise.promisify( require( "mkdirp" ) ), + amqp = require( "amqplib" ), + zipFolder = Promise.promisify( require( "zip-folder" ) ), + admZip = require( "adm-zip" ), + upload = require( "multer" )( { dest: "documents/ITDG/imports/" } ), + path = require( "path" ), + _ = require( "lodash" ); + +var authentication = require( "./authentication" ), + manifest = require( "./manifest" ), + xapi = require( "./xapi" ), + helpers = require( "./helpers" ), + version = require("../../support/client/lib/version"), + kmlHandler = require( "./kml-handler" ); + +app.use( bodyParser.json() ); +app.use( bodyParser.urlencoded( { extended: false, limit: '50mb' } ) ); +app.use( bodyParser.text() ); +app.use( cookieParser() ); +app.use( cookieSession( { secret: sessionSecret() } ) ); +app.use( flash() ); +app.use( "/favicon.ico", express.static( "public/favicon.ico" ) ); +app.use( "/ONR_Logo.jpg", express.static( "public/ONR_Logo.jpg" ) ); +app.get( "/*.bundle.*", express.static( "support/lobby" ) ); +app.use( "/node_modules/bootstrap/dist", express.static( "support/lobby/node_modules/bootstrap/dist" ) ); + +app.get( "/version", function( req, res ) { + res.json( { version, title: version.getDerivativeVersion() || "ITDG" } ); +} ); + +app.use( authentication ); + +app.use( function( req, res, next ) { + res.locals.user = req.isAuthenticated() ? req.user : undefined; + next(); +} ); + +app.get( "/", function( req, res ) { + res.sendFile( path.join( __dirname, "../../support/lobby", "index.html" ) ); +} ); + +app.get( "/manifest", function( req, res ) { + manifest().then( function( manifest ) { + res.json( manifest ); + } ); +} ); + +app.get( "/user", function( req, res ) { + res.json( req.user ); +} ); + +app.get( "/map-list", function( req, res ) { + var mapDir = "documents/ITDG/maps"; + + // Ensure that the map directory exists, then get the list of files in the map directory + mkdirp( mapDir ) + .then( made => fs.readdirAsync( mapDir ) ) + .then( files => res.send( { mapFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/image-list", function( req, res ) { + var imageDir = "documents/ITDG/image"; + + // Ensure that the image directory exists, then get the list of files in the image directory + mkdirp( imageDir ) + .then( made => fs.readdirAsync( imageDir ) ) + .then( files => res.send( { imageFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/sound-list", function( req, res ) { + var soundDir = "documents/ITDG/sound"; + + // Ensure that the sound directory exists, then get the list of files in the sound directory + mkdirp( soundDir ) + .then( made => fs.readdirAsync( soundDir ) ) + .then( files => res.send( { soundFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/video-list", function( req, res ) { + var videoDir = "documents/ITDG/video"; + + // Ensure that the video directory exists, then get the list of files in it + mkdirp( videoDir ) + .then( made => fs.readdirAsync( videoDir ) ) + .then( files => res.send( { videoFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/tracking-list", function( req, res ) { + var trackingDir = "documents/ITDG/tracking"; + + // Ensure that the tracking directory exists, then get the list of files in it + mkdirp( trackingDir ) + .then( made => fs.readdirAsync( trackingDir ) ) + .then( files => res.send( { trackingFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/affiliation-list", function( req, res ) { + var affiliationDir = "documents/ITDG/affiliation"; + + // Ensure that the affiliation directory exists, then get the list of files in it + mkdirp( affiliationDir ) + .then( made => fs.readdirAsync( affiliationDir ) ) + .then( files => res.send( { affiliationFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + +app.get( "/metrics-list", function( req, res ) { + var metricsDir = "documents/ITDG/metrics"; + + // Ensure that the metrics directory exists, then get the list of files in it + mkdirp( metricsDir ) + .then( made => fs.readdirAsync( metricsDir ) ) + .then( files => res.send( { metricsFilenames: files || [] } ) ) + .catch( err => next( err ) ); +} ); + + +app.get( "/export-scenarios", function( req, res ) { + const scenarioName = req.query.scenarioName; + const appDir = "documents/ITDG"; + const stateBaseDir = appDir + "/" + scenarioName; + let inputFilePaths = []; + Promise.all( [ + + // Get the state files + fs.readdirAsync( stateBaseDir ).then( paths => + inputFilePaths = inputFilePaths.concat( paths.map( path => stateBaseDir + "/" + path ) ) ), + + // Get the list of files referenced in the scenario + fs.readFileAsync( stateBaseDir + "/saveState.vwf.json" ) + .then( jsonBuffer => { + const filePathRegex = /"stream\/documents\/ITDG\/[^"]*"/g; + const dependencyFilePaths = + ( jsonBuffer.toString().match( filePathRegex ) || [] ) + .map( match => match.slice( 1, -1 ).replace( "stream/", "" ) ); + const fileExtensionRegex = /\.[^\.]*$/; + const tifDependencyFilePaths = + dependencyFilePaths + .map( filePath => filePath.replace( fileExtensionRegex, ".tif" ) ) + .filter( tifPath => fs.existsSync( tifPath ) ); + const tmsDependencyFilePaths = + dependencyFilePaths + .map( filePath => filePath.replace( fileExtensionRegex, ".tms" ) ) + .filter( tmsPath => fs.existsSync( tmsPath ) ); + const jpgDependencyFilePaths = + dependencyFilePaths + .map( filePath => filePath.replace( fileExtensionRegex, ".jpg" ) ) + .filter( jpgPath => fs.existsSync( jpgPath ) ); + const gifDependencyFilePaths = + dependencyFilePaths + .map( filePath => filePath.replace( fileExtensionRegex, ".gif" ) ) + .filter( gifPath => fs.existsSync( gifPath ) ); + const pngDependencyFilePaths = + dependencyFilePaths + .map( filePath => filePath.replace( fileExtensionRegex, ".png" ) ) + .filter( pngPath => fs.existsSync( pngPath ) ); + inputFilePaths = _.union( + inputFilePaths, + dependencyFilePaths, + tifDependencyFilePaths, + tmsDependencyFilePaths, + jpgDependencyFilePaths, + gifDependencyFilePaths, + pngDependencyFilePaths ); + } ) + ] ).then( () => { + + // Get an array of the output files that will be created in the staging area + const tempDir = appDir + "/export/" + Math.random(); + const stagingDir = tempDir + "/staging"; + const outputFilePaths = + inputFilePaths.map( inputFilePath => + inputFilePath.replace( "documents/ITDG", stagingDir ) ); + + // Determine the list of directories that need to be created + const zipDir = tempDir + "/output"; + const zipFilename = scenarioName + ".zip"; + const outputFileDirs = outputFilePaths.map( outputFilePath => + outputFilePath.slice( 0, outputFilePath.lastIndexOf( "/" ) ) ); + const dirsToCreate = [ stagingDir, zipDir ].concat( outputFileDirs ); + + // Determine the path for the output zip file + const zipFilePath = zipDir + "/" + zipFilename; + + // Perform the export + Promise.all( dirsToCreate.map( dir => fs.mkdirpAsync( dir ) ) ) + .then( () => + Promise.all( inputFilePaths.map( ( inputFilePath, index ) => + fs.copyAsync( inputFilePath, outputFilePaths[ index ] ) ) ) ) + .then( () => zipFolder( stagingDir, zipFilePath ) ) + .then( () => + Promise.promisify( res.download ).call( res, zipFilePath ) ) + .then( () => fs.removeAsync( tempDir ) ); + } ); +} ); + +app.post( "/scenarios", function( req, res, next ) { + + var now = new Date(); + + var templateFilename = + "documents/ITDG/" + "scenarioTemplate" + "/saveState.vwf.json"; + + var scenarioName = + req.body.name.trim().replace( /[^0-9A-Za-z]+/g, "-" ); + var scenarioTitle = + req.body.title.trim(); + var scenarioFilename = + "documents/ITDG/" + scenarioName + "/saveState.vwf.json"; + var scenarioFilename2 = + "documents/ITDG/" + scenarioName + "/saveState_" + now.valueOf() + ".vwf.json"; + + mkdirp( "documents/ITDG/" + scenarioName ). + then( () => fs.readFileAsync( templateFilename ) ). + then( json => JSON.parse( json ) ). + then( state => createScenario( state ) ). + tap( state => xapi.logCreation( state, "/ITDG", scenarioName, req.user ) ). + then( state => JSON.stringify( state ) ). + then( json => Promise.all( [ fs.writeFileAsync( scenarioFilename, json ), fs.writeFileAsync( scenarioFilename2, json ) ] ) ). + then( () => res.status( 201 ).send( { document: { uri: helpers.JoinPath( "/ITDG", helpers.GenerateInstanceID(), "load", scenarioName ) } } ) ). + catch( error => next( error ) ); + + fs.readFileAsync( templateFilename.replace( /vwf.json$/, "vwf.config.json" ) ). + then( json => Promise.all( [ fs.writeFileAsync( scenarioFilename.replace( /vwf.json$/, "vwf.config.json" ), json ), fs.writeFileAsync( scenarioFilename2.replace( /vwf.json$/, "vwf.config.json" ), json ) ] ) ). + catch( error => next( error ) ); + + /// Create a scenario from the template and request data. + + function createScenario( state ) { + + var patch = _.set( {}, "nodes[1].children.scenarioController.properties", { + scenarioName: scenarioName, + scenarioTitle: scenarioTitle, + } ); + + return _.merge( state, patch ); + } + +} ); + +app.post( "/sessions", function( req, res, next ) { + + var now = new Date(); + + var scenarioName = + req.body.name.trim().replace( /[^0-9A-Za-z]+/g, "-" ); + var scenarioFilename = + "documents/ITDG/" + scenarioName + "/saveState.vwf.json"; + + var sessionCompany = + req.body.company.trim().replace( /[^0-9A-Za-z]+/g, "-" ); + var sessionPlatoon = + Number( req.body.platoon ).toString(); + var sessionUnit = + Number( req.body.unit ).toString(); + + var sessionName = + "class_" + scenarioName + + "_Co" + sessionCompany + + "_Plt" + sessionPlatoon + + "_Unit" + sessionUnit + + "_" + now.getFullYear(); + + var sessionFilename = + "documents/ITDG/" + sessionName + "/saveState.vwf.json"; + var sessionFilename2 = + "documents/ITDG/" + sessionName + "/saveState_" + now.valueOf() + ".vwf.json"; + + mkdirp( "documents/ITDG/" + sessionName ). + then( () => fs.readFileAsync( scenarioFilename ) ). + then( json => JSON.parse( json ) ). + then( state => createSession( state ) ). + tap( state => xapi.logCreation( state, "/ITDG", sessionName, req.user ) ). + then( state => JSON.stringify( state ) ). + then( json => Promise.all( [ fs.writeFileAsync( sessionFilename, json ), fs.writeFileAsync( sessionFilename2, json ) ] ) ). + then( () => res.status( 201 ).send( { document: { uri: helpers.JoinPath( "/ITDG", helpers.GenerateInstanceID(), "load", sessionName ) } } ) ). + catch( error => next( error ) ); + + fs.readFileAsync( scenarioFilename.replace( /vwf.json$/, "vwf.config.json" ) ). + then( json => Promise.all( [ fs.writeFileAsync( sessionFilename.replace( /vwf.json$/, "vwf.config.json" ), json ), fs.writeFileAsync( sessionFilename2.replace( /vwf.json$/, "vwf.config.json" ), json ) ] ) ). + catch( error => next( error ) ); + + /// Create a session from a scenario and request data. + + function createSession( state ) { + + var patch = _.set( {}, "nodes[1].children.scenarioController.properties", { + classroom: { + company: sessionCompany, + platoon: sessionPlatoon, + unit: sessionUnit, + }, + dateOfClass: + now.toISOString(), + } ); + + return _.merge( state, patch ); + } + +} ); + +app.post( "/import-scenarios", upload.single( "file" ), function( req, res ) { + var file = req.file; + if ( file.mimetype === "application/x-zip-compressed" ) { + var zip = new admZip( file.path ); + zip.extractAllTo( "documents/ITDG", true ); + res.end(); + fs.removeAsync( file.path ); + } else { + res.status( 500 ).send( "File is not a .zip file: " + file.originalname ); + } +} ); + +app.post( "/sim", function( req, res, next ) { + amqp.connect( "amqp://" + config.get( "txs.amqp_host" ) ). + then( connection => connection.createChannel() ). + tap( channel => channel.assertExchange( config.get( "txs.amqp_exchange" ), "topic", { durable: false } ) ). + tap( channel => channel.publish( config.get( "txs.amqp_exchange" ), config.get( "txs.amqp_channel" ), new Buffer( req.body.mission ) ) ). + then( () => res.sendStatus( 200 ) ). + catch( error => next( error ) ); +} ); + +app.post( "/sendKML", function( req, res, next ) { + kmlHandler.sendKML( req, res, next ); +} ); + +/// sessionSecret + +function sessionSecret() { + return config.get( "session.secret" ) || + crypto.randomBytes( 32 ).toString( "hex" ); +} diff --git a/lib/nodejs/manifest.js b/lib/nodejs/manifest.js new file mode 100644 index 000000000..77bd8932d --- /dev/null +++ b/lib/nodejs/manifest.js @@ -0,0 +1,521 @@ +var http = require( "http" ), + rp = require( "request-promise" ), + Promise = require( "bluebird" ), + glob = Promise.promisifyAll( require( "glob" ) ), + fs = Promise.promisifyAll( require( "fs" ) ), + _ = require( "lodash" ); + +var reflector = require( "./reflector" ), + helpers = require( "./helpers" ); + +/// Return a promise for the list of applications available to launch, instances to connect to, and +/// documents to load. + +function manifest() { + return applications().then( documents ).then( instances ); +} + +/// { +/// "/path/to/application.vwf": {}, +/// "/path/to/another/application.vwf": {}, +/// ... +/// } + +function applications() { + + var applications = {}; + + return glob.globAsync( "public/**/*.vwf.@(json|yaml)" ).map( function( path ) { + + var applicationKey = path.replace( /^public/, "" ).replace( /\.(json|yaml)$/, "" ); + applications[ applicationKey ] = applications[ applicationKey ] || {}; + + } ).then( function() { + + return applications; + + } ); + +} + +/// { +/// "/path/to/application.vwf": { +/// name: { +/// application: +/// application, +/// scenario: { +/// state: { title }, +/// document: { uri, timestamp }, +/// instance, +/// }, +/// sessions: [ +/// { +/// state: { classroom: { company, platoon, unit } }, +/// document: { uri, timestamp }, +/// instance, +/// }, +/// ... +/// ], +/// }, +/// ... +/// }, +/// ... +/// } + +function documents( applications ) { + + return glob.globAsync( "documents/**/saveState?(_+([0-9])).vwf.json" ).map( function( path ) { + + var match = path.match( RegExp( "documents/(.+)/([^/]+)/saveState(?:_([0-9]+))?.vwf.json" ) ); + + if ( match ) { + + var applicationKey = "/" + match[1] + "/index.vwf"; + var name = match[2]; + var revision = match[3]; + + if ( ! revision ) { + + applications[ applicationKey ] = applications[ applicationKey ] || {}; + + return Promise.join( fs.readFileAsync( path ), fs.statAsync( path ), function( json, stats ) { + + var state = JSON.parse( json ); + + var applicationNode = ( ( state || {} ).nodes || [] ).filter( function( node ) { + return node.patches === applicationKey; + } )[ 0 ]; + + // scenarioName: + // "name" + // scenarioTitle: + // "longer title" + // classroom: { + // company: "Company", + // platoon: "1", + // unit: "1" }, + // dateOfClass: + // "1970-01-01T00:00:00Z" + + var scenarioProperties = ( ( ( applicationNode || {} ).children || {} ).scenarioController || {} ).properties || {}; + + var scenarioKey = scenarioProperties.scenarioName; + if (scenarioKey) { + var sName = scenarioKey.match( RegExp( "class_(.*)_Co" ) ); + if (sName && sName[1]){ + scenarioKey = sName[1]; + } + } + + var sessionKey = _.pick( scenarioProperties.classroom || {}, [ "company", "platoon", "unit" ] ); + + if ( _.keys( sessionKey ).length !== 3 ) { + sessionKey = undefined; + } + + var participants = ( ( ( applicationNode || {} ).children || {} ).participants || {} ).children || {}; + + var participantInstructors = Object.keys( participants ).map( function( participantName ) { + return !! ( participants[ participantName ].properties || {} ).isInstructor; + } ); + + var participantCounts = { + document: { + instructors: participantInstructors.filter( function( isInstructor ) { + return isInstructor } ).length, + students: participantInstructors.filter( function( isInstructor ) { + return ! isInstructor } ).length, + } + }; + + if ( scenarioKey ) { + + var document = { + uri: applicationKey.replace( /\/index.vwf$/, "" ) + "/" + helpers.GenerateInstanceID() + "/load/" + name + "/", + timestamp: scenarioProperties.scenarioTimestamp ? +new Date( scenarioProperties.scenarioTimestamp ) : stats.mtime + }; + + updateScenario( applications, applicationKey, scenarioKey, sessionKey, scenarioProperties, + participantCounts, document ); + + } + + } ); + + } + + } + + } ).then( function() { + + return applications; + + } ); + +} + +/// { +/// "/path/to/application.vwf": { +/// name: { +/// application: +/// application, +/// scenario: { +/// state: { title }, +/// document: { uri, timestamp }, +/// instance, +/// }, +/// sessions: [ +/// { +/// state: { classroom: { company, platoon, unit } }, +/// document: { uri, timestamp }, +/// instance, +/// }, +/// ... +/// ], +/// }, +/// ... +/// }, +/// ... +/// } + +function instances( applications ) { + + return Promise.map( Object.keys( applications ), function( applicationKey ) { + + var regexp = new RegExp( "^" + _.escapeRegExp( applicationKey ) + "(/|$)" ); + + var applicationInstanceIDs = Object.keys( reflector.GetInstances() ).filter( function( instanceID ) { + return instanceID.search( regexp ) === 0; + } ); + + return Promise.map( applicationInstanceIDs, function( instanceID ) { + + var scenarioPromise = reflector.Evaluate( instanceID, applicationKey, + "this.scenarioController && this.scenarioController.properties" ); + + var participantsPromise = reflector.Evaluate( instanceID, "http://vwf.example.com/clients.vwf", + "this.children.map( function( client ) { return !! client.instructor } )" ); + + return Promise.join( scenarioPromise, participantsPromise, function( scenarioProperties, participantInstructors ) { + + var scenarioProperties = scenarioProperties || {}; + scenarioProperties.classroom = scenarioProperties.classroom || {}; + + var scenarioKey = scenarioProperties.scenarioName; + if (scenarioKey) { + var sName = scenarioKey.match( RegExp( "class_(.*)_Co" ) ); + if (sName && sName[1]){ + scenarioKey = sName[1]; + } + } + + var sessionKey = _.pick( scenarioProperties.classroom, [ "company", "platoon", "unit" ] ); + + if ( _.keys( sessionKey ).length !== 3 ) { + sessionKey = undefined; + } + + var participantCounts = { + instance: { + instructors: participantInstructors.filter( function( isInstructor ) { + return isInstructor } ).length, + students: participantInstructors.filter( function( isInstructor ) { + return ! isInstructor } ).length, + isReview: reflector.IsReview( instanceID ) + } + }; + + if ( scenarioKey ) { + + var instance = instanceID.replace( /\/index.vwf$/, "" ) + "/"; + + updateScenario( applications, applicationKey, scenarioKey, sessionKey, scenarioProperties, + participantCounts, undefined, instance ); + } + + } ).catch( function( exception ) { + + // Catch `refector.Evaluate` timeouts. Instances that can't be read are omitted from the + // manifest since `scenarioProperties` is required to identify them. + + } ); + + } ); + + } ).then( function() { + + return applications; + + } ); + +} + +/// Update a scenario in the application database with new a document and/or instance of the +/// scenario, or a scenario session. +/// +/// @param applications +/// Application, scenario, session database. +/// @param applicationKey +/// Application id for the document/instance. +/// @param scenarioKey +/// Scenario id for the document/instance. The document/instance is the scenario if `sessionKey` +/// is falsy. +/// @param [sessionKey] +/// Session id of the document/instance if it is a session. +/// @param scenarioProperties +/// Important properties from the saved document or live instance. +/// @param [document] +/// URL and timestamp of a scenario/session saved document. +/// @param [instance] +/// URL of a scenario/session live instance. + +function updateScenario( applications, applicationKey, scenarioKey, sessionKey, scenarioProperties, + participantCounts, document, instance ) { + + /// Locate the application record in the database. + + var application = applications[ applicationKey ]; + + /// Locate or create the scenario record in the application. + + var scenario = application[ scenarioKey ] = application[ scenarioKey ] || { + application: + applicationKey, + scenario: { + state: {} }, + sessions: [], + }; + + if ( ! sessionKey ) { + + // This is a scenario. Record the document/instance state and the document and/or instance URLs. + + _.merge( scenario.scenario, { + state: scenarioProperties, + completion: participantCounts, + document: document, + instance: instance, + } ); + + } else { + + // This is a session. Update the session record if it exists, or create a new session record. + + var matchedSession = scenario.sessions.reduce( function( matchedSession, session ) { + + // If the document/instance matches an existing session, record the document and/or instance + // URLs in the session record. + + if ( _.isEqual( session.state.classroom, sessionKey ) ) { + _.merge( session, { + completion: participantCounts, + document: document, + instance: instance, + } ); + return true; + } else { + return matchedSession; + } + + }, false ); + + // If there is no matching session, record the document/instance state and the document and/or + // instance URLs in a new session record. + + if ( ! matchedSession ) { + + var session = { + state: {}, + }; + + _.merge( session, { + state: scenarioProperties, + completion: participantCounts, + document: document, + instance: instance, + } ); + + scenario.sessions.push( session ); + + } + + } + +} + +/// Return a sample list of applications available to launch, instances to connect to, and documents +/// to load. + +function sample() { + + return { + + "/TDG/index.vwf": { + + "scenario-with-document-without-instance": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-document-without-instance", + timestamp: +new Date( "2015-01-01T01:00:00-0500" ) }, + state: { + title: "Scenario with document without instance" }, + }, + }, + + "scenario-without-document-with-instance": { + application: + "/TDG/index.vwf", + scenario: { + instance: + "/TDG/0123456789ABCDEF", + state: { + title: "Scenario without document with instance" }, + }, + }, + + "scenario-with-document-with-instance": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-document-with-instance", + timestamp: +new Date( "2015-01-01T03:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + title: "Scenario with document with instance" }, + }, + }, + + "scenario-without-sessions": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-without-sessions", + timestamp: +new Date( "2015-01-01T04:00:00-0500" ) }, + state: { + title: "Scenario without sessions" }, + }, + }, + + "scenario-with-session-with-document-without-instance": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-session-with-document-without-instance", + timestamp: +new Date( "2015-01-01T05:00:00-0500" ) }, + state: { + title: "Scenario with session with document without instance" }, + }, + sessions: [ { + document: { + uri: "/TDG/load/scenario-with-session-with-document-without-instance+session1", + timestamp: +new Date( "2015-02-01T00:00:00-0500" ) }, + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + } ] + }, + + "scenario-with-session-without-document-with-instance": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-session-without-document-with-instance", + timestamp: +new Date( "2015-01-01T06:00:00-0500" ) }, + state: { + title: "Scenario with session without document with instance" }, + }, + sessions: [ { + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + } ] + }, + + "scenario-with-session-with-document-with-instance": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-session-with-document-with-instance", + timestamp: +new Date( "2015-01-01T07:00:00-0500" ) }, + state: { + title: "Scenario with session with document with instance" }, + }, + sessions: [ { + document: { + uri: "/TDG/load/scenario-with-session-with-document-with-instance+session1", + timestamp: +new Date( "2015-02-01T00:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + } ] + }, + + "scenario-with-multiple-sessions": { + application: + "/TDG/index.vwf", + scenario: { + document: { + uri: "/TDG/load/scenario-with-multiple-sessions", + timestamp: +new Date( "2015-01-01T08:00:00-0500" ) }, + state: { + title: "Scenario with multiple sessions" }, + }, + sessions: [ { + document: { + uri: "/TDG/load/scenario-with-multiple-sessions+session1", + timestamp: +new Date( "2015-02-01T00:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + }, { + document: { + uri: "/TDG/load/scenario-with-multiple-sessions+session2", + timestamp: +new Date( "2015-02-02T00:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + }, { + document: { + uri: "/TDG/load/scenario-with-multiple-sessions+session3", + timestamp: +new Date( "2015-02-03T00:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + }, { + document: { + uri: "/TDG/load/scenario-with-multiple-sessions+session4", + timestamp: +new Date( "2015-02-04T00:00:00-0500" ) }, + instance: + "/TDG/0123456789ABCDEF", + state: { + classroom: { company: "Company", platoon: "1", unit: "1" }, + } + } ] + } + + } + + }; + +} + +module.exports = manifest; +module.exports.sample = sample; diff --git a/lib/nodejs/parse-url.js b/lib/nodejs/parse-url.js index 9e1a2b909..bfa7a42ae 100755 --- a/lib/nodejs/parse-url.js +++ b/lib/nodejs/parse-url.js @@ -78,9 +78,11 @@ function Process( updatedURL ) { if ( segments.length > 0 ) { result[ 'private_path' ] = segments.join("/"); } + return result; + } else { + return undefined; } - return result; } exports.Process = Process; \ No newline at end of file diff --git a/lib/nodejs/persistence.js b/lib/nodejs/persistence.js index 9d1814deb..bd650b631 100755 --- a/lib/nodejs/persistence.js +++ b/lib/nodejs/persistence.js @@ -33,8 +33,13 @@ function LoadSaveObject( loadInfo ) { if ( loadInfo[ 'save_name' ] ) { var fileName = helpers.JoinPath( "./documents", loadInfo[ 'application_path' ], loadInfo[ 'save_name' ], "saveState_" + loadInfo[ 'save_revision' ] + ".vwf.json" ); if ( helpers.IsFile( fileName ) ) { - var fileContents = fs.readFileSync( fileName, "utf8" ); - return JSON.parse( fileContents ); + try { + var fileContents = fs.readFileSync( fileName, "utf8" ); + return JSON.parse( fileContents ); + } catch( exception ) { + console.log( "Error reading", fileName + ".", exception.toString() ); + return undefined; + } } } return undefined; @@ -249,27 +254,30 @@ function HandlePersistenceSave( request, response, parsedRequest, segments ) { CreateSaveDirectory( parsedRequest[ 'public_path' ], saveName, saveRevision ); var persistenceData = ""; var persistenceLength = 0; - request.on( 'data', function ( data ) { - persistenceData += data; - if ( persistenceData.length > 50000000 ) { - persistenceData = ""; - response.writeHead( 413, { 'Content-Type': 'text/plain' } ).end( ); - request.connection.destroy(); - } - } ); - request.on( 'end', function( ) { - if ( persistenceData.length > 0 ) { - var processedPost = querystring.parse( persistenceData ); - fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState' + processedPost[ "extension" ] ), processedPost[ "jsonState" ] ); - fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState_' + saveRevision + processedPost[ "extension" ] ), processedPost[ "jsonState" ] ); - } - } ); + if ( typeof request.body === "object" ) { + fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState' + request.body[ "extension" ] ), request.body[ "jsonState" ] ); + fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState_' + saveRevision + request.body[ "extension" ] ), request.body[ "jsonState" ] ); + response.writeHead( 200 ); + response.end(); + } else { + request.on( 'data', function ( data ) { + persistenceData += data; + } ); + request.on( 'end', function( ) { + if ( persistenceData.length > 0 ) { + var processedPost = querystring.parse( persistenceData ); + fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState' + processedPost[ "extension" ] ), processedPost[ "jsonState" ] ); + fs.writeFileSync( helpers.JoinPath( './documents', parsedRequest[ 'public_path' ], saveName, 'saveState_' + saveRevision + processedPost[ "extension" ] ), processedPost[ "jsonState" ] ); + response.writeHead( 200 ); + response.end(); + } + } ); + } return true; } return false; } - // The Serve function takes the nodeJS request, nodeJS response and the parsedRequest, and // attempts to see if it is a properly formed persistence related request. // If so, it serves the request, and returns true. @@ -309,6 +317,7 @@ function Serve( request, response, parsedRequest ) { if ( ( request.method == "POST" ) && ( segments.length > 1 ) ) { return HandlePersistenceSave( request, response, parsedRequest, segments ); } + return false; } } } diff --git a/lib/nodejs/reflector.js b/lib/nodejs/reflector.js index 97f539ce8..9f91fce20 100755 --- a/lib/nodejs/reflector.js +++ b/lib/nodejs/reflector.js @@ -3,12 +3,20 @@ var parseurl = require( './parse-url' ), persistence = require( './persistence' ), + xapi = require( "./xapi" ), helpers = require( './helpers' ), - fs = require( 'fs' ); + fs = require( 'fs' ), + cookieParser = require( 'cookie-parser' ), + cookieSession = require( 'cookie-session' ), + config = require( 'config' ); function parseSocketUrl( socket ) { - var application = socket.handshake.url.substring(0, socket.handshake.url.indexOf("/1/?t=")); - return parseurl.Process( application ); + const handshake = socket.handshake; + const url = handshake.url; + const application = url.substring( 0, url.indexOf( "/1/?t=" ) ); + const processedURL = parseurl.Process( application ); + processedURL.isReview = ( handshake.headers.referer || "" ).endsWith( "isReview=true" ); + return processedURL; } function GetLoadForSocket( processedURL ) { @@ -48,9 +56,11 @@ function OnConnection( socket ) { if( !global.instances[ namespace ] ) { global.instances[ namespace ] = { }; global.instances[ namespace ].clients = { }; + global.instances[ namespace ].pendingList = [ ]; global.instances[ namespace ].start_time = undefined; global.instances[ namespace ].pause_time = undefined; global.instances[ namespace ].rate = 1.0; + global.instances[ namespace ].isReview = processedURL.isReview; global.instances[ namespace ].setTime = function( time ) { this.start_time = GetNow( ) - time; this.pause_time = undefined; @@ -105,6 +115,7 @@ function OnConnection( socket ) { } }; global.instances[ namespace ].setTime( 0.0 ); + if ( saveObject ) { if ( saveObject[ "queue" ] ) { if ( saveObject[ "queue" ][ "time" ] ) { @@ -159,11 +170,17 @@ function OnConnection( socket ) { //keep track of the timer for this instance global.instances[ namespace ].timerID = setInterval( function ( ) { + var message = { parameters: [ ], time: global.instances[ namespace ].getTime( ) }; for ( var i in global.instances[ namespace ].clients ) { var client = global.instances[ namespace ].clients[ i ]; - client.emit( 'message', { parameters: [ ], time: global.instances[ namespace ].getTime( ) } ); + if ( ! client.pending ) { + client.emit( 'message', message ); + } } - }, 50 ); + if ( global.instances[ namespace ].pendingList.pending ) { + global.instances[ namespace ].pendingList.push( message ); + } + }, 100 ); } @@ -171,19 +188,22 @@ function OnConnection( socket ) { global.instances[ namespace ].clients[ socket.id ] = socket; socket.pending = true; - socket.pendingList = [ ]; - //Create a child in the application's 'clients.vwf' global to represent this client. - var clientMessage = { action: "createChild", parameters: [ "http://vwf.example.com/clients.vwf", socket.id, {} ], time: global.instances[ namespace ].getTime( ) }; + //Get the descriptor for the `clients.vwf` child. + var clientDescriptor = GetClientDescriptor( socket ); // The time for the setState message should be the time the new client joins, so save that time var setStateTime = global.instances[ namespace ].getTime( ); - //The client is the first, is can just load the application, and mark it not pending + // If this client is the first, it can just load the application, and mark it not pending if ( Object.keys( global.instances[ namespace ].clients ).length === 1 ) { if ( saveObject ) { - socket.emit( 'message', { action: "setState", parameters: [saveObject], time: global.instances[ namespace ].getTime( ) } ); + socket.emit( 'message', { + action: "setState", + parameters: [ saveObject ], + time: global.instances[ namespace ].getTime( ) + } ); } else { var instance = namespace; @@ -204,26 +224,46 @@ function OnConnection( socket ) { ], time: global.instances[ namespace ].getTime( ) } ); - - socket.emit( 'message', clientMessage ); - } + socket.pending = false; + + xapi.logClient( saveObject, loadInfo[ 'application_path' ], loadInfo[ 'save_name' ], namespace, clientDescriptor.properties || {}, true, true ); } else { //this client is not the first, we need to get the state and mark it pending - var firstclient = Object.keys( global.instances[ namespace ].clients )[ 0 ]; - firstclient = global.instances[ namespace ].clients[ firstclient ]; - firstclient.emit( 'message', { action: "getState", respond: true, time: global.instances[ namespace ].getTime( ) } ); - global.instances[ namespace ].Log( 'GetState from Client', 2 ); + if ( ! global.instances[ namespace ].pendingList.pending ) { + var firstclient = Object.keys( global.instances[ namespace ].clients )[ 0 ]; + firstclient = global.instances[ namespace ].clients[ firstclient ]; + firstclient.emit( 'message', { + action: "getState", + respond: true, + time: global.instances[ namespace ].getTime( ) + } ); + global.instances[ namespace ].Log( 'GetState from Client', 2 ); + global.instances[ namespace ].pendingList.pending = true; + } socket.pending = true; - socket.pendingList.push( clientMessage ); - for ( var i in global.instances[ namespace ].clients ) { - var client = global.instances[ namespace ].clients[ i ]; - if( client.id != socket.id ) { - client.emit ( 'message', clientMessage ); - } + + } + + //Create a child in the application's 'clients.vwf' global to represent this client. + var clientNodeMessage = { + action: "createChild", + parameters: [ "http://vwf.example.com/clients.vwf", socket.id, clientDescriptor ], + time: global.instances[ namespace ].getTime( ) + }; + + // Send messages to all the existing clients (that are not pending), + // telling them to create a new node under the "clients" parent for the new client + for ( var i in global.instances[ namespace ].clients ) { + var client = global.instances[ namespace ].clients[ i ]; + if ( !client.pending ) { + client.emit ( 'message', clientNodeMessage ); } } + if ( global.instances[ namespace ].pendingList.pending ) { + global.instances[ namespace ].pendingList.push( clientNodeMessage ); + } socket.on( 'message', function ( msg ) { @@ -232,62 +272,179 @@ function OnConnection( socket ) { var message = JSON.parse( msg ); } catch ( e ) { + console.error( "Error on socket message: ", e ); return; } message.client = socket.id; message.time = global.instances[ namespace ].getTime( ); - //distribute message to all clients on given instance - for ( var i in global.instances[ namespace ].clients ) { - var client = global.instances[ namespace ].clients[ i ]; + if ( message.result === undefined ) { + + //distribute message to all clients on given instance + for ( var i in global.instances[ namespace ].clients ) { + var client = global.instances[ namespace ].clients[ i ]; - //if the message was get state, then fire all the pending messages after firing the setState - if ( message.action == "getState" ) { - global.instances[ namespace ].Log( 'Got State', 2 ); - var state = message.result; - global.instances[ namespace ].Log( state, 2 ); - client.emit( 'message', { action: "setState", parameters: [ state ], time: setStateTime } ); - client.pending = false; - for ( var j = 0; j < client.pendingList.length; j++ ) { - client.emit( 'message', client.pendingList[ j ] ); - } - client.pendingList = [ ]; - } - else { //just a regular message, so push if the client is pending a load, otherwise just send it. - if ( client.pending === true ) { - client.pendingList.push( message ); - } - else { + if ( ! client.pending ) { client.emit( 'message', message ); } } + + if ( global.instances[ namespace ].pendingList.pending ) { + global.instances[ namespace ].pendingList.push( message ); + } + + } else if ( message.action == "getState" ) { + + //distribute message to all clients on given instance + for ( var i in global.instances[ namespace ].clients ) { + var client = global.instances[ namespace ].clients[ i ]; + + //if the message was get state, then fire all the pending messages after firing the setState + if ( client.pending ) { + global.instances[ namespace ].Log( 'Got State', 2 ); + var state = message.result; + global.instances[ namespace ].Log( state, 2 ); + client.emit( 'message', { action: "setState", parameters: [ state ], time: setStateTime } ); + client.pending = false; + for ( var j = 0; j < global.instances[ namespace ].pendingList.length; j++ ) { + client.emit( 'message', global.instances[ namespace ].pendingList[ j ] ); + } + xapi.logClient( state, undefined, undefined, namespace, GetClientDescriptor( client ).properties || {}, true, false ); + } + } + + global.instances[ namespace ].pendingList = [ ]; + + } else if ( message.action === "execute" ) { + + var evaluation = socket.pendingEvaluations && socket.pendingEvaluations.shift(); + + if ( evaluation ) { + evaluation.resolve( message.result ); + clearTimeout( evaluation.timeout ); + } + } + } ); // When a client disconnects, go ahead and remove the instance data socket.on( 'disconnect', function ( ) { // Remove the disconnecting client + var leavingClient = global.instances[ namespace ].clients[ socket.id ]; global.instances[ namespace ].clients[ socket.id ] = null; delete global.instances[ namespace ].clients[ socket.id ]; - + if ( leavingClient.pendingEvaluations ) { + leavingClient.pendingEvaluations.forEach( function( evaluation ) { + evaluation.reject( new Error( "connection closed" ) ); + clearTimeout( evaluation.timeout ); + } ); + } + // Notify others of the disconnecting client. Delete the child representing this client in the application's `clients.vwf` global. var clientMessage = { action: "deleteChild", parameters: [ "http://vwf.example.com/clients.vwf", socket.id ], time: global.instances[ namespace ].getTime( ) }; for ( var i in global.instances[ namespace ].clients ) { var client = global.instances[ namespace ].clients[ i ]; - if( client.id != socket.id ) { - client.emit ( 'message', clientMessage ); + if ( ! client.pending ) { + client.emit ( 'message', clientMessage ); } } + if ( global.instances[ namespace ].pendingList.pending ) { + global.instances[ namespace ].pendingList.push( clientMessage ); + } // If it's the last client, delete the data and the timer if ( Object.keys( global.instances[ namespace ].clients ).length == 0 ) { clearInterval( global.instances[ namespace ].timerID ); delete global.instances[ namespace ]; + xapi.logClient( undefined, loadInfo[ 'application_path' ], loadInfo[ 'save_name' ], namespace, clientDescriptor.properties || {}, false, true ); + } else { + xapi.logClient( undefined, loadInfo[ 'application_path' ], loadInfo[ 'save_name' ], namespace, clientDescriptor.properties || {}, false, false ); } } ); } -exports.OnConnection = OnConnection; \ No newline at end of file +function Evaluate( namespace, node, expression ) { + + return new Promise( function( resolve, reject ) { + + var firstClientID = Object.keys( global.instances[ namespace ].clients )[ 0 ]; + var firstClient = global.instances[ namespace ].clients[ firstClientID ]; + + if ( firstClient ) { + firstClient.pendingEvaluations = firstClient.pendingEvaluations || []; + firstClient.pendingEvaluations.push( { + resolve: resolve, + reject: reject, + timeout: setTimeout( function() { reject( new Error( "timeout" ) ) }, 1000 ), + } ); + firstClient.emit( "message", { node: node, action: "execute", parameters: [ expression ], respond: true, time: global.instances[ namespace ].getTime() } ); + } else { + reject( new Error( "no clients are connected" ) ); + } + + } ); + +} + +/// Get a descriptor for the `clients.vwf` child for a new client. An authenticator may set a +/// descriptor in the session at `session.vwf.client`. If the authenticator doesn't provide a +/// descriptor, use an empty node inheriting from `client.vwf`. + +function GetClientDescriptor( socket ) { + + // socket.io doesn't provide access to the request and the session, but we do have the cookies. + // Create a mock request and run it through the session middleware to recreate the session. This + // creates a session object at `mockRequest.session`. + + var mockRequest = { + headers: { cookie: socket.handshake.headers.cookie }, + connection: {}, + session: {}, + }; + + var mockResponse = { + getHeader: function() {}, + setHeader: function() {}, + }; + + sessionStack.forEach( function( middleware ) { + middleware( mockRequest, mockResponse, function() {} ); + } ); + + // Get the descriptor from `vwf.client` in the session. + + var descriptor = ( mockRequest.session.vwf || {} ).client || {}; + + // Set the default prototype. + + if ( ! descriptor.extends ) { + descriptor.extends = "http://vwf.example.com/client.vwf"; + } + + return descriptor; + +} + +/// Middleware stack to parse a cookie session from `req.headers.cookie` into `req.session`. + +var sessionStack = [ + cookieParser(), + cookieSession( { secret: config.get( 'session.secret' ) } ), +]; + +function GetInstances() { + return global.instances; +} + +function IsReview( instanceID ) { + return !!global.instances[ instanceID ].isReview; +} + +exports.OnConnection = OnConnection; +exports.Evaluate = Evaluate; +exports.GetInstances = GetInstances; +exports.IsReview = IsReview; diff --git a/lib/nodejs/serve-handler.js b/lib/nodejs/serve-handler.js index e3834def6..b98e7c822 100755 --- a/lib/nodejs/serve-handler.js +++ b/lib/nodejs/serve-handler.js @@ -18,7 +18,7 @@ function File( request, response, filename ) { function Component( request, response, filename ) { if ( request.method == "GET" ) { if ( helpers.IsFile( filename + ".yaml" ) ) { - serve.YAML( filename.replace( /\//g, libpath.sep ) + ".yaml", response, url.parse( request.url, true ) ); + serve.YAML( request, filename.replace( /\//g, libpath.sep ) + ".yaml", response, url.parse( request.url, true ) ); return true; } if ( helpers.IsFile ( filename + ".json" ) ) { diff --git a/lib/nodejs/serve.js b/lib/nodejs/serve.js index 5413ac069..83aa69fc0 100755 --- a/lib/nodejs/serve.js +++ b/lib/nodejs/serve.js @@ -4,15 +4,19 @@ var filecache = require( './file-cache' ), - YAML = require( 'js-yaml' ), + yamlcache = require( './yaml-cache' ), fs = require( 'fs' ), helpers = require( './helpers' ); -// First, if the FileCache has not been instantiated, do so. +// First, if the FileCache and YamlCache have not been instantiated, do so. if ( global.FileCache == undefined ) { var FileCache = new filecache._FileCache( ); global.FileCache = FileCache; } +if ( global.YamlCache == undefined ) { + var YamlCache = new yamlcache._YamlCache( ); + global.YamlCache = YamlCache; +} // Basic helper function to redirect a request. function ServeRedirect( url, response ) { @@ -78,46 +82,9 @@ function ServeJSONFile( filename, response, URL ) { } ); } -//Parse and serve a YAML file -function ServeYAML( filename, response, URL ) { - var tf = filename; - fs.readFile( filename, "utf8", function ( err, data ) { - if (err) { - response.writeHead( 500, { - "Content-Type": "text/plain" - } ); - response.write( err + "\n" ); - response.end(); - return; - } - - // Remove the Byte Order Mark (BOM) if one exists - var file = data.replace( /^\uFEFF/, '' ); - - //global.log(tf); - try { - var deYAML = JSON.stringify( YAML.load( file ) ); - } catch ( e ) { - global.log( "error parsing YAML " + filename ); - _404( response ); - return; - } - - var type = "application/json"; - - var callback = URL.query.callback; - - if ( callback ) { - deYAML = callback + "(" + deYAML + ")"; - type = "application/javascript"; - } - - response.writeHead( 200, { - "Content-Type": type - } ); - response.write( deYAML, "utf8" ); - response.end(); - } ); +// Serve YAML, using the YamlCache implementation. +function ServeYAML( request, filename, response, URL ) { + YamlCache.ServeYAML( request, filename, response, URL ); } diff --git a/lib/nodejs/stream.js b/lib/nodejs/stream.js new file mode 100644 index 000000000..6659a930f --- /dev/null +++ b/lib/nodejs/stream.js @@ -0,0 +1,148 @@ +var path = require( 'path' ), + mime = require( 'mime' ), + fs = require( 'fs' ), + helpers = require( './helpers' ), + util = require('util'), + formidable = require('formidable'), + os = require('os'), + parseurl = require( './parse-url' ), + AdmZip = require( 'adm-zip' ); +var streamStr = 'stream', uploadStr = 'upload'; + +function OnStreamRequest( request, response, parsedRequest, segments ) { + if ( request.url !== '' && segments.length > 1 ) { + var file = path.join(__dirname, '../..'); + for (var i = 1; i < segments.length; i++) { + file = path.join( file, segments[i] ); + } + var m = mime.lookup( file ); + if ( m.substring( 0, 5 ) === "image" ) { + fs.readFile( file, ( err, img ) => { + if ( err ) { + if ( err.code === "ENOENT" ) { + response.status( 404 ).send( file + " not found" ); + } else { + throw err; + } + } else { + response.writeHead( 200, { 'Content-Type': m } ); + response.end( img, 'binary' ); + } + } ); + } else { + fs.stat( file, ( err, stats ) => { + if ( err ) { + response.sendStatus( 404 ); + return; + } + + const total = stats.size; + if ( total > 0 ) { + const range = request.headers.range || "bytes=0-"; + const positions = range.replace( /bytes=/, "" ).split( "-" ); + const start = parseInt( positions[ 0 ], 10 ); + const end = positions[1] ? parseInt( positions[1], 10 ) : total - 1; + response.writeHead( 206, { + "Content-Range": "bytes " + start + "-" + end + "/" + total, + "Accept-Ranges": "bytes", + "Content-Length": end - start + 1, + "Content-Type": m + } ); + const stream = + fs.createReadStream( file, { start: start, end: end } ). + on( "open", () => stream.pipe( response ) ). + on( "error", error => response.end( error ) ); + } else { + response.writeHead( 206, { + "Content-Range": "bytes */0", + "Accept-Ranges": "bytes", + "Content-Length": 0, + "Content-Type": m + } ); + response.end(); + } + } ); + } + } else { + response.end(''); + } +} //close OnStreamRequest + + +function HandlePersistenceUpload( request, response, parsedRequest, segments ) { + if ( segments.length >= 2 ) { + var streamPath; + var form = new formidable.IncomingForm(); + form.keepExtensions = true; + // create the path in file system if not there + var relPath = parsedRequest[ 'public_path' ]; + for (var i = 1; i < segments.length; i++) { + var relPath = helpers.JoinPath( relPath, segments[i] ); + } + CreateDirectory( relPath ); + form.on('fileBegin', function(name, file) { + // redirect file to the specified path + var filename = file.name.replace(/\s+/g, '_'); + file.path = helpers.JoinPath( './documents', relPath, filename); + streamPath = helpers.JoinPath(streamStr, 'documents', relPath, filename); + }); + // parse the file and then send response + form.parse(request, function(err, fields, files) { + if ( ! err ) { + + // If this is a .zip file, unzip it first + if ( streamPath.endsWith( ".zip" ) ) { + var zip = new AdmZip( files.file.path ); + zip.extractAllTo( helpers.JoinPath( './documents', relPath ) ); + streamPath = streamPath.substring( 0, streamPath.indexOf( ".zip" ) ); + } + response.writeHead(200, {'content-type': 'text/plain'}); + response.end(streamPath); + } else { + console.log("Error parsing file: " + err); + response.writeHead(500); + response.end(); + } + }); + return true; + } + return false; +} // close HandlePersistenceUpload + +function CreateDirectory( relPath ) { + var application_segments = helpers.GenerateSegments( relPath ); + var current_directory = "./documents"; + while ( application_segments.length > 0 ) { + current_directory = helpers.JoinPath( current_directory, application_segments.shift() ); + if ( ! helpers.IsDirectory( current_directory ) ) { + fs.mkdirSync( current_directory ); + } + } +} + + +// The Serve function takes the nodeJS request, nodeJS response and the parsedRequest, and +// attempts to see if it is a properly formed stream related request. +function Serve( request, response, parsedRequest ) { + if ( parsedRequest[ 'private_path' ] ) { + var segments = helpers.GenerateSegments( parsedRequest[ 'private_path' ] ); + if ( segments.length > 0 ) { + switch ( segments[ 0 ] ) { + case uploadStr: + if ( request.method == "POST" ) { + var result = HandlePersistenceUpload( request, response, parsedRequest, segments ); + return result; + } + return false; + case streamStr: + if ( request.method == "GET" ) { + OnStreamRequest( request, response, parsedRequest, segments ); + return true; + } + return false; + } + } + } + return false; +} +exports.Serve = Serve; \ No newline at end of file diff --git a/lib/nodejs/vwf.js b/lib/nodejs/vwf.js index 6a0f383b4..d9de6c1f1 100755 --- a/lib/nodejs/vwf.js +++ b/lib/nodejs/vwf.js @@ -7,7 +7,9 @@ var parseurl = require( './parse-url' ), servehandler = require( './serve-handler' ), helpers = require( './helpers' ), application = require( './application' ), - url = require( 'url' ); + url = require( 'url' ), + lobby = require( './lobby' ), + finalhandler = require( 'finalhandler' ); // HandleParsableRequest takes the incoming request, and uses the helper library functions to parse the // URL into its 'public_path, application, instance and private_path' components, and then attempts to redirect @@ -16,6 +18,10 @@ var parseurl = require( './parse-url' ), function HandleParsableRequest( request, response ) { var parsedRequest = parseurl.Process( url.parse(request.url).pathname ); + if ( ! parsedRequest ) { + return false; + } + // Used to check if the URL referer was an application instance. Components added by the "includes" keyword // in yaml are loaded using jQuery which appends a query parameter to handle the callback. Checking the referer // allows those URLs to be handled correctly, instead of treating them as a new application that needs an instance ID. @@ -124,25 +130,31 @@ function HandleFileRequest( request, response ) { } // Serve is the top level function for serving requests. It first attempts to -// serve the request based on parsing the incoming URL. +// serve the request using the the lobby, which is an Express application. +// Lobby errors are handled using finalhandler in the same way that Express would. +// Otherwise, it attempts to serve the request based on parsing the incoming URL. // If that fails, it continues to attempt to serve the request as a 'proxy' request, // if that also does not serve anything to the request, then an attempt is made // to handle the request as a simple direct request for a file within the public // directory structure. // If all that fails, serve up a 404 response since the request was not handled. function Serve( request, response ) { - var handledRequest = HandleParsableRequest( request, response ); - if ( ! ( handledRequest ) ) { - handledRequest = HandleProxyRequest( request, response ); - } - if ( ! ( handledRequest ) ) { - handledRequest = HandleFileRequest( request, response ); - } - if ( ! ( handledRequest ) ) { - global.log("404 : " + url.parse( request.url ).pathname ) - serve._404( response, "404.html" ); - - } + lobby( request, response, function( err ) { + if ( err ) { + finalhandler( request, response, { + env: lobby.get('env') + } )( err ); + } else { + var handledRequest = + HandleParsableRequest( request, response ) || + HandleProxyRequest( request, response ) || + HandleFileRequest( request, response ); + if ( ! ( handledRequest ) ) { + global.log("404 : " + url.parse( request.url ).pathname ) + serve._404( response, "404.html" ); + } + } + } ); } -exports.Serve = Serve; \ No newline at end of file +exports.Serve = Serve; diff --git a/lib/nodejs/xapi.js b/lib/nodejs/xapi.js new file mode 100644 index 000000000..79e305053 --- /dev/null +++ b/lib/nodejs/xapi.js @@ -0,0 +1,207 @@ +"use strict"; + +/// xAPI logging utilities. Record user experience events in an xAPI-format log. + +var Promise = require( "bluebird" ), + fs = Promise.promisifyAll( require( "fs" ) ), + mkdirp = Promise.promisify( require( "mkdirp" ) ), + _ = require( "lodash" ); + +/// Record scenario or session creation in the xAPI log. + +exports.logCreation = function( state, application, document, user ) { + + var descriptor = { + state: + _.get( state, "nodes[1].children.scenarioController.properties", {} ), + document: { + uri: application + "/0000000000000000/load/" + document + "/" } + }; + + var statement = JSON.stringify( { + actor: xapiActor( user ), + verb: xapiVerbs.imported, + object: xapiActivity( descriptor ), + stored: ( new Date ).toISOString(), + } ) + "\n"; + + mkdirp( "log/" ).then( () => fs.appendFileAsync( "log/xapi-statements.json", statement ) ); + +}; + +exports.logClient = function( state, application, document, instance, user, joining, only ) { + + var descriptor = { + state: state && + _.get( state, "nodes[1].children.scenarioController.properties", {} ), + document: document && { + uri: application + "/0000000000000000/load/" + document + "/" }, + instance: instance && + instance.replace( /index.vwf\//, "" ) + "/", + }; + + var statements = ""; + + if ( only && joining ) { + statements += JSON.stringify( { + actor: xapiActor( user ), + verb: xapiVerbs.launched, + object: xapiActivity( descriptor ), + result: document && instance && + { response: descriptor.instance }, + stored: ( new Date ).toISOString(), + } ) + "\n"; + } + + statements += JSON.stringify( { + actor: xapiActor( user ), + verb: joining ? xapiVerbs.attended : xapiVerbs.exited, + object: xapiActivity( descriptor ), + stored: ( new Date ).toISOString(), + } ) + "\n"; + + if ( only && ! joining ) { + statements += JSON.stringify( { + actor: xapiActor( user ), + verb: xapiVerbs.terminated, + object: xapiActivity( descriptor ), + stored: ( new Date ).toISOString(), + } ) + "\n"; + } + + mkdirp( "log/" ).then( () => fs.appendFileAsync( "log/xapi-statements.json", statements ) ); + +}; + +/// Return an xAPI [Actor] (https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#actor) +/// description of the user. +/// +/// @param {Object} user +/// +/// @returns {Object} xAPI Actor + +function xapiActor( user ) { + + var name = n( user.first_name ) + n( user.middle_initial, "." ) + + n( user.last_name ); + + var account = a( user.first_name ) + a( user.middle_initial ) + + a( user.last_name ) + '[' + ( user.instructor ? 'Instructor' : 'Student' ) + '] '; + + name = name.slice( 0, -1 ) || "Unknown" + account = account.slice( 0, -1 ) || "unknown" + + return { + name: + name, + account: { + homePage: "http://itdg.example.com", + name: account + } + }; + + function n( string, terminator ) { + if ( string ) { + return string + ( terminator || "" ) + " "; + } else { + return ""; + } + } + + function a( string ) { + var slug = + (string || "").replace( /[^0-9A-Za-z]+/, "-" ).toLowerCase(); + if ( slug ) { + return slug + "."; + } else { + return ""; + } + } + +} + +/// A selection of xAPI [Verbs] (https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#verb) from +/// the [ADL Controlled Vocabulary] (http://xapi.vocab.pub/datasets/adl/). + +var xapiVerbs = { + + attended: { + id: "http://adlnet.gov/expapi/verbs/attended", + display: { "en-US": "attended" }, + }, + completed: { + id: "http://adlnet.gov/expapi/verbs/completed", + display: { "en-US": "completed" }, + }, + exited: { + id: "http://adlnet.gov/expapi/verbs/exited", + display: { "en-US": "exited" }, + }, + imported: { + id: "http://adlnet.gov/expapi/verbs/imported", + display: { "en-US": "imported" }, + }, + initialized: { + id: "http://adlnet.gov/expapi/verbs/initialized", + display: { "en-US": "initialized" }, + }, + interacted: { + id: "http://adlnet.gov/expapi/verbs/interacted", + display: { "en-US": "interacted" }, + }, + launched: { + id: "http://adlnet.gov/expapi/verbs/launched", + display: { "en-US": "launched" }, + }, + "logged-in": { + id: "https://w3id.org/xapi/adl/verbs/logged-in", + display: { "en-US": "logged-in" }, + }, + "logged-out": { + id: "https://w3id.org/xapi/adl/verbs/logged-out", + display: { "en-US": "logged-out" }, + }, + terminated: { + id: "http://adlnet.gov/expapi/verbs/terminated", + display: { "en-US": "terminated" }, + }, + +}; + +/// Return an xAPI [Activity Object] (https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#object) +/// for the a scenario or session document or instance. +/// +/// @param {Object} descriptor +/// `manifest.js`-style scenario or session descriptor containing the `state` and `document` +/// and/or `instance` fields. +/// +/// @returns {Object} xAPI Activity Object + +function xapiActivity( descriptor ) { + + return { + id: ( descriptor.document && descriptor.document.uri ) || + descriptor.instance, + definition: { + name: descriptor.state && { "en-US": title( descriptor ) }, + type: "http://adlnet.gov/expapi/activities/simulation", + } + }; + + function title( descriptor ) { + + var state = descriptor.state || {}, + classroom = state.classroom || {}; + + if ( classroom.company || classroom.platoon || classroom.unit ) { + return ( state.scenarioTitle || "Untitled Session" ) + ", " + + "Company " + ( classroom.company || "-" ) + " " + + "Platoon " + ( classroom.platoon || "-" ) + " " + + "Unit " + ( classroom.unit || "-" ); + } else { + return state.scenarioTitle || "Untitled Session"; + } + + } + +} diff --git a/lib/nodejs/yaml-cache.js b/lib/nodejs/yaml-cache.js new file mode 100644 index 000000000..e3e310b6e --- /dev/null +++ b/lib/nodejs/yaml-cache.js @@ -0,0 +1,138 @@ +// yaml-cache.js +// This file contains the implementation of the yaml cache system used by the VWF nodeJS server. + + +var fs = require( 'fs' ), + YAML = require( 'js-yaml' ), + url = require( 'url' ), + helpers = require( './helpers' ); + + +// Helper function to generate a hash for a string. +function hash( str ) { + return require( 'crypto' ).createHash( 'md5' ).update( str ).digest( "hex" ); +} + +function _YamlCache( ) { + this.filesMap = { }; + this.enabled = true; + this.clear = function ( ) { + this.filesMap = { }; + }; + + // Function for getting a file from the file cache. + // Asynchronous, returns file to the callback function. + // Passes null to the callback function if there is no such file. + this.getJsonStr = function ( path, callback ) { + + function getLastModifiedTime ( path ) { + try { + var stats = fs.statSync(path); + return stats.mtime; + } + catch(err) { + return null; + } + } + + function updateSources(obj, key, dirPath) { + if (obj instanceof Array) { + for(var i = 0; i < obj.length; i++) { + updateSources(obj[i], key, dirPath); + } + } else { + for(var prop in obj) { + if(prop === key) { + obj[prop] = getPathWithMTime(obj[prop], dirPath); + return; + } + if(obj[prop] instanceof Object || obj[prop] instanceof Array) { + updateSources(obj[prop], key, dirPath); + } + } + } + } + if ( this.filesMap[ path ] ) { + callback( this.filesMap[ path ] ); + return; + } + + function getPathWithMTime( file, dirPath ){ + var tempFile = file; + var updatedURL = url.parse( tempFile ).pathname; + if ( file.indexOf('vwf.example.com') >= 0 ) { + tempFile = helpers.JoinPath( global.vwfRoot, "support/proxy/vwf.example.com/", updatedURL ); + } else if (dirPath) { + tempFile = dirPath + tempFile; + } + var mtime = getLastModifiedTime(tempFile); + return file + (mtime ? '?m=' + mtime.getTime() : ''); + } + + + // if got here, have no record of this file yet. + var datatype = 'utf8'; + var data = fs.readFileSync( path, datatype ); + var stats = fs.statSync( path ); + + if ( data ) { + // Remove the Byte Order Mark (BOM) if one exists + var file = data.replace( /^\uFEFF/, '' ); + + //global.log(tf); + try { + // this check is done to avoid traversing entire json tree for every file + var containsSourceKey = file.indexOf('source') >= 0; + var yamlObj = YAML.load( file ); + if ( containsSourceKey ) { + var dirPath = path.substring( 0, path.lastIndexOf( '\\' ) + 1 ); + updateSources(yamlObj, 'source', dirPath); + } + var deYAML = JSON.stringify( yamlObj ); + this.filesMap[ path ] = deYAML; + callback(deYAML); + return; + } catch ( e ) { + global.log( "error parsing YAML " + filename ); + _404( response ); + callback(null); + return; + } + } + // File was not in cache, and did not exists, return null. + callback( null ); + }; + //Parse and serve a YAML file + //move this stuff to yaml-cache + this.ServeYAML = function ( request, filename, response, URL ) { + + YamlCache.getJsonStr( filename, function ( data ) { + if ( !data ) { + response.writeHead( 500, { + "Content-Type": "text/plain" + } ); + response.write( 'file load error' + '\n' ); + response.end( ); + return; + } + + var type = "application/json"; + + var callback = URL.query.callback; + + if ( callback ) { + data = callback + "(" + data + ")"; + type = "application/javascript"; + } + + response.writeHead( 200, { + "Content-Type": type + } ); + response.write( data, "utf8" ); + response.end(); + } ); + }; +} + + +exports._YamlCache = _YamlCache; \ No newline at end of file diff --git a/log/xapi-statements.json b/log/xapi-statements.json new file mode 100644 index 000000000..4d4c513b3 --- /dev/null +++ b/log/xapi-statements.json @@ -0,0 +1,14 @@ +{"actor":{"name":"qewr","account":{"homePage":"http://itdg.example.com","name":"qewr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"name":{"en-US":"newscen"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-02T19:28:51.461Z"} +{"actor":{"name":"qewr","account":{"homePage":"http://itdg.example.com","name":"qewr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/launched","display":{"en-US":"launched"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"name":{"en-US":"newscen"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"result":{"response":"/ITDG/P9YHBGn0ERGPsUIr/"},"stored":"2018-07-02T19:28:55.061Z"} +{"actor":{"name":"qewr","account":{"homePage":"http://itdg.example.com","name":"qewr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/attended","display":{"en-US":"attended"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"name":{"en-US":"newscen"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-02T19:28:55.061Z"} +{"actor":{"name":"qewr","account":{"homePage":"http://itdg.example.com","name":"qewr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/exited","display":{"en-US":"exited"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-02T19:46:20.652Z"} +{"actor":{"name":"qewr","account":{"homePage":"http://itdg.example.com","name":"qewr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/terminated","display":{"en-US":"terminated"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-02T19:46:20.653Z"} +{"actor":{"name":"quad","account":{"homePage":"http://itdg.example.com","name":"quad.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/launched","display":{"en-US":"launched"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"name":{"en-US":"newscen"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"result":{"response":"/ITDG/fhFjDMGutbFkBfa0/"},"stored":"2018-07-03T14:03:29.326Z"} +{"actor":{"name":"quad","account":{"homePage":"http://itdg.example.com","name":"quad.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/attended","display":{"en-US":"attended"}},"object":{"id":"/ITDG/0000000000000000/load/newscen/","definition":{"name":{"en-US":"newscen"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-03T14:03:29.326Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T13:50:44.170Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T13:50:46.305Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T14:14:20.895Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T14:14:23.418Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T14:15:38.866Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load//","definition":{"name":{"en-US":"Untitled Session"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T14:19:03.095Z"} +{"actor":{"name":"dr","account":{"homePage":"http://itdg.example.com","name":"dr.[Instructor]"}},"verb":{"id":"http://adlnet.gov/expapi/verbs/imported","display":{"en-US":"imported"}},"object":{"id":"/ITDG/0000000000000000/load/dgfdg/","definition":{"name":{"en-US":"dgfdg"},"type":"http://adlnet.gov/expapi/activities/simulation"}},"stored":"2018-07-05T14:32:04.737Z"} diff --git a/node_vwf.js b/node_vwf.js index bf731912c..1b8b740bd 100644 --- a/node_vwf.js +++ b/node_vwf.js @@ -148,9 +148,12 @@ function startVWF() { return null; } } - } + }, + 'destroy buffer size': Infinity, // https://github.com/socketio/socket.io/issues/1592#issuecomment-45885463; should be fixed in socket.io 1.0 } ); socketManager.set( 'transports', [ 'websocket' ] ); + socketManager.set( 'heartbeat timeout', 3600 ); // ! hour timeout + socketManager.set( 'close timeout', 3600 ); // 1 hour timeout socketManager.sockets.on( 'connection', reflector.OnConnection ); } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ce3b268cd..5770e3973 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,149 +1,2581 @@ { "name": "vwf", "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, "dependencies": { + "adm-zip": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz", + "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "amqplib": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.1.tgz", + "integrity": "sha1-fMz+ur5WwumE6noiQ/fO/m+/xs8=", + "requires": { + "bitsyntax": "0.0.4", + "bluebird": "3.4.7", + "buffer-more-ints": "0.0.2", + "readable-stream": "1.1.14" + }, + "dependencies": { + "bitsyntax": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", + "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", + "requires": { + "buffer-more-ints": "0.0.2" + } + }, + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" + }, + "buffer-more-ints": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", + "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + } + } + }, + "append-field": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", + "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" + }, + "archiver": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-0.11.0.tgz", + "integrity": "sha1-mBd9p6bAGSt/J5jzDNbquKvXZpA=", + "requires": { + "async": "0.9.2", + "buffer-crc32": "0.2.13", + "glob": "3.2.11", + "lazystream": "0.1.0", + "lodash": "2.4.2", + "readable-stream": "1.0.34", + "tar-stream": "0.4.7", + "zip-stream": "0.4.1" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "async": { + "version": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "requires": { + "readable-stream": "1.0.34" + } + }, + "bluebird": { + "version": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.0.tgz", + "integrity": "sha1-KLhHk1qLtW1/8cfro2MbCdWkmyQ=" + }, + "body-parser": { + "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.15.1.tgz", + "integrity": "sha1-m87vBmm4+LlD8K2M5dlXFr10D9I=", + "requires": { + "bytes": "2.3.0", + "content-type": "1.0.2", + "debug": "2.2.0", + "depd": "1.1.0", + "http-errors": "1.4.0", + "iconv-lite": "0.4.13", + "on-finished": "2.3.0", + "qs": "6.1.0", + "raw-body": "2.1.7", + "type-is": "1.6.13" + }, + "dependencies": { + "bytes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.3.0.tgz", + "integrity": "sha1-1baAoWW2IBc5rLYRVCqrwtjOsHA=" + }, + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "depd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=" + }, + "http-errors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.4.0.tgz", + "integrity": "sha1-bAJC3qaz33r9oVPHEImzHG6Cqr8=", + "requires": { + "inherits": "2.0.1", + "statuses": "1.3.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "statuses": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.0.tgz", + "integrity": "sha1-jlV1jLIOdoLB9Pzo3KswvwHR4Ho=" + } + } + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + }, + "dependencies": { + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + } + } + }, + "qs": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.1.0.tgz", + "integrity": "sha1-7B0WJrJCeNmfD99FSeUk4k7O6yY=" + }, + "raw-body": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + } + } + }, + "type-is": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.13.tgz", + "integrity": "sha1-boO6e8MM0zp7sLf7AHN6IIW/nQg=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.11" + }, + "dependencies": { + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + } + } + } + } + } + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "compress-commons": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-0.1.6.tgz", + "integrity": "sha1-DHQIcP3ljLpRbwrAyCLjOguF36M=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "0.3.4", + "readable-stream": "1.0.34" + } + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.2.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz", + "integrity": "sha1-i0Ou125xSDk40SqNRsbPGgCx+BY=", + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "config": { + "version": "https://registry.npmjs.org/config/-/config-1.21.0.tgz", + "integrity": "sha1-g3GcAmOmaeS8TMnJ5YGM2ZajLLk=", + "requires": { + "json5": "0.4.0" + }, + "dependencies": { + "json5": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", + "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=" + } + } + }, + "cookie-parser": { + "version": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + } + } + }, + "cookie-session": { + "version": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-alpha.1.tgz", + "integrity": "sha1-AmbRse7nynp49Td3oKCwVzvjLV8=", + "requires": { + "cookies": "0.5.1", + "debug": "2.2.0", + "on-headers": "1.0.1" + }, + "dependencies": { + "cookies": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.5.1.tgz", + "integrity": "sha1-JWDDBP6PjL0ALgi5WZ0udHnTcpg=", + "requires": { + "keygrip": "1.0.1" + }, + "dependencies": { + "keygrip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.1.tgz", + "integrity": "sha1-sC+kgW7vIajEs1yp5Skh/8iaMOk=" + } + } + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc32-stream": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-0.3.4.tgz", + "integrity": "sha1-c7wltF+sHbZjIjGnv86JJ+nwZVI=", + "requires": { + "buffer-crc32": "0.2.13", + "readable-stream": "1.0.34" + } + }, "crypto": { - "version": "0.0.3", - "from": "crypto@0.0.x" + "version": "https://registry.npmjs.org/crypto/-/crypto-0.0.3.tgz", + "integrity": "sha1-RwqBuGvkxe4XrMggeh9TFa4g27A=" }, - "socket.io": { - "version": "0.9.16", - "from": "socket.io@0.9.x", + "dateformat": { + "version": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + }, "dependencies": { - "socket.io-client": { - "version": "0.9.16", - "from": "socket.io-client@0.9.16", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz", + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.3.5", + "object-assign": "4.1.0", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, "dependencies": { - "uglify-js": { - "version": "1.2.5", - "from": "uglify-js@1.2.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz" + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } + } }, - "ws": { - "version": "0.4.31", - "from": "ws@0.4.x", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.0" + }, "dependencies": { - "commander": { - "version": "0.6.1", - "from": "commander@~0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "1.0.1" + }, + "dependencies": { + "array-find-index": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz", + "integrity": "sha1-C8Jd2slB7IpJauJY/UrBiAA+868=" + } + } }, - "nan": { - "version": "0.3.2", - "from": "nan@~0.3.0" + "signal-exit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz", + "integrity": "sha1-PAVDtl17T7xgts2UWT2b9DZzm+g=" + } + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "normalize-package-data": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", + "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=", + "requires": { + "hosted-git-info": "2.1.5", + "is-builtin-module": "1.0.0", + "semver": "5.3.0", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=" }, - "tinycolor": { - "version": "0.0.1", - "from": "tinycolor@0.x" + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + } + } }, - "options": { - "version": "0.0.5", - "from": "options@>=0.0.5" + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.3" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + } + } + }, + "spdx-expression-parse": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.3.tgz", + "integrity": "sha1-yjw4KMT+qKpEmXiEs5j8XWdDZEI=" + } + } } } }, - "xmlhttprequest": { - "version": "1.4.2", - "from": "xmlhttprequest@1.4.2", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz" + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" }, - "active-x-obfuscator": { - "version": "0.0.1", - "from": "active-x-obfuscator@0.0.1", - "resolved": "https://registry.npmjs.org/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz", + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, "dependencies": { - "zeparser": { - "version": "0.0.5", - "from": "zeparser@0.0.5", - "resolved": "https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz" + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.3.5", + "path-type": "1.1.0" + }, + "dependencies": { + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.6", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha1-UUw4dysxvuLgi+3CGgrrOr9UwZ4=" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.0" + }, + "dependencies": { + "error-ex": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "integrity": "sha1-5ntD8+gsluo6WE/+4Ln8MyXYAtk=", + "requires": { + "is-arrayish": "0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + } + } + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + }, + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + } + } + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.6", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha1-UUw4dysxvuLgi+3CGgrrOr9UwZ4=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + } + } } } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "2.0.1" + }, + "dependencies": { + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "1.0.1" + }, + "dependencies": { + "is-finite": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", + "integrity": "sha1-ZDhgPq6+J5OUj/SkJi7I2z1iWXs=", + "requires": { + "number-is-nan": "1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", + "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=" + } + } + } + } + } + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "4.0.1" + } + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.14", + "streamsearch": "0.1.2" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "express": { + "version": "https://registry.npmjs.org/express/-/express-4.13.3.tgz", + "integrity": "sha1-3bLx+0UCvzNZjSsDKwN5YMpsgKM=", + "requires": { + "accepts": "1.2.13", + "array-flatten": "1.1.1", + "content-disposition": "0.5.0", + "content-type": "1.0.2", + "cookie": "0.1.3", + "cookie-signature": "1.0.6", + "debug": "2.2.0", + "depd": "1.0.1", + "escape-html": "1.0.2", + "etag": "1.7.0", + "finalhandler": "0.4.0", + "fresh": "0.3.0", + "merge-descriptors": "1.0.0", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.1", + "path-to-regexp": "0.1.7", + "proxy-addr": "1.0.10", + "qs": "4.0.0", + "range-parser": "1.0.3", + "send": "0.13.0", + "serve-static": "1.10.3", + "type-is": "1.6.13", + "utils-merge": "1.0.0", + "vary": "1.0.1" + }, + "dependencies": { + "accepts": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz", + "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=", + "requires": { + "mime-types": "2.1.11", + "negotiator": "0.5.3" + }, + "dependencies": { + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + } + } + }, + "negotiator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz", + "integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g=" } } }, - "policyfile": { - "version": "0.0.4", - "from": "policyfile@0.0.4", - "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz" + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "base64id": { - "version": "0.1.0", - "from": "base64id@0.1.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz" + "content-disposition": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz", + "integrity": "sha1-QoT+auBjCHRjnkToCkGMKTQTXp4=" }, - "redis": { - "version": "0.7.3", - "from": "redis@0.7.3", - "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz" + "content-type": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" + }, + "cookie": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz", + "integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "depd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", + "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=" + }, + "escape-html": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz", + "integrity": "sha1-130y+pjjjC9BroXpJ44ODmuhAiw=" + }, + "etag": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", + "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=" + }, + "finalhandler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", + "requires": { + "debug": "2.2.0", + "escape-html": "1.0.2", + "on-finished": "2.3.0", + "unpipe": "1.0.0" + }, + "dependencies": { + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + } + } + }, + "fresh": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", + "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=" + }, + "merge-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz", + "integrity": "sha1-IWnPdTjhsMyH+4jhUC2EdLv3mGQ=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + }, + "dependencies": { + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + } + } + }, + "parseurl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz", + "integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=", + "requires": { + "forwarded": "0.1.0", + "ipaddr.js": "1.0.5" + }, + "dependencies": { + "forwarded": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", + "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" + }, + "ipaddr.js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz", + "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c=" + } + } + }, + "qs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz", + "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=" + }, + "range-parser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", + "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=" + }, + "send": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.13.0.tgz", + "integrity": "sha1-UY+SGusFYK7H3KspkLFM9vPM5d4=", + "requires": { + "debug": "2.2.0", + "depd": "1.0.1", + "destroy": "1.0.3", + "escape-html": "1.0.2", + "etag": "1.7.0", + "fresh": "0.3.0", + "http-errors": "1.3.1", + "mime": "1.3.4", + "ms": "0.7.1", + "on-finished": "2.3.0", + "range-parser": "1.0.3", + "statuses": "1.2.1" + }, + "dependencies": { + "destroy": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", + "integrity": "sha1-tDO0ck5x/YVR2YhRdIUcX8N34sk=" + }, + "http-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "requires": { + "inherits": "2.0.1", + "statuses": "1.2.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "statuses": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz", + "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg=" + } + } + }, + "serve-static": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz", + "integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=", + "requires": { + "escape-html": "1.0.3", + "parseurl": "1.3.1", + "send": "0.13.2" + }, + "dependencies": { + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "send": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz", + "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=", + "requires": { + "debug": "2.2.0", + "depd": "1.1.0", + "destroy": "1.0.4", + "escape-html": "1.0.3", + "etag": "1.7.0", + "fresh": "0.3.0", + "http-errors": "1.3.1", + "mime": "1.3.4", + "ms": "0.7.1", + "on-finished": "2.3.0", + "range-parser": "1.0.3", + "statuses": "1.2.1" + }, + "dependencies": { + "depd": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "http-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "requires": { + "inherits": "2.0.1", + "statuses": "1.2.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, + "mime": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "statuses": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz", + "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg=" + } + } + } + } + }, + "type-is": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.13.tgz", + "integrity": "sha1-boO6e8MM0zp7sLf7AHN6IIW/nQg=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.11" + }, + "dependencies": { + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + } + } + } + } + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + }, + "vary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz", + "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA=" } } }, - "async": { - "version": "0.2.9", - "from": "async@0.2.x" + "finalhandler": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz", + "integrity": "sha1-LEANjUUwk1vCMlScX6OF7Afeb80=", + "requires": { + "debug": "2.2.0", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + }, + "dependencies": { + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + } + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + }, + "dependencies": { + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + } + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + } + } }, - "mime": { - "version": "1.2.11", - "from": "mime@1.2.x" + "flash": { + "version": "https://registry.npmjs.org/flash/-/flash-1.1.0.tgz", + "integrity": "sha1-irKyntO2ilz7Gom/mOf2nX8aAgo=" + }, + "formidable": { + "version": "http://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz", + "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk=" + }, + "fs-extra": { + "version": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.8.1.tgz", + "integrity": "sha1-Dld5/7/t9RG8dVWVx/A8BtS0Po0=", + "requires": { + "jsonfile": "1.1.1", + "mkdirp": "0.3.5", + "ncp": "0.4.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=" + } + } + }, + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.0.3.tgz", + "integrity": "sha1-CqI1kxpKlqwT1g/6wvuHe9btT1g=", + "requires": { + "inflight": "1.0.5", + "inherits": "2.0.1", + "minimatch": "3.0.3", + "once": "1.3.3", + "path-is-absolute": "1.0.0" + }, + "dependencies": { + "inflight": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz", + "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=", + "requires": { + "once": "1.3.3", + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "1.1.6" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + } + } + } + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1.0.2" + }, + "dependencies": { + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", + "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=" + } + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "js-yaml": { - "version": "2.1.3", - "from": "js-yaml@2.1.x", + "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.1.3.tgz", + "integrity": "sha1-D/tWF75VUlh4Bj16Fq7n/dKC6Ew=", + "requires": { + "argparse": "0.1.16", + "esprima": "1.0.4" + }, "dependencies": { "argparse": { - "version": "0.1.15", - "from": "argparse@~ 0.1.11", + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", + "requires": { + "underscore": "1.7.0", + "underscore.string": "2.4.0" + }, "dependencies": { "underscore": { - "version": "1.4.4", - "from": "underscore@~1.4.3" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" }, "underscore.string": { - "version": "2.3.3", - "from": "underscore.string@~2.3.1" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", + "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=" } } }, "esprima": { "version": "1.0.4", - "from": "esprima@~ 1.0.2" + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" } } }, + "jsonfile": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz", + "integrity": "sha1-2k/WrXfxolUgPqY8e8Mtwx72RDM=" + }, + "lazystream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-0.1.0.tgz", + "integrity": "sha1-GyXWPHcqTCDwpe0KnXf0hLbhaSA=", + "requires": { + "readable-stream": "1.0.34" + } + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mime": { + "version": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + }, + "mime-db": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz", + "integrity": "sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8=" + }, + "mime-types": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz", + "integrity": "sha1-9+99l1g/yvO30oK2+LVnnaselO4=", + "requires": { + "mime-db": "1.26.0" + } + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "https://registry.npmjs.org/glob/-/glob-7.0.3.tgz", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", + "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", + "requires": { + "append-field": "0.1.0", + "busboy": "0.2.14", + "concat-stream": "1.6.0", + "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "object-assign": "3.0.0", + "on-finished": "2.3.0", + "type-is": "1.6.14", + "xtend": "4.0.1" + } + }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=" + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, "optimist": { - "version": "0.6.0", - "from": "optimist@0.6.x", + "version": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.3" + }, "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, "wordwrap": { - "version": "0.0.2", - "from": "wordwrap@~0.0.2" + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + } + } + }, + "passport": { + "version": "https://registry.npmjs.org/passport/-/passport-0.3.2.tgz", + "integrity": "sha1-ndAJ+RXo/glbASSgG4+C2gdRAQI=", + "requires": { + "passport-strategy": "1.0.0", + "pause": "0.0.1" + }, + "dependencies": { + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" }, - "minimist": { - "version": "0.0.5", - "from": "minimist@~0.0.1" + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" } } }, - "fs-extra": { - "version": "0.8.1", - "from": "fs-extra@0.8.x", + "passport-local": { + "version": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.0.0" + }, "dependencies": { - "ncp": { - "version": "0.4.2", - "from": "ncp@~0.4.2" + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + } + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "request-promise": { + "version": "https://registry.npmjs.org/request-promise/-/request-promise-1.0.2.tgz", + "integrity": "sha1-FV9BBgjZJXwInB0LJvjY96iqhqE=", + "requires": { + "bluebird": "2.11.0", + "cls-bluebird": "1.1.3", + "lodash": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "request": "2.74.0" + }, + "dependencies": { + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" }, - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@0.3.x" + "cls-bluebird": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-1.1.3.tgz", + "integrity": "sha1-syY8EaCJsDlhhaG3q5BNkPAq1Cg=", + "requires": { + "is-bluebird": "1.0.1", + "shimmer": "1.1.0" + }, + "dependencies": { + "is-bluebird": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.1.tgz", + "integrity": "sha1-wqBCwd5OnzafXFR7ZAzKln05ieo=" + }, + "shimmer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.1.0.tgz", + "integrity": "sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU=" + } + } }, - "jsonfile": { - "version": "1.1.1", - "from": "jsonfile@~1.1.0" + "request": { + "version": "2.74.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz", + "integrity": "sha1-dpPKdou7DqXIzgjAhKRe+gW4kqs=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.4.1", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.0", + "forever-agent": "0.6.1", + "form-data": "1.0.1", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.11", + "node-uuid": "1.4.7", + "oauth-sign": "0.8.2", + "qs": "6.2.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.1", + "tunnel-agent": "0.4.3" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz", + "integrity": "sha1-/efVKSRm0jDl7g9OA42d+qsI/GE=" + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.1", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + } + } + } + } + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + } + } + }, + "extend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", + "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", + "requires": { + "async": "2.0.1", + "combined-stream": "1.0.5", + "mime-types": "2.1.11" + }, + "dependencies": { + "async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz", + "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=", + "requires": { + "lodash": "4.15.0" + }, + "dependencies": { + "lodash": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.15.0.tgz", + "integrity": "sha1-MWI5HY8BQKoiz49rPDTWt/Y9Oqk=" + } + } + } + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "1.1.3", + "commander": "2.9.0", + "is-my-json-valid": "2.13.1", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": "1.0.1" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + } + } + }, + "is-my-json-valid": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.13.1.tgz", + "integrity": "sha1-1Vd4qC/rawlj/0vhEdXRaE6JBwc=", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "2.0.0", + "xtend": "4.0.1" + }, + "dependencies": { + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + }, + "dependencies": { + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + } + } + }, + "jsonpointer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz", + "integrity": "sha1-OvHdIP6FRjkQ1GmjheMwF9KgMNk=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + } + } + } + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.16.3" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.10.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.16.3" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.3.0", + "sshpk": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "jsprim": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.0.tgz", + "integrity": "sha1-zi4b74NSBLTzCZkoxgL4tq5hVlA=", + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.2", + "verror": "1.3.6" + }, + "dependencies": { + "extsprintf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=" + }, + "json-schema": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", + "integrity": "sha1-UDVPGfYDkXxpX3C4Wvp3w7DyNQY=" + }, + "verror": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "requires": { + "extsprintf": "1.0.2" + } + } + } + }, + "sshpk": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.0.tgz", + "integrity": "sha1-EE1roq+yrAmauVZ8DRk5d/Kcbfo=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.0", + "dashdash": "1.14.0", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.6", + "jodid25519": "1.0.2", + "jsbn": "0.1.0", + "tweetnacl": "0.13.3" + }, + "dependencies": { + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "bcrypt-pbkdf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz", + "integrity": "sha1-PKdrhSQccXC/fZcD57mqdGMAQNQ=", + "optional": true, + "requires": { + "tweetnacl": "0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz", + "integrity": "sha1-PaOC9nDyXe1417PReSEZvKC3Ey0=", + "optional": true + } + } + }, + "dashdash": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", + "integrity": "sha1-KeSGxUGL8PNWA0qZPVFoajPoQUE=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "getpass": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "jodid25519": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "optional": true, + "requires": { + "jsbn": "0.1.0" + } + }, + "jsbn": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", + "integrity": "sha1-ZQmH2g3XT06/WhE3eiqi0nPpff0=", + "optional": true + }, + "tweetnacl": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz", + "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y=", + "optional": true + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + } + } + }, + "node-uuid": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "qs": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", + "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=" + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "tough-cookie": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", + "integrity": "sha1-mcd9+7fYBCSeiimdTLD9gf7wg/0=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + } + } + } + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + }, + "should": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.1.tgz", + "integrity": "sha512-l+/NwEMO+DcstsHEwPHRHzC9j4UOE3VQwJGcMWSsD/vqpqHbnQ+1iSHy64Ihmmjx1uiRPD9pFadTSc3MJtXAgw==", + "dev": true, + "requires": { + "should-equal": "2.0.0", + "should-format": "3.0.3", + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0", + "should-util": "1.0.0" + } + }, + "should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dev": true, + "requires": { + "should-type": "1.4.0" + } + }, + "should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "dev": true, + "requires": { + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0" + } + }, + "should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "dev": true + }, + "should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "requires": { + "should-type": "1.4.0", + "should-util": "1.0.0" + } + }, + "should-util": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", + "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "socket.io": { + "version": "https://registry.npmjs.org/socket.io/-/socket.io-0.9.17.tgz", + "integrity": "sha512-jRHmXZUIycXQv1BStfM1ogvcVZdkI4Z7v/ZgxQzhHYw9SYT++UbOyzantuR7CHUfBhLJQrH92pZuQ9TqGvXw3A==", + "requires": { + "base64id": "0.1.0", + "policyfile": "0.0.4", + "redis": "0.7.3", + "socket.io-client": "0.9.16" + }, + "dependencies": { + "base64id": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz", + "integrity": "sha1-As4P3u4M709ACA4ec+g08LG/zj8=" + }, + "policyfile": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz", + "integrity": "sha1-1rgurZiueeviKOLa9ZAzEeyYLk0=" + }, + "redis": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz", + "integrity": "sha1-7le3pE0l7BWU5ENl2BZfp9HUgRo=", + "optional": true }, - "rimraf": { - "version": "2.2.5", - "from": "rimraf@~2.2.0" + "socket.io-client": { + "version": "0.9.16", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz", + "integrity": "sha1-TadRXF53MEHRtCOXBBW8xDDzX8Y=", + "requires": { + "active-x-obfuscator": "0.0.1", + "uglify-js": "1.2.5", + "ws": "0.4.32", + "xmlhttprequest": "1.4.2" + }, + "dependencies": { + "active-x-obfuscator": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz", + "integrity": "sha1-CJuJs3FF/x2ex0r2UwvlUmyuHxo=", + "requires": { + "zeparser": "0.0.5" + }, + "dependencies": { + "zeparser": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz", + "integrity": "sha1-A3JlYbwmjy5URPVMZlt/1KjAKeI=" + } + } + }, + "uglify-js": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz", + "integrity": "sha1-tULCx29477NLIAsgF3Y0Mw/3ArY=" + }, + "ws": { + "version": "0.4.32", + "resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz", + "integrity": "sha1-eHphVEFPPJntg8V3IVOyD+sM7DI=", + "requires": { + "commander": "2.1.0", + "nan": "1.0.0", + "options": "0.0.6", + "tinycolor": "0.0.1" + }, + "dependencies": { + "commander": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=" + }, + "nan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz", + "integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg=" + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" + }, + "tinycolor": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz", + "integrity": "sha1-MgtaUtg6u1l42Bo+iH1K77FaYWQ=" + } + } + }, + "xmlhttprequest": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz", + "integrity": "sha1-AUU6HZvtHo8XL2SVu/TIxCYyFQA=" + } + } + } + } + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "tar-stream": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-0.4.7.tgz", + "integrity": "sha1-Hx0s6evHtCdlJDyg6PG3v9oKrc0=", + "requires": { + "bl": "0.9.5", + "end-of-stream": "1.4.0", + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "type-is": { + "version": "1.6.14", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.14.tgz", + "integrity": "sha1-4hljnBfe0coHiQkt1UoDgmuBfLI=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.14" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "util": { + "version": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zip-folder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/zip-folder/-/zip-folder-1.0.0.tgz", + "integrity": "sha1-cKd0T9F4mi/rQa00GbMun9h5V7I=", + "requires": { + "archiver": "0.11.0" + } + }, + "zip-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-0.4.1.tgz", + "integrity": "sha1-TqeVqM4Z6fq0mjHR0IdyFBWfA6M=", + "requires": { + "compress-commons": "0.1.6", + "lodash": "2.4.2", + "readable-stream": "1.0.34" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" } } } diff --git a/package.json b/package.json index 5e359fae9..382331f5e 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "author": "VWF ", "scripts": { "start": "node ./node-server.js --applicationPath=./public", - "debug": "node --debug ./node-server.js --applicationPath=./public", + "debug": "node --inspect ./node-server.js --applicationPath=./public", + "prepublish": "cd support/lobby && npm install", "test": "echo \"Error: no test specified\" && exit 1" }, "directories": { @@ -18,23 +19,39 @@ "url": "https://github.com/virtual-world-framework/vwf.git" }, "dependencies": { - "crypto": "0.0.x", - "socket.io": "0.9.x", + "adm-zip": "^0.4.7", + "amdefine": "^1.0.1", + "amqplib": "^0.5.1", "async": "0.2.x", - "mime": "1.2.x", + "bluebird": "^3.0.5", + "body-parser": "^1.14.1", + "config": "^1.16.0", + "cookie-parser": "^1.4.0", + "cookie-session": "^2.0.0-alpha.1", + "crypto": "0.0.x", + "dateformat": "^1.0.11", + "express": "^4.13.3", + "finalhandler": "^0.5.1", + "flash": "^1.1.0", + "formidable": "1.0.x", + "fs-extra": "0.8.x", + "glob": "^7.0.3", "js-yaml": "2.1.x", + "lodash": "^3.10.1", + "mime": "1.2.x", + "mkdirp": "^0.5.1", + "multer": "^1.3.0", "optimist": "0.6.x", - "fs-extra": "0.8.x" + "passport": "^0.3.2", + "passport-local": "^1.0.0", + "request-promise": "^1.0.2", + "socket.io": "0.9.x", + "util": "0.10.x", + "zip-folder": "^1.0.0" }, "devDependencies": { - "node-inspector": "x.x.x", - "nodebug": "x.x.x", "mocha": "x.x.x", "should": "x.x.x" }, - "license": { - "type": "Apache", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - } + "license": "Apache-2.0" } - diff --git a/public/ONR_Logo.jpg b/public/ONR_Logo.jpg new file mode 100644 index 000000000..97f9c4efc Binary files /dev/null and b/public/ONR_Logo.jpg differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 000000000..6c8d8cb0e Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/itdg b/public/itdg new file mode 160000 index 000000000..cd979d790 --- /dev/null +++ b/public/itdg @@ -0,0 +1 @@ +Subproject commit cd979d7902a76d6248be69b100ca41a9d10aa065 diff --git a/support/client/bin/r.js b/support/client/bin/r.js index f4547f073..33c7193ee 100644 --- a/support/client/bin/r.js +++ b/support/client/bin/r.js @@ -440,7 +440,7 @@ var requirejs, require, define, xpcUtil; //Defaults. Do not set a default for map //config to speed up normalize(), which //will run faster if there is no default. - waitSeconds: 7, + waitSeconds: 0, baseUrl: './', paths: {}, bundles: {}, diff --git a/support/client/lib/ITDG/version.js b/support/client/lib/ITDG/version.js new file mode 100644 index 000000000..436001d47 --- /dev/null +++ b/support/client/lib/ITDG/version.js @@ -0,0 +1,42 @@ +// Copyright 2012-14 United States Government, as represented by the Secretary of Defense, Under +// Secretary of Defense (Personnel & Readiness). +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under +// the License. + + + +/// The version identifier has the following form: +/// +/// major, minor, patch, release, build, derivative [ app, major, minor, patch ] +/// +/// Fields are defined according to [SemVer](http://semver.org). The `release` and `build` +/// fields are optional, but they are given low-precedence values by default so that official +/// builds will always have a higher precedence than unofficial builds. The build tool removes +/// these fields when appropriate. +/// +/// The build tool overwrites the version identifier on the following line, and it isn't +/// particuarly clever about it. Take care to keep the comment and formatting intact when +/// bumping the version number. + +var version = [ 0, 8, 0, "", "", [ "ITDG", 3, 2, 2 ] ]; // version-identifier + +/// Render the version identifier as a SemVer-style string. + +version.toString = function() { + return this.slice( 0, 3 ).join( "." ) + + ( this[ 5 ] ? "-" + this[ 5 ][0] + "." + this[ 5 ].slice( 1, 4 ).join( "." ) : "" ) + + ( this[ 3 ] ? "-" + this[ 3 ] : "" ) + + ( this[ 4 ] ? "+" + this[ 4 ] : "" ); +}; + +version.getDerivativeVersion = function () { + return ( this[ 5 ] ? this[ 5 ][0] + " " + this[ 5 ].slice( 1, 4 ).join( "." ) : "" ); +} \ No newline at end of file diff --git a/support/client/lib/index.css b/support/client/lib/index.css index 63c1ce234..bd27cd4a0 100644 --- a/support/client/lib/index.css +++ b/support/client/lib/index.css @@ -20,10 +20,6 @@ form { margin: 2em; } -label { - font-size: 18px; -} - input { font-size: 18px; padding: 5px; diff --git a/support/client/lib/index.html b/support/client/lib/index.html index 511f62048..520100ccb 100644 --- a/support/client/lib/index.html +++ b/support/client/lib/index.html @@ -25,37 +25,36 @@ Virtual World Framework - + - + + - - + - + + - + - - - - + - - + + - - + + - - - + + + + - + @@ -75,14 +74,13 @@ var match; var application; var regex = /([^&=]+)=?([^&]*)/g; - var requireConfig = { paths: { jquery: "jquery-1.10.2.min", "jquery-ui": "jquery-ui-1.10.3.custom.min", hammer: "jquery.hammer", }, - shim: { + shim: { "jquery-ui": { deps: ["jquery"], exports: "$" @@ -92,9 +90,12 @@ deps: ["jquery"], exports: "Hammer" } - } + }, + // used to bust the cache, for development use (new Date()).getTime() + urlArgs: "v="+version.toString() }; require(requireConfig, ["jquery", "jquery-encoder-0.1.0"], function($) { + while(match = regex.exec(queryString)) { var key = $.encoder.canonicalize(match[1]); var parameters = $.encoder.canonicalize(match[2]); @@ -130,6 +131,7 @@ vwf.loadConfiguration(application, userLibraries, compatibilityCheck); }); + @@ -137,13 +139,11 @@ - - - + @@ -159,7 +159,7 @@
- + diff --git a/support/client/lib/mil-sym/cws.js b/support/client/lib/mil-sym/cws.js index 14a14ba1e..1f961b07f 100644 --- a/support/client/lib/mil-sym/cws.js +++ b/support/client/lib/mil-sym/cws.js @@ -2,5153 +2,8715 @@ define( function(){ - var cws = { - "def": { - "1WTRFF": "ONE-WAY TRAFFIC", - "2WTRFF": "TWO-WAY TRAFFIC", - "AA/C": "ANTI-AIRCRAFT", - "AAFF": "AXIS OF ADVANCE FOR FEINT", - "AAM": "AIR TO AIR MISSILE (AAM)", - "AARM": "ANTI ARMOR", - "AAST": "AIR ASSAULT", - "AB": "AIRPORT/AIRBASE", - "ABN": "AIRBORNE", - "ABNCP": "AIRBORNE COMMAND POST", - "ABNEW": "AIRBORNE EARLY WARNING (AEW)", - "ABNINC": "AIRBORNE INTERCEPT", - "ABNSB": "AIRBORNE SEARCH & BOMBING", - "ABP": "EXPLOSIVES, STATE OF READINESS 2 (ARMED-BUT PASSABLE)", - "ABS": "ABATIS", - "ABYARA": "ASSEMBLY AREA", - "ACA": "AIRSPACE COORDINATION AREA (ACA)", - "ACDR": "AIR CORRIDOR", - "ACP": "AIR CONTROL POINT (ACP)", - "ACTL": "AIR CONTROL", - "ACTPNT": "ACTION POINTS (GENERAL)", - "ACU": "ACOUSTIC", - "ACYC": "ANTICYCLONE CENTER", - "ADF": "AIR DEFENSE", - "ADFAD": "AIR DEFENSE (AD)", - "ADFG": "AIR DEFENSE GUN", - "ADMIN": "ADMINISTRATIVE (ADMIN)", - "AEP": "AMBULANCE EXCHANGE POINT", - "AEREXP": "AERIAL EXPLOITATION", - "AFP": "ATTACK BY FIRE POSITION", - "AHD": "AIRHEAD", - "AIMPNT": "AIM POINT", - "AIR": "AIR", - "AIRFZ": "AIRFIELD ZONE", - "AIRTRK": "AIR TRACK", - "ALM": "AIR LAUNCHED MISSILE", - "ALTUSP": "ALTERNATE DECON SITE/POINT (UNSPECIFIED)", - "AMB": "AMBUSH", - "AMBLNC": "AMBULANCE", - "AMEP": "AMMUNITION AND EXPLOSIVES PRODUCTION", - "AMP": "AMPHIBIOUS", - "AMPHC": "ATMOSPHERIC", - "AMPWS": "AMPHIBIOUS WARFARE SHIP", - "AMTP": "ARMAMENT PRODUCTION", - "ANCRG1": "ANCHORAGE", - "ANCRG2": "ANCHORAGE", - "ANCRG3": "ANCHORAGE", - "ANG": "ANGLICO", - "ANM": "ANM", - "AOO": "AREA OF OPERATIONS (AO)", - "AP": "AMMUNITION POINTS", - "APA": "AIRCRAFT PRODUCTION & ASSEMBLY", - "APL": "HIJACKING (AIRPLANE)", - "APMNE": "ANTIPERSONNEL (AP) MINES", - "APOD": "APOD/APOE", - "ARA": "AREA", - "ARATGT": "AREA TARGET", - "ARC": "ARCTIC", - "ARM": "ARMOR", - "ARMCV": "ARMORED CARRIER WITH VOLCANO", - "ARMD": "ARMORED", - "ARMERV": "ARMORED ENGINEER RECON VEHICLE (AERV)", - "ARMINF": "ARMORED INFANTRY", - "ARMPC": "ARMORED PERSONNEL CARRIER", - "ARMVM": "ARMORED VEHICLE MOUNTED", - "ARMWVH": "ARMORED WHEELED VEHICLE", - "ARR": "ARREST", - "ARS": "AREAS", - "ARTSVY": "ARTILLERY SURVEY", - "ASBW": "ANTI-SUBMARINE WARFARE (ASW)", - //"ASBW": "ANTISUBMARINE WARFARE/MPA", - "ASBWCB": "ANTISUBMARINE WARFARE (ASW) CARRIER BASED", - "ASBWF": "ANTISUBMARINE WARFARE, FIXED WING", - "ASBWR": "ANTISUBMARINE WARFARE, ROTARY WING", - "ASM": "AIR TO SURFACE MISSILE (ASM)", - "ASN": "ARSON/FIRE", - "ASP": "AMMUNITION SUPPLY POINT (ASP)", - "ASRUT": "ALTERNATE SUPPLY ROUTE", - "ASS": "ASSASSINATION/MURDER/EXECUTION", - "AST": "ARMORED ASSAULT", - "ASTCA": "ASSAULT CROSSING AREA", - "ASTPSN": "ASSAULT POSITION", - "ASTVES": "ASSAULT VESSEL", - "ASUW": "ANTI-SURFACE WARFACE (ASUW)", - "ASWSHP": "ASW SHIP", - "ASWSUB": "ASW SUBMARINE", - "AT": "ANTITANK (AT)", - "ATAC": "ATAC", - "ATCTL": "AIR TRAFFIC CONTROL", - "ATD": "ANTITANK DITCH", - "ATDATM": "ANTITANK DITCH REINFORCED WITH ANTITANK MINES TDC COMPLETE", - "ATDUC": "UNDER CONSTRUCTION", - "ATG": "ANTI-TANK GUN", - "ATIZ": "ARTILLERY TARGET INTELLIGENCE (ATI) ZONE", - "ATK": "ATTACK", - "ATKPSN": "ATTACK POSITION", - "ATMAHD": "ANTITANK MINE WITH ANTIHANDLING DEVICE", - "ATMDIR": "ANTITANK MINE (DIRECTIONAL)", - "ATMER": "ATOMIC ENERGY REACTOR", - "ATMNE": "ANTITANK MINE (AT)", - "ATN": "AIDS TO NAVIGATION", - "ATO": "ANTITANK OBSTACLES", - "ATP": "AMMUNITION TRANSFER POINT (ATP)", - "ATRFF": "ALTERNATING TRAFFIC", - "ATRL": "ANTITANK ROCKET LAUNCHER", - "ATW": "ANTITANK WALL", - "AVN": "AVIATION", - "AXSADV": "AXIS OF ADVANCE", - "BAS": "BELTS AND STRIPS", - "BB": "BERGY BIT", - "BBS": "BATTLESHIP", - "BBY": "BOOBY TRAP", - "BCN": "BEACON", - "BCON": "BRIEF CONTACT", - "BDAWTH": "BOUNDED AREAS OF WEATHER", - "BEH": "BEACH", - "BEHSPE": "BEACH SLOPE", - "BERBOX": "BEARING BOX", - "BERLNE": "BEARING LINE", - "BH": "BACKHOE", - "BIO": "BIOLOGICAL", - "BIOCA": "BIOLOGICALLY CONTAMINATED AREA", - "BIOLUM": "BIOLUMINESCENCE", - "BKN": "BROKEN COVERAGE", - "BLDS": "BOULDERS", - "BLDTSD": "BLOWING DUST OR SAND", - "BLK": "BLOCK", - "BLSNHY": "BLOWING SNOW - HEAVY", - "BLSNLM": "BLOWING SNOW - LIGHT/MODERATE", - "BLST": "BALLISTIC MISSILE", - //"BLST": "BLACK LIST LOCATION", - "BLT": "BELT", - "BM": "BOMB/BOMBING", - "BMARA": "BOMB AREA", - "BMB": "BOMBER", - "BNDS": "BOUNDARIES", - "BOAT": "HIJACKING (BOAT)", - "BRCT": "BROADCAST", - "BRG": "BRIDGE", - "BRGH": "BRIDGEHEAD", - "BRH": "BREACH", - "BRHSA": "BERTHS (ANCHOR)", - "BRHSO": "BERTHS (ONSHORE)", - "BRKS": "BREAKERS", - "BSA": "BRIGADE (BSA)", - "BT": "BATHYTHERMOGRAPH TRANSMITTING (BT)", - "BTFSVL": "BATTLEFIELD SURVEILLANCE", - "BTLPSN": "BATTLE POSITION", - "BTMCHR": "BOTTOM CHARACTERISTICS", - "BTMFAT": "BOTTOM FEATURES", - "BTMRGN": "BOTTOM ROUGHNESS", - "BTMRTN": "BOTTOM RETURN/NOMBO", - "BUOY": "BUOY DEFAULT", - "BUS": "BUS", - "BW": "BERGY WATER", - "BWGJAW": "BREAKWATER/GROIN/JETTY (ABOVE WATER)", - "BWGJBW": "BREAKWATER/GROIN/JETTY (BELOW WATER)", - "BYS": "BYPASS", - "C2ARS": "COMMAND & CONTROL AREAS", - "C2GM": "COMMAND AND CONTROL AND GENERAL MANEUVER", - "C2HQ": "SPECIAL C2 HEADQUARTERS COMPONENT", - "C2LNE": "COMMAND & CONTROL LINES", - "C2PNT": "COMMAND & CONTROL POINTS", - "C2V": "C2V/ACV", - "CALM": "CALM WINDS", - "CAP": "COMBAT AIR PATROL (CAP)", - "CASS": "COMMAND ACTIVE SONOBUOY SYSTEM (CASS)", - "CATK": "COUNTERATTACK (CATK)", - "CATKF": "COUNTERATTACK BY FIRE", - "CBNP": "CANNIBALIZATION POINT", - "CBT": "COMBAT", - "CBTPST": "COMBAT OUTPOST", - "CBTT": "COMBATANT", - "CBWP": "CHEMICAL & BIOLOGICAL WARFARE PRODUCTION", - "CCP": "CASUALTY COLLECTION POINT", - "CCTA": "CONCERTINA", - "CCTRK": "CROSS-COUNTRY TRUCK", - "CELL": "CELLULAR/MOBILE", - "CFCSG": "CABLE FERRY CROSSING", - "CFFZ": "CALL FOR FIRE ZONE (CFFZ)", - "CFL": "COORDINATED FIRE LINE (CFL)", - "CFZ": "CRITICAL FRIENDLY ZONE (CFZ)", - "CGO": "CARGO", - "CGOALT": "CARGO AIRLIFT (TRANSPORT)", - "CHKPNT": "CHECK POINT", - "CID": "CENTRAL INTELLIGENCE DIVISION (CID)", - "CINT": "COUNTER INTELLIGENCE", - "CIP": "CALL IN POINT", - "CIR": "CIRCLE", - "CIRCLR": "CIRCULAR", - "CIRTGT": "CIRCULAR TARGET", - "CLAY": "CLAY", - "CLDFRN": "COLD FRONT", - "CLE": "CIVILIAN LAW ENFORCEMENT", - "CLM": "CLAYMORE", - "CLR": "CLEAR", - "CLS1": "CLASS I", - "CLS10": "CLASS X", - "CLS2": "CLASS II", - "CLS3": "CLASS III", - "CLS4": "CLASS IV", - "CLS5": "CLASS V", - "CLS6": "CLASS VI", - "CLS7": "CLASS VII", - "CLS8": "CLASS VIII", - "CLS9": "CLASS IX", - "CLT": "COLT/FIST", - "CM": "CRUISE MISSILE", - "CMDOPN": "COMMAND OPERATIONS", - "CML": "CHEMICAL", - "CMLCA": "CHEMICALLY CONTAMINATED AREA", - "CMPS": "COMPOSITE", - "CNG": "CONVERGENCE", - "CNGLNE": "CONVERGANCE LINE", - "CNL": "CANAL", - "CNS": "CENSOR ZONE", - "CNT": "CONTAIN", - "CNVPRN": "CONVENTIONAL PROPULSION", - "CNY": "CONVOY", - "CNZ": "CANALIZE", - "COBL": "COBBLES", - "COBLOS": "COBBLES, OYSTER SHELLS", - "COMCP": "COMMUNICATION CONFIGURED PACKAGE", - "COMM": "COMMUNICATIONS", - "COMMCP": "COMMUNICATIONS CHECKPOINT (CCP)", - "CONPNT": "CONTACT POINT", - "COV": "COVER", - "CPL": "CHAPARRAL", - "CRCD": "RECRUITMENT (COERCED/IMPRESSED)", - "CRDPNT": "COORDINATION POINT", - "CRDRTB": "CORRIDOR TAB", - "CRK": "CRACKS", - "CRKASL": "CRACKS AT A SPECIFIC LOCATION", - "CRL": "CORAL", - "CRP": "CORPS", - "CRR": "CARRIER", - "CRU": "CRUISER", - "CRV": "DEPTH CURVE", - "CS": "COMBAT SUPPORT", - "CSAR": "COMBAT SEARCH AND RESCUE (CSAR)", - "CSE": "COARSE", - "CSESD": "COARSE SAND", - "CSESLT": "COARSE SILT", - "CSGSTE": "CROSSING SITE/WATER CROSSING", - "CSN": "CONSTRUCTION", - "CSNALH": "COMPACT OR WET SNOW (WITH OR WITHOUT ICE) COVERING AT LEAST ONE-HALF GROUND, BUT GROUND NOT COMPLETELY COVERED", - "CSNVEH": "CONSTRUCTION VEHICLE", - "CSS": "COMBAT SERVICE SUPPORT", - "CSSVEH": "COMBAT SERVICE SUPPORT VEHICLE", - "CSTHYD": "COASTAL HYDROGRAPHY", - "CSTLN": "COASTLINE", - "CSTSVL": "COASTAL SURVEILLANCE", - "CSV": "CREWED SPACE VEHICLE", - "CTDAPP": "CONTROLLED APPROACH", - "CTDINC": "CONTROLLED INTERCEPT", - "CTR": "SEARCH CENTER", - "CTRB": "CLUTTER (BOTTOM)", - "CTSHVY": "CONTINUOUS HEAVY", - "CTSLIT": "CONTINUOUS LIGHT", - "CTSMOD": "CONTINUOUS MODERATE", - "CTUR": "CONTOUR", - "CUDCOV": "CLOUD COVERAGE", - "CVL": "CIVIL", - "CVLAFF": "CIVIL AFFAIRS", - "CVLVEH": "CIVILIAN VEHICLE", - "CVP": "CIVILIAN COLLECTION POINT", - "CVY": "CAVALRY", - "CWSNLH": "COMPACT OR WET SNOW (WITH OR WITHOUT ICE) COVERING LESS THAN ONE-HALF OF GROUND", - "CYC": "CYCLONE CENTER", - "DA": "DEAD SPACE AREA (DA)", - "DAFF": "DIRECTION OF ATTACK FOR FEINT", - "DAFNC": "DOUBLE APRON FENCE", - "DAM": "DAM", - "DANHAZ": "DANGERS/HAZARDS", - "DAPP": "DOWNED AIRCREW PICKUP POINT", - "DATTMN": "DATA TRANSMISSION", - "DBLFNC": "DOUBLE FENCE", - "DBLSTD": "DOUBLE STRAND CONCERTINA", - "DBS": "DRIVE-BY SHOOTING", - "DBT": "MINE-NAVAL (DOUBTFUL)", - "DCDH2O": "DISCOLORED WATER", - "DCNPNT": "DECISION POINT", - "DCP": "DETAINEE COLLECTION POINT", - "DCPN": "DECEPTION", - "DCY": "DECOY", - "DD": "DESTROYER", - "DDCK": "DRYDOCK", - "DECON": "DECONTAMINATION", - "DECONP": "DECONTAMINATION (DECON) POINTS", - "DEF": "DEFENSE", - "DEFN": "MINE-NAVAL (DEFINITE)", - "DEMO": "DEMONSTRATION", - "DEN": "DENTAL", - "DFG": "DIRECT FIRE GUN", - "DFN": "DIRECTION FINDING", - "DFT": "BYPASS DIFFICULT", - "DFTY": "OBSTACLE BYPASS DIFFICULTY", - "DGOPN": "DRUG OPERATION", - "DGVEH": "DRUG VEHICLE", - "DHA": "DETAINEE HOLDING AREA", - "DICASS": "DIRECTIONAL COMMAND ACTIVE SONOBUOY SYSTEM(DICASS)", - "DIFAR": "DIRECTIONAL FREQUENCY ANALYZING AND RECORDING(DIFAR)", - "DIPPSN": "DIP POSITION", - "DIRATK": "DIRECTION OF ATTACK", - "DIV": "DIVISION", - "DLRP": "DLRP", - "DLT": "DEALT", - "DLY": "DELAY", - "DMA": "DECOY MINED AREA", - "DMAF": "DECOY MINED AREA, FENCED", - "DMD": "DISMOUNTED", - "DMY": "DUMMY (DECEPTION/DECOY)", - "DMYMD": "DUMMY MINEFIELD (DYNAMIC)", - "DMYMS": "DUMMY MINEFIELD (STATIC)", - "DOPN": "DOLPHIN", - "DPH": "DEPTH", - "DRCL": "DOSE RATE CONTOUR LINES", - "DRFT": "DRIFTER", - "DRG": "DREDGE", - "DRN": "DRONE (RPV/UAV)", - "DRPPNT": "DROP POINT", - "DRPZ": "DROP ZONE", - "DRT": "DISRUPT", - "DSA": "DIVISION (DSA)", - "DSTVES": "DISTRESSED VESSEL", - "DSTY": "DESTROY", - "DT/SD": "DUST OR SAND", - "DTDVL": "DUST DEVIL", - "DTHAC": "DITCHED AIRCRAFT", - "DTM": "DATUM", - "DVG": "DIVERGENCE", - "DVR": "DIVER (HARDTOP DIVER, SCUBA DIVER)", - "DVSN": "DIVERSIONS", - "DYN": "DYNAMIC DEPICTION", - "DYNPRO": "DYNAMIC PROCESSES", - "DZ": "DRIZZLE", - "DZR": "DOZER", - "EBB": "CURRENT FLOW - EBB", - "ECM": "ELECTRONIC COUNTERMEASURES (ECM/JAMMER)", - "ECRG": "ELECTRONIC RANGING", - "ECW": "ELECTRONIC WARFARE", - "EIEOB": "ESTIMATED ICE EDGE OR BOUNDARY", - "ELC": "ELECTRONIC", - "ELCSCG": "EVEN LAYER OF COMPACT OR WET SNOW COVERING GROUND COMPLETELY", - "ELDSCG": "EVEN LAYER OF LOOSE DRY SNOW COVERING GROUND COMPLETELY", - "ELP": "ELLIPSE", - "EM": "ELECTRO-MAGNETIC", - "EMP": "EMPLACED", - "EMTARA": "ENGAGEMENT AREA", - "ENCMT": "ENCIRCLEMENT", - "ENG": "ENGINEER", - "ENGEP": "ENGINEERING EQUIPMENT PRODUCTION", - "ENGVEH": "ENGINEER VEHICLE", - "ENTPNT": "ENTRY POINT", - "EOD": "EXPLOSIVE ORDINANCE DISPOSAL", - "EOP": "ELECTRO-OPTICAL", - "EOPI": "ELECTRO-OPTICAL INTERCEPT", - "EOTR": "EDDIES/OVERFALLS/TIDE RIPS", - "EPF": "ELECTRIC POWER FACILITY", - "EPWCP": "ENEMY PRISONER OF WAR (EPW) COLLECTION POINT", - "EPWHA": "ENEMY PRISONER OF WAR (EPW) HOLDING AREA", - "EQT": "EQUIPMENT", - "EQTMNF": "EQUIPMENT MANUFACTURE", - "EQTTRP": "DECON SITE/POINT (EQUIPMENT AND TROOPS)", - "ER": "EMERGENCY", - "ERHMR": "EARTHMOVER", - "ERHSVL": "EARTH SURVEILLANCE", - "ERP": "ENGINEER REGULATING POINT", - "ESM": "ELECTRONIC SURVEILLANCE MEASURES", - "ESTOF": "EARTHWORK, SMALL TRENCH OR FORTIFICATION", - "ESY": "BYPASS EASY", - "EW": "EARLY WARNING", - "EXCD": "ROADBLOCK COMPLETE (EXECUTED)", - "EXT": "TURBULENCE - EXTREME", - "EXTDWC": "EXTREMELY DRY WITH CRACKS", - "EXTN": "EXTORTION", - "EZ": "EXTRACTION ZONE (EZ)", - "FAADEZ": "FORWARD AREA AIR DEFENSE ZONE (FAADEZ)", - "FAC": "FACILITIES", - "FAOTP": "FALLOUT PRODUCING", - "FARP": "FORWARD ARMING AND REFUELING AREA (FARP)", - "FBG": "FLOEBERG", - "FC": "FUNNEL CLOUD (TORNADO/WATERSPOUT)", - "FCL": "FINAL COORDINATION LINE", - "FDDIST": "FOOD DISTRIBUTION", - "FEBA": "FORWARD EDGE OF BATTLE AREA (FEBA)", - "FEW": "FEW COVERAGE", - "FEWS": "FOXHOLE, EMPLACEMENT OR WEAPON SITE", - "FFA": "FIRE FREE AREA (FFA)", - "FFR": "FRIGATE/CORVETTE", - "FG": "FOG", - "FIN": "FINANCE", - "FIRCTL": "FIRE CONTROL", - "FIX": "FIX", - "FIXAVN": "FIXED WING AVIATION", - "FIXD": "FIXED WING", - "FIXPFD": "FIXED AND PREFABRICATED", - "FLDART": "FIELD ARTILLERY", - "FLGRD1": "FOUL GROUND", - "FLGRD2": "FOUL GROUND", - "FLGRD3": "FOUL GROUND", - "FLH": "FLASH (OPTICAL)", - "FLMTHR": "FLAME THROWER", - "FLOOD": "CURRENT FLOW - FLOOD", - "FLOT": "FORWARD LINE OF OWN TROOPS (FLOT)", - "FLT": "FLAT", - "FLTBD": "FLATBED TRUCK", - "FLTSUP": "FLEET SUPPORT (TENDER/TUG)", - "FLWASS": "FOLLOW AND ASSUME", - "FLWSUP": "FOLLOW AND SUPPORT", - "FNE": "FINE", - "FNESD": "FINE SAND", - "FNESLT": "FINE SILT", - "FOR": "FORCE", - "FOSF": "FOSSIL FUEL", - "FP": "FIRING POINT", - "FPF": "FINAL PROTECTIVE FIRE (FPF)", - "FRD": "FORD", - "FRDDFT": "FORD DIFFICULT", - "FRDESY": "FORD EASY", - "FRGS": "FRONTOGENESIS", - "FRGSRH": "FORAGING/SEARCHING", - "FRLS": "FRONTOLYSIS", - "FRMN": "FORMATION", - "FRNSYS": "FRONTAL SYSTEMS", - "FRT": "FORT", - "FRY": "FERRY", - "FRYCSG": "FERRY CROSSING", - "FRYTSP": "FERRY TRANSPORTER", - "FSA": "FIRE SUPPORT AREA (FSA)", - "FSCL": "FIRE SUPPORT COORDINATION LINE (FSCL)", - "FSG": "FISHING", - "FSGHBR": "FISHING HARBOR", - "FSH1": "FORESHORE", - "FSH2": "FORESHORE", - "FSH3": "FORESHORE", - "FSS": "FIRE SUPPORT STATION", - "FSTK1": "FISH STAKES/TRAPS/WEIRS", - "FSTK2": "FISH STAKES", - "FSTK3": "FISH STAKES/TRAPS/WEIRS", - "FSUPP": "FIRE SUPPORT", - "FTFDAR": "FORTIFIED AREA", - "FTFDLN": "FORTIFIED LINE", - "FTR": "FIGHTER", - "FU": "SMOKE", - "FWDCOM": "FORWARD COMMUNICATIONS", - "FWDOP": "FORWARD OBSERVER POSITION", - "FZDZ": "FREEZING DRIZZLE", - "FZLED": "FROZEN LEAD", - "FZLVL": "FREEZING LEVEL", - "FZPPN": "FREEZING/FROZEN PRECIPITATION", - "FZRA": "FREEZING RAIN", - "FZSNV": "FOG - FREEZING, SKY NOT VISIBLE", - "FZSV": "FOG - FREEZING, SKY VISIBLE", - "GAP": "GAP", - "GDD": "GUIDED MISSILE", - "GENARA": "GENERAL AREA", - "GLST": "GRAY LIST LOCATION", - "GLZGRD": "GLAZE (THIN ICE) ON GROUND", - "GNL": "GENERAL", - "GOVLDR": "GOVERNMENT LEADERSHIP", - "GPHY": "GEOPHYSICS/ACOUSTICS", - "GRD": "GROUND", - "GRDSM": "GROUND STATION MODULE", - "GRDSR": "GROUND SURVEILLANCE RADAR", - "GRDTRK": "GROUND TRACK", - "GRDVEH": "GROUND VEHICLE", - "GRDZRO": "GROUND ZERO", - "GREL": "GRENADE LAUNCHER", - "GRF": "GRAFITTI", - "GTL": "GENTLE", - "GUD": "GUARD", - "GUNUNT": "GUN UNIT", - "GVL": "GRAVEL", - "GWL": "GROWLER", - "H2O": "WATER", - "H2OCRT": "WATER CRAFT", - "H2OTRB": "WATER TURBULENCE", - "HAMEZ": "HIGH ALTITUDE MEZ", - "HAZ": "HAZARD", - "HAZMAT": "HAZARDOUS MATERIALS (HAZMAT)", - "HBR": "HARBOR (GENERAL)", - "HC": "HURRICANE/TYPHOON", - "HCNY": "HALTED CONVOY", - "HGH": "HIGH", - "HGHCTR": "HIGH PRESSURE CENTER", - "HGL": "HOLDING LINE", - "HGTFDG": "HEIGHT FINDING", - "HIDACZ": "HIGH DENSITY AIRSPACE CONTROL ZONE (HIDACZ)", - "HJKG": "HIJACKING", - "HL": "HAIL", - "HMAD": "H/MAD", - "HMG": "HEAVY MACHINE GUN", - "HOV": "HOVERCRAFT", - "HOW": "HOWITZER/GUN", - "HP": "HIDE POINT", - "HRE": "HORSE", - "HSP": "HOSPITAL", - "HSPSHP": "HOSPITAL SHIP", - "HTHP": "HOUSE-TO-HOUSE PROPAGANDA", - "HUM": "RIDGES OR HUMMOCKS", - "HVY": "HEAVY", - "HWFNC": "HIGH WIRE FENCE", - "HWK": "HAWK", - "HYDGRY": "HYDROGRAPHY", - "HZ": "HAZE", - "IB": "ICEBERG", - "IC": "ICE CRYSTALS (DIAMOND DUST)", - "ICG": "ICING", - "ICN": "ICE CONCENTRATION", - "ID": "ICE DRIFT (DIRECTION)", - "IDFF": "IDENTIFICATION FRIEND/FOE (INTERROGATOR)", - "IEOBFR": "ICE EDGE OR BOUNDARY FROM RADAR", - "IF": "ICE FREE", - "IFF": "IFF (TRANSPONDER)", - "IFR": "INSTRUMENT FLIGHT RULE (IFR)", - "II": "ICE ISLAND", - "IMP": "BYPASS IMPOSSIBLE", - "IMTBUR": "IMPACT BURIAL", - "IMTPNT": "IMPACT POINT", - "INC": "INTERCEPT", - "INCR": "INTERCEPTOR", - "INF": "INFANTRY", - "INFFV": "INFANTRY FIGHTING VEHICLE", - "INFNLE": "INFILTRATION LANE", - "INMHVY": "INTERMITTENT HEAVY", - "INMLIT": "INTERMITTENT LIGHT", - "INMMOD": "INTERMITTENT MODERATE", - "INS": "INSTALLATION", - "INT": "INTELLIGENCE (OCEANOGRAPHIC, AGI)", - "INTGN": "INTERROGATION", - "INTMR": "INTERMEDIATE RANGE", - "IRR": "IRREGULAR", - "ISB": "ISOBAR - SURFACE", - "ISD": "ISODROSOTHERM", - "ISF": "INTERNAL SECURITY FORCES", - "ISH": "ISOTACH", - "ISL": "ISOLATE", - "ISND": "ISLAND", - "ISP": "ISOPLETHS", - "IST": "ISOTHERM", - "ISTB": "INSTABILITY LINE", - "ISYS": "ICE SYSTEMS", - "ITCZ": "INTER-TROPICAL CONVERGANCE ZONE", - "ITD": "INTER-TROPICAL DISCONTINUITY", - "ITDT": "INTERDICT", - "ITEST": "ICE THICKNESS (ESTIMATED)", - "ITM": "ITEMS", - "ITOBS": "ICE THICKNESS (OBSERVED)", - "IWU": "INFORMATION WARFARE UNIT", - "JAG": "JUDGE ADVOCATE GENERAL (JAG)", - "JBB": "JAMMED BRASH BARRIER", - "JIB": "JOINT INFORMATION BUREAU (JIB)", - "JINTCT": "JOINT INTELLIGENCE CENTER", - "JMG": "JAMMING", - "JTSM": "JET STREAM", - "KDNG": "KIDNAPPING", - "KGP": "KINGPIN", - "KLP1": "KELP/SEAWEED", - "KLP2": "KELP/SEAWEED", - "KLP3": "KELP/SEAWEED", - "KNIVEH": "KNOWN INSURGENT VEHICLE", - "LAARA": "LIMITED ACCESS AREA", - "LAMEZ": "LOW ALTITUDE MEZ", - "LANE": "LANE", - "LAR": "LIGHT ARMORED RECONNAISSNACE (LAR)", - "LARMVH": "LIGHT ARMORED VEHICLE", - "LAWENU": "LAW ENFORCEMENT UNIT", - "LAWENV": "LAW ENFORCEMENT VESSEL", - "LBR": "LABOR", - "LCCP": "LARGE COMMUNICATION CONFIGURED PACKAGE (LCCP)", - "LCCTRK": "LIMITED CROSS-COUNTRY TRUCK", - "LCK": "LOCK", - "LCON": "LOST CONTACT", - "LD": "LINE OF DEPARTURE", - "LDGLNE": "LEADING LINE", - "LDLC": "LINE OF DEPARTURE/LINE OF CONTACT (LD/LC)", - "LDNCGC": "LOOSE DRY DUST OR SAND NOT COVERING GROUND COMPLETELY", - "LDSALH": "LOOSE DRY SNOW COVERING AT LEAST ONE-HALF GROUND, BUT GROUND NOT COMPLETELY COVERED", - "LDSNLH": "LOOSE DRY SNOW COVERING LESS THAN ONE-HALF OF GROUND", - "LDY": "LAUNDRY/BATH", - "LED": "LEAD", - "LEN": "LARGE EXTENSION NODE", - "LESCRT": "LEISURE CRAFT", - "LIT": "LIGHT", - "LITHSE": "LIGHTHOUSE", - "LITLNE": "LIGHT LINE", - "LITMOD": "DUST/SAND STORM - LIGHT TO MODERATE", - "LITVES": "LIGHT VESSEL/LIGHTSHIP", - "LLTR": "LOW LEVEL TRANSIT ROUTE (LLTR)", - "LMG": "LIGHT MACHINE GUN", - "LMT": "LIMITS", - "LMTADV": "LIMIT OF ADVANCE", - "LND": "LAND", - "LNDCRT": "LANDING CRAFT", - "LNDMNE": "LAND MINES", - "LNDPLC": "LANDING PLACE", - "LNDRNG": "LANDING RING", - "LNDSHP": "LANDING SHIP", - "LNDSUP": "LANDING SUPPORT", - "LNE": "LINE", - "LNGR": "LONG RANGE", - "LNKUPT": "LINKUP POINT", - "LNRTGT": "LINEAR TARGET", - "LOC": "LINE OF CONTACT", - "LOCAT": "LOCATIONS", - "LOFAR": "LOW FREQUENCY ANALYZING AND RECORDING (LOFAR)", - "LORO": "LIMIT OF RADAR OBSERVATION", - "LOU": "LIMIT OF UNDERCAST", - "LOVO": "LIMIT OF VISUAL OBSERVATION", - "LOWCTR": "LOW PRESSURE CENTER", - "LP": "LAUNCH POINT", - "LPC": "LIQUID PRECIPITATION - CONVECTIVE", - "LPNCI": "LIQUID PRECIPITATION - NON-CONVECTIVE CONTINUOUS OR INTERMITTENT", - "LRP": "LOGISTICS RELEASE POINT (LRP)", - "LRS": "LONG RANGE SURVEILLANCE (LRS)", - "LSR": "LASER", - "LSTGT": "LINEAR SMOKE TARGET", - "LTA": "LIGHTER THAN AIR", - "LTG": "LIGHTNING", - "LTL": "LESS THAN LETHAL", - "LW": "LOW", - "LWFNC": "LOW WIRE FENCE", - "LZ": "LANDING ZONE (LZ)", - "MAINT": "MAINTENANCE", - "MANATK": "MAIN ATTACK", - "MAR": "MARINE", - "MARLFE": "MARINE LIFE", - "MARTAR": "MARITIME AREA", - "MARTLB": "MARITIME LIMIT BOUNDARY", - "MCC": "MOVEMENT CONTROL CENTER(MCC)", - "MCLST": "MINE CLUSTER", - "MCMDRN": "MCM DRONE", - "MCMSUP": "MCM SUPPORT", - "MCNY": "MOVING CONVOY", - "MCP": "MAINTENANCE COLLECTION POINT", - "MCT": "MERCHANT", - "MCVEH": "MINE CLEARING VEHICLE", - "MDM": "MEDIUM", - "MDMSD": "MEDIUM SAND", - "MDMSLT": "MEDIUM SILT", - "MECH": "MECHANIZED", - "MED": "MEDICAL", - "MEDF": "MEDICAL FACILITY", - "MEDTF": "MEDICAL TREATMENT FACILITY", - "MEDV": "MEDEVAC", - "METO": "METEOROLOGICAL", - "MEZ": "MISSILE ENGAGEMENT ZONE (MEZ)", - "MFN": "MULTI-FUNCTION", - "MIL": "MILITARY", - "MILBF": "MILITARY BASE/FACILITY", - "MILINT": "MILITARY INTELLIGENCE", - "MILP": "MILITARY POLICE", - "MILVP": "MILITARY VEHICLE PRODUCTION", - "MIST": "MIST", - "MIWBC": "MIW BOTTOM CATEGORY", - "MIWBS": "MIW-BOTTOM SEDIMENTS", - "MIWBT": "MIW BOTTOM TYPE", - "MIX": "MIXED ICING", - "ML": "MINE LAYING", - "MLDCGC": "MODERATE/THICK LOOSE DRY DUST OR SAND COVERING GROUND COMPLETELY", - "MLVEH": "MINE LAYING VEHICLE", - "MMD": "MAN-MADE STRUCTURES", - "MMF": "MILITARY MATERIEL FACILITY", - "MNDARA": "MINED AREA", - "MNE": "MINE", - "MNECM": "MINE COUNTERMEASURES", - "MNEFLD": "MINEFIELDS", - "MNEHNT": "MINEHUNTER", - "MNELYR": "MINELAYER", - "MNENAV": "MINE-NAVAL", - "MNESWE": "MINESWEEPER", - "MNEWBD": "MINE WARFARE BOTTOM DESCRIPTORS", - "MNEWV": "MINE WARFARE VESSEL", - "MNT": "MOUNTAIN", - "MNTWAV": "MOUNTAIN WAVES", - "MNY": "MANY ICEBERGS", - "MNYBB": "MANY BERGY BITS", - "MNYGNL": "MANY ICEBERGS - GENERAL", - "MNYGWL": "MANY GROWLERS", - "MOBSU": "MOBILITY/SURVIVABILITY", - "MOD": "MODERATE", - //"MODHVY": "FREEZING DRIZZLE - MODERATE/HEAVY", - //"MODHVY": "FREEZING RAIN - MODERATE/HEAVY", - //"MODHVY": "HAIL - MODERATE/HEAVY NOT ASSOCIATED WITH THUNDER", - "MODHVY": "RAIN SHOWERS - MODERATE/HEAVY", - //"MODHVY": "SNOW SHOWERS - MODERATE/HEAVY", - "MOOTW": "MILITARY OPERATIONS OTHER THAN WAR (MOOTW)", - "MORT": "MORTAR", - "MOT": "MOTORIZED", - "MPOFI": "MELT PUDDLES OR FLOODED ICE", - "MRK": "MARKER", - "MRL": "MULTIPLE ROCKET LAUNCHER", - "MRR": "MINIMUM RISK ROUTE (MRR)", - "MRSH": "MARSHALL", - "MRSPD": "MULTI ROCKET SELF-PROPELLED", - "MRTOW": "MULTI ROCKET TOWED", - "MRTRK": "MULTI ROCKET TRUCK", - "MSDZ": "MINIMUM SAFE DISTANCE ZONES", - "MSE": "MULTIPLE SUBSCRIBER ELEMENT", - "MSL": "MISSILE", - "MSLAQ": "MISSILE ACQUISITION", - "MSLDL": "MISSILE DOWNLINK", - "MSLGDN": "MISSILE GUIDANCE", - "MSLIF": "MISSILE IN FLIGHT", - "MSLL": "MISSILE LAUNCHER", - "MSLPNT": "MSL DETECT POINT", - "MSLTRK": "MISSILE TRACKING", - "MSRUT": "MAIN SUPPLY ROUTE", - "MSSP": "MISSILE & SPACE SYSTEM PRODUCTION", - "MTRY": "MORTUARY/GRAVES REGISTRY", - "MUD": "MUD", - "MVB": "MOVEABLE", - "MVBPFD": "MOVEABLE AND PREFABRICATED", - "MVFR": "MARGINAL VISUAL FLIGHT RULE (MVFR)", - "MWR": "MORALE, WELFARE, RECREATION (MWR)", - "NAI": "NAMED AREA OF INTEREST (NAI)", - "NAV": "NAVAL", - "NAVGRP": "NAVY GROUP", - "NAVREF": "NAV REFERENCE", - "NAVTF": "NAVY TASK FORCE", - "NAVTG": "NAVY TASK GROUP", - "NAVTU": "NAVY TASK UNIT", - "NBC": "NUCLEAR, BIOLOGICAL AND CHEMICAL", - "NBCEQT": "NBC EQUIPMENT", - "NBCOP": "NBC OBSERVATION POST (DISMOUNTED)", - "NCBTT": "NONCOMBATANT", - "NDGZ": "NUCLEAR DETINATIONS GROUND ZERO", - "NENY": "NUCLEAR ENERGY", - "NEUT": "NEUTRALIZE", - "NFA": "NO-FIRE AREA (NFA)", - "NFL": "NO-FIRE LINE (NFL)", - "NMIL": "NON-MILITARY", - "NMP": "NUCLEAR MATERIAL PRODUCTION", - "NMS": "NUCLEAR MATERIAL STORAGE", - "NODAT": "NO DATA", - "NODCTR": "NODE CENTER", - "NPRN": "NUCLEAR PROPULSION", - "NPT": "NUCLEAR PLANT", - "NSUB": "NON-SUBMARINE", - "NUC": "NUCLEAR", - "NUCTGT": "NUCLEAR TARGET", - "NVGL": "NAVIGATIONAL", - "OBJ": "OBJECTIVE", - "OBSEFT": "OBSTACLE EFFECT", - "OBSPST": "OBSERVATION POST/OUTPOST", - "OBST": "OBSTACLES", - "OBSTBP": "OBSTACLE BYPASS", - "OCA": "OCEANIC", - "OCC": "OCCUPY", - "OCD": "OCCLUDED FRONT", - "OCNGRY": "OCEANOGRAPHY", - "OD": "OPERATOR-DEFINED", - "ODFF": "OPERATOR-DEFINED FREEFORM", - "OFA": "OBSTACLE FREE AREA", - "OFF": "OFFENSE", - "OIEOB": "OBSERVED ICE EDGE OR BOUNDARY", - "OITI": "OPENINGS IN THE ICE", - "OLOS": "OMNI-LINE-OF-SIGHT (LOS)", - "OLR": "OILER/TANKER", - "OLRG": "OIL/GAS RIG", - "OLRGFD": "OIL/GAS RIG FIELD", - "OPDECN": "DECON SITE/POINT (OPERATIONAL DECONTAMINATION)", - "OPN": "OPERATIONS", - "ORA": "OBSTACLE RESTRICTED AREA", - "ORD": "ORDNANCE", - "OSLF1": "OFFSHORE LOADING FACILITY", - "OSLF2": "OFFSHORE LOADING FACILITY", - "OSLF3": "OFFSHORE LOADING FACILITY", - "OTH": "OTHER", - "OVC": "OVERCAST COVERAGE", - "OWN": "OWN TRACK", - "PAA": "POSITION AREA FOR ARTILLERY (PAA)", - "PAT": "PATROL", - "PATG": "PATROLLING", - "PATT": "PATRIOT", - "PBL": "PEBBLES", - "PBLSHE": "PEBBLES, SHELLS", - "PBNO": "PREPARED BUT NOT OCCUPIED", - "PBX": "PENETRATION BOX", - "PDF": "PRINCIPAL DIRECTION OF FIRE (PDF)", - "PDMIC": "PREDOMINATELY ICE COVERED", - "PE": "ICE PELLETS (SLEET)", - "PERSVC": "PERSONNEL SERVICES", - "PF": "PROCESSING FACILITY", - "PGO": "PETROLEUM/GAS/OIL", - "PHELNE": "PHASE LINE", - "PHG": "PHOTOGRAPHIC", - "PHOSWT": "TELEPHONE SWITCH", - "PIM": "PIM", - "PIPNT": "PREDICTED IMPACT POINT", - "PIW": "PERSON IN WATER", - "PKAN": "PACK ANIMAL(S)", - "PKT": "PICKET", - "PLD": "PROBABLE LINE OF DEPLOYMENT (PLD)", - "PLE": "PILE/PILING/POST", - "PLND": "PLANNED", - "PLT": "WIND PLOT", - "PNE": "PENETRATE", - "PNT": "POINT", - "PNTA": "POINT A", - "PNTD": "POINT OF DEPARTURE", - "PNTINR": "POINT OF INTEREST", - "PNTQ": "POINT Q", - "PNTR": "POINT R", - "PNTX": "POINT X", - "PNTY": "POINT Y", - "POUTAI": "PRECIPITATION OF UNKNOWN TYPE AND INTENSITY", - "PPELNE": "PIPELINES/PIPE", - "PRH1": "PERCHES/STAKES", - "PRH2": "PERCHES/STAKES", - "PRH3": "PERCHES/STAKES", - "PRS": "PRESSURE SYSTEMS", - "PRT": "PORTS", - "PRTHBR": "PORTS AND HARBORS", - "PSG": "PASSENGER", - "PSNG": "POISONING", - "PSSPNT": "PASSAGE POINT", - "PST": "POSTAL", - "PSY": "PSYCHOLOGICAL", - "PSYOP": "PSYCHOLOGICAL OPERATIONS (PSYOP)", - "PTGT": "POINT/SINGLE TARGET", - "PTHY": "FOG - PATCHY", - "PTNCTR": "PATTERN CENTER", - "PTPLOS": "POINT-TO-POINT LINE-OF-SIGHT (LOS)", - "PUBAFF": "PUBLIC AFFAIRS", - "PUP": "PULL-UP POINT (PUP)", - "PUR": "PURIFICATION", - "PWQ": "PIER/WHARF/QUAY", - "PWS": "PUBLIC WATER SERVICES", - "PZ": "PICKUP ZONE (PZ)", - "QLFYTM": "QUALIFYING TERMS", - "RA": "RAIN", - "RAD": "RADAR", - "RADA": "RADIOACTIVE AREA", - "RALRD": "RAILROAD", - "RAMPAW": "RAMP (ABOVE WATER)", - "RAMPBW": "RAMP (BELOW WATER)", - "RASN": "RAIN AND SNOW MIXED", - "RASWR": "RAIN SHOWERS", - "RAYPNT": "RALLY POINT", - "RCBB": "ROADBLOCKS, CRATERS, AND BLOWN BRIDGES", - "RCK": "ROCK", - "RCKAWD": "ROCK AWASHED", - "RCKSBM": "ROCK SUBMERGERED", - "RCMT": "RECRUITMENT", - "RCY": "RECOVERY", - "RDGAXS": "RIDGE AXIS", - "RDOUNT": "RADIO UNIT", - "RDSLIT": "RAIN OR DRIZZLE AND SNOW - LIGHT", - "RDSMH": "RAIN OR DRIZZLE AND SNOW - MODERATE/HEAVY", - "RDV": "RENDEZVOUS", - "RECEQP": "RECON EQUIPPED", - "RECL": "RECOILLESS", - "RECON": "RECONNAISSANCE", - "REEF": "REEF", - "REEVNT": "RELEASE EVENTS", - "REFPNT": "REFERENCE POINT", - "REL": "RELEASE LINE", - "RELG": "RELIGIOUS/CHAPLAIN", - "RELPNT": "RELEASE POINT", - "RFA": "RESTRICTIVE FIRE AREA (RFA)", - "RFE": "REFUEL", - "RFG": "REFUGEES", - "RFL": "RESTRICTIVE FIRE LINE (RFL)", - "RFT": "RAFT SITE", - "RFTG": "RAFTING", - "RGH": "ROUGH", - "RGR": "RANGER", - "RHA": "REFUGEE HOLDING AREA", - "RHD": "RAILHEAD", - "RHU": "REPLACEMENT HOLDING UNIT (RHU)", - "RIF": "RIFLE", - "RIFWPN": "RIFLE/AUTOMATIC WEAPON", - "RIME": "RIME ICING", - "RIP": "RELIEF IN PLACE (RIP)", - "RIV": "RIVERINE", - "RLY": "RELAY", - "RMP": "RAW MATERIAL PRODUCTION/STORAGE", - "RO": "RANGE ONLY (RO)", - "ROC": "ROCKET", - "ROM": "REFUEL ON THE MOVE (ROM) POINT", - "RORO": "ROLL ON/ROLL OFF", - "ROT": "ROTARY WING", - "ROZ": "RESTRICTED OPERATIONS ZONE (ROZ)", - "RP": "RELOAD POINT", - "RPH": "REPLENISH", - "RRRP": "REARM, REFUEL AND RESUPPLY POINT", - "RSA": "REGIMENTAL (RSA)", - "RSC": "RESCUE", - "RSDARA": "RESTRICTED AREA", - "RTE": "ROUTE", - "RTG": "RECTANGULAR", - "RTGTGT": "RECTANGULAR TARGET", - "RTM": "RETIREMENT", - "RTN": "RETAIN", - "SA": "SEA ANOMALY (WAKE, CURRENT, KNUCKLE)", - "SAAFR": "STANDARD-USE ARMY AIRCRAFT FLIGHT ROUTE (SAAFR)", - "SAFE": "EXPLOSIVES, STATE OF READINESS 1 (SAFE)", - "SAFHSE": "SAFE HOUSE", - "SAM": "SURFACE TO AIR MISSILE (SAM)", - "SAR": "SEARCH AND RESCUE", - "SAT": "SATELLITE", - "SATDL": "SATELLITE DOWN-LINK", - "SATUL": "SATELLITE UP-LINK", - "SBM": "WRECK (SUBMERGED)", - "SBMCRB": "SUBMERGED CRIB", - "SBRSOO": "SEABED ROCK/STONE, OBSTACLE, OTHER", - "SBSM": "SUBSURFACE TO SURFACE MISSILE (S/SSM)", - "SBSUF": "SUBSURFACE TRACK", - "SBT": "SPECIAL BOAT", - "SC": "SNOW COVER", - "SCE": "SECURE", - "SCGC": "SNOW COVERING GROUND COMPLETELY; DEEP DRIFTS", - "SCM": "SCM", - "SCN": "SCREEN", - "SCP": "SURVEY CONTROL POINT", - "SCR": "SECTOR", - "SCT": "SCATTERED COVERAGE", - "SCUT": "SCOUT", - "SD": "SAND", - "SD&SHE": "SAND AND SHELLS", - "SEAL": "SEAL", - "SEC": "SECURITY", - "SECPOL": "SECURITY POLICE (AIR)", - "SEMI": "SEMI", - "SEN": "SMALL EXTENSION NODE", - "SFP": "SUPPORT BY FIRE POSITION", - "SG": "SNOW GRAINS", - "SGTGT": "SERIES OR GROUP OF TARGETS", - "SHA": "SHEAR LINE", - "SHAZ": "SHEARING OR SHEAR ZONE", - "SHE": "SHELL", - "SHETKG": "SHELL TRACKING", - "SHPCSN": "SHIP CONSTRUCTION", - "SHRLNE": "SHORELINE PROTECTION", - "SHRPAT": "SHORE PATROL", - "SHTR": "SHORT RANGE", - "SHWCTS": "FOG - SHALLOW CONTINUOUS", - "SHWPTH": "FOG - SHALLOW PATCHES", - "SI": "SEA ICE", - "SIGINC": "SIGNAL INTERCEPT", - "SIGINT": "SIGNALS INTELLIGENCE", - "SIGSUP": "SIGNAL SUPPORT", - "SIGUNT": "SIGNAL UNIT", - "SKC": "CLEAR SKY", - "SKEIP": "STRIKE IP", - "SKYOBD": "FOG - SKY OBSCURED", - "SKYVSB": "FOG - SKY VISIBLE", - "SLDRCK": "SOLID ROCK", - "SLM": "SURFACE LAUNCHED MISSILE", - "SLP": "SUPPLY", - "SLPRUT": "SUPPLY ROUTES", - "SLT": "SILT", - "SMDCY": "SEA MINE DECOY", - "SMF": "SEA MINE (FLOATING)", - "SMG": "SEA MINE (GROUND)", - "SMH": "SMOOTH", - "SMK": "SMOKE", - "SMKDEC": "SMOKE/DECON", - "SML": "SEA MINE-LIKE", - "SMLNE": "STREAM LINE", - "SMM": "SEA MINE (MOORED)", - "SMNE": "SEA MINE", - "SMOP": "SEA MINE (OTHER POSITION)", - "SN": "SNOW", - "SNAG": "SNAGS/STUMPS", - "SNBY": "SONOBUOY", - "SND": "SOUND", - "SNDG": "SOUNDINGS", - "SNG": "SINGLE CONCERTINA", - "SNGFNC": "SINGLE FENCE", - "SNK": "SINKER", - "SNS": "SENSOR", - "SNSZ": "SENSOR ZONE", - "SOF": "SPECIAL OPERATIONS FORCES (SOF)", - "SOFUNT": "SPECIAL OPERATIONS FORCES (SOF) UNIT", - "SOP": "SENSOR OUTPOST/LISTENING POST (OP/LP)", - "SP": "SEAPORT/NAVAL BASE", - "SPC": "SPACE", - "SPD": "SELF-PROPELLED", - "SPDTRK": "SELF-PROPELLED TRACKED", - "SPDWHD": "SELF-PROPELLED WHEELED", - "SPG": "SNIPING", - "SPL": "SPECIAL", - "SPLPNT": "SPECIAL POINT", - "SPOD": "SPOD/SPOE", - "SPT": "SUPPLY POINTS", - "SPY": "SPY", - "SQL": "SQUALL", - "SRH": "SEARCH", - "SRHARA": "SEARCH AREA/RECONNAISSANCE AREA", - "SRL": "SINGLE ROCKET LAUNCHER", - "SRSPD": "SINGLE ROCKET SELF-PROPELLED", - "SRTOW": "SINGLE ROCKET TOWED", - "SRTRK": "SINGLE ROCKET TRUCK", - "SRUF": "SERVICE, RESEARCH, UTILITY FACILITY", - "SSH": "SERVICE & SUPPORT HARBOR (YARDCRAFT, BARGE, HARBOR, TUG)", - "SSL": "SEVERE SQUALL LINE", - "SSM": "SURFACE TO SURFACE MISSILE (SSM)", - "SSSNR": "SPECIAL SSNR", - "SST": "SPACE STATION", - "SSUBSR": "SEA SUBSURFACE RETURNS", - "SSUF": "SEA SURFACE TRACK", - "SSWR": "SNOW SHOWERS", - "STAT": "STATIONARY FRONT", - "STC": "STATIC DEPICTION", - "STG": "STINGER", - "STGC": "STRATEGIC", - "STMS": "STORMS", - "STN": "STATION", - "STNE": "STONES", - "STOG": "STATE OF THE GROUND", - "STOPO": "SKY TOTALLY OR PARTIALLY OBSCURED", - "STP": "STEEP", - "STRGPT": "STRONG POINT", - "STRPNT": "START POINT", - "SU": "SURVIVABILITY", - "SUB": "SUBMARINE", - "SUBCBL": "SUBMARINE CABLE", - "SUF": "SURF-SURF (SS)", - "SUFDRY": "SURFACE DRY WITHOUT CRACKS OR APPRECIABLE DUST OR LOOSE SAND", - "SUFFLD": "SURFACE FLOODED", - "SUFFZN": "SURFACE FROZEN", - "SUFMST": "SURFACE MOIST", - "SUFSHL": "SURFACE SHELTER", - "SUFSRH": "SURFACE SEARCH", - "SUFWET": "SURFACE WET, STANDING WATER IN SMALL OR LARGE POOLS", - "SUP": "SUPPORT", - "SUPARS": "SUPPORT AREAS", - "SUPATK": "SUPPORTING ATTACK", - "SUPPLY": "QUARTERMASTER (SUPPLY)", - "SUV": "SPORT UTILITY VEHICLE (SUV)", - "SVL": "SURVEILLANCE", - "SVR": "SEVERE", - "SW": "SEAWALL", - "SWO": "SASTRUGI (WITH ORIENTATION)", - "SWPARA": "SWEPT AREA", - "SWRLIT": "RAIN AND SNOW SHOWERS - LIGHT", - "SWRMOD": "RAIN AND SNOW SHOWERS - MODERATE/HEAVY", - "SYM": "CLOUD COVERAGE SYMBOLS", - "SZE": "SEIZE", - "TAC": "TACTICAL", - "TACEXP": "TACTICAL EXPLOIT", - "TACGRP": "TACTICAL GRAPHICS", - "TACSAT": "TACTICAL SATELLITE", - "TAI": "TARGETED AREA OF INTEREST (TAI)", - "TAK": "TANKING", - "TANK": "TANK", - "TARP": "PSYOP (TV AND RADIO PROPAGANDA)", - "TBA": "TARGET BUILD-UP AREA (TBA)", - "TCF": "TELECOMMUNICATIONS FACILITY", - "TCN": "TACAN", - "TCP": "TRAFFIC CONTROL POST (TCP)", - "TDECUR": "TIDE AND CURRENT", - "TDEDP": "TIDE DATA POINT", - "TDEG": "TIDE GAUGE", - "TDTSM": "ANTITANK OBSTACLES: TETRAHEDRONS, DRAGONS TEETH, AND OTHER SIMILAR OBSTACLES", - "TELAR": "TELAR", - "TGT": "TARGET", - "TGTAQ": "TARGET ACQUISITION", - "TGTAQZ": "TARGET ACQUISTION ZONES", - "TGTGUT": "TARGETING UNIT", - "TGTILL": "TARGET ILLUMINATOR", - "TGTREF": "TARGET REFERENCE", - "TGTTRK": "TARGET TRACKING", - "THK": "THICKNESS", - "THT": "THEATER", - "TKD": "TRACKED", - "TLAR": "TLAR", - "TLDCGC": "THIN LOOSE DRY DUST OR SAND COVERING GROUND COMPLETELY", - "TM": "TRAILER MOUNTED", - "TMC": "TOMCAT", - "TMDU": "THEATER MISSILE DEFENSE UNIT", - "TNE": "TRAINER", - "TNK": "TANKER", - "TOPFTR": "TOPOGRAPHICAL FEATURES", - "TOR": "RAIN SHOWERS - TORRENTIAL", - "TOW": "TOWED", - "TOWTRK": "TOW TRUCK", - "TOWVES": "TOWING VESSEL", - "TPD": "TORPEDO", - "TPLSYS": "TROPICAL STORM SYSTEMS", - "TPSSCT": "TROPOSPHERIC SCATTER", - "TPT": "TRANSPORTATION", - "TRB": "TURBULENCE", - "TRF": "TECHNOLOGICAL RESEARCH FACILITY", - "TRGARA": "TRAINING AREA", - "TRGH": "DECON SITE/POINT (THOROUGH DECONTAMINATION)", - "TRIPWR": "TRIP WIRE", - "TRISTD": "TRIPLE STRAND CONCERTINA", - "TRK": "TRACK", - "TRKMV": "TRUCK MOUNTED WITH VOLCANO", - "TRNLCO": "TRAIN LOCOMOTIVE", - "TROPDN": "TROPICAL DEPRESSION", - "TROPHG": "TROPOPAUSE HIGH", - "TROPLV": "TROPOPAUSE LEVEL", - "TROPLW": "TROPOPAUSE LOW", - "TROPSM": "TROPICAL STORM", - "TRP": "DECON SITE/POINT (TROOPS)", - "TRUAXS": "TROUGH AXIS", - "TRW": "TRAWLER", - //"TS": "THUNDERSTORM - NO PRECIPITATION", - "TS": "THUNDERSTORMS", - "TSHVNH": "THUNDERSTORM HEAVY WITH RAIN/SNOW - NO HAIL", - //"TSHVWH": "THUNDERSTORM HEAVY - WITH HAIL", - "TSK": "TASKS", - "TSLMNH": "THUNDERSTORM LIGHT TO MODERATE WITH RAIN/SNOW - NO HAIL", - "TSLMWH": "THUNDERSTORM LIGHT TO MODERATE - WITH HAIL", - "TSPF": "TRANSPORT FACILITY", - "TSWADL": "TROPICAL STORM WIND AREAS AND DATE/TIME LABELS", - "TTP": "TRAILER TRANSFER POINT", - "TTYCTR": "TELETYPE CENTER", - "TUG": "TUG", - "TUR": "TURN", - "TVAR": "TARGET VALUE AREA (TVAR)", - "UAV": "UNMANNED AERIAL VEHICLE", - "UAVR": "UNMANNED AERIAL VEHICLE (UAV) ROUTE", - "UCOV": "WRECK (UNCOVERS)", - "UGDSHL": "UNDERGROUND SHELTER", - "UH2": "UNDERWATER", - "UH2DAN": "UNDERWATER DANGER/HAZARD", - "UH2DCY": "UNDERWATER DECOY", - "UH2DML": "UNDERWATER DEMOLITION TEAM", - "UH2WPN": "UNDERWATER WEAPON", - "ULCSCG": "UNEVEN LAYER OF COMPACT OR WET SNOW COVERING GROUND COMPLETELY", - "ULDSCG": "UNEVEN LAYER OF LOOSE DRY SNOW COVERING GROUND COMPLETELY", - "UMC": "UNIT MAINTENANCE COLLECTION POINT", - "UNK": "UNKNOWN", - "UNT": "UNIT", - "UPP": "UPPER", - "USP": "UNSPECIFIED", - "USPMNE": "UNSPECIFIED MINE", - "USW": "UNDER SEA WARFARE", - "UTY": "UTILITY", - "UTYVEH": "UTILITY VEHICLE", - "UUV": "UNMANNED UNDERWATER VEHICLE (UUV)", - "UWRPM": "UNDERWAY REPLENISHMENT (OILER/TANKER, STORES, AMMUNITION, TROOP TRANSPORT)", - "UXO": "UNEXPLODED ORDINANCE AREA (UXO)", - "VCSESD": "VERY COARSE SAND", - "VDR1-2": "VDR LEVEL 1-2", - "VDR2-3": "VDR LEVEL 2-3", - "VDR3-4": "VDR LEVEL 3-4", - "VDR4-5": "VDR LEVEL 4-5", - "VDR5-6": "VDR LEVEL 5-6", - "VDR6-7": "VDR LEVEL 6-7", - "VDR7-8": "VDR LEVEL 7-8", - "VDR8-9": "VDR LEVEL 8-9", - "VDR9-0": "VDR LEVEL 9-10", - "VEH": "HIJACKING (VEHICLE)", - "VFNESD": "VERY FINE SAND", - "VFNSLT": "VERY FINE SILT", - "VIOATY": "VIOLENT ACTIVITIES (DEATH CAUSING)", - "VLAD": "VERTICAL LINE ARRAY DIFAR (VLAD)", - "VNY": "VETERINARY", - "VOLASH": "VOLCANIC ASH", - "VOLERN": "VOLCANIC ERUPTION", - "VRLRPS": "VANDALISM/RAPE/LOOT/RANSACK/PLUNDER/SACK", - "VSTOL": "VERTICAL/SHORT TAKEOFF AND LANDING (V/STOL)", - "VUL": "VULCAN", - "WAMNE": "WIDE AREA MINES", - "WAP": "WAYPOINT", - "WAR": "WARFIGHTING SYMBOLS", - "WARMVH": "WHEELED ARMORED VEHICLE", - "WAVS": "WHEELED ARMORED VEHICLE SURVEILLANCE", - "WDR": "WITHDRAW", - "WDRUP": "WITHDRAW UNDER PRESSURE", - "WFZ": "WEAPONS FREE ZONE", - "WHD": "WHEELED", - "WHMECH": "WHEELED MECHANIZED", - "WLG": "RECRUITMENT (WILLING)", - "WLST": "WHITE LIST LOCATION", - "WND": "WINDS", - "WOSMIC": "WITHOUT SNOW OR MEASURABLE ICE COVER", - "WP": "PSYOP (WRITTEN PROPAGANDA)", - "WPN": "WEAPON", - "WPNGR": "WEAPONS GRADE", - "WPNRF": "WEAPONS/RADAR RANGE FANS", - "WREOBS": "WIRE OBSTACLE", - "WRK": "WRECK", - "WRKD": "WRECK, DANGEROUS", - "WRKND": "WRECK, NON DANGEROUS", - "WRMFRN": "WARM FRONT", - "WSMIC": "WITH SNOW OR MEASURABLE ICE COVER", - "WTH": "WEATHER SYMBOLS", - "WWRT": "WATER WITH RADAR TARGETS", - "Z": "ZONE", - "ZOR": "ZONE OF RESPONSIBILITY (ZOR)" - }, - - "space": { - - "WAR.SPC": { - "symbolID": "SUPP------*****", - "tag": "WAR" - }, - "WAR.SPC.SAT": { - "symbolID": "SUPPS-----*****", - "tag": "WAR" - }, - "WAR.SPC.CSV": { - "symbolID": "SUPPV-----*****", - "tag": "WAR" - }, - "WAR.SPC.SST": { - "symbolID": "SUPPT-----*****", - "tag": "WAR" - } - }, - - "air": { - "WAR.AIRTRK": { - "symbolID": "SUAP------*****", - "tag": "WAR" - }, - "WAR.AIRTRK.MIL": { - "symbolID": "SUAPM-----*****", - "tag": "WAR" - }, - "WAR.AIRTRK.MIL.FIXD": { - "symbolID": "SUAPMF----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.MIL.FIXD.BMB": { - "symbolID": "SUAPMFB---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.FTR": { - "symbolID": "SUAPMFF---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.FTR.INCR": { - "symbolID": "SUAPMFFI--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.TNE": { - "symbolID": "SUAPMFT---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.ATK": { - "symbolID": "SUAPMFA---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.VSTOL": { - "symbolID": "SUAPMFL---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.TNK": { - "symbolID": "SUAPMFK---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.CGOALT": { - "symbolID": "SUAPMFC---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.CGOALT.LIT": { - "symbolID": "SUAPMFCL--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.CGOALT.MDM": { - "symbolID": "SUAPMFCM--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.CGOALT.HVY": { - "symbolID": "SUAPMFCH--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.ECM": { - "symbolID": "SUAPMFJ---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.MEDV": { - "symbolID": "SUAPMFO---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.RECON": { - "symbolID": "SUAPMFR---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.RECON.ABNEW": { - "symbolID": "SUAPMFRW--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.RECON.ESM": { - "symbolID": "SUAPMFRZ--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.RECON.PHG": { - "symbolID": "SUAPMFRX--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.PAT": { - "symbolID": "SUAPMFP---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.PAT.ASUW": { - "symbolID": "SUAPMFPN--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.PAT.MNECM": { - "symbolID": "SUAPMFPM--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.UTY": { - "symbolID": "SUAPMFU---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.UTY.LIT": { - "symbolID": "SUAPMFUL--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.UTY.MDM": { - "symbolID": "SUAPMFUM--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.UTY.HVY": { - "symbolID": "SUAPMFUH--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.COMM": { - "symbolID": "SUAPMFY---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.CSAR": { - "symbolID": "SUAPMFH---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.ABNCP": { - "symbolID": "SUAPMFD---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.DRN": { - "symbolID": "SUAPMFQ---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.ATK": { - "symbolID": "SUAPMFQA--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.BMB": { - "symbolID": "SUAPMFQB--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.CGO": { - "symbolID": "SUAPMFQC--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.ABNCP": { - "symbolID": "SUAPMFQD--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.FTR": { - "symbolID": "SUAPMFQF--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.CSAR": { - "symbolID": "SUAPMFQH--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.ECM": { - "symbolID": "SUAPMFQJ--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.TNK": { - "symbolID": "SUAPMFQK--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.VSTOL": { - "symbolID": "SUAPMFQL--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.SOF": { - "symbolID": "SUAPMFQM--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.MNECM": { - "symbolID": "SUAPMFQI--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.ASUW": { - "symbolID": "SUAPMFQN--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.PAT": { - "symbolID": "SUAPMFQP--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.RECON": { - "symbolID": "SUAPMFQR--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.RECON.ABNEW": { - "symbolID": "SUAPMFQRW-*****", - "tag": "DRN" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.RECON.ESM": { - "symbolID": "SUAPMFQRZ-*****", - "tag": "DRN" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.RECON.PHG": { - "symbolID": "SUAPMFQRX-*****", - "tag": "DRN" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.ASBW": { - "symbolID": "SUAPMFQS--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.TNE": { - "symbolID": "SUAPMFQT--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.UTY": { - "symbolID": "SUAPMFQU--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.COMM": { - "symbolID": "SUAPMFQY--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.DRN.MEDV": { - "symbolID": "SUAPMFQO--*****", - "tag": "FIXD" - }, - "WAR.AIRTRK.MIL.FIXD.ASBWCB": { - "symbolID": "SUAPMFS---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.FIXD.SOF": { - "symbolID": "SUAPMFM---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT": { - "symbolID": "SUAPMH----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.MIL.ROT.ATK": { - "symbolID": "SUAPMHA---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.ASBW": { - "symbolID": "SUAPMHS---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.UTY": { - "symbolID": "SUAPMHU---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.UTY.LIT": { - "symbolID": "SUAPMHUL--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.UTY.MDM": { - "symbolID": "SUAPMHUM--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.UTY.HVY": { - "symbolID": "SUAPMHUH--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.MNECM": { - "symbolID": "SUAPMHI---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.CSAR": { - "symbolID": "SUAPMHH---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.RECON": { - "symbolID": "SUAPMHR---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.DRN": { - "symbolID": "SUAPMHQ---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.CGOALT": { - "symbolID": "SUAPMHC---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.CGOALT.LIT": { - "symbolID": "SUAPMHCL--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.CGOALT.MDM": { - "symbolID": "SUAPMHCM--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.CGOALT.HVY": { - "symbolID": "SUAPMHCH--*****", - "tag": "ROT" - }, - "WAR.AIRTRK.MIL.ROT.TNE": { - "symbolID": "SUAPMHT---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.MEDV": { - "symbolID": "SUAPMHO---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.SOF": { - "symbolID": "SUAPMHM---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.ABNCP": { - "symbolID": "SUAPMHD---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.TNK": { - "symbolID": "SUAPMHK---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.ROT.ECM": { - "symbolID": "SUAPMHJ---*****", - "tag": "MIL" - }, - "WAR.AIRTRK.MIL.LTA": { - "symbolID": "SUAPML----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.WPN": { - "symbolID": "SUAPW-----*****", - "tag": "WAR" - }, - "WAR.AIRTRK.WPN.MSLIF": { - "symbolID": "SUAPWM----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.WPN.MSLIF.SLM": { - "symbolID": "SUAPWMS---*****", - "tag": "WPN" - }, - "WAR.AIRTRK.WPN.MSLIF.SLM.SSM": { - "symbolID": "SUAPWMSS--*****", - "tag": "MSLIF" - }, - "WAR.AIRTRK.WPN.MSLIF.SLM.SAM": { - "symbolID": "SUAPWMSA--*****", - "tag": "MSLIF" - }, - "WAR.AIRTRK.WPN.MSLIF.ALM": { - "symbolID": "SUAPWMA---*****", - "tag": "WPN" - }, - "WAR.AIRTRK.WPN.MSLIF.ALM.ASM": { - "symbolID": "SUAPWMAS--*****", - "tag": "MSLIF" - }, - "WAR.AIRTRK.WPN.MSLIF.ALM.AAM": { - "symbolID": "SUAPWMAA--*****", - "tag": "MSLIF" - }, - "WAR.AIRTRK.WPN.MSLIF.SBSM": { - "symbolID": "SUAPWMU---*****", - "tag": "WPN" - }, - "WAR.AIRTRK.WPN.MSLIF.CM": { - "symbolID": "SUAPWMCM--*****", - "tag": "WPN" - }, - "WAR.AIRTRK.WPN.DCY": { - "symbolID": "SUAPWD----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.CVL": { - "symbolID": "SUAPC-----*****", - "tag": "WAR" - }, - "WAR.AIRTRK.CVL.FIXD": { - "symbolID": "SUAPCF----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.CVL.ROT": { - "symbolID": "SUAPCH----*****", - "tag": "AIRTRK" - }, - "WAR.AIRTRK.CVL.LTA": { - "symbolID": "SUAPCL----*****", - "tag": "AIRTRK" - } - }, - - "ground": { - "WAR.GRDTRK": { - "symbolID": "SUGP------*****", - "tag": "WAR" - }, - "WAR.GRDTRK.UNT": { - "symbolID": "SUGPU-----*****", - "tag": "WAR" - }, - "WAR.GRDTRK.UNT.CBT": { - "symbolID": "SUGPUC----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.UNT.CBT.ADF": { - "symbolID": "SUGPUCD---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.SHTR": { - "symbolID": "SUGPUCDS--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.SHTR.CPL": { - "symbolID": "SUGPUCDSC-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.SHTR.STG": { - "symbolID": "SUGPUCDSS-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.SHTR.VUL": { - "symbolID": "SUGPUCDSV-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL": { - "symbolID": "SUGPUCDM--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT": { - "symbolID": "SUGPUCDML-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT.MOT": { - "symbolID": "SUGPUCDMLA*****", - "tag": "MSL" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.MDM": { - "symbolID": "SUGPUCDMM-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.HVY": { - "symbolID": "SUGPUCDMH-*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD": { - "symbolID": "SUGPUCDH--*****", - "tag": "ADF" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.HWK": { - "symbolID": "SUGPUCDHH-*****", - "tag": "MSL" - }, - "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.PATT": { - "symbolID": "SUGPUCDHP-*****", - "tag": "MSL" - }, - "WAR.GRDTRK.UNT.CBT.ADF.GUNUNT": { - "symbolID": "SUGPUCDG--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.CMPS": { - "symbolID": "SUGPUCDC--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.TGTGUT": { - "symbolID": "SUGPUCDT--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ADF.TMDU": { - "symbolID": "SUGPUCDO--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ARM": { - "symbolID": "SUGPUCA---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK": { - "symbolID": "SUGPUCAT--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.ABN": { - "symbolID": "SUGPUCATA-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP": { - "symbolID": "SUGPUCATW-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP.RCY": { - "symbolID": "SUGPUCATWR*****", - "tag": "TRK" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.LIT": { - "symbolID": "SUGPUCATL-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.MDM": { - "symbolID": "SUGPUCATM-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.HVY": { - "symbolID": "SUGPUCATH-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.TRK.RCY": { - "symbolID": "SUGPUCATR-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD": { - "symbolID": "SUGPUCAW--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.AAST": { - "symbolID": "SUGPUCAWS-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.ABN": { - "symbolID": "SUGPUCAWA-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP": { - "symbolID": "SUGPUCAWW-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP.RCY": { - "symbolID": "SUGPUCAWWR*****", - "tag": "WHD" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.LIT": { - "symbolID": "SUGPUCAWL-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.MDM": { - "symbolID": "SUGPUCAWM-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.HVY": { - "symbolID": "SUGPUCAWH-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.ARM.WHD.RCY": { - "symbolID": "SUGPUCAWR-*****", - "tag": "ARM" - }, - "WAR.GRDTRK.UNT.CBT.AARM": { - "symbolID": "SUGPUCAA--*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.DMD": { - "symbolID": "SUGPUCAAD-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.LIT": { - "symbolID": "SUGPUCAAL-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ABN": { - "symbolID": "SUGPUCAAM-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.AAST": { - "symbolID": "SUGPUCAAS-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.MNT": { - "symbolID": "SUGPUCAAU-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ARC": { - "symbolID": "SUGPUCAAC-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ARMD": { - "symbolID": "SUGPUCAAA-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ARMD.TKD": { - "symbolID": "SUGPUCAAAT*****", - "tag": "AARM" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ARMD.WHD": { - "symbolID": "SUGPUCAAAW*****", - "tag": "AARM" - }, - "WAR.GRDTRK.UNT.CBT.AARM.ARMD.AAST": { - "symbolID": "SUGPUCAAAS*****", - "tag": "AARM" - }, - "WAR.GRDTRK.UNT.CBT.AARM.MOT": { - "symbolID": "SUGPUCAAO-*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AARM.MOT.AAST": { - "symbolID": "SUGPUCAAOS*****", - "tag": "AARM" - }, - "WAR.GRDTRK.UNT.CBT.AVN": { - "symbolID": "SUGPUCV---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.FIXD": { - "symbolID": "SUGPUCVF--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.FIXD.UTY": { - "symbolID": "SUGPUCVFU-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.FIXD.ATK": { - "symbolID": "SUGPUCVFA-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.FIXD.RECON": { - "symbolID": "SUGPUCVFR-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT": { - "symbolID": "SUGPUCVR--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.ATK": { - "symbolID": "SUGPUCVRA-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.SCUT": { - "symbolID": "SUGPUCVRS-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.ASBW": { - "symbolID": "SUGPUCVRW-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY": { - "symbolID": "SUGPUCVRU-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.LIT": { - "symbolID": "SUGPUCVRUL*****", - "tag": "ROT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.MDM": { - "symbolID": "SUGPUCVRUM*****", - "tag": "ROT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.HVY": { - "symbolID": "SUGPUCVRUH*****", - "tag": "ROT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.C2": { - "symbolID": "SUGPUCVRUC*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.MEDV": { - "symbolID": "SUGPUCVRUE*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.ROT.MNECM": { - "symbolID": "SUGPUCVRM-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.SAR": { - "symbolID": "SUGPUCVS--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.CMPS": { - "symbolID": "SUGPUCVC--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.VSTOL": { - "symbolID": "SUGPUCVV--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.UAV": { - "symbolID": "SUGPUCVU--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.AVN.UAV.FIXD": { - "symbolID": "SUGPUCVUF-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.AVN.UAV.ROT": { - "symbolID": "SUGPUCVUR-*****", - "tag": "AVN" - }, - "WAR.GRDTRK.UNT.CBT.INF": { - "symbolID": "SUGPUCI---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.INF.LIT": { - "symbolID": "SUGPUCIL--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.MOT": { - "symbolID": "SUGPUCIM--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.MNT": { - "symbolID": "SUGPUCIO--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.ABN": { - "symbolID": "SUGPUCIA--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.AAST": { - "symbolID": "SUGPUCIS--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.MECH": { - "symbolID": "SUGPUCIZ--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.NAV": { - "symbolID": "SUGPUCIN--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.INFFV": { - "symbolID": "SUGPUCII--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.INF.ARC": { - "symbolID": "SUGPUCIC--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ENG": { - "symbolID": "SUGPUCE---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT": { - "symbolID": "SUGPUCEC--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.AAST": { - "symbolID": "SUGPUCECS-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.ABN": { - "symbolID": "SUGPUCECA-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.ARC": { - "symbolID": "SUGPUCECC-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.LIT": { - "symbolID": "SUGPUCECL-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.MDM": { - "symbolID": "SUGPUCECM-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.HVY": { - "symbolID": "SUGPUCECH-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.MECH": { - "symbolID": "SUGPUCECT-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.MOT": { - "symbolID": "SUGPUCECW-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.MNT": { - "symbolID": "SUGPUCECO-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CBT.RECON": { - "symbolID": "SUGPUCECR-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CSN": { - "symbolID": "SUGPUCEN--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ENG.CSN.NAV": { - "symbolID": "SUGPUCENN-*****", - "tag": "ENG" - }, - "WAR.GRDTRK.UNT.CBT.FLDART": { - "symbolID": "SUGPUCF---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW": { - "symbolID": "SUGPUCFH--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.SPD": { - "symbolID": "SUGPUCFHE-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.AAST": { - "symbolID": "SUGPUCFHS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.ABN": { - "symbolID": "SUGPUCFHA-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.ARC": { - "symbolID": "SUGPUCFHC-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.MNT": { - "symbolID": "SUGPUCFHO-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.LIT": { - "symbolID": "SUGPUCFHL-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.MDM": { - "symbolID": "SUGPUCFHM-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.HVY": { - "symbolID": "SUGPUCFHH-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.HOW.AMP": { - "symbolID": "SUGPUCFHX-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC": { - "symbolID": "SUGPUCFR--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL": { - "symbolID": "SUGPUCFRS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRSPD": { - "symbolID": "SUGPUCFRSS*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTRK": { - "symbolID": "SUGPUCFRSR*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTOW": { - "symbolID": "SUGPUCFRST*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL": { - "symbolID": "SUGPUCFRM-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRSPD": { - "symbolID": "SUGPUCFRMS*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTRK": { - "symbolID": "SUGPUCFRMR*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTOW": { - "symbolID": "SUGPUCFRMT*****", - "tag": "ROC" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ": { - "symbolID": "SUGPUCFT--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.RAD": { - "symbolID": "SUGPUCFTR-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.SND": { - "symbolID": "SUGPUCFTS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.FLH": { - "symbolID": "SUGPUCFTF-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT": { - "symbolID": "SUGPUCFTC-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.DMD": { - "symbolID": "SUGPUCFTCD*****", - "tag": "TGTAQ" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.TKD": { - "symbolID": "SUGPUCFTCM*****", - "tag": "TGTAQ" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.ANG": { - "symbolID": "SUGPUCFTA-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT": { - "symbolID": "SUGPUCFM--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDTRK": { - "symbolID": "SUGPUCFMS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDWHD": { - "symbolID": "SUGPUCFMW-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW": { - "symbolID": "SUGPUCFMT-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ABN": { - "symbolID": "SUGPUCFMTA*****", - "tag": "MORT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.AAST": { - "symbolID": "SUGPUCFMTS*****", - "tag": "MORT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ARC": { - "symbolID": "", - "tag": "MORT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.MNT": { - "symbolID": "SUGPUCFMTO*****", - "tag": "MORT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.MORT.AMP": { - "symbolID": "SUGPUCFML-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY": { - "symbolID": "SUGPUCFS--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.AAST": { - "symbolID": "SUGPUCFSS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.ABN": { - "symbolID": "SUGPUCFSA-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.LIT": { - "symbolID": "SUGPUCFSL-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.MNT": { - "symbolID": "SUGPUCFSO-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.METO": { - "symbolID": "SUGPUCFO--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.METO.AAST": { - "symbolID": "SUGPUCFOS-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.METO.ABN": { - "symbolID": "SUGPUCFOA-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.METO.LIT": { - "symbolID": "SUGPUCFOL-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.FLDART.METO.MNT": { - "symbolID": "SUGPUCFOO-*****", - "tag": "FLDART" - }, - "WAR.GRDTRK.UNT.CBT.RECON": { - "symbolID": "SUGPUCR---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.HRE": { - "symbolID": "SUGPUCRH--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.CVY": { - "symbolID": "SUGPUCRV--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.CVY.ARMD": { - "symbolID": "SUGPUCRVA-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.CVY.MOT": { - "symbolID": "SUGPUCRVM-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.CVY.GRD": { - "symbolID": "SUGPUCRVG-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.CVY.AIR": { - "symbolID": "SUGPUCRVO-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.ARC": { - "symbolID": "SUGPUCRC--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.AAST": { - "symbolID": "SUGPUCRS--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.ABN": { - "symbolID": "SUGPUCRA--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.MNT": { - "symbolID": "SUGPUCRO--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.LIT": { - "symbolID": "SUGPUCRL--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.MAR": { - "symbolID": "SUGPUCRR--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.RECON.MAR.DIV": { - "symbolID": "SUGPUCRRD-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.MAR.FOR": { - "symbolID": "SUGPUCRRF-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.MAR.LAR": { - "symbolID": "SUGPUCRRL-*****", - "tag": "RECON" - }, - "WAR.GRDTRK.UNT.CBT.RECON.LRS": { - "symbolID": "SUGPUCRX--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.MSL": { - "symbolID": "SUGPUCM---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.MSL.TAC": { - "symbolID": "SUGPUCMT--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.MSL.STGC": { - "symbolID": "SUGPUCMS--*****", - "tag": "CBT" - }, - // "WAR.GRDTRK.UNT.CBT.MSL": { - // "symbolID": "SUGPUCM---*****", - // "tag": "UNT" - // }, - // "WAR.GRDTRK.UNT.CBT.MSL.TAC": { - // "symbolID": "SUGPUCMT--*****", - // "tag": "CBT" - // }, - // "WAR.GRDTRK.UNT.CBT.MSL.STGC": { - // "symbolID": "SUGPUCMS--*****", - // "tag": "CBT" - // }, - "WAR.GRDTRK.UNT.CBT.ISF": { - "symbolID": "SUGPUCS---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CBT.ISF.RIV": { - "symbolID": "SUGPUCSW--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ISF.GRD": { - "symbolID": "SUGPUCSG--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ISF.GRD.DMD": { - "symbolID": "SUGPUCSGD-*****", - "tag": "ISF" - }, - "WAR.GRDTRK.UNT.CBT.ISF.GRD.MOT": { - "symbolID": "SUGPUCSGM-*****", - "tag": "ISF" - }, - "WAR.GRDTRK.UNT.CBT.ISF.GRD.MECH": { - "symbolID": "SUGPUCSGA-*****", - "tag": "ISF" - }, - "WAR.GRDTRK.UNT.CBT.ISF.WHMECH": { - "symbolID": "SUGPUCSM--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ISF.RALRD": { - "symbolID": "SUGPUCSR--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CBT.ISF.AVN": { - "symbolID": "SUGPUCSA--*****", - "tag": "CBT" - }, - "WAR.GRDTRK.UNT.CS": { - "symbolID": "SUGPUU----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.UNT.CS.NBC": { - "symbolID": "SUGPUUA---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML": { - "symbolID": "SUGPUUAC--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC": { - "symbolID": "SUGPUUACC-*****", - "tag": "NBC" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MECH": { - "symbolID": "SUGPUUACCK*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MOT": { - "symbolID": "SUGPUUACCM*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMK": { - "symbolID": "SUGPUUACS-*****", - "tag": "NBC" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMK.MOT": { - "symbolID": "SUGPUUACSM*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.SMK.ARM": { - "symbolID": "SUGPUUACSA*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.RECON": { - "symbolID": "SUGPUUACR-*****", - "tag": "NBC" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WARMVH": { - "symbolID": "SUGPUUACRW*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WAVS": { - "symbolID": "SUGPUUACRS*****", - "tag": "CML" - }, - "WAR.GRDTRK.UNT.CS.NBC.NUC": { - "symbolID": "SUGPUUAN--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.NBC.BIO": { - "symbolID": "SUGPUUAB--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.NBC.BIO.RECEQP": { - "symbolID": "SUGPUUABR-*****", - "tag": "NBC" - }, - "WAR.GRDTRK.UNT.CS.NBC.DECON": { - "symbolID": "SUGPUUAD--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT": { - "symbolID": "SUGPUUM---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.AEREXP": { - "symbolID": "SUGPUUMA--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT": { - "symbolID": "SUGPUUMS--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW": { - "symbolID": "SUGPUUMSE-*****", - "tag": "MILINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.ARMWVH": { - "symbolID": "SUGPUUMSEA*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.DFN": { - "symbolID": "SUGPUUMSED*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.INC": { - "symbolID": "SUGPUUMSEI*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.JMG": { - "symbolID": "SUGPUUMSEJ*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.THT": { - "symbolID": "SUGPUUMSET*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.CRP": { - "symbolID": "SUGPUUMSEC*****", - "tag": "SIGINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.CINT": { - "symbolID": "SUGPUUMC--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL": { - "symbolID": "SUGPUUMR--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSR": { - "symbolID": "SUGPUUMRG-*****", - "tag": "MILINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS": { - "symbolID": "SUGPUUMRS-*****", - "tag": "MILINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS.SCM": { - "symbolID": "SUGPUUMRSS*****", - "tag": "SVL" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSM": { - "symbolID": "SUGPUUMRX-*****", - "tag": "MILINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.SVL.METO": { - "symbolID": "SUGPUUMMO-*****", - "tag": "MILINT" - }, - "WAR.GRDTRK.UNT.CS.MILINT.OPN": { - "symbolID": "SUGPUUMO--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.TACEXP": { - "symbolID": "SUGPUUMT--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.INTGN": { - "symbolID": "SUGPUUMQ--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.MILINT.JINTCT": { - "symbolID": "SUGPUUMJ--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.LAWENU": { - "symbolID": "SUGPUUL---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.LAWENU.SHRPAT": { - "symbolID": "SUGPUULS--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.LAWENU.MILP": { - "symbolID": "SUGPUULM--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.LAWENU.CLE": { - "symbolID": "SUGPUULC--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.LAWENU.SECPOL": { - "symbolID": "SUGPUULF--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.LAWENU.CID": { - "symbolID": "SUGPUULD--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT": { - "symbolID": "SUGPUUS---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.ARA": { - "symbolID": "SUGPUUSA--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.COMCP": { - "symbolID": "SUGPUUSC--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.COMCP.LCCP": { - "symbolID": "SUGPUUSCL-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.CMDOPN": { - "symbolID": "SUGPUUSO--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.FWDCOM": { - "symbolID": "SUGPUUSF--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.MSE": { - "symbolID": "SUGPUUSM--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.SEN": { - "symbolID": "SUGPUUSMS-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.LEN": { - "symbolID": "SUGPUUSML-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.NODCTR": { - "symbolID": "SUGPUUSMN-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT": { - "symbolID": "SUGPUUSR--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TACSAT": { - "symbolID": "SUGPUUSRS-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TTYCTR": { - "symbolID": "SUGPUUSRT-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.RLY": { - "symbolID": "SUGPUUSRW-*****", - "tag": "SIGUNT" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.SIGSUP": { - "symbolID": "SUGPUUSS--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.PHOSWT": { - "symbolID": "SUGPUUSW--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.SIGUNT.ECRG": { - "symbolID": "SUGPUUSX--*****", - "tag": "CS" - }, - "WAR.GRDTRK.UNT.CS.IWU": { - "symbolID": "SUGPUUI---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.LNDSUP": { - "symbolID": "SUGPUUP---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CS.EOD": { - "symbolID": "SUGPUUE---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS": { - "symbolID": "SUGPUS----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN": { - "symbolID": "SUGPUSA---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.THT": { - "symbolID": "SUGPUSAT--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.CRP": { - "symbolID": "SUGPUSAC--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.JAG": { - "symbolID": "SUGPUSAJ--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.JAG.THT": { - "symbolID": "SUGPUSAJT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.JAG.CRP": { - "symbolID": "SUGPUSAJC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PST": { - "symbolID": "SUGPUSAO--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PST.THT": { - "symbolID": "SUGPUSAOT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PST.CRP": { - "symbolID": "SUGPUSAOC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.FIN": { - "symbolID": "SUGPUSAF--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.FIN.THT": { - "symbolID": "SUGPUSAFT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.FIN.CRP": { - "symbolID": "SUGPUSAFC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC": { - "symbolID": "SUGPUSAS--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.THT": { - "symbolID": "SUGPUSAST-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.CRP": { - "symbolID": "SUGPUSASC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY": { - "symbolID": "SUGPUSAM--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.THT": { - "symbolID": "SUGPUSAMT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.CRP": { - "symbolID": "SUGPUSAMC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RELG": { - "symbolID": "SUGPUSAR--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RELG.THT": { - "symbolID": "SUGPUSART-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RELG.CRP": { - "symbolID": "SUGPUSARC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF": { - "symbolID": "SUGPUSAP--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.THT": { - "symbolID": "SUGPUSAPT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.CRP": { - "symbolID": "SUGPUSAPC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT": { - "symbolID": "SUGPUSAPB-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.THT": { - "symbolID": "SUGPUSAPBT*****", - "tag": "PUBAFF" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.CRP": { - "symbolID": "SUGPUSAPBC*****", - "tag": "PUBAFF" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB": { - "symbolID": "SUGPUSAPM-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.THT": { - "symbolID": "SUGPUSAPMT*****", - "tag": "PUBAFF" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.CRP": { - "symbolID": "SUGPUSAPMC*****", - "tag": "PUBAFF" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RHU": { - "symbolID": "SUGPUSAX--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RHU.THT": { - "symbolID": "SUGPUSAXT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.RHU.CRP": { - "symbolID": "SUGPUSAXC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.LBR": { - "symbolID": "SUGPUSAL--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.LBR.THT": { - "symbolID": "SUGPUSALT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.LBR.CRP": { - "symbolID": "SUGPUSALC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MWR": { - "symbolID": "SUGPUSAW--*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MWR.THT": { - "symbolID": "SUGPUSAWT-*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.MWR.CRP": { - "symbolID": "SUGPUSAWC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY": { - "symbolID": "SUGPUSAQ--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.THT": { - "symbolID": "SUGPUSAQT-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.CRP": { - "symbolID": "SUGPUSAQC-*****", - "tag": "ADMIN" - }, - "WAR.GRDTRK.UNT.CSS.MED": { - "symbolID": "SUGPUSM---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS.MED.THT": { - "symbolID": "SUGPUSMT--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.CRP": { - "symbolID": "SUGPUSMC--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.MEDTF": { - "symbolID": "SUGPUSMM--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.MEDTF.THT": { - "symbolID": "SUGPUSMMT-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.MEDTF.CRP": { - "symbolID": "SUGPUSMMC-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.VNY": { - "symbolID": "SUGPUSMV--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.VNY.THT": { - "symbolID": "SUGPUSMVT-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.VNY.CRP": { - "symbolID": "SUGPUSMVC-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.DEN": { - "symbolID": "SUGPUSMD--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.DEN.THT": { - "symbolID": "SUGPUSMDT-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.DEN.CRP": { - "symbolID": "SUGPUSMDC-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.PSY": { - "symbolID": "SUGPUSMP--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MED.PSY.THT": { - "symbolID": "SUGPUSMPT-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.MED.PSY.CRP": { - "symbolID": "SUGPUSMPC-*****", - "tag": "MED" - }, - "WAR.GRDTRK.UNT.CSS.SLP": { - "symbolID": "SUGPUSS---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS.SLP.THT": { - "symbolID": "SUGPUSST--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CRP": { - "symbolID": "SUGPUSSC--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS1": { - "symbolID": "SUGPUSS1--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS1.THT": { - "symbolID": "SUGPUSS1T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS1.CRP": { - "symbolID": "SUGPUSS1C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS2": { - "symbolID": "SUGPUSS2--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS2.THT": { - "symbolID": "SUGPUSS2T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS2.CRP": { - "symbolID": "SUGPUSS2C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3": { - "symbolID": "SUGPUSS3--*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3.THT": { - "symbolID": "SUGPUSS3T-*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3.CRP": { - "symbolID": "SUGPUSS3C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN": { - "symbolID": "SUGPUSS3A-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.THT": { - "symbolID": "SUGPUSS3AT*****", - "tag": "CLS3" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.CRP": { - "symbolID": "SUGPUSS3AC*****", - "tag": "CLS3" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS4": { - "symbolID": "SUGPUSS4--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS4.THT": { - "symbolID": "SUGPUSS4T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS4.CRP": { - "symbolID": "SUGPUSS4C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS5": { - "symbolID": "SUGPUSS5--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS5.THT": { - "symbolID": "SUGPUSS5T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS5.CRP": { - "symbolID": "SUGPUSS5C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS6": { - "symbolID": "SUGPUSS6--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS6.THT": { - "symbolID": "SUGPUSS6T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS6.CRP": { - "symbolID": "SUGPUSS6C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS7": { - "symbolID": "SUGPUSS7--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS7.THT": { - "symbolID": "SUGPUSS7T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS7.CRP": { - "symbolID": "SUGPUSS7C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS8": { - "symbolID": "SUGPUSS8--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS8.THT": { - "symbolID": "SUGPUSS8T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS8.CRP": { - "symbolID": "SUGPUSS8C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS9": { - "symbolID": "SUGPUSS9--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS9.THT": { - "symbolID": "SUGPUSS9T-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS9.CRP": { - "symbolID": "SUGPUSS9C-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS10": { - "symbolID": "SUGPUSSX--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS10.THT": { - "symbolID": "SUGPUSSXT-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.CLS10.CRP": { - "symbolID": "SUGPUSSXC-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.LDY": { - "symbolID": "SUGPUSSL--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.LDY.THT": { - "symbolID": "SUGPUSSLT-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.LDY.CRP": { - "symbolID": "SUGPUSSLC-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O": { - "symbolID": "SUGPUSSW--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O.THT": { - "symbolID": "SUGPUSSWT-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O.CRP": { - "symbolID": "SUGPUSSWC-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR": { - "symbolID": "SUGPUSSWP-*****", - "tag": "SLP" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.THT": { - "symbolID": "SUGPUSSWPT*****", - "tag": "H2O" - }, - "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.CRP": { - "symbolID": "SUGPUSSWPC*****", - "tag": "H2O" - }, - "WAR.GRDTRK.UNT.CSS.TPT": { - "symbolID": "SUGPUST---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.THT": { - "symbolID": "SUGPUSTT--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.CRP": { - "symbolID": "SUGPUSTC--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MCC": { - "symbolID": "SUGPUSTM--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MCC.THT": { - "symbolID": "SUGPUSTMT-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MCC.CRP": { - "symbolID": "SUGPUSTMC-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.RHD": { - "symbolID": "SUGPUSTR--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.RHD.THT": { - "symbolID": "SUGPUSTRT-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.RHD.CRP": { - "symbolID": "SUGPUSTRC-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.SPOD": { - "symbolID": "SUGPUSTS--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.SPOD.THT": { - "symbolID": "SUGPUSTST-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.SPOD.CRP": { - "symbolID": "SUGPUSTSC-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.APOD": { - "symbolID": "SUGPUSTA--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.APOD.THT": { - "symbolID": "SUGPUSTAT-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.APOD.CRP": { - "symbolID": "SUGPUSTAC-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MSL": { - "symbolID": "SUGPUSTI--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MSL.THT": { - "symbolID": "SUGPUSTIT-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.TPT.MSL.CRP": { - "symbolID": "SUGPUSTIC-*****", - "tag": "TPT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT": { - "symbolID": "SUGPUSX---*****", - "tag": "UNT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.THT": { - "symbolID": "SUGPUSXT--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.CRP": { - "symbolID": "SUGPUSXC--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.HVY": { - "symbolID": "SUGPUSXH--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.HVY.THT": { - "symbolID": "SUGPUSXHT-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.HVY.CRP": { - "symbolID": "SUGPUSXHC-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.RCY": { - "symbolID": "SUGPUSXR--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.RCY.THT": { - "symbolID": "SUGPUSXRT-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.RCY.CRP": { - "symbolID": "SUGPUSXRC-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD": { - "symbolID": "SUGPUSXO--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD.THT": { - "symbolID": "SUGPUSXOT-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD.CRP": { - "symbolID": "SUGPUSXOC-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL": { - "symbolID": "SUGPUSXOM-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.THT": { - "symbolID": "SUGPUSXOMT*****", - "tag": "ORD" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.CRP": { - "symbolID": "SUGPUSXOMC*****", - "tag": "ORD" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.EOP": { - "symbolID": "SUGPUSXE--*****", - "tag": "CSS" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.EOP.THT": { - "symbolID": "SUGPUSXET-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.CSS.MAINT.EOP.CRP": { - "symbolID": "SUGPUSXEC-*****", - "tag": "MAINT" - }, - "WAR.GRDTRK.UNT.C2HQ": { - "symbolID": "SUGPUH----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.EQT": { - "symbolID": "SUGPE-----*****", - "tag": "WAR" - }, - "WAR.GRDTRK.EQT.WPN.MSLL": { - "symbolID": "SUGPEWM---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD": { - "symbolID": "SUGPEWMA--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR": { - "symbolID": "SUGPEWMAS-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TLAR": { - "symbolID": "SUGPEWMASR*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TELAR": { - "symbolID": "SUGPEWMASE*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR": { - "symbolID": "SUGPEWMAI-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TLAR": { - "symbolID": "SUGPEWMAIR*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TELAR": { - "symbolID": "SUGPEWMAIE*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR": { - "symbolID": "SUGPEWMAL-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TLAR": { - "symbolID": "SUGPEWMALR*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TELAR": { - "symbolID": "SUGPEWMALE*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT": { - "symbolID": "SUGPEWMAT-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TLAR": { - "symbolID": "", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TELAR": { - "symbolID": "SUGPEWMATE*****", - "tag": "ADFAD" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.SUF": { - "symbolID": "SUGPEWMS--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.SUF.SHTR": { - "symbolID": "SUGPEWMSS-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.SUF.INTMR": { - "symbolID": "SUGPEWMSI-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.SUF.LNGR": { - "symbolID": "SUGPEWMSL-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.AT": { - "symbolID": "SUGPEWMT--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.AT.LIT": { - "symbolID": "SUGPEWMTL-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.AT.MDM": { - "symbolID": "SUGPEWMTM-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.MSLL.AT.HVY": { - "symbolID": "SUGPEWMTH-*****", - "tag": "MSLL" - }, - "WAR.GRDTRK.EQT.WPN.SRL": { - "symbolID": "SUGPEWS---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.SRL.LIT": { - "symbolID": "SUGPEWSL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.SRL.MDM": { - "symbolID": "SUGPEWSM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.SRL.HVY": { - "symbolID": "SUGPEWSH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MRL": { - "symbolID": "SUGPEWX---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.MRL.LIT": { - "symbolID": "SUGPEWXL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MRL.MDM": { - "symbolID": "SUGPEWXM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MRL.HVY": { - "symbolID": "SUGPEWXH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATRL": { - "symbolID": "SUGPEWT---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.ATRL.LIT": { - "symbolID": "SUGPEWTL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATRL.MDM": { - "symbolID": "SUGPEWTM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATRL.HVY": { - "symbolID": "SUGPEWTH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.RIFWPN": { - "symbolID": "SUGPEWR---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.RIFWPN.RIF": { - "symbolID": "SUGPEWRR--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.RIFWPN.LMG": { - "symbolID": "SUGPEWRL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.RIFWPN.HMG": { - "symbolID": "SUGPEWRH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.GREL": { - "symbolID": "SUGPEWZ---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.GREL.LIT": { - "symbolID": "SUGPEWZL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.GREL.MDM": { - "symbolID": "SUGPEWZM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.GREL.HVY": { - "symbolID": "SUGPEWZH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MORT": { - "symbolID": "SUGPEWO---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.MORT.LIT": { - "symbolID": "SUGPEWOL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MORT.MDM": { - "symbolID": "SUGPEWOM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.MORT.HVY": { - "symbolID": "SUGPEWOH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.HOW": { - "symbolID": "SUGPEWH---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.HOW.LIT": { - "symbolID": "SUGPEWHL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.HOW.LIT.SPD": { - "symbolID": "SUGPEWHLS-*****", - "tag": "HOW" - }, - "WAR.GRDTRK.EQT.WPN.HOW.MDM": { - "symbolID": "SUGPEWHM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.HOW.MDM.SPD": { - "symbolID": "SUGPEWHMS-*****", - "tag": "HOW" - }, - "WAR.GRDTRK.EQT.WPN.HOW.HVY": { - "symbolID": "SUGPEWHH--*****", - "tag": "WPN" - }, - // "WAR.GRDTRK.EQT.WPN.HOW.HVY": { - // "symbolID": "SUGPEWHHS-*****", - // "tag": "HOW" - // }, - "WAR.GRDTRK.EQT.WPN.ATG": { - "symbolID": "SUGPEWG---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.ATG.LIT": { - "symbolID": "SUGPEWGL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATG.MDM": { - "symbolID": "SUGPEWGM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATG.HVY": { - "symbolID": "SUGPEWGH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ATG.RECL": { - "symbolID": "SUGPEWGR--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.DFG": { - "symbolID": "SUGPEWD---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.DFG.LIT": { - "symbolID": "SUGPEWDL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.DFG.LIT.SPD": { - "symbolID": "SUGPEWDLS-*****", - "tag": "DFG" - }, - "WAR.GRDTRK.EQT.WPN.DFG.MDM": { - "symbolID": "SUGPEWDM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.DFG.MDM.SPD": { - "symbolID": "SUGPEWDMS-*****", - "tag": "DFG" - }, - "WAR.GRDTRK.EQT.WPN.DFG.HVY": { - "symbolID": "SUGPEWDH--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.DFG.HVY.SPD": { - "symbolID": "SUGPEWDHS-*****", - "tag": "DFG" - }, - "WAR.GRDTRK.EQT.WPN.ADFG": { - "symbolID": "SUGPEWA---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.WPN.ADFG.LIT": { - "symbolID": "SUGPEWAL--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ADFG.MDM": { - "symbolID": "SUGPEWAM--*****", - "tag": "WPN" - }, - "WAR.GRDTRK.EQT.WPN.ADFG.HVY": { - "symbolID": "SUGPEWAH--*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.GRDVEH": { - "symbolID": "SUGPEV----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD": { - "symbolID": "SUGPEVA---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK": { - "symbolID": "SUGPEVAT--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT": { - "symbolID": "SUGPEVATL-*****", - "tag": "ARMD" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT.RCY": { - "symbolID": "SUGPEVATLR*****", - "tag": "TANK" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM": { - "symbolID": "SUGPEVATM-*****", - "tag": "ARMD" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM.RCY": { - "symbolID": "SUGPEVATMR*****", - "tag": "TANK" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY": { - "symbolID": "SUGPEVATH-*****", - "tag": "ARMD" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY.RCY": { - "symbolID": "SUGPEVATHR*****", - "tag": "TANK" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC": { - "symbolID": "SUGPEVAA--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC.RCY": { - "symbolID": "SUGPEVAAR-*****", - "tag": "ARMD" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMINF": { - "symbolID": "SUGPEVAI--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.C2V": { - "symbolID": "SUGPEVAC--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.CSSVEH": { - "symbolID": "SUGPEVAS--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ARMD.LARMVH": { - "symbolID": "SUGPEVAL--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH": { - "symbolID": "SUGPEVU---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.BUS": { - "symbolID": "SUGPEVUB--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI": { - "symbolID": "SUGPEVUS--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.LIT": { - "symbolID": "SUGPEVUSL-*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.MDM": { - "symbolID": "SUGPEVUS--*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.HVY": { - "symbolID": "SUGPEVUS--*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.LCCTRK": { - "symbolID": "SUGPEVUL--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.CCTRK": { - "symbolID": "SUGPEVUX--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.H2OCRT": { - "symbolID": "SUGPEVUR--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK": { - "symbolID": "SUGPEVUT--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.LIT": { - "symbolID": "SUGPEVUTL-*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.HVY": { - "symbolID": "SUGPEVUTH-*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC": { - "symbolID": "SUGPEVUA--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC.ARMD": { - "symbolID": "SUGPEVUAA-*****", - "tag": "UTYVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH": { - "symbolID": "EQT", - "tag": "SUGPEVE---*****" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BRG": { - "symbolID": "SUGPEVEB--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ERHMR": { - "symbolID": "SUGPEVEE--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.CSNVEH": { - "symbolID": "SUGPEVEC--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH": { - "symbolID": "SUGPEVEM--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.ARMCV": { - "symbolID": "SUGPEVEMV-*****", - "tag": "ENGVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.TRKMV": { - "symbolID": "SUGPEVEML-*****", - "tag": "ENGVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH": { - "symbolID": "SUGPEVEA--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.ARMVM": { - "symbolID": "SUGPEVEAA-*****", - "tag": "ENGVEH" - }, - // "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.TRKMV": { - // "symbolID": "SUGPEVEML-*****", - // "tag": "ENGVEH" - // }, - // "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH": { - // "symbolID": "SUGPEVEA--*****", - // "tag": "GRDVEH" - // }, - // "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.ARMVM": { - // "symbolID": "SUGPEVEAA-*****", - // "tag": "ENGVEH" - // }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.TM": { - "symbolID": "SUGPEVEAT-*****", - "tag": "ENGVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR": { - "symbolID": "SUGPEVED--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR.ARMD": { - "symbolID": "SUGPEVEDA-*****", - "tag": "ENGVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.AST": { - "symbolID": "SUGPEVES--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ARMERV": { - "symbolID": "SUGPEVER--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BH": { - "symbolID": "SUGPEVEH--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.FRYTSP": { - "symbolID": "SUGPEVEF--*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.TRNLCO": { - "symbolID": "SUGPEVT---*****", - "tag": "GRDVEH" - }, - "WAR.GRDTRK.EQT.GRDVEH.CVLVEH": { - "symbolID": "SUGPEVC---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.GRDVEH.PKAN": { - "symbolID": "SUGPEVM---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SNS": { - "symbolID": "SUGPES----*****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.EQT.SNS.RAD": { - "symbolID": "SUGPESR---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SNS.EMP": { - "symbolID": "SUGPESE---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SPL.LSR": { - "symbolID": "SUGPEXL---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SPL.NBCEQT": { - "symbolID": "SUGPEXN---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SPL.FLMTHR": { - "symbolID": "SUGPEXF---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SPL.LNDMNE": { - "symbolID": "SUGPEXM---*****", - "tag": "EQT" - }, - "WAR.GRDTRK.EQT.SPL.LNDMNE.CLM": { - "symbolID": "SUGPEXMC--*****", - "tag": "SPL" - }, - "WAR.GRDTRK.EQT.SPL.LNDMNE.LTL": { - "symbolID": "SUGPEXML--*****", - "tag": "SPL" - }, - "WAR.GRDTRK.INS": { - "symbolID": "SUGPI-----H****", - "tag": "WAR" - }, - "WAR.GRDTRK.INS.RMP": { - "symbolID": "SUGPIR----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.RMP.MNE": { - "symbolID": "SUGPIRM---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.RMP.PGO": { - "symbolID": "SUGPIRP---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.RMP.NBC": { - "symbolID": "SUGPIRN---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.RMP.NBC.BIO": { - "symbolID": "SUGPIRNB--H****", - "tag": "RMP" - }, - "WAR.GRDTRK.INS.RMP.NBC.CML": { - "symbolID": "SUGPIRNC--H****", - "tag": "RMP" - }, - "WAR.GRDTRK.INS.RMP.NBC.NUC": { - "symbolID": "SUGPIRNN--H****", - "tag": "RMP" - }, - "WAR.GRDTRK.INS.PF": { - "symbolID": "SUGPIP----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.PF.DECON": { - "symbolID": "SUGPIPD---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.EQTMNF": { - "symbolID": "SUGPIE----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.SRUF": { - "symbolID": "SUGPIU----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.SRUF.TRF": { - "symbolID": "SUGPIUR---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.SRUF.TCF": { - "symbolID": "SUGPIUT---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.SRUF.EPF": { - "symbolID": "SUGPIUE---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.SRUF.EPF.NPT": { - "symbolID": "SUGPIUEN--H****", - "tag": "SRUF" - }, - "WAR.GRDTRK.INS.SRUF.EPF.DAM": { - "symbolID": "SUGPIUED--H****", - "tag": "SRUF" - }, - "WAR.GRDTRK.INS.SRUF.EPF.FOSF": { - "symbolID": "SUGPIUEF--H****", - "tag": "SRUF" - }, - "WAR.GRDTRK.INS.SRUF.PWS": { - "symbolID": "SUGPIUP---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.NENY": { - "symbolID": "SUGPIMF---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.NENY.ATMER": { - "symbolID": "SUGPIMFA--H****", - "tag": "MMF" - }, - "WAR.GRDTRK.INS.MMF.NENY.NMP": { - "symbolID": "SUGPIMFP--H****", - "tag": "MMF" - }, - "WAR.GRDTRK.INS.MMF.NENY.NMP.WPNGR": { - "symbolID": "SUGPIMFPWH****", - "tag": "NENY" - }, - "WAR.GRDTRK.INS.MMF.NENY.NMS": { - "symbolID": "SUGPIMFS--H****", - "tag": "MMF" - }, - "WAR.GRDTRK.INS.MMF.APA": { - "symbolID": "SUGPIMA---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.AMEP": { - "symbolID": "SUGPIME---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.AMTP": { - "symbolID": "SUGPIMG---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.MILVP": { - "symbolID": "SUGPIMV---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.ENGEP": { - "symbolID": "SUGPIMN---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.ENGEP.BRG": { - "symbolID": "SUGPIMNB--H****", - "tag": "MMF" - }, - "WAR.GRDTRK.INS.MMF.CBWP": { - "symbolID": "SUGPIMC---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.SHPCSN": { - "symbolID": "SUGPIMS---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MMF.MSSP": { - "symbolID": "SUGPIMM---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.GOVLDR": { - "symbolID": "SUGPIG----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.MILBF": { - "symbolID": "SUGPIB----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.MILBF.AB": { - "symbolID": "SUGPIBA---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.MILBF.SP": { - "symbolID": "SUGPIBN---H****", - "tag": "INS" - }, - "WAR.GRDTRK.INS.TSPF": { - "symbolID": "SUGPIT----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.MEDF": { - "symbolID": "SUGPIX----H****", - "tag": "GRDTRK" - }, - "WAR.GRDTRK.INS.MEDF.HSP": { - "symbolID": "SUGPIXH---H****", - "tag": "INS" - } - }, - - "sea": { - "WAR.SSUF": { - "symbolID": "SUSP------*****", - "tag": "WAR" - }, - "WAR.SSUF.CBTT": { - "symbolID": "SUSPC-----*****", - "tag": "WAR" - }, - "WAR.SSUF.CBTT.LNE": { - "symbolID": "SUSPCL----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.LNE.CRR": { - "symbolID": "SUSPCLCV--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.LNE.BBS": { - "symbolID": "SUSPCLBB--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.LNE.CRU": { - "symbolID": "SUSPCLCC--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.LNE.DD": { - "symbolID": "SUSPCLDD--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.LNE.FFR": { - "symbolID": "SUSPCLFF--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.AMPWS": { - "symbolID": "SUSPCA----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.AMPWS.ASTVES": { - "symbolID": "SUSPCALA--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.AMPWS.LNDSHP": { - "symbolID": "SUSPCALS--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.AMPWS.LNDSHP.MDM": { - "symbolID": "SUSPCALSM-*****", - "tag": "AMPWS" - }, - "WAR.SSUF.CBTT.AMPWS.LNDSHP.TANK": { - "symbolID": "SUSPCALST-*****", - "tag": "AMPWS" - }, - "WAR.SSUF.CBTT.AMPWS.LNDCRT": { - "symbolID": "SUSPCALC--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.MNEWV": { - "symbolID": "SUSPCM----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.MNEWV.MNELYR": { - "symbolID": "SUSPCMML--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.MNEWV.MNESWE": { - "symbolID": "SUSPCMMS--*****", - "tag": "CBTT" + var cws = { + "def": { + "1WTRFF": "ONE-WAY TRAFFIC", + "2WTRFF": "TWO-WAY TRAFFIC", + "AA/C": "ANTI-AIRCRAFT", + "AAFF": "AXIS OF ADVANCE FOR FEINT", + "AAM": "AIR TO AIR MISSILE (AAM)", + "AARM": "ANTI ARMOR", + "AAST": "AIR ASSAULT", + "AB": "AIRPORT/AIRBASE", + "ABN": "AIRBORNE", + "ABNCP": "AIRBORNE COMMAND POST", + "ABNEW": "AIRBORNE EARLY WARNING (AEW)", + "ABNINC": "AIRBORNE INTERCEPT", + "ABNSB": "AIRBORNE SEARCH & BOMBING", + "ABP": "EXPLOSIVES, STATE OF READINESS 2 (ARMED-BUT PASSABLE)", + "ABS": "ABATIS", + "ABYARA": "ASSEMBLY AREA", + "ACA": "AIRSPACE COORDINATION AREA (ACA)", + "ACDR": "AIR CORRIDOR", + "ACP": "AIR CONTROL POINT (ACP)", + "ACTL": "AIR CONTROL", + "ACTPNT": "ACTION POINTS (GENERAL)", + "ACU": "ACOUSTIC", + "ACYC": "ANTICYCLONE CENTER", + "ADF": "AIR DEFENSE", + "ADFAD": "AIR DEFENSE (AD)", + "ADFG": "AIR DEFENSE GUN", + "ADMIN": "ADMINISTRATIVE (ADMIN)", + "AEP": "AMBULANCE EXCHANGE POINT", + "AEREXP": "AERIAL EXPLOITATION", + "AFP": "ATTACK BY FIRE POSITION", + "AHD": "AIRHEAD", + "AIMPNT": "AIM POINT", + "AIR": "AIR", + "AIRFZ": "AIRFIELD ZONE", + "AIRTRK": "AIR TRACK", + "ALM": "AIR LAUNCHED MISSILE", + "ALTUSP": "ALTERNATE DECON SITE/POINT (UNSPECIFIED)", + "AMB": "AMBUSH", + "AMBLNC": "AMBULANCE", + "AMEP": "AMMUNITION AND EXPLOSIVES PRODUCTION", + "AMP": "AMPHIBIOUS", + "AMPHC": "ATMOSPHERIC", + "AMPWS": "AMPHIBIOUS WARFARE SHIP", + "AMTP": "ARMAMENT PRODUCTION", + "ANCRG1": "ANCHORAGE", + "ANCRG2": "ANCHORAGE", + "ANCRG3": "ANCHORAGE", + "ANG": "ANGLICO", + "ANM": "ANM", + "AOO": "AREA OF OPERATIONS (AO)", + "AP": "AMMUNITION POINTS", + "APA": "AIRCRAFT PRODUCTION & ASSEMBLY", + "APL": "HIJACKING (AIRPLANE)", + "APMNE": "ANTIPERSONNEL (AP) MINES", + "APOD": "APOD/APOE", + "ARA": "AREA", + "ARATGT": "AREA TARGET", + "ARC": "ARCTIC", + "ARM": "ARMOR", + "ARMCV": "ARMORED CARRIER WITH VOLCANO", + "ARMD": "ARMORED", + "ARMERV": "ARMORED ENGINEER RECON VEHICLE (AERV)", + "ARMINF": "ARMORED INFANTRY", + "ARMPC": "ARMORED PERSONNEL CARRIER", + "ARMVM": "ARMORED VEHICLE MOUNTED", + "ARMWVH": "ARMORED WHEELED VEHICLE", + "ARR": "ARREST", + "ARS": "AREAS", + "ARTSVY": "ARTILLERY SURVEY", + "ASBW": "ANTI-SUBMARINE WARFARE (ASW)", + //"ASBW": "ANTISUBMARINE WARFARE/MPA", + "ASBWCB": "ANTISUBMARINE WARFARE (ASW) CARRIER BASED", + "ASBWF": "ANTISUBMARINE WARFARE, FIXED WING", + "ASBWR": "ANTISUBMARINE WARFARE, ROTARY WING", + "ASM": "AIR TO SURFACE MISSILE (ASM)", + "ASN": "ARSON/FIRE", + "ASP": "AMMUNITION SUPPLY POINT (ASP)", + "ASRUT": "ALTERNATE SUPPLY ROUTE", + "ASS": "ASSASSINATION/MURDER/EXECUTION", + "AST": "ARMORED ASSAULT", + "ASTCA": "ASSAULT CROSSING AREA", + "ASTPSN": "ASSAULT POSITION", + "ASTVES": "ASSAULT VESSEL", + "ASUW": "ANTI-SURFACE WARFACE (ASUW)", + "ASWSHP": "ASW SHIP", + "ASWSUB": "ASW SUBMARINE", + "AT": "ANTITANK (AT)", + "ATAC": "ATAC", + "ATCTL": "AIR TRAFFIC CONTROL", + "ATD": "ANTITANK DITCH", + "ATDATM": "ANTITANK DITCH REINFORCED WITH ANTITANK MINES TDC COMPLETE", + "ATDUC": "UNDER CONSTRUCTION", + "ATG": "ANTI-TANK GUN", + "ATIZ": "ARTILLERY TARGET INTELLIGENCE (ATI) ZONE", + "ATK": "ATTACK", + "ATKPSN": "ATTACK POSITION", + "ATMAHD": "ANTITANK MINE WITH ANTIHANDLING DEVICE", + "ATMDIR": "ANTITANK MINE (DIRECTIONAL)", + "ATMER": "ATOMIC ENERGY REACTOR", + "ATMNE": "ANTITANK MINE (AT)", + "ATN": "AIDS TO NAVIGATION", + "ATO": "ANTITANK OBSTACLES", + "ATP": "AMMUNITION TRANSFER POINT (ATP)", + "ATRFF": "ALTERNATING TRAFFIC", + "ATRL": "ANTITANK ROCKET LAUNCHER", + "ATW": "ANTITANK WALL", + "AVN": "AVIATION", + "AXSADV": "AXIS OF ADVANCE", + "BAS": "BELTS AND STRIPS", + "BB": "BERGY BIT", + "BBS": "BATTLESHIP", + "BBY": "BOOBY TRAP", + "BCN": "BEACON", + "BCON": "BRIEF CONTACT", + "BDAWTH": "BOUNDED AREAS OF WEATHER", + "BEH": "BEACH", + "BEHSPE": "BEACH SLOPE", + "BERBOX": "BEARING BOX", + "BERLNE": "BEARING LINE", + "BH": "BACKHOE", + "BIO": "BIOLOGICAL", + "BIOCA": "BIOLOGICALLY CONTAMINATED AREA", + "BIOLUM": "BIOLUMINESCENCE", + "BKN": "BROKEN COVERAGE", + "BLDS": "BOULDERS", + "BLDTSD": "BLOWING DUST OR SAND", + "BLK": "BLOCK", + "BLSNHY": "BLOWING SNOW - HEAVY", + "BLSNLM": "BLOWING SNOW - LIGHT/MODERATE", + "BLST": "BALLISTIC MISSILE", + //"BLST": "BLACK LIST LOCATION", + "BLT": "BELT", + "BM": "BOMB/BOMBING", + "BMARA": "BOMB AREA", + "BMB": "BOMBER", + "BNDS": "BOUNDARIES", + "BOAT": "HIJACKING (BOAT)", + "BRCT": "BROADCAST", + "BRG": "BRIDGE", + "BRGH": "BRIDGEHEAD", + "BRH": "BREACH", + "BRHSA": "BERTHS (ANCHOR)", + "BRHSO": "BERTHS (ONSHORE)", + "BRKS": "BREAKERS", + "BSA": "BRIGADE (BSA)", + "BT": "BATHYTHERMOGRAPH TRANSMITTING (BT)", + "BTFSVL": "BATTLEFIELD SURVEILLANCE", + "BTLPSN": "BATTLE POSITION", + "BTMCHR": "BOTTOM CHARACTERISTICS", + "BTMFAT": "BOTTOM FEATURES", + "BTMRGN": "BOTTOM ROUGHNESS", + "BTMRTN": "BOTTOM RETURN/NOMBO", + "BUOY": "BUOY DEFAULT", + "BUS": "BUS", + "BW": "BERGY WATER", + "BWGJAW": "BREAKWATER/GROIN/JETTY (ABOVE WATER)", + "BWGJBW": "BREAKWATER/GROIN/JETTY (BELOW WATER)", + "BYS": "BYPASS", + "C2ARS": "COMMAND & CONTROL AREAS", + "C2GM": "COMMAND AND CONTROL AND GENERAL MANEUVER", + "C2HQ": "SPECIAL C2 HEADQUARTERS COMPONENT", + "C2LNE": "COMMAND & CONTROL LINES", + "C2PNT": "COMMAND & CONTROL POINTS", + "C2V": "C2V/ACV", + "CALM": "CALM WINDS", + "CAP": "COMBAT AIR PATROL (CAP)", + "CASS": "COMMAND ACTIVE SONOBUOY SYSTEM (CASS)", + "CATK": "COUNTERATTACK (CATK)", + "CATKF": "COUNTERATTACK BY FIRE", + "CBNP": "CANNIBALIZATION POINT", + "CBT": "COMBAT", + "CBTPST": "COMBAT OUTPOST", + "CBTT": "COMBATANT", + "CBWP": "CHEMICAL & BIOLOGICAL WARFARE PRODUCTION", + "CCP": "CASUALTY COLLECTION POINT", + "CCTA": "CONCERTINA", + "CCTRK": "CROSS-COUNTRY TRUCK", + "CELL": "CELLULAR/MOBILE", + "CFCSG": "CABLE FERRY CROSSING", + "CFFZ": "CALL FOR FIRE ZONE (CFFZ)", + "CFL": "COORDINATED FIRE LINE (CFL)", + "CFZ": "CRITICAL FRIENDLY ZONE (CFZ)", + "CGO": "CARGO", + "CGOALT": "CARGO AIRLIFT (TRANSPORT)", + "CHKPNT": "CHECK POINT", + "CID": "CENTRAL INTELLIGENCE DIVISION (CID)", + "CINT": "COUNTER INTELLIGENCE", + "CIP": "CALL IN POINT", + "CIR": "CIRCLE", + "CIRCLR": "CIRCULAR", + "CIRTGT": "CIRCULAR TARGET", + "CLAY": "CLAY", + "CLDFRN": "COLD FRONT", + "CLE": "CIVILIAN LAW ENFORCEMENT", + "CLM": "CLAYMORE", + "CLR": "CLEAR", + "CLS1": "CLASS I", + "CLS10": "CLASS X", + "CLS2": "CLASS II", + "CLS3": "CLASS III", + "CLS4": "CLASS IV", + "CLS5": "CLASS V", + "CLS6": "CLASS VI", + "CLS7": "CLASS VII", + "CLS8": "CLASS VIII", + "CLS9": "CLASS IX", + "CLT": "COLT/FIST", + "CM": "CRUISE MISSILE", + "CMDOPN": "COMMAND OPERATIONS", + "CML": "CHEMICAL", + "CMLCA": "CHEMICALLY CONTAMINATED AREA", + "CMPS": "COMPOSITE", + "CNG": "CONVERGENCE", + "CNGLNE": "CONVERGANCE LINE", + "CNL": "CANAL", + "CNS": "CENSOR ZONE", + "CNT": "CONTAIN", + "CNVPRN": "CONVENTIONAL PROPULSION", + "CNY": "CONVOY", + "CNZ": "CANALIZE", + "COBL": "COBBLES", + "COBLOS": "COBBLES, OYSTER SHELLS", + "COMCP": "COMMUNICATION CONFIGURED PACKAGE", + "COMM": "COMMUNICATIONS", + "COMMCP": "COMMUNICATIONS CHECKPOINT (CCP)", + "CONPNT": "CONTACT POINT", + "COV": "COVER", + "CPL": "CHAPARRAL", + "CRCD": "RECRUITMENT (COERCED/IMPRESSED)", + "CRDPNT": "COORDINATION POINT", + "CRDRTB": "CORRIDOR TAB", + "CRK": "CRACKS", + "CRKASL": "CRACKS AT A SPECIFIC LOCATION", + "CRL": "CORAL", + "CRP": "CORPS", + "CRR": "CARRIER", + "CRU": "CRUISER", + "CRV": "DEPTH CURVE", + "CS": "COMBAT SUPPORT", + "CSAR": "COMBAT SEARCH AND RESCUE (CSAR)", + "CSE": "COARSE", + "CSESD": "COARSE SAND", + "CSESLT": "COARSE SILT", + "CSGSTE": "CROSSING SITE/WATER CROSSING", + "CSN": "CONSTRUCTION", + "CSNALH": "COMPACT OR WET SNOW (WITH OR WITHOUT ICE) COVERING AT LEAST ONE-HALF GROUND, BUT GROUND NOT COMPLETELY COVERED", + "CSNVEH": "CONSTRUCTION VEHICLE", + "CSS": "COMBAT SERVICE SUPPORT", + "CSSVEH": "COMBAT SERVICE SUPPORT VEHICLE", + "CSTHYD": "COASTAL HYDROGRAPHY", + "CSTLN": "COASTLINE", + "CSTSVL": "COASTAL SURVEILLANCE", + "CSV": "CREWED SPACE VEHICLE", + "CTDAPP": "CONTROLLED APPROACH", + "CTDINC": "CONTROLLED INTERCEPT", + "CTR": "SEARCH CENTER", + "CTRB": "CLUTTER (BOTTOM)", + "CTSHVY": "CONTINUOUS HEAVY", + "CTSLIT": "CONTINUOUS LIGHT", + "CTSMOD": "CONTINUOUS MODERATE", + "CTUR": "CONTOUR", + "CUDCOV": "CLOUD COVERAGE", + "CVL": "CIVIL", + "CVLAFF": "CIVIL AFFAIRS", + "CVLVEH": "CIVILIAN VEHICLE", + "CVP": "CIVILIAN COLLECTION POINT", + "CVY": "CAVALRY", + "CWSNLH": "COMPACT OR WET SNOW (WITH OR WITHOUT ICE) COVERING LESS THAN ONE-HALF OF GROUND", + "CYC": "CYCLONE CENTER", + "DA": "DEAD SPACE AREA (DA)", + "DAFF": "DIRECTION OF ATTACK FOR FEINT", + "DAFNC": "DOUBLE APRON FENCE", + "DAM": "DAM", + "DANHAZ": "DANGERS/HAZARDS", + "DAPP": "DOWNED AIRCREW PICKUP POINT", + "DATTMN": "DATA TRANSMISSION", + "DBLFNC": "DOUBLE FENCE", + "DBLSTD": "DOUBLE STRAND CONCERTINA", + "DBS": "DRIVE-BY SHOOTING", + "DBT": "MINE-NAVAL (DOUBTFUL)", + "DCDH2O": "DISCOLORED WATER", + "DCNPNT": "DECISION POINT", + "DCP": "DETAINEE COLLECTION POINT", + "DCPN": "DECEPTION", + "DCY": "DECOY", + "DD": "DESTROYER", + "DDCK": "DRYDOCK", + "DECON": "DECONTAMINATION", + "DECONP": "DECONTAMINATION (DECON) POINTS", + "DEF": "DEFENSE", + "DEFN": "MINE-NAVAL (DEFINITE)", + "DEMO": "DEMONSTRATION", + "DEN": "DENTAL", + "DFG": "DIRECT FIRE GUN", + "DFN": "DIRECTION FINDING", + "DFT": "BYPASS DIFFICULT", + "DFTY": "OBSTACLE BYPASS DIFFICULTY", + "DGOPN": "DRUG OPERATION", + "DGVEH": "DRUG VEHICLE", + "DHA": "DETAINEE HOLDING AREA", + "DICASS": "DIRECTIONAL COMMAND ACTIVE SONOBUOY SYSTEM(DICASS)", + "DIFAR": "DIRECTIONAL FREQUENCY ANALYZING AND RECORDING(DIFAR)", + "DIPPSN": "DIP POSITION", + "DIRATK": "DIRECTION OF ATTACK", + "DIV": "DIVISION", + "DLRP": "DLRP", + "DLT": "DEALT", + "DLY": "DELAY", + "DMA": "DECOY MINED AREA", + "DMAF": "DECOY MINED AREA, FENCED", + "DMD": "DISMOUNTED", + "DMY": "DUMMY (DECEPTION/DECOY)", + "DMYMD": "DUMMY MINEFIELD (DYNAMIC)", + "DMYMS": "DUMMY MINEFIELD (STATIC)", + "DOPN": "DOLPHIN", + "DPH": "DEPTH", + "DRCL": "DOSE RATE CONTOUR LINES", + "DRFT": "DRIFTER", + "DRG": "DREDGE", + "DRN": "DRONE (RPV/UAV)", + "DRPE": "DROP POINT", + "DRPPNT": "DISPLACED PERSONS, REFUGEES, AND EVACUEES", + "DRPZ": "DROP ZONE", + "DRT": "DISRUPT", + "DSA": "DIVISION (DSA)", + "DSTVES": "DISTRESSED VESSEL", + "DSTY": "DESTROY", + "DT/SD": "DUST OR SAND", + "DTDVL": "DUST DEVIL", + "DTHAC": "DITCHED AIRCRAFT", + "DTM": "DATUM", + "DVG": "DIVERGENCE", + "DVR": "DIVER (HARDTOP DIVER, SCUBA DIVER)", + "DVSN": "DIVERSIONS", + "DYN": "DYNAMIC DEPICTION", + "DYNPRO": "DYNAMIC PROCESSES", + "DZ": "DRIZZLE", + "DZR": "DOZER", + "EBB": "CURRENT FLOW - EBB", + "ECM": "ELECTRONIC COUNTERMEASURES (ECM/JAMMER)", + "ECRG": "ELECTRONIC RANGING", + "ECW": "ELECTRONIC WARFARE", + "EIEOB": "ESTIMATED ICE EDGE OR BOUNDARY", + "ELC": "ELECTRONIC", + "ELCSCG": "EVEN LAYER OF COMPACT OR WET SNOW COVERING GROUND COMPLETELY", + "ELDSCG": "EVEN LAYER OF LOOSE DRY SNOW COVERING GROUND COMPLETELY", + "ELP": "ELLIPSE", + "EM": "ELECTRO-MAGNETIC", + "EMP": "EMPLACED", + "EMTARA": "ENGAGEMENT AREA", + "ENCMT": "ENCIRCLEMENT", + "ENG": "ENGINEER", + "ENGEP": "ENGINEERING EQUIPMENT PRODUCTION", + "ENGVEH": "ENGINEER VEHICLE", + "ENTPNT": "ENTRY POINT", + "EOD": "EXPLOSIVE ORDINANCE DISPOSAL", + "EOP": "ELECTRO-OPTICAL", + "EOPI": "ELECTRO-OPTICAL INTERCEPT", + "EOTR": "EDDIES/OVERFALLS/TIDE RIPS", + "EPF": "ELECTRIC POWER FACILITY", + "EPWCP": "ENEMY PRISONER OF WAR (EPW) COLLECTION POINT", + "EPWHA": "ENEMY PRISONER OF WAR (EPW) HOLDING AREA", + "EQT": "EQUIPMENT", + "EQTMNF": "EQUIPMENT MANUFACTURE", + "EQTTRP": "DECON SITE/POINT (EQUIPMENT AND TROOPS)", + "ER": "EMERGENCY", + "ERHMR": "EARTHMOVER", + "ERHSVL": "EARTH SURVEILLANCE", + "ERP": "ENGINEER REGULATING POINT", + "ESM": "ELECTRONIC SURVEILLANCE MEASURES", + "ESTOF": "EARTHWORK, SMALL TRENCH OR FORTIFICATION", + "ESY": "BYPASS EASY", + "EW": "EARLY WARNING", + "EXCD": "ROADBLOCK COMPLETE (EXECUTED)", + "EXT": "TURBULENCE - EXTREME", + "EXTDWC": "EXTREMELY DRY WITH CRACKS", + "EXTN": "EXTORTION", + "EZ": "EXTRACTION ZONE (EZ)", + "FAADEZ": "FORWARD AREA AIR DEFENSE ZONE (FAADEZ)", + "FAC": "FACILITIES", + "FAOTP": "FALLOUT PRODUCING", + "FARP": "FORWARD ARMING AND REFUELING AREA (FARP)", + "FBG": "FLOEBERG", + "FC": "FUNNEL CLOUD (TORNADO/WATERSPOUT)", + "FCL": "FINAL COORDINATION LINE", + "FDDIST": "FOOD DISTRIBUTION", + "FEBA": "FORWARD EDGE OF BATTLE AREA (FEBA)", + "FEW": "FEW COVERAGE", + "FEWS": "FOXHOLE, EMPLACEMENT OR WEAPON SITE", + "FFA": "FIRE FREE AREA (FFA)", + "FFR": "FRIGATE/CORVETTE", + "FG": "FOG", + "FIN": "FINANCE", + "FIRCTL": "FIRE CONTROL", + "FIX": "FIX", + "FIXAVN": "FIXED WING AVIATION", + "FIXD": "FIXED WING", + "FIXPFD": "FIXED AND PREFABRICATED", + "FLDART": "FIELD ARTILLERY", + "FLGRD1": "FOUL GROUND", + "FLGRD2": "FOUL GROUND", + "FLGRD3": "FOUL GROUND", + "FLH": "FLASH (OPTICAL)", + "FLMTHR": "FLAME THROWER", + "FLOOD": "CURRENT FLOW - FLOOD", + "FLOT": "FORWARD LINE OF OWN TROOPS (FLOT)", + "FLT": "FLAT", + "FLTBD": "FLATBED TRUCK", + "FLTSUP": "FLEET SUPPORT (TENDER/TUG)", + "FLWASS": "FOLLOW AND ASSUME", + "FLWSUP": "FOLLOW AND SUPPORT", + "FNE": "FINE", + "FNESD": "FINE SAND", + "FNESLT": "FINE SILT", + "FOR": "FORCE", + "FOSF": "FOSSIL FUEL", + "FP": "FIRING POINT", + "FPF": "FINAL PROTECTIVE FIRE (FPF)", + "FRD": "FORD", + "FRDDFT": "FORD DIFFICULT", + "FRDESY": "FORD EASY", + "FRGS": "FRONTOGENESIS", + "FRGSRH": "FORAGING/SEARCHING", + "FRLS": "FRONTOLYSIS", + "FRMN": "FORMATION", + "FRNSYS": "FRONTAL SYSTEMS", + "FRT": "FORT", + "FRY": "FERRY", + "FRYCSG": "FERRY CROSSING", + "FRYTSP": "FERRY TRANSPORTER", + "FSA": "FIRE SUPPORT AREA (FSA)", + "FSCL": "FIRE SUPPORT COORDINATION LINE (FSCL)", + "FSG": "FISHING", + "FSGHBR": "FISHING HARBOR", + "FSH1": "FORESHORE", + "FSH2": "FORESHORE", + "FSH3": "FORESHORE", + "FSS": "FIRE SUPPORT STATION", + "FSTK1": "FISH STAKES/TRAPS/WEIRS", + "FSTK2": "FISH STAKES", + "FSTK3": "FISH STAKES/TRAPS/WEIRS", + "FSUPP": "FIRE SUPPORT", + "FTFDAR": "FORTIFIED AREA", + "FTFDLN": "FORTIFIED LINE", + "FTR": "FIGHTER", + "FU": "SMOKE", + "FWDCOM": "FORWARD COMMUNICATIONS", + "FWDOP": "FORWARD OBSERVER POSITION", + "FZDZ": "FREEZING DRIZZLE", + "FZLED": "FROZEN LEAD", + "FZLVL": "FREEZING LEVEL", + "FZPPN": "FREEZING/FROZEN PRECIPITATION", + "FZRA": "FREEZING RAIN", + "FZSNV": "FOG - FREEZING, SKY NOT VISIBLE", + "FZSV": "FOG - FREEZING, SKY VISIBLE", + "GAP": "GAP", + "GDD": "GUIDED MISSILE", + "GENARA": "GENERAL AREA", + "GLST": "GRAY LIST LOCATION", + "GLZGRD": "GLAZE (THIN ICE) ON GROUND", + "GNL": "GENERAL", + "GOVLDR": "GOVERNMENT LEADERSHIP", + "GPHY": "GEOPHYSICS/ACOUSTICS", + "GRD": "GROUND", + "GRDSM": "GROUND STATION MODULE", + "GRDSR": "GROUND SURVEILLANCE RADAR", + "GRDTRK": "GROUND TRACK", + "GRDVEH": "GROUND VEHICLE", + "GRDZRO": "GROUND ZERO", + "GREL": "GRENADE LAUNCHER", + "GRF": "GRAFITTI", + "GTL": "GENTLE", + "GUD": "GUARD", + "GUNUNT": "GUN UNIT", + "GVL": "GRAVEL", + "GWL": "GROWLER", + "H2O": "WATER", + "H2OCRT": "WATER CRAFT", + "H2OTRB": "WATER TURBULENCE", + "HAMEZ": "HIGH ALTITUDE MEZ", + "HAZ": "HAZARD", + "HAZMAT": "HAZARDOUS MATERIALS (HAZMAT)", + "HBR": "HARBOR (GENERAL)", + "HC": "HURRICANE/TYPHOON", + "HCNY": "HALTED CONVOY", + "HGH": "HIGH", + "HGHCTR": "HIGH PRESSURE CENTER", + "HGL": "HOLDING LINE", + "HGTFDG": "HEIGHT FINDING", + "HIDACZ": "HIGH DENSITY AIRSPACE CONTROL ZONE (HIDACZ)", + "HJKG": "HIJACKING", + "HL": "HAIL", + "HMAD": "H/MAD", + "HMG": "HEAVY MACHINE GUN", + "HOV": "HOVERCRAFT", + "HOW": "HOWITZER/GUN", + "HP": "HIDE POINT", + "HRE": "HORSE", + "HSP": "HOSPITAL", + "HSPSHP": "HOSPITAL SHIP", + "HTHP": "HOUSE-TO-HOUSE PROPAGANDA", + "HUM": "RIDGES OR HUMMOCKS", + "HVY": "HEAVY", + "HWFNC": "HIGH WIRE FENCE", + "HWK": "HAWK", + "HYDGRY": "HYDROGRAPHY", + "HZ": "HAZE", + "IB": "ICEBERG", + "IC": "ICE CRYSTALS (DIAMOND DUST)", + "ICG": "ICING", + "ICN": "ICE CONCENTRATION", + "ID": "ICE DRIFT (DIRECTION)", + "IDFF": "IDENTIFICATION FRIEND/FOE (INTERROGATOR)", + "IEOBFR": "ICE EDGE OR BOUNDARY FROM RADAR", + "IF": "ICE FREE", + "IFF": "IFF (TRANSPONDER)", + "IFR": "INSTRUMENT FLIGHT RULE (IFR)", + "II": "ICE ISLAND", + "IMP": "BYPASS IMPOSSIBLE", + "IMTBUR": "IMPACT BURIAL", + "IMTPNT": "IMPACT POINT", + "INC": "INTERCEPT", + "INCR": "INTERCEPTOR", + "INF": "INFANTRY", + "INFFV": "INFANTRY FIGHTING VEHICLE", + "INFNLE": "INFILTRATION LANE", + "INMHVY": "INTERMITTENT HEAVY", + "INMLIT": "INTERMITTENT LIGHT", + "INMMOD": "INTERMITTENT MODERATE", + "INS": "INSTALLATION", + "INT": "INTELLIGENCE (OCEANOGRAPHIC, AGI)", + "INTGN": "INTERROGATION", + "INTMR": "INTERMEDIATE RANGE", + "IRR": "IRREGULAR", + "ISB": "ISOBAR - SURFACE", + "ISD": "ISODROSOTHERM", + "ISF": "INTERNAL SECURITY FORCES", + "ISH": "ISOTACH", + "ISL": "ISOLATE", + "ISND": "ISLAND", + "ISP": "ISOPLETHS", + "IST": "ISOTHERM", + "ISTB": "INSTABILITY LINE", + "ISYS": "ICE SYSTEMS", + "ITCZ": "INTER-TROPICAL CONVERGANCE ZONE", + "ITD": "INTER-TROPICAL DISCONTINUITY", + "ITDT": "INTERDICT", + "ITEST": "ICE THICKNESS (ESTIMATED)", + "ITM": "ITEMS", + "ITOBS": "ICE THICKNESS (OBSERVED)", + "IWU": "INFORMATION WARFARE UNIT", + "JAG": "JUDGE ADVOCATE GENERAL (JAG)", + "JBB": "JAMMED BRASH BARRIER", + "JIB": "JOINT INFORMATION BUREAU (JIB)", + "JINTCT": "JOINT INTELLIGENCE CENTER", + "JMG": "JAMMING", + "JTSM": "JET STREAM", + "KDNG": "KIDNAPPING", + "KGP": "KINGPIN", + "KLP1": "KELP/SEAWEED", + "KLP2": "KELP/SEAWEED", + "KLP3": "KELP/SEAWEED", + "KNIVEH": "KNOWN INSURGENT VEHICLE", + "LAARA": "LIMITED ACCESS AREA", + "LAMEZ": "LOW ALTITUDE MEZ", + "LANE": "LANE", + "LAR": "LIGHT ARMORED RECONNAISSNACE (LAR)", + "LARMVH": "LIGHT ARMORED VEHICLE", + "LAWENU": "LAW ENFORCEMENT UNIT", + "LAWENV": "LAW ENFORCEMENT VESSEL", + "LBR": "LABOR", + "LCCP": "LARGE COMMUNICATION CONFIGURED PACKAGE (LCCP)", + "LCCTRK": "LIMITED CROSS-COUNTRY TRUCK", + "LCK": "LOCK", + "LCON": "LOST CONTACT", + "LD": "LINE OF DEPARTURE", + "LDGLNE": "LEADING LINE", + "LDLC": "LINE OF DEPARTURE/LINE OF CONTACT (LD/LC)", + "LDNCGC": "LOOSE DRY DUST OR SAND NOT COVERING GROUND COMPLETELY", + "LDSALH": "LOOSE DRY SNOW COVERING AT LEAST ONE-HALF GROUND, BUT GROUND NOT COMPLETELY COVERED", + "LDSNLH": "LOOSE DRY SNOW COVERING LESS THAN ONE-HALF OF GROUND", + "LDY": "LAUNDRY/BATH", + "LED": "LEAD", + "LEN": "LARGE EXTENSION NODE", + "LESCRT": "LEISURE CRAFT", + "LIT": "LIGHT", + "LITHSE": "LIGHTHOUSE", + "LITLNE": "LIGHT LINE", + "LITMOD": "DUST/SAND STORM - LIGHT TO MODERATE", + "LITVES": "LIGHT VESSEL/LIGHTSHIP", + "LLTR": "LOW LEVEL TRANSIT ROUTE (LLTR)", + "LMG": "LIGHT MACHINE GUN", + "LMT": "LIMITS", + "LMTADV": "LIMIT OF ADVANCE", + "LND": "LAND", + "LNDCRT": "LANDING CRAFT", + "LNDMNE": "LAND MINES", + "LNDPLC": "LANDING PLACE", + "LNDRNG": "LANDING RING", + "LNDSHP": "LANDING SHIP", + "LNDSUP": "LANDING SUPPORT", + "LNE": "LINE", + "LNGR": "LONG RANGE", + "LNKUPT": "LINKUP POINT", + "LNRTGT": "LINEAR TARGET", + "LOC": "LINE OF CONTACT", + "LOCAT": "LOCATIONS", + "LOFAR": "LOW FREQUENCY ANALYZING AND RECORDING (LOFAR)", + "LORO": "LIMIT OF RADAR OBSERVATION", + "LOU": "LIMIT OF UNDERCAST", + "LOVO": "LIMIT OF VISUAL OBSERVATION", + "LOWCTR": "LOW PRESSURE CENTER", + "LP": "LAUNCH POINT", + "LPC": "LIQUID PRECIPITATION - CONVECTIVE", + "LPNCI": "LIQUID PRECIPITATION - NON-CONVECTIVE CONTINUOUS OR INTERMITTENT", + "LRP": "LOGISTICS RELEASE POINT (LRP)", + "LRS": "LONG RANGE SURVEILLANCE (LRS)", + "LSR": "LASER", + "LSTGT": "LINEAR SMOKE TARGET", + "LTA": "LIGHTER THAN AIR", + "LTG": "LIGHTNING", + "LTL": "LESS THAN LETHAL", + "LW": "LOW", + "LWFNC": "LOW WIRE FENCE", + "LZ": "LANDING ZONE (LZ)", + "MAINT": "MAINTENANCE", + "MANATK": "MAIN ATTACK", + "MAR": "MARINE", + "MARLFE": "MARINE LIFE", + "MARTAR": "MARITIME AREA", + "MARTLB": "MARITIME LIMIT BOUNDARY", + "MCC": "MOVEMENT CONTROL CENTER(MCC)", + "MCLST": "MINE CLUSTER", + "MCMDRN": "MCM DRONE", + "MCMSUP": "MCM SUPPORT", + "MCNY": "MOVING CONVOY", + "MCP": "MAINTENANCE COLLECTION POINT", + "MCT": "MERCHANT", + "MCVEH": "MINE CLEARING VEHICLE", + "MDM": "MEDIUM", + "MDMSD": "MEDIUM SAND", + "MDMSLT": "MEDIUM SILT", + "MECH": "MECHANIZED", + "MED": "MEDICAL", + "MEDF": "MEDICAL FACILITY", + "MEDTF": "MEDICAL TREATMENT FACILITY", + "MEDV": "MEDEVAC", + "METO": "METEOROLOGICAL", + "MEZ": "MISSILE ENGAGEMENT ZONE (MEZ)", + "MFN": "MULTI-FUNCTION", + "MIL": "MILITARY", + "MILBF": "MILITARY BASE/FACILITY", + "MILINT": "MILITARY INTELLIGENCE", + "MILP": "MILITARY POLICE", + "MILVP": "MILITARY VEHICLE PRODUCTION", + "MIST": "MIST", + "MIWBC": "MIW BOTTOM CATEGORY", + "MIWBS": "MIW-BOTTOM SEDIMENTS", + "MIWBT": "MIW BOTTOM TYPE", + "MIX": "MIXED ICING", + "ML": "MINE LAYING", + "MLDCGC": "MODERATE/THICK LOOSE DRY DUST OR SAND COVERING GROUND COMPLETELY", + "MLVEH": "MINE LAYING VEHICLE", + "MMD": "MAN-MADE STRUCTURES", + "MMF": "MILITARY MATERIEL FACILITY", + "MNDARA": "MINED AREA", + "MNE": "MINE", + "MNECM": "MINE COUNTERMEASURES", + "MNEFLD": "MINEFIELDS", + "MNEHNT": "MINEHUNTER", + "MNELYR": "MINELAYER", + "MNENAV": "MINE-NAVAL", + "MNESWE": "MINESWEEPER", + "MNEWBD": "MINE WARFARE BOTTOM DESCRIPTORS", + "MNEWV": "MINE WARFARE VESSEL", + "MNT": "MOUNTAIN", + "MNTWAV": "MOUNTAIN WAVES", + "MNY": "MANY ICEBERGS", + "MNYBB": "MANY BERGY BITS", + "MNYGNL": "MANY ICEBERGS - GENERAL", + "MNYGWL": "MANY GROWLERS", + "MOBSU": "MOBILITY/SURVIVABILITY", + "MOD": "MODERATE", + //"MODHVY": "FREEZING DRIZZLE - MODERATE/HEAVY", + //"MODHVY": "FREEZING RAIN - MODERATE/HEAVY", + //"MODHVY": "HAIL - MODERATE/HEAVY NOT ASSOCIATED WITH THUNDER", + "MODHVY": "RAIN SHOWERS - MODERATE/HEAVY", + //"MODHVY": "SNOW SHOWERS - MODERATE/HEAVY", + "MOOTW": "MILITARY OPERATIONS OTHER THAN WAR (MOOTW)", + "MORT": "MORTAR", + "MOT": "MOTORIZED", + "MPOFI": "MELT PUDDLES OR FLOODED ICE", + "MRK": "MARKER", + "MRL": "MULTIPLE ROCKET LAUNCHER", + "MRR": "MINIMUM RISK ROUTE (MRR)", + "MRSH": "MARSHALL", + "MRSPD": "MULTI ROCKET SELF-PROPELLED", + "MRTOW": "MULTI ROCKET TOWED", + "MRTRK": "MULTI ROCKET TRUCK", + "MSDZ": "MINIMUM SAFE DISTANCE ZONES", + "MSE": "MULTIPLE SUBSCRIBER ELEMENT", + "MSL": "MISSILE", + "MSLAQ": "MISSILE ACQUISITION", + "MSLDL": "MISSILE DOWNLINK", + "MSLGDN": "MISSILE GUIDANCE", + "MSLIF": "MISSILE IN FLIGHT", + "MSLL": "MISSILE LAUNCHER", + "MSLPNT": "MSL DETECT POINT", + "MSLTRK": "MISSILE TRACKING", + "MSRUT": "MAIN SUPPLY ROUTE", + "MSSP": "MISSILE & SPACE SYSTEM PRODUCTION", + "MTRY": "MORTUARY/GRAVES REGISTRY", + "MUD": "MUD", + "MVB": "MOVEABLE", + "MVBPFD": "MOVEABLE AND PREFABRICATED", + "MVFR": "MARGINAL VISUAL FLIGHT RULE (MVFR)", + "MWR": "MORALE, WELFARE, RECREATION (MWR)", + "NAI": "NAMED AREA OF INTEREST (NAI)", + "NAV": "NAVAL", + "NAVGRP": "NAVY GROUP", + "NAVREF": "NAV REFERENCE", + "NAVTF": "NAVY TASK FORCE", + "NAVTG": "NAVY TASK GROUP", + "NAVTU": "NAVY TASK UNIT", + "NBC": "NUCLEAR, BIOLOGICAL AND CHEMICAL", + "NBCEQT": "NBC EQUIPMENT", + "NBCOP": "NBC OBSERVATION POST (DISMOUNTED)", + "NCBTT": "NONCOMBATANT", + "NDGZ": "NUCLEAR DETINATIONS GROUND ZERO", + "NENY": "NUCLEAR ENERGY", + "NEUT": "NEUTRALIZE", + "NFA": "NO-FIRE AREA (NFA)", + "NFL": "NO-FIRE LINE (NFL)", + "NMIL": "NON-MILITARY", + "NMP": "NUCLEAR MATERIAL PRODUCTION", + "NMS": "NUCLEAR MATERIAL STORAGE", + "NODAT": "NO DATA", + "NODCTR": "NODE CENTER", + "NPRN": "NUCLEAR PROPULSION", + "NPT": "NUCLEAR PLANT", + "NSUB": "NON-SUBMARINE", + "NUC": "NUCLEAR", + "NUCTGT": "NUCLEAR TARGET", + "NVGL": "NAVIGATIONAL", + "OBJ": "OBJECTIVE", + "OBSEFT": "OBSTACLE EFFECT", + "OBSPST": "OBSERVATION POST/OUTPOST", + "OBST": "OBSTACLES", + "OBSTBP": "OBSTACLE BYPASS", + "OCA": "OCEANIC", + "OCC": "OCCUPY", + "OCD": "OCCLUDED FRONT", + "OCNGRY": "OCEANOGRAPHY", + "OD": "OPERATOR-DEFINED", + "ODFF": "OPERATOR-DEFINED FREEFORM", + "OFA": "OBSTACLE FREE AREA", + "OFF": "OFFENSE", + "OIEOB": "OBSERVED ICE EDGE OR BOUNDARY", + "OITI": "OPENINGS IN THE ICE", + "OLOS": "OMNI-LINE-OF-SIGHT (LOS)", + "OLR": "OILER/TANKER", + "OLRG": "OIL/GAS RIG", + "OLRGFD": "OIL/GAS RIG FIELD", + "OPDECN": "DECON SITE/POINT (OPERATIONAL DECONTAMINATION)", + "OPN": "OPERATIONS", + "ORA": "OBSTACLE RESTRICTED AREA", + "ORD": "ORDNANCE", + "OSLF1": "OFFSHORE LOADING FACILITY", + "OSLF2": "OFFSHORE LOADING FACILITY", + "OSLF3": "OFFSHORE LOADING FACILITY", + "OTH": "OTHER", + "OVC": "OVERCAST COVERAGE", + "OWN": "OWN TRACK", + "PAA": "POSITION AREA FOR ARTILLERY (PAA)", + "PAT": "PATROL", + "PATG": "PATROLLING", + "PATT": "PATRIOT", + "PBL": "PEBBLES", + "PBLSHE": "PEBBLES, SHELLS", + "PBNO": "PREPARED BUT NOT OCCUPIED", + "PBX": "PENETRATION BOX", + "PDF": "PRINCIPAL DIRECTION OF FIRE (PDF)", + "PDMIC": "PREDOMINATELY ICE COVERED", + "PE": "ICE PELLETS (SLEET)", + "PERSVC": "PERSONNEL SERVICES", + "PF": "PROCESSING FACILITY", + "PGO": "PETROLEUM/GAS/OIL", + "PHELNE": "PHASE LINE", + "PHG": "PHOTOGRAPHIC", + "PHOSWT": "TELEPHONE SWITCH", + "PIM": "PIM", + "PIPNT": "PREDICTED IMPACT POINT", + "PIW": "PERSON IN WATER", + "PKAN": "PACK ANIMAL(S)", + "PKT": "PICKET", + "PLD": "PROBABLE LINE OF DEPLOYMENT (PLD)", + "PLE": "PILE/PILING/POST", + "PLND": "PLANNED", + "PLT": "WIND PLOT", + "PNE": "PENETRATE", + "PNT": "POINT", + "PNTA": "POINT A", + "PNTD": "POINT OF DEPARTURE", + "PNTINR": "POINT OF INTEREST", + "PNTQ": "POINT Q", + "PNTR": "POINT R", + "PNTX": "POINT X", + "PNTY": "POINT Y", + "POUTAI": "PRECIPITATION OF UNKNOWN TYPE AND INTENSITY", + "PPELNE": "PIPELINES/PIPE", + "PRH1": "PERCHES/STAKES", + "PRH2": "PERCHES/STAKES", + "PRH3": "PERCHES/STAKES", + "PRS": "PRESSURE SYSTEMS", + "PRT": "PORTS", + "PRTHBR": "PORTS AND HARBORS", + "PSG": "PASSENGER", + "PSNG": "POISONING", + "PSSPNT": "PASSAGE POINT", + "PST": "POSTAL", + "PSY": "PSYCHOLOGICAL", + "PSYOP": "PSYCHOLOGICAL OPERATIONS (PSYOP)", + "PTGT": "POINT/SINGLE TARGET", + "PTHY": "FOG - PATCHY", + "PTNCTR": "PATTERN CENTER", + "PTPLOS": "POINT-TO-POINT LINE-OF-SIGHT (LOS)", + "PUBAFF": "PUBLIC AFFAIRS", + "PUP": "PULL-UP POINT (PUP)", + "PUR": "PURIFICATION", + "PWQ": "PIER/WHARF/QUAY", + "PWS": "PUBLIC WATER SERVICES", + "PZ": "PICKUP ZONE (PZ)", + "QLFYTM": "QUALIFYING TERMS", + "RA": "RAIN", + "RAD": "RADAR", + "RADA": "RADIOACTIVE AREA", + "RALRD": "RAILROAD", + "RAMPAW": "RAMP (ABOVE WATER)", + "RAMPBW": "RAMP (BELOW WATER)", + "RASN": "RAIN AND SNOW MIXED", + "RASWR": "RAIN SHOWERS", + "RAYPNT": "RALLY POINT", + "RCBB": "ROADBLOCKS, CRATERS, AND BLOWN BRIDGES", + "RCK": "ROCK", + "RCKAWD": "ROCK AWASHED", + "RCKSBM": "ROCK SUBMERGERED", + "RCMT": "RECRUITMENT", + "RCY": "RECOVERY", + "RDGAXS": "RIDGE AXIS", + "RDOUNT": "RADIO UNIT", + "RDSLIT": "RAIN OR DRIZZLE AND SNOW - LIGHT", + "RDSMH": "RAIN OR DRIZZLE AND SNOW - MODERATE/HEAVY", + "RDV": "RENDEZVOUS", + "RECEQP": "RECON EQUIPPED", + "RECL": "RECOILLESS", + "RECON": "RECONNAISSANCE", + "REEF": "REEF", + "REEVNT": "RELEASE EVENTS", + "REFPNT": "REFERENCE POINT", + "REL": "RELEASE LINE", + "RELG": "RELIGIOUS/CHAPLAIN", + "RELPNT": "RELEASE POINT", + "RFA": "RESTRICTIVE FIRE AREA (RFA)", + "RFE": "REFUEL", + "RFG": "REFUGEES", + "RFL": "RESTRICTIVE FIRE LINE (RFL)", + "RFT": "RAFT SITE", + "RFTG": "RAFTING", + "RGH": "ROUGH", + "RGR": "RANGER", + "RHA": "REFUGEE HOLDING AREA", + "RHD": "RAILHEAD", + "RHU": "REPLACEMENT HOLDING UNIT (RHU)", + "RIF": "RIFLE", + "RIFWPN": "RIFLE/AUTOMATIC WEAPON", + "RIME": "RIME ICING", + "RIP": "RELIEF IN PLACE (RIP)", + "RIV": "RIVERINE", + "RLY": "RELAY", + "RMP": "RAW MATERIAL PRODUCTION/STORAGE", + "RO": "RANGE ONLY (RO)", + "ROC": "ROCKET", + "ROM": "REFUEL ON THE MOVE (ROM) POINT", + "RORO": "ROLL ON/ROLL OFF", + "ROT": "ROTARY WING", + "ROZ": "RESTRICTED OPERATIONS ZONE (ROZ)", + "RP": "RELOAD POINT", + "RPH": "REPLENISH", + "RRRP": "REARM, REFUEL AND RESUPPLY POINT", + "RSA": "REGIMENTAL (RSA)", + "RSC": "RESCUE", + "RSDARA": "RESTRICTED AREA", + "RTE": "ROUTE", + "RTG": "RECTANGULAR", + "RTGTGT": "RECTANGULAR TARGET", + "RTM": "RETIREMENT", + "RTN": "RETAIN", + "SA": "SEA ANOMALY (WAKE, CURRENT, KNUCKLE)", + "SAAFR": "STANDARD-USE ARMY AIRCRAFT FLIGHT ROUTE (SAAFR)", + "SAFE": "EXPLOSIVES, STATE OF READINESS 1 (SAFE)", + "SAFHSE": "SAFE HOUSE", + "SAM": "SURFACE TO AIR MISSILE (SAM)", + "SAR": "SEARCH AND RESCUE", + "SAT": "SATELLITE", + "SATDL": "SATELLITE DOWN-LINK", + "SATUL": "SATELLITE UP-LINK", + "SBM": "WRECK (SUBMERGED)", + "SBMCRB": "SUBMERGED CRIB", + "SBRSOO": "SEABED ROCK/STONE, OBSTACLE, OTHER", + "SBSM": "SUBSURFACE TO SURFACE MISSILE (S/SSM)", + "SBSUF": "SUBSURFACE TRACK", + "SBT": "SPECIAL BOAT", + "SC": "SNOW COVER", + "SCE": "SECURE", + "SCGC": "SNOW COVERING GROUND COMPLETELY; DEEP DRIFTS", + "SCM": "SCM", + "SCN": "SCREEN", + "SCP": "SURVEY CONTROL POINT", + "SCR": "SECTOR", + "SCT": "SCATTERED COVERAGE", + "SCUT": "SCOUT", + "SD": "SAND", + "SD&SHE": "SAND AND SHELLS", + "SEAL": "SEAL", + "SEC": "SECURITY", + "SECPOL": "SECURITY POLICE (AIR)", + "SEMI": "SEMI", + "SEN": "SMALL EXTENSION NODE", + "SFP": "SUPPORT BY FIRE POSITION", + "SG": "SNOW GRAINS", + "SGTGT": "SERIES OR GROUP OF TARGETS", + "SHA": "SHEAR LINE", + "SHAZ": "SHEARING OR SHEAR ZONE", + "SHE": "SHELL", + "SHETKG": "SHELL TRACKING", + "SHPCSN": "SHIP CONSTRUCTION", + "SHRLNE": "SHORELINE PROTECTION", + "SHRPAT": "SHORE PATROL", + "SHTR": "SHORT RANGE", + "SHWCTS": "FOG - SHALLOW CONTINUOUS", + "SHWPTH": "FOG - SHALLOW PATCHES", + "SI": "SEA ICE", + "SIGINC": "SIGNAL INTERCEPT", + "SIGINT": "SIGNALS INTELLIGENCE", + "SIGSUP": "SIGNAL SUPPORT", + "SIGUNT": "SIGNAL UNIT", + "SKC": "CLEAR SKY", + "SKEIP": "STRIKE IP", + "SKYOBD": "FOG - SKY OBSCURED", + "SKYVSB": "FOG - SKY VISIBLE", + "SLDRCK": "SOLID ROCK", + "SLM": "SURFACE LAUNCHED MISSILE", + "SLP": "SUPPLY", + "SLPRUT": "SUPPLY ROUTES", + "SLT": "SILT", + "SMDCY": "SEA MINE DECOY", + "SMF": "SEA MINE (FLOATING)", + "SMG": "SEA MINE (GROUND)", + "SMH": "SMOOTH", + "SMK": "SMOKE", + "SMKDEC": "SMOKE/DECON", + "SML": "SEA MINE-LIKE", + "SMLNE": "STREAM LINE", + "SMM": "SEA MINE (MOORED)", + "SMNE": "SEA MINE", + "SMOP": "SEA MINE (OTHER POSITION)", + "SN": "SNOW", + "SNAG": "SNAGS/STUMPS", + "SNBY": "SONOBUOY", + "SND": "SOUND", + "SNDG": "SOUNDINGS", + "SNG": "SINGLE CONCERTINA", + "SNGFNC": "SINGLE FENCE", + "SNK": "SINKER", + "SNS": "SENSOR", + "SNSZ": "SENSOR ZONE", + "SOF": "SPECIAL OPERATIONS FORCES (SOF)", + "SOFUNT": "SPECIAL OPERATIONS FORCES (SOF) UNIT", + "SOP": "SENSOR OUTPOST/LISTENING POST (OP/LP)", + "SP": "SEAPORT/NAVAL BASE", + "SPC": "SPACE", + "SPD": "SELF-PROPELLED", + "SPDTRK": "SELF-PROPELLED TRACKED", + "SPDWHD": "SELF-PROPELLED WHEELED", + "SPG": "SNIPING", + "SPL": "SPECIAL", + "SPLPNT": "SPECIAL POINT", + "SPOD": "SPOD/SPOE", + "SPT": "SUPPLY POINTS", + "SPY": "SPY", + "SQL": "SQUALL", + "SRH": "SEARCH", + "SRHARA": "SEARCH AREA/RECONNAISSANCE AREA", + "SRL": "SINGLE ROCKET LAUNCHER", + "SRSPD": "SINGLE ROCKET SELF-PROPELLED", + "SRTOW": "SINGLE ROCKET TOWED", + "SRTRK": "SINGLE ROCKET TRUCK", + "SRUF": "SERVICE, RESEARCH, UTILITY FACILITY", + "SSH": "SERVICE & SUPPORT HARBOR (YARDCRAFT, BARGE, HARBOR, TUG)", + "SSL": "SEVERE SQUALL LINE", + "SSM": "SURFACE TO SURFACE MISSILE (SSM)", + "SSSNR": "SPECIAL SSNR", + "SST": "SPACE STATION", + "SSUBSR": "SEA SUBSURFACE RETURNS", + "SSUF": "SEA SURFACE TRACK", + "SSWR": "SNOW SHOWERS", + "STAT": "STATIONARY FRONT", + "STC": "STATIC DEPICTION", + "STG": "STINGER", + "STGC": "STRATEGIC", + "STMS": "STORMS", + "STN": "STATION", + "STNE": "STONES", + "STOG": "STATE OF THE GROUND", + "STOPO": "SKY TOTALLY OR PARTIALLY OBSCURED", + "STP": "STEEP", + "STRGPT": "STRONG POINT", + "STRPNT": "START POINT", + "SU": "SURVIVABILITY", + "SUB": "SUBMARINE", + "SUBCBL": "SUBMARINE CABLE", + "SUF": "SURF-SURF (SS)", + "SUFDRY": "SURFACE DRY WITHOUT CRACKS OR APPRECIABLE DUST OR LOOSE SAND", + "SUFFLD": "SURFACE FLOODED", + "SUFFZN": "SURFACE FROZEN", + "SUFMST": "SURFACE MOIST", + "SUFSHL": "SURFACE SHELTER", + "SUFSRH": "SURFACE SEARCH", + "SUFWET": "SURFACE WET, STANDING WATER IN SMALL OR LARGE POOLS", + "SUP": "SUPPORT", + "SUPARS": "SUPPORT AREAS", + "SUPATK": "SUPPORTING ATTACK", + "SUPPLY": "QUARTERMASTER (SUPPLY)", + "SUV": "SPORT UTILITY VEHICLE (SUV)", + "SVL": "SURVEILLANCE", + "SVR": "SEVERE", + "SW": "SEAWALL", + "SWO": "SASTRUGI (WITH ORIENTATION)", + "SWPARA": "SWEPT AREA", + "SWRLIT": "RAIN AND SNOW SHOWERS - LIGHT", + "SWRMOD": "RAIN AND SNOW SHOWERS - MODERATE/HEAVY", + "SYM": "CLOUD COVERAGE SYMBOLS", + "SZE": "SEIZE", + "TAC": "TACTICAL", + "TACEXP": "TACTICAL EXPLOIT", + "TACGRP": "TACTICAL GRAPHICS", + "TACSAT": "TACTICAL SATELLITE", + "TAI": "TARGETED AREA OF INTEREST (TAI)", + "TAK": "TANKING", + "TANK": "TANK", + "TARP": "PSYOP (TV AND RADIO PROPAGANDA)", + "TBA": "TARGET BUILD-UP AREA (TBA)", + "TCF": "TELECOMMUNICATIONS FACILITY", + "TCN": "TACAN", + "TCP": "TRAFFIC CONTROL POST (TCP)", + "TDECUR": "TIDE AND CURRENT", + "TDEDP": "TIDE DATA POINT", + "TDEG": "TIDE GAUGE", + "TDTSM": "ANTITANK OBSTACLES: TETRAHEDRONS, DRAGONS TEETH, AND OTHER SIMILAR OBSTACLES", + "TELAR": "TELAR", + "TGT": "TARGET", + "TGTAQ": "TARGET ACQUISITION", + "TGTAQZ": "TARGET ACQUISTION ZONES", + "TGTGUT": "TARGETING UNIT", + "TGTILL": "TARGET ILLUMINATOR", + "TGTREF": "TARGET REFERENCE", + "TGTTRK": "TARGET TRACKING", + "THK": "THICKNESS", + "THT": "THEATER", + "TKD": "TRACKED", + "TLAR": "TLAR", + "TLDCGC": "THIN LOOSE DRY DUST OR SAND COVERING GROUND COMPLETELY", + "TM": "TRAILER MOUNTED", + "TMC": "TOMCAT", + "TMDU": "THEATER MISSILE DEFENSE UNIT", + "TNE": "TRAINER", + "TNK": "TANKER", + "TOPFTR": "TOPOGRAPHICAL FEATURES", + "TOR": "RAIN SHOWERS - TORRENTIAL", + "TOW": "TOWED", + "TOWTRK": "TOW TRUCK", + "TOWVES": "TOWING VESSEL", + "TPD": "TORPEDO", + "TPLSYS": "TROPICAL STORM SYSTEMS", + "TPSSCT": "TROPOSPHERIC SCATTER", + "TPT": "TRANSPORTATION", + "TRB": "TURBULENCE", + "TRF": "TECHNOLOGICAL RESEARCH FACILITY", + "TRGARA": "TRAINING AREA", + "TRGH": "DECON SITE/POINT (THOROUGH DECONTAMINATION)", + "TRIPWR": "TRIP WIRE", + "TRISTD": "TRIPLE STRAND CONCERTINA", + "TRK": "TRACK", + "TRKMV": "TRUCK MOUNTED WITH VOLCANO", + "TRNLCO": "TRAIN LOCOMOTIVE", + "TROPDN": "TROPICAL DEPRESSION", + "TROPHG": "TROPOPAUSE HIGH", + "TROPLV": "TROPOPAUSE LEVEL", + "TROPLW": "TROPOPAUSE LOW", + "TROPSM": "TROPICAL STORM", + "TRP": "DECON SITE/POINT (TROOPS)", + "TRUAXS": "TROUGH AXIS", + "TRW": "TRAWLER", + //"TS": "THUNDERSTORM - NO PRECIPITATION", + "TS": "THUNDERSTORMS", + "TSHVNH": "THUNDERSTORM HEAVY WITH RAIN/SNOW - NO HAIL", + //"TSHVWH": "THUNDERSTORM HEAVY - WITH HAIL", + "TSK": "TASKS", + "TSLMNH": "THUNDERSTORM LIGHT TO MODERATE WITH RAIN/SNOW - NO HAIL", + "TSLMWH": "THUNDERSTORM LIGHT TO MODERATE - WITH HAIL", + "TSPF": "TRANSPORT FACILITY", + "TSWADL": "TROPICAL STORM WIND AREAS AND DATE/TIME LABELS", + "TTP": "TRAILER TRANSFER POINT", + "TTYCTR": "TELETYPE CENTER", + "TUG": "TUG", + "TUR": "TURN", + "TVAR": "TARGET VALUE AREA (TVAR)", + "UAV": "UNMANNED AERIAL VEHICLE", + "UAVR": "UNMANNED AERIAL VEHICLE (UAV) ROUTE", + "UCOV": "WRECK (UNCOVERS)", + "UGDSHL": "UNDERGROUND SHELTER", + "UH2": "UNDERWATER", + "UH2DAN": "UNDERWATER DANGER/HAZARD", + "UH2DCY": "UNDERWATER DECOY", + "UH2DML": "UNDERWATER DEMOLITION TEAM", + "UH2WPN": "UNDERWATER WEAPON", + "ULCSCG": "UNEVEN LAYER OF COMPACT OR WET SNOW COVERING GROUND COMPLETELY", + "ULDSCG": "UNEVEN LAYER OF LOOSE DRY SNOW COVERING GROUND COMPLETELY", + "UMC": "UNIT MAINTENANCE COLLECTION POINT", + "UNK": "UNKNOWN", + "UNT": "UNIT", + "UPP": "UPPER", + "USP": "UNSPECIFIED", + "USPMNE": "UNSPECIFIED MINE", + "USW": "UNDER SEA WARFARE", + "UTY": "UTILITY", + "UTYVEH": "UTILITY VEHICLE", + "UUV": "UNMANNED UNDERWATER VEHICLE (UUV)", + "UWRPM": "UNDERWAY REPLENISHMENT (OILER/TANKER, STORES, AMMUNITION, TROOP TRANSPORT)", + "UXO": "UNEXPLODED ORDINANCE AREA (UXO)", + "VCSESD": "VERY COARSE SAND", + "VDR1-2": "VDR LEVEL 1-2", + "VDR2-3": "VDR LEVEL 2-3", + "VDR3-4": "VDR LEVEL 3-4", + "VDR4-5": "VDR LEVEL 4-5", + "VDR5-6": "VDR LEVEL 5-6", + "VDR6-7": "VDR LEVEL 6-7", + "VDR7-8": "VDR LEVEL 7-8", + "VDR8-9": "VDR LEVEL 8-9", + "VDR9-0": "VDR LEVEL 9-10", + "VEH": "HIJACKING (VEHICLE)", + "VFNESD": "VERY FINE SAND", + "VFNSLT": "VERY FINE SILT", + "VIOATY": "VIOLENT ACTIVITIES (DEATH CAUSING)", + "VLAD": "VERTICAL LINE ARRAY DIFAR (VLAD)", + "VNY": "VETERINARY", + "VOLASH": "VOLCANIC ASH", + "VOLERN": "VOLCANIC ERUPTION", + "VRLRPS": "VANDALISM/RAPE/LOOT/RANSACK/PLUNDER/SACK", + "VSTOL": "VERTICAL/SHORT TAKEOFF AND LANDING (V/STOL)", + "VUL": "VULCAN", + "WAMNE": "WIDE AREA MINES", + "WAP": "WAYPOINT", + "WAR": "WARFIGHTING SYMBOLS", + "WARMVH": "WHEELED ARMORED VEHICLE", + "WAVS": "WHEELED ARMORED VEHICLE SURVEILLANCE", + "WDR": "WITHDRAW", + "WDRUP": "WITHDRAW UNDER PRESSURE", + "WFZ": "WEAPONS FREE ZONE", + "WHD": "WHEELED", + "WHMECH": "WHEELED MECHANIZED", + "WLG": "RECRUITMENT (WILLING)", + "WLST": "WHITE LIST LOCATION", + "WND": "WINDS", + "WOSMIC": "WITHOUT SNOW OR MEASURABLE ICE COVER", + "WP": "PSYOP (WRITTEN PROPAGANDA)", + "WPN": "WEAPON", + "WPNGR": "WEAPONS GRADE", + "WPNRF": "WEAPONS/RADAR RANGE FANS", + "WREOBS": "WIRE OBSTACLE", + "WRK": "WRECK", + "WRKD": "WRECK, DANGEROUS", + "WRKND": "WRECK, NON DANGEROUS", + "WRMFRN": "WARM FRONT", + "WSMIC": "WITH SNOW OR MEASURABLE ICE COVER", + "WTH": "WEATHER SYMBOLS", + "WWRT": "WATER WITH RADAR TARGETS", + "Z": "ZONE", + "ZOR": "ZONE OF RESPONSIBILITY (ZOR)" }, - "WAR.SSUF.CBTT.MNEWV.MNEHNT": { - "symbolID": "SUSPCMMH--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.MNEWV.MCMSUP": { - "symbolID": "SUSPCMMA--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.MNEWV.MCMDRN": { - "symbolID": "SUSPCMMD--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.PAT": { - "symbolID": "SUSPCP----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.PAT.ASBW": { - "symbolID": "SUSPCPSB--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.PAT.ASUW": { - "symbolID": "SUSPCPSU--*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.HOV": { - "symbolID": "SUSPCH----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.STN": { - "symbolID": "SUSPS-----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.STN.PKT": { - "symbolID": "SUSPSP----*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.STN.ASWSHP": { - "symbolID": "SUSPSA----*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.NAVGRP": { - "symbolID": "SUSPG-----*****", - "tag": "SSUF" - }, - "WAR.SSUF.CBTT.NAVGRP.NAVTF": { - "symbolID": "SUSPGT----*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.NAVGRP.NAVTG": { - "symbolID": "SUSPGG----*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.NAVGRP.NAVTU": { - "symbolID": "SUSPGU----*****", - "tag": "CBTT" - }, - "WAR.SSUF.CBTT.NAVGRP.CNY": { - "symbolID": "SUSPGC----*****", - "tag": "CBTT" - }, - "WAR.SSUF.NCBTT": { - "symbolID": "SUSPN-----*****", - "tag": "WAR" - }, - "WAR.SSUF.NCBTT.UWRPM": { - "symbolID": "SUSPNR----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.FLTSUP": { - "symbolID": "SUSPNF----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.INT": { - "symbolID": "SUSPNI----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.SSH": { - "symbolID": "SUSPNS----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.HSPSHP": { - "symbolID": "SUSPNM----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.HOV": { - "symbolID": "SUSPNH----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.STN": { - "symbolID": "SUSPNN----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NCBTT.STN.RSC": { - "symbolID": "SUSPNNR---*****", - "tag": "NCBTT" - }, - "WAR.SSUF.NMIL": { - "symbolID": "N/A", - "tag": "WAR" - }, - "WAR.SSUF.NMIL.MCT": { - "symbolID": "SUSPXM----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NMIL.MCT.CGO": { - "symbolID": "SUSPXMC---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.RORO": { - "symbolID": "SUSPXMR---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.OLR": { - "symbolID": "SUSPXMO---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.TUG": { - "symbolID": "SUSPXMTU--*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.FRY": { - "symbolID": "SUSPXMF---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.PSG": { - "symbolID": "SUSPXMP---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.HAZMAT": { - "symbolID": "SUSPXMH---*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.MCT.TOWVES": { - "symbolID": "SUSPXMTO--*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.FSG": { - "symbolID": "SUSPXF----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NMIL.FSG.DRFT": { - "symbolID": "SUSPXFDF--*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.FSG.DRG": { - "symbolID": "SUSPXFDR--*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.FSG.TRW": { - "symbolID": "SUSPXFTR--*****", - "tag": "NMIL" - }, - "WAR.SSUF.NMIL.LESCRT": { - "symbolID": "SUSPXR----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NMIL.LAWENV": { - "symbolID": "SUSPXL----*****", - "tag": "SSUF" - }, - "WAR.SSUF.NMIL.HOV": { - "symbolID": "SUSPXH----*****", - "tag": "SSUF" - }, - "WAR.SSUF.OWN": { - "symbolID": "SUSPO-----*****", - "tag": "WAR" - }, - }, - "subsurface": { - "WAR.SBSUF": { - "symbolID": "SUUP------*****", - "tag": "WAR" - }, - "WAR.SBSUF.SUB": { - "symbolID": "SUUPS-----*****", - "tag": "WAR" - }, - "WAR.SBSUF.SUB.NPRN": { - "symbolID": "SUUPSN----*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.SUB.NPRN.ATK": { - "symbolID": "SUUPSNA---*****", - "tag": "SUB" - }, - "WAR.SBSUF.SUB.NPRN.MSL": { - "symbolID": "SUUPSNM---*****", - "tag": "SUB" - }, - "WAR.SBSUF.SUB.NPRN.GDD": { - "symbolID": "SUUPSNG---*****", - "tag": "SUB" - }, - "WAR.SBSUF.SUB.CNVPRN.BLST": { - "symbolID": "SUUPSCB---*****", - "tag": "SUB" - }, - "WAR.SBSUF.SUB.OTH": { - "symbolID": "SUUPSO----*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.SUB.OTH.UUV": { - "symbolID": "SUUPSU----*****", - "tag": "SUB" - }, - "WAR.SBSUF.SUB.STN": { - "symbolID": "SUUPSS----*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.SUB.STN.ASWSUB": { - "symbolID": "SUUPSSA---*****", - "tag": "SUB" - }, - "WAR.SBSUF.UH2WPN": { - "symbolID": "SUUPW-----*****", - "tag": "WAR" - }, - "WAR.SBSUF.UH2WPN.TPD": { - "symbolID": "SUUPWT----*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.UH2WPN.SMNE": { - "symbolID": "SUUPWM----*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.UH2WPN.SMNE.DLT": { - "symbolID": "SUUPWMD---*****", - "tag": "UH2WPN" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMG": { - "symbolID": "SUUPWMG---*****", - "tag": "UH2WPN" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMG.DLT": { - "symbolID": "SUUPWMGD--*****", - "tag": "SMNE" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMM": { - "symbolID": "SUUPWMM---*****", - "tag": "UH2WPN" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMM.DLT": { - "symbolID": "SUUPWMMD--*****", - "tag": "SMNE" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMF": { - "symbolID": "SUUPWMF---*****", - "tag": "UH2WPN" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMF.DLT": { - "symbolID": "SUUPWMFD--*****", - "tag": "SMNE" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMOP": { - "symbolID": "SUUPWMO---*****", - "tag": "UH2WPN" - }, - "WAR.SBSUF.UH2WPN.SMNE.SMOP.DLT": { - "symbolID": "SUUPWMOD--*****", - "tag": "SMNE" - }, - "WAR.SBSUF.UH2DCY": { - "symbolID": "SUUPWD----*****", - "tag": "WAR" - }, - "WAR.SBSUF.UH2DCY.SMDCY": { - "symbolID": "SUUPWDM---*****", - "tag": "SBSUF" - }, - "WAR.SBSUF.NSUB": { - "symbolID": "N/A", - "tag": "WAR" - }, - "WAR.SBSUF.NSUB.DVR": { - "symbolID": "SUUPND----*****", - "tag": "SBSUF" - }, - }, + "unk": { - "sof": { - "WAR.SOFUNT": { - "symbolID": "SUFP------*****", - "tag": "WAR" - }, - "WAR.SOFUNT.AVN": { - "symbolID": "SUFPA-----*****", - "tag": "WAR" - }, - "WAR.SOFUNT.AVN.FIXD": { - "symbolID": "SUFPAF----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.AVN.FIXD.ATK": { - "symbolID": "SUFPAFA---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.FIXD.RFE": { - "symbolID": "SUFPAFK---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.FIXD.UTY": { - "symbolID": "SUFPAFU---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.FIXD.UTY.LIT": { - "symbolID": "SUFPAFUL--*****", - "tag": "FIXD" - }, - "WAR.SOFUNT.AVN.FIXD.UTY.MDM": { - "symbolID": "SUFPAFUM--*****", - "tag": "FIXD" - }, - "WAR.SOFUNT.AVN.FIXD.UTY.HVY": { - "symbolID": "SUFPAFUH--*****", - "tag": "FIXD" - }, - "WAR.SOFUNT.AVN.VSTOL": { - "symbolID": "SUFPAV----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.AVN.ROT": { - "symbolID": "SUFPAH----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.AVN.ROT.CSAR": { - "symbolID": "SUFPAHH---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.ROT.ATK": { - "symbolID": "SUFPAHA---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.ROT.UTY": { - "symbolID": "SUFPAHU---*****", - "tag": "AVN" - }, - "WAR.SOFUNT.AVN.ROT.UTY.LIT": { - "symbolID": "SUFPAHUL--*****", - "tag": "ROT" - }, - "WAR.SOFUNT.AVN.ROT.UTY.MDM": { - "symbolID": "SUFPAHUM--*****", - "tag": "ROT" - }, - "WAR.SOFUNT.AVN.ROT.UTY.HVY": { - "symbolID": "SUFPAHUH--*****", - "tag": "ROT" - }, - "WAR.SOFUNT.NAV": { - "symbolID": "SUFPN-----*****", - "tag": "WAR" - }, - "WAR.SOFUNT.NAV.SEAL": { - "symbolID": "SUFPNS----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.NAV.UH2DML": { - "symbolID": "SUFPNU----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.NAV.SBT": { - "symbolID": "SUFPNB----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.NAV.SSSNR": { - "symbolID": "SUFPNN----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.GRD": { - "symbolID": "SUFPG-----*****", - "tag": "WAR" - }, - "WAR.SOFUNT.GRD.SOF": { - "symbolID": "SUFPGS----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.GRD.RGR": { - "symbolID": "SUFPGR----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.GRD.PSYOP": { - "symbolID": "SUFPGP----*****", - "tag": "SOFUNT" - }, - "WAR.SOFUNT.GRD.PSYOP.FIXAVN": { - "symbolID": "SUFPGPA---*****", - "tag": "GRD" - }, - "WAR.SOFUNT.GRD.CVLAFF": { - "symbolID": "SUFPGC----*****", - "tag": "SOFUNT" + "WAR.UNK": { + "symbolID": "SUZP------*****", + "tag": "UNK" + } }, - "WAR.SOFUNT.SUP": { - "symbolID": "SUFPB-----*****", - "tag": "WAR" - } - }, - // Task point Tactical Graphics - "task": { - "TACGRP.TSK.DSTY": { - "symbolID": "GUTPD-----****X", - "tag": "TACGRP" - }, - "TACGRP.TSK.ITDT": { - "symbolID": "GUTPI-----****X", - "tag": "TACGRP" - }, - "TACGRP.TSK.NEUT": { - "symbolID": "GUTPN-----****X", - "tag": "TACGRP" - } - }, - - // Command Control General Maneuver point Tactical Graphics - "c2gm": { - "TACGRP.C2GM.GNL.PNT.REFPNT": { - "symbolID": "GUGPGPR---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.NAVREF": { - "symbolID": "GUGPGPRN--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.SPLPNT": { - "symbolID": "GUGPGPRS--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.DLRP": { - "symbolID": "GUGPGPRD--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.PIM": { - "symbolID": "GUGPGPRP--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.MRSH": { - "symbolID": "GUGPGPRM--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.WAP": { - "symbolID": "GUGPGPRW--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.CRDRTB": { - "symbolID": "GUGPGPRC--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.REFPNT.PNTINR": { - "symbolID": "GUGPGPRI--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.AIMPNT": { - "symbolID": "GUGPGPWA--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.DRPPNT": { - "symbolID": "GUGPGPWD--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.ENTPNT": { - "symbolID": "GUGPGPWE--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.GRDZRO": { - "symbolID": "GUGPGPWG--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.MSLPNT": { - "symbolID": "GUGPGPWM--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.IMTPNT": { - "symbolID": "GUGPGPWI--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.WPN.PIPNT": { - "symbolID": "GUGPGPWP--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.FRMN": { - "symbolID": "GUGPGPF---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.HBR": { - "symbolID": "GUGPGPH---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.HBR.PNTQ": { - "symbolID": "GUGPGPHQ--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.HBR.PNTA": { - "symbolID": "GUGPGPHA--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.HBR.PNTX": { - "symbolID": "GUGPGPHX--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE": { - "symbolID": "GUGPGPO---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE.RDV": { - "symbolID": "GUGPGPOZ--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE.DVSN": { - "symbolID": "GUGPGPOD--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE.WAP": { - "symbolID": "GUGPGPOW--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE.PIM": { - "symbolID": "GUGPGPOP--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.RTE.PNTR": { - "symbolID": "GUGPGPOR--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT": { - "symbolID": "GUGPGPP---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.CHKPNT": { - "symbolID": "GUGPGPPK--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.CONPNT": { - "symbolID": "GUGPGPPC--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.CRDPNT": { - "symbolID": "GUGPGPPO--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.DCNPNT": { - "symbolID": "GUGPGPPD--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.LNKUPT": { - "symbolID": "GUGPGPPL--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.PSSPNT": { - "symbolID": "GUGPGPPP--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.RAYPNT": { - "symbolID": "GUGPGPPR--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.RELPNT": { - "symbolID": "GUGPGPPE--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.STRPNT": { - "symbolID": "GUGPGPPS--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.AMNPNT": { - "symbolID": "GUGPGPPA--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.GNL.PNT.ACTPNT.WAP": { - "symbolID": "GUGPGPPW--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.TGTREF": { - "symbolID": "GUGPDPT---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST": { - "symbolID": "GUGPDPO---****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST.CBTPST": { - "symbolID": "GUGPDPOC--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST.RECON": { - "symbolID": "GUGPDPOR--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST.FWDOP": { - "symbolID": "GUGPDPOF--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST.SOP": { - "symbolID": "GUGPDPOS--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.DEF.PNT.OBSPST.CBRN": { - "symbolID": "GUGPDPON--****X", - "tag": "TACGRP" - }, - "TACGRP.C2GM.OFF.PNT.PNTD": { - "symbolID": "GUGPOPP---****X", - "tag": "TACGRP" - } - }, - - // Mobility/Survivability point Tactical Graphics - "mobsu": { - "TACGRP.MOBSU.OBST.ATO.TDTSM.FIXPFD": { - "symbolID": "GUMPOAOF--****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.ATO.TDTSM.MVB": { - "symbolID": "GUMPOAOM--****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.ATO.TDTSM.MVBPFD": { - "symbolID": "GUMPOAOP--****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.BBY": { - "symbolID": "GUMPOB----****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.USPMNE": { - "symbolID": "GUMPOMU---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.ATMNE": { - "symbolID": "GUMPOMT---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.ATMAHD": { - "symbolID": "GUMPOMD---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.ATMDIR": { - "symbolID": "GUMPOME---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.APMNE": { - "symbolID": "GUMPOMP---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBST.MNE.WAMNE": { - "symbolID": "GUMPOMW---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.OBSTBP.CSGSTE.ERP": { - "symbolID": "GUMPBCP---****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.SU.ESTOF": { - "symbolID": "GUMPSE----****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.SU.FRT": { - "symbolID": "GUMPSF----****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.SU.SUFSHL": { - "symbolID": "GUMPSS----****X", - "tag": "TACGRP" - }, - "TACGRP.MOBSU.SU.UGDSHL": { - "symbolID": "GUMPSU----****X", - "tag": "TACGRP" - } - }, + "space": { - // Fire Support point Tactical Graphics - "fsupp": { - "TACGRP.FSUPP.PNT.TGT.PTGT": { - "symbolID": "GUFPPTS---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.TGT.NUCTGT": { - "symbolID": "GUFPPTN---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.FSS": { - "symbolID": "GUFPPCF---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.SCP": { - "symbolID": "GUFPPCS---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.FP": { - "symbolID": "GUFPPCB---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.RP": { - "symbolID": "GUFPPCR---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.HP": { - "symbolID": "GUFPPCH---****X", - "tag": "TACGRP" - }, - "TACGRP.FSUPP.PNT.C2PNT.LP": { - "symbolID": "GUFPPCL---****X", - "tag": "TACGRP" - } - }, - - // Combat Service Support point Tactical Graphics - "css": { - "TACGRP.CSS.PNT.AEP": { - "symbolID": "GUSPPX----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.CBNP": { - "symbolID": "GUSPPC----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.CCP": { - "symbolID": "GUSPPY----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.CVP": { - "symbolID": "GUSPPT----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.DCP": { - "symbolID": "GUSPPD----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.EPWCP": { - "symbolID": "GUSPPE----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.LRP": { - "symbolID": "GUSPPL----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.MCP": { - "symbolID": "GUSPPM----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.RRRP": { - "symbolID": "GUSPPR----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.ROM": { - "symbolID": "GUSPPU----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.TCP": { - "symbolID": "GUSPPO----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.TTP": { - "symbolID": "GUSPPI----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.UMC": { - "symbolID": "GUSPPN----****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.GNL": { - "symbolID": "GUSPPSZ---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS1": { - "symbolID": "GUSPPSA---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS2": { - "symbolID": "GUSPPSB---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS3": { - "symbolID": "GUSPPSC---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS4": { - "symbolID": "GUSPPSD---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS5": { - "symbolID": "GUSPPSE---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS6": { - "symbolID": "GUSPPSF---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS7": { - "symbolID": "GUSPPSG---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS8": { - "symbolID": "GUSPPSH---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.SPT.CLS9": { - "symbolID": "GUSPPSI---****X", - "tag": "TACGRP" + "WAR.SPC": { + "symbolID": "SUPP------*****", + "tag": "WAR" + }, + "WAR.SPC.SAT": { + "symbolID": "SUPPS-----*****", + "tag": "WAR" + }, + "WAR.SPC.CSV": { + "symbolID": "SUPPV-----*****", + "tag": "WAR" + }, + "WAR.SPC.SST": { + "symbolID": "SUPPT-----*****", + "tag": "WAR" + } }, - "TACGRP.CSS.PNT.SPT.CLS10": { - "symbolID": "GUSPPSJ---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.AP.ASP": { - "symbolID": "GUSPPAS---****X", - "tag": "TACGRP" - }, - "TACGRP.CSS.PNT.AP.ATP": { - "symbolID": "GUSPPAT---****X", - "tag": "TACGRP" - } - }, - - // Stabilizing Operations point graphics - "stbops": { - "STBOPS.VIOATY.ASN": { - "symbolID": "OUVPA-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.KILL": { - "symbolID": "OUVPM-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.KILL.MDR": { - "symbolID": "OUVPMA----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.KILL.EX": { - "symbolID": "OUVPMB----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.KILL.ASS": { - "symbolID": "OUVPMC----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.BM": { - "symbolID": "OUVPB-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.BBY": { - "symbolID": "OUVPY-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.DBS": { - "symbolID": "OUVPD-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.SPG": { - "symbolID": "OUVPS-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.PSNG": { - "symbolID": "OUVPP-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.EXPLSN": { - "symbolID": "OUVPE-----*****", - "tag": "STBOPS" - }, - "STBOPS.VIOATY.EXPLSN.EXPLSN": { - "symbolID": "OUVPEI----*****", - "tag": "STBOPS" - }, - "STBOPS.LOCAT.BLST": { - "symbolID": "OULPB-----*****", - "tag": "STBOPS" - }, - "STBOPS.LOCAT.GLST": { - "symbolID": "OULPG-----*****", - "tag": "STBOPS" - }, - "STBOPS.LOCAT.WLST": { - "symbolID": "OULPW-----*****", - "tag": "STBOPS" - }, - "STBOPS.LOCAT.MASS": { - "symbolID": "OULPM-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.PATG": { - "symbolID": "OUOPP-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.DEMO": { - "symbolID": "OUOPD-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.ML": { - "symbolID": "OUOPM-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.FRGSRH": { - "symbolID": "OUOPF-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.SPY": { - "symbolID": "OUOPS-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.FDDIST": { - "symbolID": "OUOPO-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.EXTN": { - "symbolID": "OUOPE-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.HJKG.VEH": { - "symbolID": "OUOPHT----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.HJKG.APL": { - "symbolID": "OUOPHA----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.HJKG.BOAT": { - "symbolID": "OUOPHV----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.KDNG": { - "symbolID": "OUOPK-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.KDNG.ATEMPT": { - "symbolID": "OUOPK-----*****", - "tag": "STBOPS" - }, - "STBOPS.OPN.ARR": { - "symbolID": "OUOPA-----*****", - "tag": "STBOPS" + + "air": { + "WAR.AIRTRK": { + "symbolID": "SUAP------*****", + "tag": "WAR" + }, + "WAR.AIRTRK.MIL": { + "symbolID": "SUAPM-----*****", + "tag": "WAR" + }, + "WAR.AIRTRK.MIL.FIXD": { + "symbolID": "SUAPMF----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.MIL.FIXD.BMB": { + "symbolID": "SUAPMFB---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.FTR": { + "symbolID": "SUAPMFF---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.FTR.INCR": { + "symbolID": "SUAPMFFI--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.TNE": { + "symbolID": "SUAPMFT---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.ATK": { + "symbolID": "SUAPMFA---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.VSTOL": { + "symbolID": "SUAPMFL---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.TNK": { + "symbolID": "SUAPMFK---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.CGOALT": { + "symbolID": "SUAPMFC---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.CGOALT.LIT": { + "symbolID": "SUAPMFCL--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.CGOALT.MDM": { + "symbolID": "SUAPMFCM--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.CGOALT.HVY": { + "symbolID": "SUAPMFCH--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.ECM": { + "symbolID": "SUAPMFJ---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.MEDV": { + "symbolID": "SUAPMFO---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.RECON": { + "symbolID": "SUAPMFR---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.RECON.ABNEW": { + "symbolID": "SUAPMFRW--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.RECON.ESM": { + "symbolID": "SUAPMFRZ--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.RECON.PHG": { + "symbolID": "SUAPMFRX--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.PAT": { + "symbolID": "SUAPMFP---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.PAT.ASUW": { + "symbolID": "SUAPMFPN--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.PAT.MNECM": { + "symbolID": "SUAPMFPM--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.UTY": { + "symbolID": "SUAPMFU---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.UTY.LIT": { + "symbolID": "SUAPMFUL--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.UTY.MDM": { + "symbolID": "SUAPMFUM--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.UTY.HVY": { + "symbolID": "SUAPMFUH--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.COMM": { + "symbolID": "SUAPMFY---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.CSAR": { + "symbolID": "SUAPMFH---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.ABNCP": { + "symbolID": "SUAPMFD---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.DRN": { + "symbolID": "SUAPMFQ---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.ATK": { + "symbolID": "SUAPMFQA--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.BMB": { + "symbolID": "SUAPMFQB--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.CGO": { + "symbolID": "SUAPMFQC--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.ABNCP": { + "symbolID": "SUAPMFQD--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.FTR": { + "symbolID": "SUAPMFQF--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.CSAR": { + "symbolID": "SUAPMFQH--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.ECM": { + "symbolID": "SUAPMFQJ--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.TNK": { + "symbolID": "SUAPMFQK--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.VSTOL": { + "symbolID": "SUAPMFQL--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.SOF": { + "symbolID": "SUAPMFQM--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.MNECM": { + "symbolID": "SUAPMFQI--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.ASUW": { + "symbolID": "SUAPMFQN--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.PAT": { + "symbolID": "SUAPMFQP--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.RECON": { + "symbolID": "SUAPMFQR--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.RECON.ABNEW": { + "symbolID": "SUAPMFQRW-*****", + "tag": "DRN" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.RECON.ESM": { + "symbolID": "SUAPMFQRZ-*****", + "tag": "DRN" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.RECON.PHG": { + "symbolID": "SUAPMFQRX-*****", + "tag": "DRN" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.ASBW": { + "symbolID": "SUAPMFQS--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.TNE": { + "symbolID": "SUAPMFQT--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.UTY": { + "symbolID": "SUAPMFQU--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.COMM": { + "symbolID": "SUAPMFQY--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.DRN.MEDV": { + "symbolID": "SUAPMFQO--*****", + "tag": "FIXD" + }, + "WAR.AIRTRK.MIL.FIXD.ASBWCB": { + "symbolID": "SUAPMFS---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.FIXD.SOF": { + "symbolID": "SUAPMFM---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT": { + "symbolID": "SUAPMH----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.MIL.ROT.ATK": { + "symbolID": "SUAPMHA---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.ASBW": { + "symbolID": "SUAPMHS---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.UTY": { + "symbolID": "SUAPMHU---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.UTY.LIT": { + "symbolID": "SUAPMHUL--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.UTY.MDM": { + "symbolID": "SUAPMHUM--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.UTY.HVY": { + "symbolID": "SUAPMHUH--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.MNECM": { + "symbolID": "SUAPMHI---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.CSAR": { + "symbolID": "SUAPMHH---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.RECON": { + "symbolID": "SUAPMHR---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.DRN": { + "symbolID": "SUAPMHQ---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.CGOALT": { + "symbolID": "SUAPMHC---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.CGOALT.LIT": { + "symbolID": "SUAPMHCL--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.CGOALT.MDM": { + "symbolID": "SUAPMHCM--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.CGOALT.HVY": { + "symbolID": "SUAPMHCH--*****", + "tag": "ROT" + }, + "WAR.AIRTRK.MIL.ROT.TNE": { + "symbolID": "SUAPMHT---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.MEDV": { + "symbolID": "SUAPMHO---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.SOF": { + "symbolID": "SUAPMHM---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.ABNCP": { + "symbolID": "SUAPMHD---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.TNK": { + "symbolID": "SUAPMHK---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.ROT.ECM": { + "symbolID": "SUAPMHJ---*****", + "tag": "MIL" + }, + "WAR.AIRTRK.MIL.LTA": { + "symbolID": "SUAPML----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.MIL.VIP": { + "symbolID": "SUAPMV----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.MIL.ESCORT": { + "symbolID": "SUAPME----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.WPN": { + "symbolID": "SUAPW-----*****", + "tag": "WAR" + }, + "WAR.AIRTRK.WPN.MSLIF": { + "symbolID": "SUAPWM----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.WPN.MSLIF.SLM": { + "symbolID": "SUAPWMS---*****", + "tag": "WPN" + }, + "WAR.AIRTRK.WPN.MSLIF.SLM.SSM": { + "symbolID": "SUAPWMSS--*****", + "tag": "MSLIF" + }, + "WAR.AIRTRK.WPN.MSLIF.SLM.SAM": { + "symbolID": "SUAPWMSA--*****", + "tag": "MSLIF" + }, + "WAR.AIRTRK.WPN.MSLIF.ALM": { + "symbolID": "SUAPWMA---*****", + "tag": "WPN" + }, + "WAR.AIRTRK.WPN.MSLIF.ALM.ASM": { + "symbolID": "SUAPWMAS--*****", + "tag": "MSLIF" + }, + "WAR.AIRTRK.WPN.MSLIF.ALM.AAM": { + "symbolID": "SUAPWMAA--*****", + "tag": "MSLIF" + }, + "WAR.AIRTRK.WPN.MSLIF.SBSM": { + "symbolID": "SUAPWMU---*****", + "tag": "WPN" + }, + "WAR.AIRTRK.WPN.MSLIF.CM": { + "symbolID": "SUAPWMCM--*****", + "tag": "WPN" + }, + "WAR.AIRTRK.WPN.DCY": { + "symbolID": "SUAPWD----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.CVL": { + "symbolID": "SUAPC-----*****", + "tag": "WAR" + }, + "WAR.AIRTRK.CVL.FIXD": { + "symbolID": "SUAPCF----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.CVL.ROT": { + "symbolID": "SUAPCH----*****", + "tag": "AIRTRK" + }, + "WAR.AIRTRK.CVL.LTA": { + "symbolID": "SUAPCL----*****", + "tag": "AIRTRK" + } }, - "STBOPS.OPN.DGOPN": { - "symbolID": "OUOPU-----*****", - "tag": "STBOPS" + + "ground": { + "WAR.GRDTRK": { + "symbolID": "SUGP------*****", + "tag": "WAR" + }, + "WAR.GRDTRK.UNT": { + "symbolID": "SUGPU-----*****", + "tag": "WAR" + }, + "WAR.GRDTRK.UNT.CBT": { + "symbolID": "SUGPUC----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.UNT.CBT.ADF": { + "symbolID": "SUGPUCD---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.SHTR": { + "symbolID": "SUGPUCDS--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.SHTR.CPL": { + "symbolID": "SUGPUCDSC-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.SHTR.STG": { + "symbolID": "SUGPUCDSS-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.SHTR.VUL": { + "symbolID": "SUGPUCDSV-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL": { + "symbolID": "SUGPUCDM--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT": { + "symbolID": "SUGPUCDML-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT.MOT": { + "symbolID": "SUGPUCDMLA*****", + "tag": "MSL" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.MDM": { + "symbolID": "SUGPUCDMM-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.HVY": { + "symbolID": "SUGPUCDMH-*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD": { + "symbolID": "SUGPUCDH--*****", + "tag": "ADF" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.HWK": { + "symbolID": "SUGPUCDHH-*****", + "tag": "MSL" + }, + "WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.PATT": { + "symbolID": "SUGPUCDHP-*****", + "tag": "MSL" + }, + "WAR.GRDTRK.UNT.CBT.ADF.GUNUNT": { + "symbolID": "SUGPUCDG--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.CMPS": { + "symbolID": "SUGPUCDC--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.TGTGUT": { + "symbolID": "SUGPUCDT--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ADF.TMDU": { + "symbolID": "SUGPUCDO--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ARM": { + "symbolID": "SUGPUCA---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK": { + "symbolID": "SUGPUCAT--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.ABN": { + "symbolID": "SUGPUCATA-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP": { + "symbolID": "SUGPUCATW-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP.RCY": { + "symbolID": "SUGPUCATWR*****", + "tag": "TRK" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.LIT": { + "symbolID": "SUGPUCATL-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.MDM": { + "symbolID": "SUGPUCATM-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.HVY": { + "symbolID": "SUGPUCATH-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.TRK.RCY": { + "symbolID": "SUGPUCATR-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD": { + "symbolID": "SUGPUCAW--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.AAST": { + "symbolID": "SUGPUCAWS-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.ABN": { + "symbolID": "SUGPUCAWA-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP": { + "symbolID": "SUGPUCAWW-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP.RCY": { + "symbolID": "SUGPUCAWWR*****", + "tag": "WHD" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.LIT": { + "symbolID": "SUGPUCAWL-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.MDM": { + "symbolID": "SUGPUCAWM-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.HVY": { + "symbolID": "SUGPUCAWH-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.ARM.WHD.RCY": { + "symbolID": "SUGPUCAWR-*****", + "tag": "ARM" + }, + "WAR.GRDTRK.UNT.CBT.AARM": { + "symbolID": "SUGPUCAA--*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.DMD": { + "symbolID": "SUGPUCAAD-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.LIT": { + "symbolID": "SUGPUCAAL-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ABN": { + "symbolID": "SUGPUCAAM-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.AAST": { + "symbolID": "SUGPUCAAS-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.MNT": { + "symbolID": "SUGPUCAAU-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ARC": { + "symbolID": "SUGPUCAAC-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ARMD": { + "symbolID": "SUGPUCAAA-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ARMD.TKD": { + "symbolID": "SUGPUCAAAT*****", + "tag": "AARM" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ARMD.WHD": { + "symbolID": "SUGPUCAAAW*****", + "tag": "AARM" + }, + "WAR.GRDTRK.UNT.CBT.AARM.ARMD.AAST": { + "symbolID": "SUGPUCAAAS*****", + "tag": "AARM" + }, + "WAR.GRDTRK.UNT.CBT.AARM.MOT": { + "symbolID": "SUGPUCAAO-*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AARM.MOT.AAST": { + "symbolID": "SUGPUCAAOS*****", + "tag": "AARM" + }, + "WAR.GRDTRK.UNT.CBT.AVN": { + "symbolID": "SUGPUCV---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.FIXD": { + "symbolID": "SUGPUCVF--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.FIXD.UTY": { + "symbolID": "SUGPUCVFU-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.FIXD.ATK": { + "symbolID": "SUGPUCVFA-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.FIXD.RECON": { + "symbolID": "SUGPUCVFR-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT": { + "symbolID": "SUGPUCVR--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.ATK": { + "symbolID": "SUGPUCVRA-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.SCUT": { + "symbolID": "SUGPUCVRS-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.ASBW": { + "symbolID": "SUGPUCVRW-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY": { + "symbolID": "SUGPUCVRU-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.LIT": { + "symbolID": "SUGPUCVRUL*****", + "tag": "ROT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.MDM": { + "symbolID": "SUGPUCVRUM*****", + "tag": "ROT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.HVY": { + "symbolID": "SUGPUCVRUH*****", + "tag": "ROT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.C2": { + "symbolID": "SUGPUCVRUC*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.MEDV": { + "symbolID": "SUGPUCVRUE*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.ROT.MNECM": { + "symbolID": "SUGPUCVRM-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.SAR": { + "symbolID": "SUGPUCVS--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.CMPS": { + "symbolID": "SUGPUCVC--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.VSTOL": { + "symbolID": "SUGPUCVV--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.UAV": { + "symbolID": "SUGPUCVU--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.AVN.UAV.FIXD": { + "symbolID": "SUGPUCVUF-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.AVN.UAV.ROT": { + "symbolID": "SUGPUCVUR-*****", + "tag": "AVN" + }, + "WAR.GRDTRK.UNT.CBT.INF": { + "symbolID": "SUGPUCI---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.INF.LIT": { + "symbolID": "SUGPUCIL--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.MOT": { + "symbolID": "SUGPUCIM--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.MNT": { + "symbolID": "SUGPUCIO--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.ABN": { + "symbolID": "SUGPUCIA--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.AAST": { + "symbolID": "SUGPUCIS--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.MECH": { + "symbolID": "SUGPUCIZ--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.NAV": { + "symbolID": "SUGPUCIN--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.INFFV": { + "symbolID": "SUGPUCII--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.INF.ARC": { + "symbolID": "SUGPUCIC--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ENG": { + "symbolID": "SUGPUCE---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT": { + "symbolID": "SUGPUCEC--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.AAST": { + "symbolID": "SUGPUCECS-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.ABN": { + "symbolID": "SUGPUCECA-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.ARC": { + "symbolID": "SUGPUCECC-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.LIT": { + "symbolID": "SUGPUCECL-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.MDM": { + "symbolID": "SUGPUCECM-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.HVY": { + "symbolID": "SUGPUCECH-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.MECH": { + "symbolID": "SUGPUCECT-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.MOT": { + "symbolID": "SUGPUCECW-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.MNT": { + "symbolID": "SUGPUCECO-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CBT.RECON": { + "symbolID": "SUGPUCECR-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CSN": { + "symbolID": "SUGPUCEN--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ENG.CSN.NAV": { + "symbolID": "SUGPUCENN-*****", + "tag": "ENG" + }, + "WAR.GRDTRK.UNT.CBT.FLDART": { + "symbolID": "SUGPUCF---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW": { + "symbolID": "SUGPUCFH--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.SPD": { + "symbolID": "SUGPUCFHE-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.AAST": { + "symbolID": "SUGPUCFHS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.ABN": { + "symbolID": "SUGPUCFHA-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.ARC": { + "symbolID": "SUGPUCFHC-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.MNT": { + "symbolID": "SUGPUCFHO-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.LIT": { + "symbolID": "SUGPUCFHL-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.MDM": { + "symbolID": "SUGPUCFHM-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.HVY": { + "symbolID": "SUGPUCFHH-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.HOW.AMP": { + "symbolID": "SUGPUCFHX-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC": { + "symbolID": "SUGPUCFR--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL": { + "symbolID": "SUGPUCFRS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRSPD": { + "symbolID": "SUGPUCFRSS*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTRK": { + "symbolID": "SUGPUCFRSR*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTOW": { + "symbolID": "SUGPUCFRST*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL": { + "symbolID": "SUGPUCFRM-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRSPD": { + "symbolID": "SUGPUCFRMS*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTRK": { + "symbolID": "SUGPUCFRMR*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTOW": { + "symbolID": "SUGPUCFRMT*****", + "tag": "ROC" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ": { + "symbolID": "SUGPUCFT--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.RAD": { + "symbolID": "SUGPUCFTR-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.SND": { + "symbolID": "SUGPUCFTS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.FLH": { + "symbolID": "SUGPUCFTF-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT": { + "symbolID": "SUGPUCFTC-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.DMD": { + "symbolID": "SUGPUCFTCD*****", + "tag": "TGTAQ" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.TKD": { + "symbolID": "SUGPUCFTCM*****", + "tag": "TGTAQ" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.ANG": { + "symbolID": "SUGPUCFTA-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT": { + "symbolID": "SUGPUCFM--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDTRK": { + "symbolID": "SUGPUCFMS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDWHD": { + "symbolID": "SUGPUCFMW-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW": { + "symbolID": "SUGPUCFMT-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ABN": { + "symbolID": "SUGPUCFMTA*****", + "tag": "MORT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.AAST": { + "symbolID": "SUGPUCFMTS*****", + "tag": "MORT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ARC": { + "symbolID": "SUGPUCFMTC*****", + "tag": "MORT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.MNT": { + "symbolID": "SUGPUCFMTO*****", + "tag": "MORT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.MORT.AMP": { + "symbolID": "SUGPUCFML-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY": { + "symbolID": "SUGPUCFS--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.AAST": { + "symbolID": "SUGPUCFSS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.ABN": { + "symbolID": "SUGPUCFSA-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.LIT": { + "symbolID": "SUGPUCFSL-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.MNT": { + "symbolID": "SUGPUCFSO-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.METO": { + "symbolID": "SUGPUCFO--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.METO.AAST": { + "symbolID": "SUGPUCFOS-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.METO.ABN": { + "symbolID": "SUGPUCFOA-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.METO.LIT": { + "symbolID": "SUGPUCFOL-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.FLDART.METO.MNT": { + "symbolID": "SUGPUCFOO-*****", + "tag": "FLDART" + }, + "WAR.GRDTRK.UNT.CBT.RECON": { + "symbolID": "SUGPUCR---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.HRE": { + "symbolID": "SUGPUCRH--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.CVY": { + "symbolID": "SUGPUCRV--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.CVY.ARMD": { + "symbolID": "SUGPUCRVA-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.CVY.MOT": { + "symbolID": "SUGPUCRVM-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.CVY.GRD": { + "symbolID": "SUGPUCRVG-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.CVY.AIR": { + "symbolID": "SUGPUCRVO-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.ARC": { + "symbolID": "SUGPUCRC--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.AAST": { + "symbolID": "SUGPUCRS--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.ABN": { + "symbolID": "SUGPUCRA--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.MNT": { + "symbolID": "SUGPUCRO--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.LIT": { + "symbolID": "SUGPUCRL--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.MAR": { + "symbolID": "SUGPUCRR--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.RECON.MAR.DIV": { + "symbolID": "SUGPUCRRD-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.MAR.FOR": { + "symbolID": "SUGPUCRRF-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.MAR.LAR": { + "symbolID": "SUGPUCRRL-*****", + "tag": "RECON" + }, + "WAR.GRDTRK.UNT.CBT.RECON.LRS": { + "symbolID": "SUGPUCRX--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.MSL": { + "symbolID": "SUGPUCM---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.MSL.TAC": { + "symbolID": "SUGPUCMT--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.MSL.STGC": { + "symbolID": "SUGPUCMS--*****", + "tag": "CBT" + }, + // "WAR.GRDTRK.UNT.CBT.MSL": { + // "symbolID": "SUGPUCM---*****", + // "tag": "UNT" + // }, + // "WAR.GRDTRK.UNT.CBT.MSL.TAC": { + // "symbolID": "SUGPUCMT--*****", + // "tag": "CBT" + // }, + // "WAR.GRDTRK.UNT.CBT.MSL.STGC": { + // "symbolID": "SUGPUCMS--*****", + // "tag": "CBT" + // }, + "WAR.GRDTRK.UNT.CBT.ISF": { + "symbolID": "SUGPUCS---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CBT.ISF.RIV": { + "symbolID": "SUGPUCSW--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ISF.GRD": { + "symbolID": "SUGPUCSG--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ISF.GRD.DMD": { + "symbolID": "SUGPUCSGD-*****", + "tag": "ISF" + }, + "WAR.GRDTRK.UNT.CBT.ISF.GRD.MOT": { + "symbolID": "SUGPUCSGM-*****", + "tag": "ISF" + }, + "WAR.GRDTRK.UNT.CBT.ISF.GRD.MECH": { + "symbolID": "SUGPUCSGA-*****", + "tag": "ISF" + }, + "WAR.GRDTRK.UNT.CBT.ISF.WHMECH": { + "symbolID": "SUGPUCSM--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ISF.RALRD": { + "symbolID": "SUGPUCSR--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CBT.ISF.AVN": { + "symbolID": "SUGPUCSA--*****", + "tag": "CBT" + }, + "WAR.GRDTRK.UNT.CS": { + "symbolID": "SUGPUU----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.UNT.CS.NBC": { + "symbolID": "SUGPUUA---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML": { + "symbolID": "SUGPUUAC--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC": { + "symbolID": "SUGPUUACC-*****", + "tag": "NBC" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MECH": { + "symbolID": "SUGPUUACCK*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MOT": { + "symbolID": "SUGPUUACCM*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMK": { + "symbolID": "SUGPUUACS-*****", + "tag": "NBC" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMK.MOT": { + "symbolID": "SUGPUUACSM*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.SMK.ARM": { + "symbolID": "SUGPUUACSA*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.RECON": { + "symbolID": "SUGPUUACR-*****", + "tag": "NBC" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WARMVH": { + "symbolID": "SUGPUUACRW*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WAVS": { + "symbolID": "SUGPUUACRS*****", + "tag": "CML" + }, + "WAR.GRDTRK.UNT.CS.NBC.NUC": { + "symbolID": "SUGPUUAN--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.NBC.BIO": { + "symbolID": "SUGPUUAB--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.NBC.BIO.RECEQP": { + "symbolID": "SUGPUUABR-*****", + "tag": "NBC" + }, + "WAR.GRDTRK.UNT.CS.NBC.DECON": { + "symbolID": "SUGPUUAD--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT": { + "symbolID": "SUGPUUM---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.AEREXP": { + "symbolID": "SUGPUUMA--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT": { + "symbolID": "SUGPUUMS--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW": { + "symbolID": "SUGPUUMSE-*****", + "tag": "MILINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.ARMWVH": { + "symbolID": "SUGPUUMSEA*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.DFN": { + "symbolID": "SUGPUUMSED*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.INC": { + "symbolID": "SUGPUUMSEI*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.JMG": { + "symbolID": "SUGPUUMSEJ*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.THT": { + "symbolID": "SUGPUUMSET*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.CRP": { + "symbolID": "SUGPUUMSEC*****", + "tag": "SIGINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.CINT": { + "symbolID": "SUGPUUMC--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL": { + "symbolID": "SUGPUUMR--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSR": { + "symbolID": "SUGPUUMRG-*****", + "tag": "MILINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS": { + "symbolID": "SUGPUUMRS-*****", + "tag": "MILINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS.SCM": { + "symbolID": "SUGPUUMRSS*****", + "tag": "SVL" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSM": { + "symbolID": "SUGPUUMRX-*****", + "tag": "MILINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.SVL.METO": { + "symbolID": "SUGPUUMMO-*****", + "tag": "MILINT" + }, + "WAR.GRDTRK.UNT.CS.MILINT.OPN": { + "symbolID": "SUGPUUMO--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.TACEXP": { + "symbolID": "SUGPUUMT--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.INTGN": { + "symbolID": "SUGPUUMQ--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.MILINT.JINTCT": { + "symbolID": "SUGPUUMJ--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.LAWENU": { + "symbolID": "SUGPUUL---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.LAWENU.SHRPAT": { + "symbolID": "SUGPUULS--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.LAWENU.MILP": { + "symbolID": "SUGPUULM--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.LAWENU.CLE": { + "symbolID": "SUGPUULC--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.LAWENU.SECPOL": { + "symbolID": "SUGPUULF--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.LAWENU.CID": { + "symbolID": "SUGPUULD--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT": { + "symbolID": "SUGPUUS---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.ARA": { + "symbolID": "SUGPUUSA--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.COMCP": { + "symbolID": "SUGPUUSC--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.COMCP.LCCP": { + "symbolID": "SUGPUUSCL-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.CMDOPN": { + "symbolID": "SUGPUUSO--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.FWDCOM": { + "symbolID": "SUGPUUSF--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.MSE": { + "symbolID": "SUGPUUSM--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.SEN": { + "symbolID": "SUGPUUSMS-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.LEN": { + "symbolID": "SUGPUUSML-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.MSE.NODCTR": { + "symbolID": "SUGPUUSMN-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT": { + "symbolID": "SUGPUUSR--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TACSAT": { + "symbolID": "SUGPUUSRS-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TTYCTR": { + "symbolID": "SUGPUUSRT-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.RLY": { + "symbolID": "SUGPUUSRW-*****", + "tag": "SIGUNT" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.SIGSUP": { + "symbolID": "SUGPUUSS--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.PHOSWT": { + "symbolID": "SUGPUUSW--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.SIGUNT.ECRG": { + "symbolID": "SUGPUUSX--*****", + "tag": "CS" + }, + "WAR.GRDTRK.UNT.CS.IWU": { + "symbolID": "SUGPUUI---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.LNDSUP": { + "symbolID": "SUGPUUP---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CS.EOD": { + "symbolID": "SUGPUUE---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS": { + "symbolID": "SUGPUS----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN": { + "symbolID": "SUGPUSA---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.THT": { + "symbolID": "SUGPUSAT--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.CRP": { + "symbolID": "SUGPUSAC--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.JAG": { + "symbolID": "SUGPUSAJ--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.JAG.THT": { + "symbolID": "SUGPUSAJT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.JAG.CRP": { + "symbolID": "SUGPUSAJC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PST": { + "symbolID": "SUGPUSAO--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PST.THT": { + "symbolID": "SUGPUSAOT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PST.CRP": { + "symbolID": "SUGPUSAOC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.FIN": { + "symbolID": "SUGPUSAF--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.FIN.THT": { + "symbolID": "SUGPUSAFT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.FIN.CRP": { + "symbolID": "SUGPUSAFC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC": { + "symbolID": "SUGPUSAS--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.THT": { + "symbolID": "SUGPUSAST-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.CRP": { + "symbolID": "SUGPUSASC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY": { + "symbolID": "SUGPUSAM--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.THT": { + "symbolID": "SUGPUSAMT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.CRP": { + "symbolID": "SUGPUSAMC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RELG": { + "symbolID": "SUGPUSAR--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RELG.THT": { + "symbolID": "SUGPUSART-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RELG.CRP": { + "symbolID": "SUGPUSARC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF": { + "symbolID": "SUGPUSAP--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.THT": { + "symbolID": "SUGPUSAPT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.CRP": { + "symbolID": "SUGPUSAPC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT": { + "symbolID": "SUGPUSAPB-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.THT": { + "symbolID": "SUGPUSAPBT*****", + "tag": "PUBAFF" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.CRP": { + "symbolID": "SUGPUSAPBC*****", + "tag": "PUBAFF" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB": { + "symbolID": "SUGPUSAPM-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.THT": { + "symbolID": "SUGPUSAPMT*****", + "tag": "PUBAFF" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.CRP": { + "symbolID": "SUGPUSAPMC*****", + "tag": "PUBAFF" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RHU": { + "symbolID": "SUGPUSAX--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RHU.THT": { + "symbolID": "SUGPUSAXT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.RHU.CRP": { + "symbolID": "SUGPUSAXC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.LBR": { + "symbolID": "SUGPUSAL--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.LBR.THT": { + "symbolID": "SUGPUSALT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.LBR.CRP": { + "symbolID": "SUGPUSALC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MWR": { + "symbolID": "SUGPUSAW--*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MWR.THT": { + "symbolID": "SUGPUSAWT-*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.MWR.CRP": { + "symbolID": "SUGPUSAWC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY": { + "symbolID": "SUGPUSAQ--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.THT": { + "symbolID": "SUGPUSAQT-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.CRP": { + "symbolID": "SUGPUSAQC-*****", + "tag": "ADMIN" + }, + "WAR.GRDTRK.UNT.CSS.MED": { + "symbolID": "SUGPUSM---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS.MED.THT": { + "symbolID": "SUGPUSMT--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.CRP": { + "symbolID": "SUGPUSMC--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.MEDTF": { + "symbolID": "SUGPUSMM--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.MEDTF.THT": { + "symbolID": "SUGPUSMMT-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.MEDTF.CRP": { + "symbolID": "SUGPUSMMC-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.VNY": { + "symbolID": "SUGPUSMV--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.VNY.THT": { + "symbolID": "SUGPUSMVT-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.VNY.CRP": { + "symbolID": "SUGPUSMVC-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.DEN": { + "symbolID": "SUGPUSMD--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.DEN.THT": { + "symbolID": "SUGPUSMDT-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.DEN.CRP": { + "symbolID": "SUGPUSMDC-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.PSY": { + "symbolID": "SUGPUSMP--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MED.PSY.THT": { + "symbolID": "SUGPUSMPT-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.MED.PSY.CRP": { + "symbolID": "SUGPUSMPC-*****", + "tag": "MED" + }, + "WAR.GRDTRK.UNT.CSS.SLP": { + "symbolID": "SUGPUSS---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS.SLP.THT": { + "symbolID": "SUGPUSST--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CRP": { + "symbolID": "SUGPUSSC--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS1": { + "symbolID": "SUGPUSS1--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS1.THT": { + "symbolID": "SUGPUSS1T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS1.CRP": { + "symbolID": "SUGPUSS1C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS2": { + "symbolID": "SUGPUSS2--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS2.THT": { + "symbolID": "SUGPUSS2T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS2.CRP": { + "symbolID": "SUGPUSS2C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3": { + "symbolID": "SUGPUSS3--*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3.THT": { + "symbolID": "SUGPUSS3T-*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3.CRP": { + "symbolID": "SUGPUSS3C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN": { + "symbolID": "SUGPUSS3A-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.THT": { + "symbolID": "SUGPUSS3AT*****", + "tag": "CLS3" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.CRP": { + "symbolID": "SUGPUSS3AC*****", + "tag": "CLS3" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS4": { + "symbolID": "SUGPUSS4--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS4.THT": { + "symbolID": "SUGPUSS4T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS4.CRP": { + "symbolID": "SUGPUSS4C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS5": { + "symbolID": "SUGPUSS5--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS5.THT": { + "symbolID": "SUGPUSS5T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS5.CRP": { + "symbolID": "SUGPUSS5C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS6": { + "symbolID": "SUGPUSS6--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS6.THT": { + "symbolID": "SUGPUSS6T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS6.CRP": { + "symbolID": "SUGPUSS6C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS7": { + "symbolID": "SUGPUSS7--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS7.THT": { + "symbolID": "SUGPUSS7T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS7.CRP": { + "symbolID": "SUGPUSS7C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS8": { + "symbolID": "SUGPUSS8--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS8.THT": { + "symbolID": "SUGPUSS8T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS8.CRP": { + "symbolID": "SUGPUSS8C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS9": { + "symbolID": "SUGPUSS9--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS9.THT": { + "symbolID": "SUGPUSS9T-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS9.CRP": { + "symbolID": "SUGPUSS9C-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS10": { + "symbolID": "SUGPUSSX--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS10.THT": { + "symbolID": "SUGPUSSXT-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.CLS10.CRP": { + "symbolID": "SUGPUSSXC-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.LDY": { + "symbolID": "SUGPUSSL--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.LDY.THT": { + "symbolID": "SUGPUSSLT-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.LDY.CRP": { + "symbolID": "SUGPUSSLC-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O": { + "symbolID": "SUGPUSSW--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O.THT": { + "symbolID": "SUGPUSSWT-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O.CRP": { + "symbolID": "SUGPUSSWC-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR": { + "symbolID": "SUGPUSSWP-*****", + "tag": "SLP" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.THT": { + "symbolID": "SUGPUSSWPT*****", + "tag": "H2O" + }, + "WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.CRP": { + "symbolID": "SUGPUSSWPC*****", + "tag": "H2O" + }, + "WAR.GRDTRK.UNT.CSS.TPT": { + "symbolID": "SUGPUST---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.THT": { + "symbolID": "SUGPUSTT--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.CRP": { + "symbolID": "SUGPUSTC--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MCC": { + "symbolID": "SUGPUSTM--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MCC.THT": { + "symbolID": "SUGPUSTMT-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MCC.CRP": { + "symbolID": "SUGPUSTMC-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.RHD": { + "symbolID": "SUGPUSTR--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.RHD.THT": { + "symbolID": "SUGPUSTRT-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.RHD.CRP": { + "symbolID": "SUGPUSTRC-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.SPOD": { + "symbolID": "SUGPUSTS--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.SPOD.THT": { + "symbolID": "SUGPUSTST-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.SPOD.CRP": { + "symbolID": "SUGPUSTSC-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.APOD": { + "symbolID": "SUGPUSTA--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.APOD.THT": { + "symbolID": "SUGPUSTAT-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.APOD.CRP": { + "symbolID": "SUGPUSTAC-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MSL": { + "symbolID": "SUGPUSTI--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MSL.THT": { + "symbolID": "SUGPUSTIT-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.TPT.MSL.CRP": { + "symbolID": "SUGPUSTIC-*****", + "tag": "TPT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT": { + "symbolID": "SUGPUSX---*****", + "tag": "UNT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.THT": { + "symbolID": "SUGPUSXT--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.CRP": { + "symbolID": "SUGPUSXC--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.HVY": { + "symbolID": "SUGPUSXH--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.HVY.THT": { + "symbolID": "SUGPUSXHT-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.HVY.CRP": { + "symbolID": "SUGPUSXHC-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.RCY": { + "symbolID": "SUGPUSXR--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.RCY.THT": { + "symbolID": "SUGPUSXRT-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.RCY.CRP": { + "symbolID": "SUGPUSXRC-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD": { + "symbolID": "SUGPUSXO--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD.THT": { + "symbolID": "SUGPUSXOT-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD.CRP": { + "symbolID": "SUGPUSXOC-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL": { + "symbolID": "SUGPUSXOM-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.THT": { + "symbolID": "SUGPUSXOMT*****", + "tag": "ORD" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.CRP": { + "symbolID": "SUGPUSXOMC*****", + "tag": "ORD" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.EOP": { + "symbolID": "SUGPUSXE--*****", + "tag": "CSS" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.EOP.THT": { + "symbolID": "SUGPUSXET-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.CSS.MAINT.EOP.CRP": { + "symbolID": "SUGPUSXEC-*****", + "tag": "MAINT" + }, + "WAR.GRDTRK.UNT.C2HQ": { + "symbolID": "SUGPUH----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.EQT": { + "symbolID": "SUGPE-----*****", + "tag": "WAR" + }, + "WAR.GRDTRK.EQT.WPN.MSLL": { + "symbolID": "SUGPEWM---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD": { + "symbolID": "SUGPEWMA--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR": { + "symbolID": "SUGPEWMAS-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TLAR": { + "symbolID": "SUGPEWMASR*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TELAR": { + "symbolID": "SUGPEWMASE*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR": { + "symbolID": "SUGPEWMAI-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TLAR": { + "symbolID": "SUGPEWMAIR*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TELAR": { + "symbolID": "SUGPEWMAIE*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR": { + "symbolID": "SUGPEWMAL-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TLAR": { + "symbolID": "SUGPEWMALR*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TELAR": { + "symbolID": "SUGPEWMALE*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT": { + "symbolID": "SUGPEWMAT-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TLAR": { + "symbolID": "SUGPEWMATR*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TELAR": { + "symbolID": "SUGPEWMATE*****", + "tag": "ADFAD" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.SUF": { + "symbolID": "SUGPEWMS--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.SUF.SHTR": { + "symbolID": "SUGPEWMSS-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.SUF.INTMR": { + "symbolID": "SUGPEWMSI-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.SUF.LNGR": { + "symbolID": "SUGPEWMSL-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.AT": { + "symbolID": "SUGPEWMT--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.AT.LIT": { + "symbolID": "SUGPEWMTL-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.AT.MDM": { + "symbolID": "SUGPEWMTM-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.MSLL.AT.HVY": { + "symbolID": "SUGPEWMTH-*****", + "tag": "MSLL" + }, + "WAR.GRDTRK.EQT.WPN.SRL": { + "symbolID": "SUGPEWS---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.SRL.LIT": { + "symbolID": "SUGPEWSL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.SRL.MDM": { + "symbolID": "SUGPEWSM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.SRL.HVY": { + "symbolID": "SUGPEWSH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MRL": { + "symbolID": "SUGPEWX---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.MRL.LIT": { + "symbolID": "SUGPEWXL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MRL.MDM": { + "symbolID": "SUGPEWXM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MRL.HVY": { + "symbolID": "SUGPEWXH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATRL": { + "symbolID": "SUGPEWT---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.ATRL.LIT": { + "symbolID": "SUGPEWTL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATRL.MDM": { + "symbolID": "SUGPEWTM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATRL.HVY": { + "symbolID": "SUGPEWTH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.RIFWPN": { + "symbolID": "SUGPEWR---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.RIFWPN.RIF": { + "symbolID": "SUGPEWRR--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.RIFWPN.LMG": { + "symbolID": "SUGPEWRL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.RIFWPN.HMG": { + "symbolID": "SUGPEWRH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.GREL": { + "symbolID": "SUGPEWZ---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.GREL.LIT": { + "symbolID": "SUGPEWZL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.GREL.MDM": { + "symbolID": "SUGPEWZM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.GREL.HVY": { + "symbolID": "SUGPEWZH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MORT": { + "symbolID": "SUGPEWO---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.MORT.LIT": { + "symbolID": "SUGPEWOL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MORT.MDM": { + "symbolID": "SUGPEWOM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.MORT.HVY": { + "symbolID": "SUGPEWOH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.HOW": { + "symbolID": "SUGPEWH---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.HOW.LIT": { + "symbolID": "SUGPEWHL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.HOW.LIT.SPD": { + "symbolID": "SUGPEWHLS-*****", + "tag": "HOW" + }, + "WAR.GRDTRK.EQT.WPN.HOW.MDM": { + "symbolID": "SUGPEWHM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.HOW.MDM.SPD": { + "symbolID": "SUGPEWHMS-*****", + "tag": "HOW" + }, + "WAR.GRDTRK.EQT.WPN.HOW.HVY": { + "symbolID": "SUGPEWHH--*****", + "tag": "WPN" + }, + // "WAR.GRDTRK.EQT.WPN.HOW.HVY": { + // "symbolID": "SUGPEWHHS-*****", + // "tag": "HOW" + // }, + "WAR.GRDTRK.EQT.WPN.ATG": { + "symbolID": "SUGPEWG---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.ATG.LIT": { + "symbolID": "SUGPEWGL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATG.MDM": { + "symbolID": "SUGPEWGM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATG.HVY": { + "symbolID": "SUGPEWGH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ATG.RECL": { + "symbolID": "SUGPEWGR--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.DFG": { + "symbolID": "SUGPEWD---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.DFG.LIT": { + "symbolID": "SUGPEWDL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.DFG.LIT.SPD": { + "symbolID": "SUGPEWDLS-*****", + "tag": "DFG" + }, + "WAR.GRDTRK.EQT.WPN.DFG.MDM": { + "symbolID": "SUGPEWDM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.DFG.MDM.SPD": { + "symbolID": "SUGPEWDMS-*****", + "tag": "DFG" + }, + "WAR.GRDTRK.EQT.WPN.DFG.HVY": { + "symbolID": "SUGPEWDH--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.DFG.HVY.SPD": { + "symbolID": "SUGPEWDHS-*****", + "tag": "DFG" + }, + "WAR.GRDTRK.EQT.WPN.ADFG": { + "symbolID": "SUGPEWA---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.WPN.ADFG.LIT": { + "symbolID": "SUGPEWAL--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ADFG.MDM": { + "symbolID": "SUGPEWAM--*****", + "tag": "WPN" + }, + "WAR.GRDTRK.EQT.WPN.ADFG.HVY": { + "symbolID": "SUGPEWAH--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH": { + "symbolID": "SUGPEV----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD": { + "symbolID": "SUGPEVA---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK": { + "symbolID": "SUGPEVAT--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT": { + "symbolID": "SUGPEVATL-*****", + "tag": "ARMD" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT.RCY": { + "symbolID": "SUGPEVATLR*****", + "tag": "TANK" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM": { + "symbolID": "SUGPEVATM-*****", + "tag": "ARMD" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM.RCY": { + "symbolID": "SUGPEVATMR*****", + "tag": "TANK" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY": { + "symbolID": "SUGPEVATH-*****", + "tag": "ARMD" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY.RCY": { + "symbolID": "SUGPEVATHR*****", + "tag": "TANK" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC": { + "symbolID": "SUGPEVAA--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC.RCY": { + "symbolID": "SUGPEVAAR-*****", + "tag": "ARMD" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMINF": { + "symbolID": "SUGPEVAI--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.C2V": { + "symbolID": "SUGPEVAC--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.CSSVEH": { + "symbolID": "SUGPEVAS--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ARMD.LARMVH": { + "symbolID": "SUGPEVAL--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH": { + "symbolID": "SUGPEVU---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.BUS": { + "symbolID": "SUGPEVUB--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI": { + "symbolID": "SUGPEVUS--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.LIT": { + "symbolID": "SUGPEVUSL-*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.MDM": { + "symbolID": "SUGPEVUS--*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.HVY": { + "symbolID": "SUGPEVUS--*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.LCCTRK": { + "symbolID": "SUGPEVUL--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.CCTRK": { + "symbolID": "SUGPEVUX--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.H2OCRT": { + "symbolID": "SUGPEVUR--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK": { + "symbolID": "SUGPEVUT--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.LIT": { + "symbolID": "SUGPEVUTL-*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.HVY": { + "symbolID": "SUGPEVUTH-*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC": { + "symbolID": "SUGPEVUA--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC.ARMD": { + "symbolID": "SUGPEVUAA-*****", + "tag": "UTYVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH": { + "symbolID": "SUGPEVE---*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BRG": { + "symbolID": "SUGPEVEB--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ERHMR": { + "symbolID": "SUGPEVEE--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.CSNVEH": { + "symbolID": "SUGPEVEC--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH": { + "symbolID": "SUGPEVEM--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.ARMCV": { + "symbolID": "SUGPEVEMV-*****", + "tag": "ENGVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.TRKMV": { + "symbolID": "SUGPEVEML-*****", + "tag": "ENGVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH": { + "symbolID": "SUGPEVEA--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.ARMVM": { + "symbolID": "SUGPEVEAA-*****", + "tag": "ENGVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.TM": { + "symbolID": "SUGPEVEAT-*****", + "tag": "ENGVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR": { + "symbolID": "SUGPEVED--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR.ARMD": { + "symbolID": "SUGPEVEDA-*****", + "tag": "ENGVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.AST": { + "symbolID": "SUGPEVES--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ARMERV": { + "symbolID": "SUGPEVER--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BH": { + "symbolID": "SUGPEVEH--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.ENGVEH.FRYTSP": { + "symbolID": "SUGPEVEF--*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.TRNLCO": { + "symbolID": "SUGPEVT---*****", + "tag": "GRDVEH" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH": { + "symbolID": "SUGPEVC---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT": { + "symbolID": "SUGPEVCA--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.CPCT": { + "symbolID": "SUGPEVCAL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.MDSZ": { + "symbolID": "SUGPEVCAM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.SDN": { + "symbolID": "SUGPEVCAH-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK": { + "symbolID": "SUGPEVCO--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.PU": { + "symbolID": "SUGPEVCOL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.SMAL": { + "symbolID": "SUGPEVCOM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.LRG": { + "symbolID": "SUGPEVCOH-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV": { + "symbolID": "SUGPEVCM--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.VAN": { + "symbolID": "SUGPEVCML-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.SBUS": { + "symbolID": "SUGPEVCMM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.LBUS": { + "symbolID": "SUGPEVCMH-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH": { + "symbolID": "SUGPEVCU--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SUV": { + "symbolID": "SUGPEVCUL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SBOX": { + "symbolID": "SUGPEVCUM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.LBOX": { + "symbolID": "SUGPEVCUH-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP": { + "symbolID": "SUGPEVCJ--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.SMAL": { + "symbolID": "SUGPEVCJL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.MDM": { + "symbolID": "SUGPEVCJM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.LRG": { + "symbolID": "SUGPEVCJH-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL": { + "symbolID": "SUGPEVCT--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.SMAL": { + "symbolID": "SUGPEVCTL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.MDM": { + "symbolID": "SUGPEVCTM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.LRG": { + "symbolID": "SUGPEVCTL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF": { + "symbolID": "SUGPEVCF--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.SMAL": { + "symbolID": "SUGPEVCFL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.MDM": { + "symbolID": "SUGPEVCFM-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.LRG": { + "symbolID": "SUGPEVCFL-*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.PKAN": { + "symbolID": "SUGPEVM---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT": { + "symbolID": "SUGPEVS---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TLDR": { + "symbolID": "SUGPEVST--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TPTR": { + "symbolID": "SUGPEVSR--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT.CRN": { + "symbolID": "SUGPEVSC--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT.PLNT": { + "symbolID": "SUGPEVSP--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.GRDVEH.MSLSPT.WH": { + "symbolID": "SUGPEVSW--*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SNS": { + "symbolID": "SUGPES----*****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.EQT.SNS.RAD": { + "symbolID": "SUGPESR---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SNS.EMP": { + "symbolID": "SUGPESE---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SPL.LSR": { + "symbolID": "SUGPEXL---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SPL.NBCEQT": { + "symbolID": "SUGPEXN---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SPL.FLMTHR": { + "symbolID": "SUGPEXF---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SPL.LNDMNE": { + "symbolID": "SUGPEXM---*****", + "tag": "EQT" + }, + "WAR.GRDTRK.EQT.SPL.LNDMNE.CLM": { + "symbolID": "SUGPEXMC--*****", + "tag": "SPL" + }, + "WAR.GRDTRK.EQT.SPL.LNDMNE.LTL": { + "symbolID": "SUGPEXML--*****", + "tag": "SPL" + }, + "WAR.GRDTRK.INS": { + "symbolID": "SUGPI-----H****", + "tag": "WAR" + }, + "WAR.GRDTRK.INS.RMP": { + "symbolID": "SUGPIR----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.RMP.MNE": { + "symbolID": "SUGPIRM---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.RMP.PGO": { + "symbolID": "SUGPIRP---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.RMP.NBC": { + "symbolID": "SUGPIRN---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.RMP.NBC.BIO": { + "symbolID": "SUGPIRNB--H****", + "tag": "RMP" + }, + "WAR.GRDTRK.INS.RMP.NBC.CML": { + "symbolID": "SUGPIRNC--H****", + "tag": "RMP" + }, + "WAR.GRDTRK.INS.RMP.NBC.NUC": { + "symbolID": "SUGPIRNN--H****", + "tag": "RMP" + }, + "WAR.GRDTRK.INS.PF": { + "symbolID": "SUGPIP----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.PF.DECON": { + "symbolID": "SUGPIPD---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.EQTMNF": { + "symbolID": "SUGPIE----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.SRUF": { + "symbolID": "SUGPIU----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.SRUF.TRF": { + "symbolID": "SUGPIUR---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.SRUF.TCF": { + "symbolID": "SUGPIUT---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.SRUF.EPF": { + "symbolID": "SUGPIUE---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.SRUF.EPF.NPT": { + "symbolID": "SUGPIUEN--H****", + "tag": "SRUF" + }, + "WAR.GRDTRK.INS.SRUF.EPF.DAM": { + "symbolID": "SUGPIUED--H****", + "tag": "SRUF" + }, + "WAR.GRDTRK.INS.SRUF.EPF.FOSF": { + "symbolID": "SUGPIUEF--H****", + "tag": "SRUF" + }, + "WAR.GRDTRK.INS.SRUF.PWS": { + "symbolID": "SUGPIUP---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.NENY": { + "symbolID": "SUGPIMF---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.NENY.ATMER": { + "symbolID": "SUGPIMFA--H****", + "tag": "MMF" + }, + "WAR.GRDTRK.INS.MMF.NENY.NMP": { + "symbolID": "SUGPIMFP--H****", + "tag": "MMF" + }, + "WAR.GRDTRK.INS.MMF.NENY.NMP.WPNGR": { + "symbolID": "SUGPIMFPWH****", + "tag": "NENY" + }, + "WAR.GRDTRK.INS.MMF.NENY.NMS": { + "symbolID": "SUGPIMFS--H****", + "tag": "MMF" + }, + "WAR.GRDTRK.INS.MMF.APA": { + "symbolID": "SUGPIMA---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.AMEP": { + "symbolID": "SUGPIME---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.AMTP": { + "symbolID": "SUGPIMG---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.MILVP": { + "symbolID": "SUGPIMV---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.ENGEP": { + "symbolID": "SUGPIMN---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.ENGEP.BRG": { + "symbolID": "SUGPIMNB--H****", + "tag": "MMF" + }, + "WAR.GRDTRK.INS.MMF.CBWP": { + "symbolID": "SUGPIMC---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.SHPCSN": { + "symbolID": "SUGPIMS---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MMF.MSSP": { + "symbolID": "SUGPIMM---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.GOVLDR": { + "symbolID": "SUGPIG----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.MILBF": { + "symbolID": "SUGPIB----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.MILBF.AB": { + "symbolID": "SUGPIBA---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.MILBF.SP": { + "symbolID": "SUGPIBN---H****", + "tag": "INS" + }, + "WAR.GRDTRK.INS.TSPF": { + "symbolID": "SUGPIT----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.MEDF": { + "symbolID": "SUGPIX----H****", + "tag": "GRDTRK" + }, + "WAR.GRDTRK.INS.MEDF.HSP": { + "symbolID": "SUGPIXH---H****", + "tag": "INS" + } }, - "STBOPS.ITM.RFG": { - "symbolID": "OUIPR-----*****", - "tag": "STBOPS" + + "sea": { + "WAR.SSUF": { + "symbolID": "SUSP------*****", + "tag": "WAR" + }, + "WAR.SSUF.CBTT": { + "symbolID": "SUSPC-----*****", + "tag": "WAR" + }, + "WAR.SSUF.CBTT.LNE": { + "symbolID": "SUSPCL----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.LNE.CRR": { + "symbolID": "SUSPCLCV--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.LNE.BBS": { + "symbolID": "SUSPCLBB--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.LNE.CRU": { + "symbolID": "SUSPCLCC--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.LNE.DD": { + "symbolID": "SUSPCLDD--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.LNE.FFR": { + "symbolID": "SUSPCLFF--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.AMPWS": { + "symbolID": "SUSPCA----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.AMPWS.ASTVES": { + "symbolID": "SUSPCALA--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.AMPWS.LNDSHP": { + "symbolID": "SUSPCALS--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.AMPWS.LNDSHP.MDM": { + "symbolID": "SUSPCALSM-*****", + "tag": "AMPWS" + }, + "WAR.SSUF.CBTT.AMPWS.LNDSHP.TANK": { + "symbolID": "SUSPCALST-*****", + "tag": "AMPWS" + }, + "WAR.SSUF.CBTT.AMPWS.LNDCRT": { + "symbolID": "SUSPCALC--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.MNEWV": { + "symbolID": "SUSPCM----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.MNEWV.MNELYR": { + "symbolID": "SUSPCMML--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.MNEWV.MNESWE": { + "symbolID": "SUSPCMMS--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.MNEWV.MNEHNT": { + "symbolID": "SUSPCMMH--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.MNEWV.MCMSUP": { + "symbolID": "SUSPCMMA--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.MNEWV.MCMDRN": { + "symbolID": "SUSPCMMD--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.PAT": { + "symbolID": "SUSPCP----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.PAT.ASBW": { + "symbolID": "SUSPCPSB--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.PAT.ASUW": { + "symbolID": "SUSPCPSU--*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.HOV": { + "symbolID": "SUSPCH----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.STN": { + "symbolID": "SUSPS-----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.STN.PKT": { + "symbolID": "SUSPSP----*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.STN.ASWSHP": { + "symbolID": "SUSPSA----*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.NAVGRP": { + "symbolID": "SUSPG-----*****", + "tag": "SSUF" + }, + "WAR.SSUF.CBTT.NAVGRP.NAVTF": { + "symbolID": "SUSPGT----*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.NAVGRP.NAVTG": { + "symbolID": "SUSPGG----*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.NAVGRP.NAVTU": { + "symbolID": "SUSPGU----*****", + "tag": "CBTT" + }, + "WAR.SSUF.CBTT.NAVGRP.CNY": { + "symbolID": "SUSPGC----*****", + "tag": "CBTT" + }, + "WAR.SSUF.NCBTT": { + "symbolID": "SUSPN-----*****", + "tag": "WAR" + }, + "WAR.SSUF.NCBTT.UWRPM": { + "symbolID": "SUSPNR----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.FLTSUP": { + "symbolID": "SUSPNF----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.INT": { + "symbolID": "SUSPNI----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.SSH": { + "symbolID": "SUSPNS----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.HSPSHP": { + "symbolID": "SUSPNM----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.HOV": { + "symbolID": "SUSPNH----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.STN": { + "symbolID": "SUSPNN----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NCBTT.STN.RSC": { + "symbolID": "SUSPNNR---*****", + "tag": "NCBTT" + }, + "WAR.SSUF.NMIL.MCT": { + "symbolID": "SUSPXM----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.MCT.CGO": { + "symbolID": "SUSPXMC---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.RORO": { + "symbolID": "SUSPXMR---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.OLR": { + "symbolID": "SUSPXMO---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.TUG": { + "symbolID": "SUSPXMTU--*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.FRY": { + "symbolID": "SUSPXMF---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.PSG": { + "symbolID": "SUSPXMP---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.HAZMAT": { + "symbolID": "SUSPXMH---*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.MCT.TOWVES": { + "symbolID": "SUSPXMTO--*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.FSG": { + "symbolID": "SUSPXF----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.FSG.DRFT": { + "symbolID": "SUSPXFDF--*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.FSG.DRG": { + "symbolID": "SUSPXFDR--*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.FSG.TRW": { + "symbolID": "SUSPXFTR--*****", + "tag": "NMIL" + }, + "WAR.SSUF.NMIL.LESCRT": { + "symbolID": "SUSPXR----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.LAWENV": { + "symbolID": "SUSPXL----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.HOV": { + "symbolID": "SUSPXH----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.FSTREC": { + "symbolID": "SUSPXA----*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.FSTREC.RHIB": { + "symbolID": "SUSPXAR---*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.FSTREC.SPDBT": { + "symbolID": "SUSPXAS---*****", + "tag": "SSUF" + }, + "WAR.SSUF.NMIL.PWC": { + "symbolID": "SUSPXP----*****", + "tag": "SSUF" + }, + "WAR.SSUF.OWN": { + "symbolID": "SUSPO-----*****", + "tag": "WAR" + } }, - "STBOPS.ITM.SAFHSE": { - "symbolID": "OUIPS-----*****", - "tag": "STBOPS" + + "subsurface": { + "WAR.SBSUF": { + "symbolID": "SUUP------*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB": { + "symbolID": "SUUPS-----*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB.SURF": { + "symbolID": "SUUPSF----*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB.BOTTMD": { + "symbolID": "SUUPSB----*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB.CRT": { + "symbolID": "SUUPSR----*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB.NONSUB": { + "symbolID": "SUUPSX----*****", + "tag": "WAR" + }, + "WAR.SBSUF.SUB.NPRN": { + "symbolID": "SUUPSN----*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.SUB.NPRN.SURF": { + "symbolID": "SUUPSNF---*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.SUB.NPRN.ATK": { + "symbolID": "SUUPSNA---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.NPRN.MSL": { + "symbolID": "SUUPSNM---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.NPRN.GDD": { + "symbolID": "SUUPSNG---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.NPRN.BLST": { + "symbolID": "SUUPSNB---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN": { + "symbolID": "SUUPSC----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN.SURF": { + "symbolID": "SUUPSCF---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN.ATK": { + "symbolID": "SUUPSCA---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN.MSL": { + "symbolID": "SUUPSCM---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN.GDD": { + "symbolID": "SUUPSCG---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.CNVPRN.BLST": { + "symbolID": "SUUPSCB---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.OTH": { + "symbolID": "SUUPSO----*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.SUB.OTH.SURF": { + "symbolID": "SUUPSOF---*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.SUB.UUV": { + "symbolID": "SUUPSU----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.UUV.MNEW": { + "symbolID": "SUUPSUM---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.UUV.ASBW": { + "symbolID": "SUUPSUS---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.UUV.ASUW": { + "symbolID": "SUUPSUN---*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.POSS1": { + "symbolID": "SUUPS1-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.POSS2": { + "symbolID": "SUUPS2-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.POSS3": { + "symbolID": "SUUPS3-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.POSS4": { + "symbolID": "SUUPS4-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.PRBSUB": { + "symbolID": "SUUPSL-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.SUB.SNORKL": { + "symbolID": "SUUPSK-----*****", + "tag": "SUB" + }, + "WAR.SBSUF.UH2WPN": { + "symbolID": "SUUPW-----*****", + "tag": "WAR" + }, + "WAR.SBSUF.UH2WPN.TPD": { + "symbolID": "SUUPWT----*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.UH2WPN.SMNE": { + "symbolID": "SUUPWM----*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.UH2WPN.SMNE.NTRLZD": { + "symbolID": "SUUPWMD---*****", + "tag": "UH2WPN" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG": { + "symbolID": "SUUPWMG---*****", + "tag": "UH2WPN" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.NTRLZD": { + "symbolID": "SUUPWMGD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.EXER": { + "symbolID": "SUUPWMGX--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.MILEC": { + "symbolID": "SUUPWMGE--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.MILCO": { + "symbolID": "SUUPWMGD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.NRGEAC": { + "symbolID": "SUUPWMGD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMG.NMMLCO": { + "symbolID": "SUUPWMGD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM": { + "symbolID": "SUUPWMM---*****", + "tag": "UH2WPN" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.NTRLZD": { + "symbolID": "SUUPWMMD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.EXER": { + "symbolID": "SUUPWMMX--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.MILEC": { + "symbolID": "SUUPWMME--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.MILCO": { + "symbolID": "SUUPWMMD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.NRGEAC": { + "symbolID": "SUUPWMMD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMM.NMMLCO": { + "symbolID": "SUUPWMMD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF": { + "symbolID": "SUUPWMF---*****", + "tag": "UH2WPN" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.NTRLZD": { + "symbolID": "SUUPWMFD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.EXER": { + "symbolID": "SUUPWMFX--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.MILEC": { + "symbolID": "SUUPWMFE--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.MILCO": { + "symbolID": "SUUPWMFD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.NRGEAC": { + "symbolID": "SUUPWMFD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMF.NMMLCO": { + "symbolID": "SUUPWMFD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMOP": { + "symbolID": "SUUPWMO---*****", + "tag": "UH2WPN" + }, + "WAR.SBSUF.UH2WPN.SMNE.SMOP.NTRLZD": { + "symbolID": "SUUPWMOD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.EXER": { + "symbolID": "SUUPWMF---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.MILEC": { + "symbolID": "SUUPWME---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.ANCHOR": { + "symbolID": "SUUPWMA---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.MILCO": { + "symbolID": "SUUPWMD---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.NRGEAC": { + "symbolID": "SUUPWMD---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.OBSTRC": { + "symbolID": "SUUPWMB---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.OBSTRC.NTRLZD": { + "symbolID": "SUUPWMBD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.NMMLCO": { + "symbolID": "SUUPWMD---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.RISING": { + "symbolID": "SUUPWMS---*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.RISING.EXER": { + "symbolID": "SUUPWMSX--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2WPN.SMNE.RISING.NTRLZD": { + "symbolID": "SUUPWMSD--*****", + "tag": "SMNE" + }, + "WAR.SBSUF.UH2DCY": { + "symbolID": "SUUPWD----*****", + "tag": "WAR" + }, + "WAR.SBSUF.UH2DCY.SMDCY": { + "symbolID": "SUUPWDM---*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.UH2DCY.SMDCY.GRND": { + "symbolID": "SUUPWDMG--*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.UH2DCY.SMDCY.MOORED": { + "symbolID": "SUUPWDMM--*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.NSUB": { + "symbolID": "N/A", + "tag": "WAR" + }, + "WAR.SBSUF.NSUB.DVR": { + "symbolID": "SUUPND----*****", + "tag": "SBSUF" + }, + "WAR.SBSUF.ERL": { + "symbolID": "SUUPE------*****", + "tag": "WAR" + }, + "WAR.SBSUF.DRL": { + "symbolID": "SUUPV------*****", + "tag": "WAR" + }, + "WAR.SBSUF.UXO": { + "symbolID": "SUUPX------*****", + "tag": "WAR" + } }, - "STBOPS.ITM.GRF": { - "symbolID": "OUIPG-----*****", - "tag": "STBOPS" + + "sof": { + "WAR.SOFUNT": { + "symbolID": "SUFP------*****", + "tag": "WAR" + }, + "WAR.SOFUNT.AVN": { + "symbolID": "SUFPA-----*****", + "tag": "WAR" + }, + "WAR.SOFUNT.AVN.FIXD": { + "symbolID": "SUFPAF----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.AVN.FIXD.ATK": { + "symbolID": "SUFPAFA---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.FIXD.RFE": { + "symbolID": "SUFPAFK---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.FIXD.UTY": { + "symbolID": "SUFPAFU---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.FIXD.UTY.LIT": { + "symbolID": "SUFPAFUL--*****", + "tag": "FIXD" + }, + "WAR.SOFUNT.AVN.FIXD.UTY.MDM": { + "symbolID": "SUFPAFUM--*****", + "tag": "FIXD" + }, + "WAR.SOFUNT.AVN.FIXD.UTY.HVY": { + "symbolID": "SUFPAFUH--*****", + "tag": "FIXD" + }, + "WAR.SOFUNT.AVN.VSTOL": { + "symbolID": "SUFPAV----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.AVN.ROT": { + "symbolID": "SUFPAH----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.AVN.ROT.CSAR": { + "symbolID": "SUFPAHH---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.ROT.ATK": { + "symbolID": "SUFPAHA---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.ROT.UTY": { + "symbolID": "SUFPAHU---*****", + "tag": "AVN" + }, + "WAR.SOFUNT.AVN.ROT.UTY.LIT": { + "symbolID": "SUFPAHUL--*****", + "tag": "ROT" + }, + "WAR.SOFUNT.AVN.ROT.UTY.MDM": { + "symbolID": "SUFPAHUM--*****", + "tag": "ROT" + }, + "WAR.SOFUNT.AVN.ROT.UTY.HVY": { + "symbolID": "SUFPAHUH--*****", + "tag": "ROT" + }, + "WAR.SOFUNT.NAV": { + "symbolID": "SUFPN-----*****", + "tag": "WAR" + }, + "WAR.SOFUNT.NAV.SEAL": { + "symbolID": "SUFPNS----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.NAV.UH2DML": { + "symbolID": "SUFPNU----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.NAV.SBT": { + "symbolID": "SUFPNB----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.NAV.SSSNR": { + "symbolID": "SUFPNN----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.GRD": { + "symbolID": "SUFPG-----*****", + "tag": "WAR" + }, + "WAR.SOFUNT.GRD.SOF": { + "symbolID": "SUFPGS----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.GRD.RGR": { + "symbolID": "SUFPGR----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.GRD.PSYOP": { + "symbolID": "SUFPGP----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.GRD.PSYOP.FIXAVN": { + "symbolID": "SUFPGPA---*****", + "tag": "GRD" + }, + "WAR.SOFUNT.GRD.CVLAFF": { + "symbolID": "SUFPGC----*****", + "tag": "SOFUNT" + }, + "WAR.SOFUNT.SUP": { + "symbolID": "SUFPB-----*****", + "tag": "WAR" + } }, - "STBOPS.ITM.VRLRPS": { - "symbolID": "OUIPV-----*****", - "tag": "STBOPS" + + // Task point Tactical Graphics + "task": { + "TACGRP.TSK.DSTY": { + "symbolID": "GUTPD-----****X", + "tag": "TACGRP" + }, + "TACGRP.TSK.ITDT": { + "symbolID": "GUTPI-----****X", + "tag": "TACGRP" + }, + "TACGRP.TSK.NEUT": { + "symbolID": "GUTPN-----****X", + "tag": "TACGRP" + } + }, + + // Command Control General Maneuver point Tactical Graphics + "c2gm": { + "TACGRP.C2GM.GNL.PNT.REFPNT": { + "symbolID": "GUGPGPR---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.NAVREF": { + "symbolID": "GUGPGPRN--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.SPLPNT": { + "symbolID": "GUGPGPRS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.DLRP": { + "symbolID": "GUGPGPRD--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.PIM": { + "symbolID": "GUGPGPRP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.MRSH": { + "symbolID": "GUGPGPRM--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.WAP": { + "symbolID": "GUGPGPRW--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.CRDRTB": { + "symbolID": "GUGPGPRC--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.REFPNT.PNTINR": { + "symbolID": "GUGPGPRI--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.AIMPNT": { + "symbolID": "GUGPGPWA--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.DRPPNT": { + "symbolID": "GUGPGPWD--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.ENTPNT": { + "symbolID": "GUGPGPWE--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.GRDZRO": { + "symbolID": "GUGPGPWG--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.MSLPNT": { + "symbolID": "GUGPGPWM--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.IMTPNT": { + "symbolID": "GUGPGPWI--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.WPN.PIPNT": { + "symbolID": "GUGPGPWP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.FRMN": { + "symbolID": "GUGPGPF---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.HBR": { + "symbolID": "GUGPGPH---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.HBR.PNTQ": { + "symbolID": "GUGPGPHQ--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.HBR.PNTA": { + "symbolID": "GUGPGPHA--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.HBR.PNTX": { + "symbolID": "GUGPGPHX--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE": { + "symbolID": "GUGPGPO---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE.RDV": { + "symbolID": "GUGPGPOZ--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE.DVSN": { + "symbolID": "GUGPGPOD--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE.WAP": { + "symbolID": "GUGPGPOW--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE.PIM": { + "symbolID": "GUGPGPOP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.RTE.PNTR": { + "symbolID": "GUGPGPOR--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT": { + "symbolID": "GUGPGPP---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.CHKPNT": { + "symbolID": "GUGPGPPK--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.CONPNT": { + "symbolID": "GUGPGPPC--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.CRDPNT": { + "symbolID": "GUGPGPPO--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.DCNPNT": { + "symbolID": "GUGPGPPD--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.LNKUPT": { + "symbolID": "GUGPGPPL--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.PSSPNT": { + "symbolID": "GUGPGPPP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.RAYPNT": { + "symbolID": "GUGPGPPR--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.RELPNT": { + "symbolID": "GUGPGPPE--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.STRPNT": { + "symbolID": "GUGPGPPS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.AMNPNT": { + "symbolID": "GUGPGPPA--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTPNT.WAP": { + "symbolID": "GUGPGPPW--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.TGTREF": { + "symbolID": "GUGPDPT---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST": { + "symbolID": "GUGPDPO---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST.CBTPST": { + "symbolID": "GUGPDPOC--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST.RECON": { + "symbolID": "GUGPDPOR--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST.FWDOP": { + "symbolID": "GUGPDPOF--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST.SOP": { + "symbolID": "GUGPDPOS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.DEF.PNT.OBSPST.CBRN": { + "symbolID": "GUGPDPON--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.OFF.PNT.PNTD": { + "symbolID": "GUGPOPP---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.AVN.PNT.ACP": { + "symbolID": "GUGPAPP---****X", + "tag": "TACGRP", + "specialModifiers": [ "altitudeDepth", "routeName", "routeSequenceNum" ] + }, + "TACGRP.C2GM.AVN.PNT.COMMCP": { + "symbolID": "GUGPAPC---****X", + "tag": "TACGRP", + "specialModifiers": [ "altitudeDepth", "routeName", "routeSequenceNum" ] + }, + "TACGRP.C2GM.AVN.PNT.PUP": { + "symbolID": "GUGPAPU---****X", + "tag": "TACGRP", + "specialModifiers": [ "altitudeDepth", "routeName", "routeSequenceNum" ] + }, + "TACGRP.C2GM.AVN.PNT.DAPP": { + "symbolID": "GUGPAPD---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.UH2.DTM": { + "symbolID": "GUGPGPUUD-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.UH2.BCON": { + "symbolID": "GUGPGPUUB-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.UH2.LCON": { + "symbolID": "GUGPGPUUL-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.UH2.DTM": { + "symbolID": "GUGPGPUUD-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.UH2.SNK": { + "symbolID": "GUGPGPUUS-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY": { + "symbolID": "GUGPGPUY--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.PTNCTR": { + "symbolID": "GUGPGPUYP-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.DIFAR": { + "symbolID": "GUGPGPUYD-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.LOFAR": { + "symbolID": "GUGPGPUYL-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.CASS": { + "symbolID": "GUGPGPUYC-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.DICASS": { + "symbolID": "GUGPGPUYS-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.BT": { + "symbolID": "GUGPGPUYB-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.ANM": { + "symbolID": "GUGPGPUYA-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.VLAD": { + "symbolID": "GUGPGPUYV-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.ATAC": { + "symbolID": "GUGPGPUYT-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.RO": { + "symbolID": "GUGPGPUYR-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.KGP": { + "symbolID": "GUGPGPUYK-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SNBY.EXP": { + "symbolID": "GUGPGPUYX-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SRH": { + "symbolID": "GUGPGPUS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SRH.ARA": { + "symbolID": "GUGPGPUSA-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SRH.DIPPSN": { + "symbolID": "GUGPGPUSD-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.USW.SRH.CTR": { + "symbolID": "GUGPGPUSC-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL": { + "symbolID": "GUGPGPA---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.CAP": { + "symbolID": "GUGPGPAP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ABNEW": { + "symbolID": "GUGPGPAW--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.TAK": { + "symbolID": "GUGPGPAK--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ASBWF": { + "symbolID": "GUGPGPAA--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ASBWR": { + "symbolID": "GUGPGPAH--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.SUWF": { + "symbolID": "GUGPGPAB--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.SUWR": { + "symbolID": "GUGPGPAC--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.MIWF": { + "symbolID": "GUGPGPAD--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.MIWR": { + "symbolID": "GUGPGPAE--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.SKEIP": { + "symbolID": "GUGPGPAS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.TCN": { + "symbolID": "GUGPGPAT--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.TMC": { + "symbolID": "GUGPGPAO--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.RSC": { + "symbolID": "GUGPGPAR--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.RPH": { + "symbolID": "GUGPGPAL--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.UA": { + "symbolID": "GUGPGPAF--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.VTUA": { + "symbolID": "GUGPGPAG--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ORB": { + "symbolID": "GUGPGPAI--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ORBF8": { + "symbolID": "GUGPGPAJ--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ORBRT": { + "symbolID": "GUGPGPAM--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.ACTL.ORBRD": { + "symbolID": "GUGPGPAN--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL": { + "symbolID": "GUGPGPC---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.USV": { + "symbolID": "GUGPGPCU--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.USV.RMV": { + "symbolID": "GUGPGPCUR-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.USV.ASW": { + "symbolID": "GUGPGPCUA-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.USV.SUW": { + "symbolID": "GUGPGPCUS-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.USV.MIW": { + "symbolID": "GUGPGPCUM-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.ASW": { + "symbolID": "GUGPGPCA--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.SUW": { + "symbolID": "GUGPGPCS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.MIW": { + "symbolID": "GUGPGPCM--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.PKT": { + "symbolID": "GUGPGPCP--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.RDV": { + "symbolID": "GUGPGPCR--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.RSC": { + "symbolID": "GUGPGPCC--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.REP": { + "symbolID": "GUGPGPCE--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.SCTL.NCBTT": { + "symbolID": "GUGPGPCN--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL": { + "symbolID": "GUGPGPB---****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.UUV": { + "symbolID": "GUGPGPBU--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.UUV.ASW": { + "symbolID": "GUGPGPBUA-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.UUV.SUW": { + "symbolID": "GUGPGPBUS-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.UUV.MIW": { + "symbolID": "GUGPGPBUM-****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.SBSTN": { + "symbolID": "GUGPGPBS--****X", + "tag": "TACGRP" + }, + "TACGRP.C2GM.GNL.PNT.UCTL.SBSTN.ASW": { + "symbolID": "GUGPGPBSA-****X", + "tag": "TACGRP" + } + }, + + // Mobility/Survivability point Tactical Graphics + "mobsu": { + "TACGRP.MOBSU.OBST.ATO.TDTSM.FIXPFD": { + "symbolID": "GUMPOAOF--****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.ATO.TDTSM.MVB": { + "symbolID": "GUMPOAOM--****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.ATO.TDTSM.MVBPFD": { + "symbolID": "GUMPOAOP--****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.BBY": { + "symbolID": "GUMPOB----****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.USPMNE": { + "symbolID": "GUMPOMU---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.ATMNE": { + "symbolID": "GUMPOMT---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.ATMAHD": { + "symbolID": "GUMPOMD---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.ATMDIR": { + "symbolID": "GUMPOME---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.APMNE": { + "symbolID": "GUMPOMP---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBST.MNE.WAMNE": { + "symbolID": "GUMPOMW---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.ERP": { + "symbolID": "GUMPBCP---****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.SU.ESTOF": { + "symbolID": "GUMPSE----****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.SU.FRT": { + "symbolID": "GUMPSF----****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.SU.SUFSHL": { + "symbolID": "GUMPSS----****X", + "tag": "TACGRP" + }, + "TACGRP.MOBSU.SU.UGDSHL": { + "symbolID": "GUMPSU----****X", + "tag": "TACGRP" + } }, - "STBOPS.ITM.KNIVEH": { - "symbolID": "OUIPI-----*****", - "tag": "STBOPS" + + // Fire Support point Tactical Graphics + "fsupp": { + "TACGRP.FSUPP.PNT.TGT.PTGT": { + "symbolID": "GUFPPTS---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.TGT.NUCTGT": { + "symbolID": "GUFPPTN---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.FSS": { + "symbolID": "GUFPPCF---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.SCP": { + "symbolID": "GUFPPCS---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.FP": { + "symbolID": "GUFPPCB---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.RP": { + "symbolID": "GUFPPCR---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.HP": { + "symbolID": "GUFPPCH---****X", + "tag": "TACGRP" + }, + "TACGRP.FSUPP.PNT.C2PNT.LP": { + "symbolID": "GUFPPCL---****X", + "tag": "TACGRP" + } + }, + + // Combat Service Support point Tactical Graphics + "css": { + "TACGRP.CSS.PNT.AEP": { + "symbolID": "GUSPPX----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.CBNP": { + "symbolID": "GUSPPC----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.CCP": { + "symbolID": "GUSPPY----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.CVP": { + "symbolID": "GUSPPT----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.DCP": { + "symbolID": "GUSPPD----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.EPWCP": { + "symbolID": "GUSPPE----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.LRP": { + "symbolID": "GUSPPL----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.MCP": { + "symbolID": "GUSPPM----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.RRRP": { + "symbolID": "GUSPPR----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.ROM": { + "symbolID": "GUSPPU----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.TCP": { + "symbolID": "GUSPPO----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.TTP": { + "symbolID": "GUSPPI----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.UMC": { + "symbolID": "GUSPPN----****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.GNL": { + "symbolID": "GUSPPSZ---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS1": { + "symbolID": "GUSPPSA---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS2": { + "symbolID": "GUSPPSB---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS3": { + "symbolID": "GUSPPSC---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS4": { + "symbolID": "GUSPPSD---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS5": { + "symbolID": "GUSPPSE---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS6": { + "symbolID": "GUSPPSF---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS7": { + "symbolID": "GUSPPSG---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS8": { + "symbolID": "GUSPPSH---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS9": { + "symbolID": "GUSPPSI---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.SPT.CLS10": { + "symbolID": "GUSPPSJ---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.AP.ASP": { + "symbolID": "GUSPPAS---****X", + "tag": "TACGRP" + }, + "TACGRP.CSS.PNT.AP.ATP": { + "symbolID": "GUSPPAT---****X", + "tag": "TACGRP" + } + }, + + // Stabilizing Operations point graphics + "stbops": { + "STBOPS.VIOATY.ASN": { + "symbolID": "OUVPA-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.KILL": { + "symbolID": "OUVPM-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.KILL.MDR": { + "symbolID": "OUVPMA----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.KILL.EX": { + "symbolID": "OUVPMB----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.KILL.ASS": { + "symbolID": "OUVPMC----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.BM": { + "symbolID": "OUVPB-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.BBY": { + "symbolID": "OUVPY-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.DBS": { + "symbolID": "OUVPD-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.SPG": { + "symbolID": "OUVPS-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.PSNG": { + "symbolID": "OUVPP-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.EXPLSN": { + "symbolID": "OUVPE-----*****", + "tag": "STBOPS" + }, + "STBOPS.VIOATY.EXPLSN.EXPLSN": { + "symbolID": "OUVPEI----*****", + "tag": "STBOPS" + }, + "STBOPS.LOCAT.BLST": { + "symbolID": "OULPB-----*****", + "tag": "STBOPS" + }, + "STBOPS.LOCAT.GLST": { + "symbolID": "OULPG-----*****", + "tag": "STBOPS" + }, + "STBOPS.LOCAT.WLST": { + "symbolID": "OULPW-----*****", + "tag": "STBOPS" + }, + "STBOPS.LOCAT.MASS": { + "symbolID": "OULPM-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.PATG": { + "symbolID": "OUOPP-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.RECMT.WLG": { + "symbolID": "OUOPRW----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.RECMT.CRCD": { + "symbolID": "OUOPRC----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.DEMO": { + "symbolID": "OUOPD-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.ML": { + "symbolID": "OUOPM-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.PSYOP": { + "symbolID": "OUOPY-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.PSYOP.TARP": { + "symbolID": "OUOPYT----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.PSYOP.WP": { + "symbolID": "OUOPYW----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.PSYOP.HTHP": { + "symbolID": "OUOPYH----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.FRGSRH": { + "symbolID": "OUOPF-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.SPY": { + "symbolID": "OUOPS-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.FDDIST": { + "symbolID": "OUOPO-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.EXTN": { + "symbolID": "OUOPE-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.HJKG.VEH": { + "symbolID": "OUOPHT----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.HJKG.APL": { + "symbolID": "OUOPHA----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.HJKG.BOAT": { + "symbolID": "OUOPHV----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.KDNG": { + "symbolID": "OUOPK-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.KDNG.ATEMPT": { + "symbolID": "OUOPKA----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.ARR": { + "symbolID": "OUOPA-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.DGOPN": { + "symbolID": "OUOPU-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.CMPLSS": { + "symbolID": "OUOPC-----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.CMPLSS.COMBAT": { + "symbolID": "OUOPCA----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.CMPLSS.ACCDNT": { + "symbolID": "OUOPCB----*****", + "tag": "STBOPS" + }, + "STBOPS.OPN.CMPLSS.OTHER": { + "symbolID": "OUOPCC----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.RFG": { + "symbolID": "OUIPR-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.SAFHSE": { + "symbolID": "OUIPS-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.GRF": { + "symbolID": "OUIPG-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.VRLRPS": { + "symbolID": "OUIPV-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.KNIVEH": { + "symbolID": "OUIPI-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.DGVEH": { + "symbolID": "OUIPD-----*****", + "tag": "STBOPS" + }, + "STBOPS.ITM.ISF": { + "symbolID": "OUIPF-----*****", + "tag": "STBOPS" + }, + "STBOPS.INDIV": { + "symbolID": "OUPP------*****", + "tag": "STBOPS" + }, + "STBOPS.INDIV.LEADER": { + "symbolID": "OUPPA-----*****", + "tag": "STBOPS" + }, + "STBOPS.INDIV.TRGTD": { + "symbolID": "OUPPB-----*****", + "tag": "STBOPS" + }, + "STBOPS.INDIV.TERRST": { + "symbolID": "OUPPC-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG": { + "symbolID": "OUGP------*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.DPRE": { + "symbolID": "OUGPA-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.NGO": { + "symbolID": "OUGPB-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.TERRST": { + "symbolID": "OUGPC-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.RELIGS": { + "symbolID": "OUGPD-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.FNFGHT": { + "symbolID": "OUGPE-----*****", + "tag": "STBOPS" + }, + "STBOPS.GRPORG.GANG": { + "symbolID": "OUGPF-----*****", + "tag": "STBOPS" + }, + "STBOPS.RAPE": { + "symbolID": "OURP------*****", + "tag": "STBOPS" + }, + "STBOPS.RAPE.ATEMPT": { + "symbolID": "OURPA-----*****", + "tag": "STBOPS" + } + }, + + // Emergency Management Services point graphics + "ems": { + "EMS.INCDNT.CVDIS": { + "symbolID": "EUIPA-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CVDIS.DEMO": { + "symbolID": "O*O*D-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT": { + "symbolID": "EUIPB-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.BMTTHT": { + "symbolID": "EUIPBA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.BM": { + "symbolID": "OUVPB-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.EXPLN": { + "symbolID": "EUIPBC----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.LOOT": { + "symbolID": "EUIPBD----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.PSNG": { + "symbolID": "OUVPP-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.CRMACT.SHTG": { + "symbolID": "EUIPBF----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE": { + "symbolID": "EUIPC-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.HTSPT": { + "symbolID": "EUIPCA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.NRES": { + "symbolID": "EUIPCB----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.ORGN": { + "symbolID": "EUIPCC----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.RES": { + "symbolID": "EUIPCD----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.SCH": { + "symbolID": "EUIPCE----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.SMK": { + "symbolID": "EUIPCF----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.SN": { + "symbolID": "EUIPCG----*****", + "tag": "EMS" + }, + "EMS.INCDNT.FIRE.WLD": { + "symbolID": "EUIPCH----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT": { + "symbolID": "EUIPD-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.CHMAGT": { + "symbolID": "EUIPDA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.CORMTL": { + "symbolID": "EUIPDB----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.WHWET": { + "symbolID": "EUIPDC----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.EXPLV": { + "symbolID": "EUIPDD----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.FLGAS": { + "symbolID": "EUIPDE----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.FLLIQ": { + "symbolID": "EUIPDF----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.FLSLD": { + "symbolID": "EUIPDG----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.NFLGAS": { + "symbolID": "EUIPDH----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.ORGPER": { + "symbolID": "EUIPDI----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.OXDZR": { + "symbolID": "EUIPDJ----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.RADMTL": { + "symbolID": "EUIPDK----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.SPCMB": { + "symbolID": "EUIPDL----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.TXGAS": { + "symbolID": "EUIPDM----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.TXINF": { + "symbolID": "EUIPDN----*****", + "tag": "EMS" + }, + "EMS.INCDNT.HAZMAT.UNXORD": { + "symbolID": "EUIPDO----*****", + "tag": "EMS" + }, + "EMS.INCDNT.AIR": { + "symbolID": "EUIPE-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.AIR.ACDNT": { + "symbolID": "EUIPEA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.AIR.HJKG": { + "symbolID": "OUOPHA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.MRN": { + "symbolID": "EUIPF-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.MRN.ACDNT": { + "symbolID": "EUIPFA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.MRN.HJKNG": { + "symbolID": "OUOPHV----*****", + "tag": "EMS" + }, + "EMS.INCDNT.RAIL": { + "symbolID": "EUIPG-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.RAIL.ACDNT": { + "symbolID": "EUIPGA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.RAIL.HJKG": { + "symbolID": "EUIPGB----*****", + "tag": "EMS" + }, + "EMS.INCDNT.VEH": { + "symbolID": "EUIPH-----*****", + "tag": "EMS" + }, + "EMS.INCDNT.VEH.ACDNT": { + "symbolID": "EUIPHA----*****", + "tag": "EMS" + }, + "EMS.INCDNT.VEH.HJKG": { + "symbolID": "OUOPHT----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.AFTSHK": { + "symbolID": "EUNPAA----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.AVL": { + "symbolID": "EUNPAB----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.EQKEPI": { + "symbolID": "EUNPAC----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.LNDSLD": { + "symbolID": "EUNPAD----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.SBSDNC": { + "symbolID": "EUNPAE----*****", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.VOLERN": { + "symbolID": "WAS-WSVE--P----", + "tag": "EMS" + }, + "EMS.NATEVT.GEO.VLCTHT": { + "symbolID": "EUNPAG----*****", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.DZ": { + "symbolID": "WAS-WSD-LIP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.DRGHT": { + "symbolID": "EUNPBB----*****", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.FLD": { + "symbolID": "EUNPBC----*****", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.FG": { + "symbolID": "WAS-WSFGSOP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.HL": { + "symbolID": "WAS-WSGRL-P----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.INV": { + "symbolID": "EUNPBF----*****", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.RA": { + "symbolID": "WAS-WSR-LIP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.DT/SD": { + "symbolID": "WAS-WSDSLMP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.SN": { + "symbolID": "WAS-WSS-LIP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.TSTRM": { + "symbolID": "WAS-WSTMH-P----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.TNDO": { + "symbolID": "WAS-WST-FCP----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.TRPCYC": { + "symbolID": "WAS-WSTSS-P----", + "tag": "EMS" + }, + "EMS.NATEVT.HYDMET.TSNMI": { + "symbolID": "EUNPBM----*****", + "tag": "EMS" + }, + "EMS.NATEVT.INFST.BIRD": { + "symbolID": "EUNPCA----*****", + "tag": "EMS" + }, + "EMS.NATEVT.INFST.INSCT": { + "symbolID": "EUNPCB----*****", + "tag": "EMS" + }, + "EMS.NATEVT.INFST.MICROB": { + "symbolID": "EUNPCC----*****", + "tag": "EMS" + }, + "EMS.NATEVT.INFST.REPT": { + "symbolID": "EUNPCD----*****", + "tag": "EMS" + }, + "EMS.NATEVT.INFST.RDNT": { + "symbolID": "EUNPCE----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED": { + "symbolID": "EUOPA-----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.UNT": { + "symbolID": "EUOPAA----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.EQPT": { + "symbolID": "EUOPAB----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.INS": { + "symbolID": "EUOPAC----H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.EMTLOC": { + "symbolID": "EUOPAD----H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.AMBLNC": { + "symbolID": "EUOPAE----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.MEH": { + "symbolID": "EUOPAF----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.HDF": { + "symbolID": "EUOPAG----H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.HSP": { + "symbolID": "SUGPIXH---H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.HSPSHP": { + "symbolID": "SUSPNM----*****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.MFOP": { + "symbolID": "EUOPAJ----H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.RX": { + "symbolID": "EUOPAL----H****", + "tag": "EMS" + }, + "EMS.OPN.EMMED.TRIAGE": { + "symbolID": "EUOPAM----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN": { + "symbolID": "EUOPB-----*****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.UNT": { + "symbolID": "EUOPBA----*****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EQPT": { + "symbolID": "EUOPBB----*****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.INS": { + "symbolID": "EUOPBC----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.ECEP": { + "symbolID": "EUOPBD----*****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EICC": { + "symbolID": "EUOPBE----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EOC": { + "symbolID": "EUOPBF----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EPIC": { + "symbolID": "EUOPBG----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EMSHLT": { + "symbolID": "EUOPBH----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.ESA": { + "symbolID": "EUOPBI----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EMTM": { + "symbolID": "EUOPBJ----*****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.EWDC": { + "symbolID": "EUOPBK----H****", + "tag": "EMS" + }, + "EMS.OPN.EMOPN.FDDIST": { + "symbolID": "EUOPBL----H****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT": { + "symbolID": "EUOPC-----*****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT.FIRFTU": { + "symbolID": "EUOPCA----*****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT.FIRFTE": { + "symbolID": "EUOPCB----*****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT.FIRHYD": { + "symbolID": "EUOPCC----*****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT.OTHH2O": { + "symbolID": "EUOPCD----H****", + "tag": "EMS" + }, + "EMS.OPN.FIRFT.FIRSTN": { + "symbolID": "EUOPCE----H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF": { + "symbolID": "EUOPD-----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.LAWENU": { + "symbolID": "EUOPDA----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.LAWENE": { + "symbolID": "EUOPDB----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.LAWENI": { + "symbolID": "EUOPDC----H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.ATF": { + "symbolID": "EUOPDD----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.ATF.ATFUNT": { + "symbolID": "EUOPDDA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.ATF.ATFEQP": { + "symbolID": "EUOPDDB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.ATF.ATFINS": { + "symbolID": "EUOPDDC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.BDRPT": { + "symbolID": "EUOPDE----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.BDRPT.BDRPTU": { + "symbolID": "EUOPDEA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.BDRPT.BDRPTE": { + "symbolID": "EUOPDEB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.BDRPT.BDRPTI": { + "symbolID": "EUOPDEC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTM": { + "symbolID": "EUOPDF----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTM.CSTMUN": { + "symbolID": "EUOPDFA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTM.CSTMEQ": { + "symbolID": "EUOPDFB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTM.CSTMIN": { + "symbolID": "EUOPDFC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DEA": { + "symbolID": "EUOPDG----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DEA.DEAUNT": { + "symbolID": "EUOPDGA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DEA.DEAEQP": { + "symbolID": "EUOPDGB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DEA.DEAINS": { + "symbolID": "EUOPDGC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DOJ": { + "symbolID": "EUOPDH----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DOJ.DOJUNT": { + "symbolID": "EUOPDHA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DOJ.DOJEQP": { + "symbolID": "EUOPDHB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.DOJ.DOJINS": { + "symbolID": "EUOPDHC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.FBI": { + "symbolID": "EUOPDI----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.FBI.FBIUNT": { + "symbolID": "EUOPDIA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.FBI.FBIEQP": { + "symbolID": "EUOPDIB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.FBI.FBIINS": { + "symbolID": "EUOPDIC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.POL": { + "symbolID": "EUOPDJ----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.POL.POLEQP": { + "symbolID": "EUOPDJB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.POL.POLINS": { + "symbolID": "EUOPDJC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.PRSN": { + "symbolID": "EUOPDK----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.SECSR": { + "symbolID": "EUOPDL----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.SECSR.SECSRU": { + "symbolID": "EUOPDLA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.SECSR.SECSRE": { + "symbolID": "EUOPDLB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.SECSR.SECSRI": { + "symbolID": "EUOPDLC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.TSA": { + "symbolID": "EUOPDM----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.TSA.TSAUNT": { + "symbolID": "EUOPDMA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.TSA.TSAEQP": { + "symbolID": "EUOPDMB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.TSA.TSAINS": { + "symbolID": "EUOPDMC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTGD": { + "symbolID": "EUOPDN----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTGD.CSTGDU": { + "symbolID": "EUOPDNA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTGD.CSTGDE": { + "symbolID": "SUSPXL----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.CSTGD.CSTGDI": { + "symbolID": "EUOPDNC---H****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.USMAR": { + "symbolID": "EUOPDO----*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.USMAR.USMARU": { + "symbolID": "EUOPDOA---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.USMAR.USMARE": { + "symbolID": "EUOPDOB---*****", + "tag": "EMS" + }, + "EMS.OPN.LAWENF.USMAR.USMARI": { + "symbolID": "EUOPDOC---H****", + "tag": "EMS" + }, + "EMS.OPN.SNS": { + "symbolID": "SUGPES----*****", + "tag": "EMS" + }, + "EMS.OPN.SNS.BIO": { + "symbolID": "EUOPEA----*****", + "tag": "EMS" + }, + "EMS.OPN.SNS.CML": { + "symbolID": "EUOPEB----*****", + "tag": "EMS" + }, + "EMS.OPN.SNS.INT": { + "symbolID": "EUOPEC----*****", + "tag": "EMS" + }, + "EMS.OPN.SNS.NUC": { + "symbolID": "EUOPED----*****", + "tag": "EMS" + }, + "EMS.OPN.SNS.RAD": { + "symbolID": "EUOPEE----*****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD": { + "symbolID": "EUFPA-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.AGLAB": { + "symbolID": "EUFPAA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.AFL": { + "symbolID": "EUFPAB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.CFDC": { + "symbolID": "EUFPAC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.FRMRNC": { + "symbolID": "EUFPAD----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.FPC": { + "symbolID": "EUFPAE----H****", + "tag": "EMS" + }, + "EMS.INFSTR.AGFD.FDRTL": { + "symbolID": "EUFPAF----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI": { + "symbolID": "EUFPB-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI.ATM": { + "symbolID": "EUFPBA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI.BANK": { + "symbolID": "EUFPBB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI.BLSTR": { + "symbolID": "EUFPBC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI.FRB": { + "symbolID": "EUFPBD----H****", + "tag": "EMS" + }, + "EMS.INFSTR.BFI.FINEX": { + "symbolID": "EUFPBE----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL": { + "symbolID": "EUFPC-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.CMPLN": { + "symbolID": "EUFPCA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.FIRMAN": { + "symbolID": "EUFPCB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.FIRRET": { + "symbolID": "EUFPCC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.HZMTPR": { + "symbolID": "EUFPCD----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.HZMTST": { + "symbolID": "EUFPCE----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.INDSTE": { + "symbolID": "EUFPCF----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.LNDFL": { + "symbolID": "EUFPCG----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.RXMFG": { + "symbolID": "EUFPCH----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.CHWS": { + "symbolID": "EUFPCI----H****", + "tag": "EMS" + }, + "EMS.INFSTR.CMCL.TXRLIN": { + "symbolID": "EUFPCJ----H****", + "tag": "EMS" + }, + "EMS.INFSTR.EDFAC": { + "symbolID": "EUFPD-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.EDFAC.COLLUNI": { + "symbolID": "EUFPDA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.EDFAC.SCHOOL": { + "symbolID": "EUFPDB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC": { + "symbolID": "SUGPIUE---H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC.GENSTA": { + "symbolID": "EUFPEA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC.NTLGAS": { + "symbolID": "EUFPEB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC.NUCFAC": { + "symbolID": "SUGPIUEN--H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC.PETFAC": { + "symbolID": "SUGPIRP---H****", + "tag": "EMS" + }, + "EMS.INFSTR.ENGFAC.PROPNE": { + "symbolID": "EUFPEE----H****", + "tag": "EMS" + }, + "EMS.INFSTR.GVTSTE": { + "symbolID": "EUFPF-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.MIL": { + "symbolID": "EUFPG-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.MIL.ARMORY": { + "symbolID": "EUFPGA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.MIL.MILBF": { + "symbolID": "SUGPIB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PSTSRV": { + "symbolID": "EUFPH-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PSTSRV.PDC": { + "symbolID": "EUFPHA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PSTSRV.PO": { + "symbolID": "EUFPHB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PUBVEN": { + "symbolID": "EUFPI-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PUBVEN.ENCFAC": { + "symbolID": "EUFPIA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PUBVEN.OPNFAC": { + "symbolID": "EUFPIB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PUBVEN.RECARE": { + "symbolID": "EUFPIC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.PUBVEN.RELIG": { + "symbolID": "EUFPID----H****", + "tag": "EMS" + }, + "EMS.INFSTR.SPCNDS": { + "symbolID": "EUFPJ-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.SPCNDS.ADLTDC": { + "symbolID": "EUFPJA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.SPCNDS.CHLDDC": { + "symbolID": "EUFPJB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.SPCNDS.ELDERC": { + "symbolID": "EUFPJC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TELCOM": { + "symbolID": "EUFPK-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TELCOM.TCF": { + "symbolID": "SUGPIUT---H****", + "tag": "EMS" + }, + "EMS.INFSTR.TELCOM.TCTWR": { + "symbolID": "EUFPKB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP": { + "symbolID": "EUFPL-----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.ATCF": { + "symbolID": "EUFPLA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.AIRPT": { + "symbolID": "SUGPIBA---H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.BRG": { + "symbolID": "G*M*BCB---H***X", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.BSTN": { + "symbolID": "EUFPLD----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.FRYTRM": { + "symbolID": "EUFPLE----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.HLS": { + "symbolID": "EUFPLF----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.LCK": { + "symbolID": "WOS-ML----P----", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.MAINTF": { + "symbolID": "EUFPLH----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.SP": { + "symbolID": "SUGPIBN---H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.RLSTN": { + "symbolID": "EUFPLJ----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.RSTSTP": { + "symbolID": "EUFPLI----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.ANCRG": { + "symbolID": "WOS-HPBA--P----", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.TOLLF": { + "symbolID": "EUFPLM----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.TCP": { + "symbolID": "GUSPPO----H***X", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.TIF": { + "symbolID": "EUFPLO----H****", + "tag": "EMS" + }, + "EMS.INFSTR.TSP.TNL": { + "symbolID": "EUFPLP----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS": { + "symbolID": "SUGPIUP---H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.CV": { + "symbolID": "EUFPMA----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.DAM": { + "symbolID": "EUFPMB----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.DO": { + "symbolID": "EUFPMC----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.GWWELL": { + "symbolID": "EUFPMD----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.PMPSTN": { + "symbolID": "EUFPME----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.RSVR": { + "symbolID": "EUFPMF----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.STRTWR": { + "symbolID": "EUFPMG----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.SWI": { + "symbolID": "EUFPMH----H****", + "tag": "EMS" + }, + "EMS.INFSTR.WS.WH2OTF": { + "symbolID": "EUFPMI----H****", + "tag": "EMS" + } }, - "STBOPS.ITM.DGVEH": { - "symbolID": "OUIPD-----*****", - "tag": "STBOPS" + + "sigint": { + "SIGINT.SPC.SIGINC.COMM.SATDL": { + "symbolID": "IUPPSCD-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.ERHSVL": { + "symbolID": "IUPPSRE-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.IFF": { + "symbolID": "IUPPSRI-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.MFN": { + "symbolID": "IUPPSRM-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.TGTAQ": { + "symbolID": "IUPPSRT-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.SPC": { + "symbolID": "IUPPSRS-----***", + "tag": "SIGINC" + }, + "SIGINT.SPC.SIGINC.RAD.UNK": { + "symbolID": "IUPPSRU-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.COMM.CELL": { + "symbolID": "IUAPSCC-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.COMM.OLOS": { + "symbolID": "IUAPSCO-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.COMM.PIPLOS": { + "symbolID": "IUAPSCP-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.COMM.SATUL": { + "symbolID": "IUAPSCS-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.ABNINC": { + "symbolID": "IUAPSRAI----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.ABNSB": { + "symbolID": "IUAPSRAS----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.CTDINC": { + "symbolID": "IUAPSRC-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.DATTMN": { + "symbolID": "IUAPSRD-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.EW": { + "symbolID": "IUAPSRE-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.FIRCTL": { + "symbolID": "IUAPSRF-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.IFF": { + "symbolID": "IUAPSRI-----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.MSLAQ": { + "symbolID": "IUAPSRMA----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.MSLDL": { + "symbolID": "IUAPSRMD----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.MSLGDN": { + "symbolID": "IUAPSRMG----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.MSLTRK": { + "symbolID": "IUAPSRMT----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.MFN": { + "symbolID": "IUAPSRMF----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.TGTILL": { + "symbolID": "IUAPSRTI----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.TGTAQ": { + "symbolID": "IUAPSRTA----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.TGTTRK": { + "symbolID": "IUAPSRTT----***", + "tag": "SIGINC" + }, + "SIGINT.AIRTRK.SIGINC.RAD.UNK": { + "symbolID": "IUAPSRU-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.COMM.CELL": { + "symbolID": "IUGPSCC-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.COMM.OLOS": { + "symbolID": "IUGPSCO-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.COMM.PTPLOS": { + "symbolID": "IUGPSCP-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.COMM.SATUL": { + "symbolID": "IUGPSCS-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.COMM.TPSSCT": { + "symbolID": "IUGPSCT-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.ATCTL": { + "symbolID": "IUGPSRAT----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.AA/C": { + "symbolID": "IUGPSRAA----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.BTFSVL": { + "symbolID": "IUGPSRB-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.CSTSVL": { + "symbolID": "IUGPSRCS----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.CTDAPP": { + "symbolID": "IUGPSRCA----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.DATTMN": { + "symbolID": "IUGPSRD-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.EW": { + "symbolID": "IUGPSRE-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.FIRCTL": { + "symbolID": "IUGPSRF-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.HGTFDG": { + "symbolID": "IUGPSRH-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.IDIFF": { + "symbolID": "IUGPSRI-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.METO": { + "symbolID": "IUGPSRMM----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.MSLAQ": { + "symbolID": "IUGPSRMA----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.MSLGDN": { + "symbolID": "IUGPSRMG----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.MSLTRK": { + "symbolID": "IUGPSRMT----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.MFN": { + "symbolID": "IUGPSRMF----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.SHETKG": { + "symbolID": "IUGPSRS-----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.TGTAQ": { + "symbolID": "IUGPSRTA----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.TGTILL": { + "symbolID": "IUGPSRTI----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.TGTTRK": { + "symbolID": "IUGPSRTT----***", + "tag": "SIGINC" + }, + "SIGINT.GRDTRK.SIGINC.RAD.UNK": { + "symbolID": "IUGPSRU-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.COMM.CELL": { + "symbolID": "IUSPSCC-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.COMM.OLOS": { + "symbolID": "IUSPSCO-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.COMM.PTPLOS": { + "symbolID": "IUSPSCP-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.COMM.SATUL": { + "symbolID": "IUSPSCS-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.ATCTL": { + "symbolID": "IUSPSRAT----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.AA/C": { + "symbolID": "IUSPSRAA----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.CTDAPP": { + "symbolID": "IUSPSRCA----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.DATTMN": { + "symbolID": "IUSPSRD-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.EW": { + "symbolID": "IUSPSRE-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.FIRCTL": { + "symbolID": "IUSPSRF-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.HGTFDG": { + "symbolID": "IUSPSRH-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.IDIFF": { + "symbolID": "IUSPSRI-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.METO": { + "symbolID": "IUSPSRMM----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.MSLAQ": { + "symbolID": "IUSPSRMA----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.MSLGDN": { + "symbolID": "IUSPSRMG----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.MSLTRK": { + "symbolID": "IUSPSRMT----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.MFN": { + "symbolID": "IUSPSRMF----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.SUFSRH": { + "symbolID": "IUSPSRS-----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.TGTAQ": { + "symbolID": "IUSPSRTA----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.TGTILL": { + "symbolID": "IUSPSRTI----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.TGTTRK": { + "symbolID": "IUSPSRTT----***", + "tag": "SIGINC" + }, + "SIGINT.SSUF.SIGINC.RAD.UNK": { + "symbolID": "IUSPSRU-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.COMM.OLOS": { + "symbolID": "IUUPSCO-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.COMM.PTPLOS": { + "symbolID": "IUUPSCP-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.COMM.SATUL": { + "symbolID": "IUUPSCS-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.DATTMN": { + "symbolID": "IUUPSRD-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.EW": { + "symbolID": "IUUPSRE-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.MFN": { + "symbolID": "IUUPSRM-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.SUFSRH": { + "symbolID": "IUUPSRS-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.TGTAQ": { + "symbolID": "IUUPSRT-----***", + "tag": "SIGINC" + }, + "SIGINT.SBSUF.SIGINC.RAD.UNK": { + "symbolID": "IUUPSRU-----***", + "tag": "SIGINC" + } }, - "STBOPS.ITM.ISF": { - "symbolID": "OUIPF-----*****", - "tag": "STBOPS" + + "tacticalTasks": { + "TACGRP.TSK.CNT": { + "symbolID": "G*TPJ-----****X", + "tag": "CONTAIN", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 50,100, 50,0, 100,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.BRH": { + "symbolID": "G*TPH-----****X", + "tag": "BREACH", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.BYS": { + "symbolID": "G*TPY-----****X", + "tag": "BYPASS", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.CNZ": { + "symbolID": "G*TPC-----****X", + "tag": "CANALIZE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.CLR": { + "symbolID": "G*TPX-----****X", + "tag": "CLEAR", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.PNE": { + "symbolID": "G*TPP-----****X", + "tag": "PENETRATE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.ISL": { + "symbolID": "G*TPE-----****X", + "tag": "ISOLATE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 50,50, 0,50, 0,100, 100,100 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.OCC": { + "symbolID": "G*TPO-----****X", + "tag": "OCCUPY", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 50,50, 0,50, 0,100, 100,100 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.SCE": { + "symbolID": "G*TPS-----****X", + "tag": "SECURE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 50,50, 0,50, 0,100, 100,100 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.RTN": { + "symbolID": "G*TPQ-----****X", + "tag": "RETAIN", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 50,50, 0,50, 0,100, 100,100 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.C2GM.GNL.ARS.SRHARA": { + "symbolID": "G*GPGAS---****X", + "tag": "RECONNAISSANCE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 10,40, 100,80, 100,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.FLWASS.FLWASS": { + "symbolID": "G*TPA-----****X", + "tag": "FOLLOW AND ASSUME", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,100, 100,0, 0,0 ], + "defaultDimensions": [100, 20], + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.TSK.FLWASS.FLWSUP": { + "symbolID": "G*TPAS----****X", + "tag": "FOLLOW AND SUPPORT", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,100, 100,0, 0,0 ], + "defaultDimensions": [100, 20], + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.TSK.SZE": { + "symbolID": "G*TPZ-----****X", + "tag": "SEIZE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 10,50, 100,90, 20,10 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.DLY": { + "symbolID": "G*TPL-----****X", + "tag": "DELAY", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 80,80, 80,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.RTM": { + "symbolID": "G*TPM-----****X", + "tag": "RETIREMENT", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 80,80, 80,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.WDR": { + "symbolID": "G*TPW-----****X", + "tag": "WITHDRAW", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 80,80, 80,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.WDR.WDRUP": { + "symbolID": "G*TPWP----****X", + "tag": "WITHDRAW UNDER PRESSURE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 80,80, 80,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.RIP": { + "symbolID": "G*TPR-----****X", + "tag": "RELIEF IN PLACE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 80,80, 80,1, 0,1 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.TSK.SEC.SCN": { + "symbolID": "G*TPUS----****X", + "tag": "SCREEN", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,10, 50,0, 50,0, 100,10 ], + "defaultDimensions": [100, 10] + }, + "TACGRP.TSK.SEC.GUD": { + "symbolID": "G*TPUG----****X", + "tag": "GUARD", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,10, 50,0, 50,0, 100,10 ], + "defaultDimensions": [100, 10] + }, + "TACGRP.TSK.SEC.COV": { + "symbolID": "G*TPUC----****X", + "tag": "COVER", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,10, 50,0, 50,0, 100,10 ], + "defaultDimensions": [100, 10] + }, + "TACGRP.TSK.CATK": { + "symbolID": "G*TPK-----****X", + "tag": "COUNTERATTACK", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.TSK.CATKF": { + "symbolID": "G*TPKF----****X", + "tag": "COUNTERATTACK BY FIRE", + "symbolType": "MultiSegmentArrow", + "arrowLeafAngle": 0, + "arrowLeafOffset": 40 + } }, - "STBOPS.INDIV": { - "symbolID": "OUPP------*****", - "tag": "STBOPS" + + "obstacleEffects": { + "TACGRP.MOBSU.OBST.OBSEFT.BLK": { + "symbolID": "G*TPB-----****X", + "tag": "BLOCK", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.MOBSU.OBST.OBSEFT.DRT": { + "symbolID": "G*MPOED---****X", + "tag": "DISRUPT", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,0, 0,100, 100,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.MOBSU.OBST.OBSEFT.FIX": { + "symbolID": "G*MPOEF---****X", + "tag": "FIX", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,0, 0,0, 100,100 ], + "defaultDimensions": [100, 20] + } }, - "STBOPS.INDIV.LEADER": { - "symbolID": "OUPPA-----*****", - "tag": "STBOPS" + + "obstacleBypass": { + "TACGRP.MOBSU.OBSTBP.DFTY.DFT": { + "symbolID": "G*MPBDD---****X", + "tag": "BYPASS DIFFICULT", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.MOBSU.OBSTBP.DFTY.IMP": { + "symbolID": "G*MPBDI---****X", + "tag": "BYPASS IMPOSSIBLE", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,100, 100,0, 0,50 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.LANE": { + "symbolID": "G*MPBCL---****X", + "tag": "WATER CROSSING LANE", + "symbolType": "SimpleLine" + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.RFT": { + "symbolID": "G*MPBCR---****X", + "tag": "WATER CROSSING RAFT SITE", + "symbolType": "SimpleLine" + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.ASTCA": { + "symbolID": "G*MPBCA---****X", + "tag": "WATER CROSSING ASSAULT CROSSING AREA", + "symbolType": "SimplePath", + "numberPoints": 4, + "width": 20 + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.BRG": { + "symbolID": "G*MPBCB---****X", + "tag": "WATER CROSSING BRIDGE OR GAP", + "symbolType": "SimplePath", + "numberPoints": 4, + "width": 20 + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.FRDESY": { + "symbolID": "G*MPBCE---****X", + "tag": "WATER CROSSING FORD EASY", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + }, + "TACGRP.MOBSU.OBSTBP.CSGSTE.FRDDFT": { + "symbolID": "G*MPBCD---****X", + "tag": "WATER CROSSING FORD DIFFICULT", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + } }, - "STBOPS.INDIV.TRGTD": { - "symbolID": "OUPPB-----*****", - "tag": "STBOPS" + + "maneuvers": { + "TACGRP.C2GM.OFF.ARS.SFP": { + "symbolID": "G*GPOAS---****X", + "tag": "SUPPORT BY FIRE POSITION", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 0,80, 0,20, 100,100, 100,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.C2GM.SPL.LNE.AMB": { + "symbolID": "G*GPSLA---****X", + "tag": "AMBUSH", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,50, 0,100, 0,0 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.C2GM.OFF.ARS.AFP": { + "symbolID": "G*GPOAF---****X", + "tag": "ATTACK BY FIRE POSITION", + "symbolType": "DefinedMissionGraphic", + "defaultControlPts": [ 100,50, 0,80, 0,20 ], + "defaultDimensions": [100, 100] + }, + "TACGRP.C2GM.OFF.LNE.DIRATK.GRD.MANATK": { + "symbolID": "G*GPOLKGM-****X", + "tag": "DIRECTION OF MAIN ATTACK", + "symbolType": "SimpleArrow" + }, + "TACGRP.C2GM.OFF.LNE.DIRATK.GRD.SUPATK": { + "symbolID": "G*GPOLKGS-****X", + "tag": "DIRECTION OF SUPPORTING ATTACK", + "symbolType": "SimpleArrow" + }, + "TACGRP.C2GM.DCPN.DAFF": { + "symbolID": "G*GPPF----****X", + "tag": "DIRECTION OF ATTACK FOR FEINT", + "symbolType": "SimpleArrow" + }, + "TACGRP.C2GM.OFF.LNE.DIRATK.AVN": { + "symbolID": "G*GPOLKA--****X", + "tag": "DIRECTION OF ATTACK AVIATION", + "symbolType": "SimpleArrow" + }, + "TACGRP.C2GM.SPL.ARA.AOO": { + "symbolID": "G*GPSAO---****X", + "tag": "AREA OF OPERATIONS (AO)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.ARA.AHD": { + "symbolID": "G*GPSAA---****X", + "tag": "AIRHEAD", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.ARA.ENCMT": { + "symbolID": "G*GPSAE---****X", + "tag": "ENCIRCLEMENT", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + }, + "TACGRP.C2GM.SPL.ARA.NAI": { + "symbolID": "G*GPSAN---****X", + "tag": "NAMED AREA OF INTEREST (NAI)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.ARA.TAI": { + "symbolID": "G*GPSAT---****X", + "tag": "TARGETED AREA OF INTEREST (TAI)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.LNE.AXSADV.AVN": { + "symbolID": "G*GPOLAV--****X", + "tag": "AVIATION AXIS OF ADVANCE", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.OFF.LNE.AXSADV.ABN": { + "symbolID": "G*GPOLAA--****X", + "tag": "AIRBORNE AXIS OF ADVANCE", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.OFF.LNE.AXSADV.ATK": { + "symbolID": "G*GPOLAR--****X", + "tag": "RWA ATTACK AXIS OF ADVANCE", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.OFF.LNE.AXSADV.GRD.MANATK": { + "symbolID": "G*GPOLAGM-****X", + "tag": "GROUND MAIN ATTACK", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.OFF.LNE.AXSADV.GRD.SUPATK": { + "symbolID": "G*GPOLAGS-****X", + "tag": "GROUND SUPPORTING ATTACK", + "symbolType": "MultiSegmentArrow", + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.DCPN.AAFF": { + "symbolID": "G*GPPA----****X", + "tag": "AXIS OF ADVANCE FOR FEINT", + "symbolType": "MultiSegmentArrow", + "arrowLeafAngle": 40, + "arrowLeafOffset": 40 + }, + "TACGRP.C2GM.OFF.LNE.INFNLE": { + "symbolID": "G*GPOLI---****X", + "tag": "INFILTRATION LANE", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20, + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.GNL.ARS.GENARA": { + "symbolID": "G*GPGAG---****X", + "tag": "GENERAL AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.ABYARA": { + "symbolID": "G*GPGAA---****X", + "tag": "ASSEMBLY AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.EMTARA": { + "symbolID": "G*GPGAE---****X", + "tag": "ENGAGEMENT AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.FTFARA": { + "symbolID": "G*GPGAF---****X", + "tag": "FORTIFIED AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.DRPZ": { + "symbolID": "G*GPGAD---****X", + "tag": "DROP ZONE (DZ)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.EZ": { + "symbolID": "G*GPGAX---****X", + "tag": "EXTRACTION ZONE (EZ)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.LZ": { + "symbolID": "G*GPGAL---****X", + "tag": "LANDING ZONE (LZ)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.PZ": { + "symbolID": "G*GPGAP---****X", + "tag": "PICKUP ZONE (PZ)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile" ] + }, + "TACGRP.C2GM.GNL.ARS.AIRFZ": { + "symbolID": "G*GPGAZ---****X", + "tag": "AIRFIELD ZONE", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + } }, - "STBOPS.INDIV.TERRST": { - "symbolID": "OUPPC-----*****", - "tag": "STBOPS" + + "lines": { + "TACGRP.C2GM.GNL.LNE.PHELNE": { + "symbolID": "G*GPGLP---****X", + "tag": "PHASE LINE (PL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.GNL.LNE.LITLNE": { + "symbolID": "G*GPGLL---****X", + "tag": "LIGHT LINE (LL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.LNE.REL": { + "symbolID": "G*GPSLR---****X", + "tag": "RELEASE LINE", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.LNE.HGL": { + "symbolID": "G*GPSLH---****X", + "tag": "HOLDING LINE", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.SPL.LNE.BRGH": { + "symbolID": "G*GPSLB---****X", + "tag": "BRIDGEHEAD", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.LNE.PLD": { + "symbolID": "G*GPOLP---****X", + "tag": "PROBABLE LINE OF DEPLOYMENT (PLD)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.LNE.LD": { + "symbolID": "G*GPOLT---****X", + "tag": "LINE OF DEPARTURE", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.LNE.LMTADV": { + "symbolID": "G*GPOLL---****X", + "tag": "LIMIT OF ADVANCE (LOA)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.LNE.LDLC": { + "symbolID": "G*GPOLC---****X", + "tag": "LINE OF DEPARTURE/LINE OF CONTACT (LD/LC)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.GNL.LNE.LOC": { + "symbolID": "G*GPGLC---****X", + "tag": "LINE OF CONTACT (LOC)", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.C2GM.GNL.LNE.BNDS": { + "symbolID": "G*GPGLB---****X", + "tag": "BOUNDARY LINE", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2", "hostile", "echelon" ] + }, + "TACGRP.C2GM.GNL.LNE.FLOT": { + "symbolID": "G*GPGLF---****X", + "tag": "FORWARD LINE OF OWN TROOPS (FLOT)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "hostile" ] + }, + "TACGRP.C2GM.DEF.LNE.FEBA": { + "symbolID": "G*GPDLF---****X", + "tag": "FORWARD EDGE OF BATTLE AREA (FEBA)", + "symbolType": "SimpleLine" + }, + "TACGRP.C2GM.OFF.LNE.FCL": { + "symbolID": "G*GPOLF---****X", + "tag": "FINAL COORDINATION LINE (FCL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.LNE.C2LNE": { + "symbolID": "G*FPLCF---****X", + "tag": "FIRE SUPPORT COORDINATION LINE (FSCL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.LNE.C2LNE.CFL": { + "symbolID": "G*FPLCC---****X", + "tag": "COORDINATED FIRE LINE (CFL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.LNE.C2LNE.NFL": { + "symbolID": "G*FPLCN---****X", + "tag": "NO-FIRE LINE (NFL)", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.FSUPP.LNE.C2LNE.RFL": { + "symbolID": "G*FPLCR---****X", + "tag": "RESTRICTIVE FIRE LINE (RFL)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2", "DTG1", "DTG2" ] + }, + "TACGRP.MOBSU.SU.FTFDLN": { + "symbolID": "G*MPSL----****X", + "tag": "FORTIFIED LINE (FL)", + "symbolType": "MultiSegmentLine" + } }, - "STBOPS.GRPORG": { - "symbolID": "OUGP------*****", - "tag": "STBOPS" + + "offenseAreas": { + "TACGRP.C2GM.OFF.ARS.OBJ": { + "symbolID": "G*GPOAO---****X", + "tag": "OBJECTIVE", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.ARS.PBX": { + "symbolID": "G*GPOAP---****X", + "tag": "PENETRATION BOX", + "symbolType": "MultiSegmentPolygon" + }, + "TACGRP.C2GM.OFF.ARS.ASTPSN": { + "symbolID": "G*GPOAA---****X", + "tag": "ASSAULT POSITION", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.C2GM.OFF.ARS.ATKPSN": { + "symbolID": "G*GPOAK---****X", + "tag": "ATTACK POSITION", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + } }, - "STBOPS.GRPORG.DPRE": { - "symbolID": "OUGPA-----*****", - "tag": "STBOPS" + + "defenseAreas": { + "TACGRP.C2GM.DEF.ARS.BTLPSN": { + "symbolID": "G*GPDAB---****X", + "tag": "BATTLE POSITION (BP)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile", "echelon" ] + }, + "TACGRP.C2GM.DEF.ARS.BTLPSN.PBNO": { + "symbolID": "G*GPDABP--****X", + "tag": "BATTLE POSITION PREPARED BUT NOT OCCUPIED", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "hostile", "echelon" ] + }, + "TACGRP.C2GM.DEF.ARS.EMTARA": { + "symbolID": "G*GPDAE---****X", + "tag": "ENGAGEMENT AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + } }, - "STBOPS.GRPORG.NGO": { - "symbolID": "OUGPB-----*****", - "tag": "STBOPS" + + "wire-fence": { + "TACGRP.MOBSU.OBST.WREOBS.USP": { + "symbolID": "G*MPOWU---****X", + "tag": "WIRE OBSTACLE UNSPECIFIED", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.SNGFN": { + "symbolID": "G*MPOWS---****X", + "tag": "SINGLE FENCE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.DBLFN": { + "symbolID": "G*MPOWD---****X", + "tag": "DOUBLE FENCE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.DAFNC": { + "symbolID": "G*MPOWA---****X", + "tag": "DOUBLE APRON FENCE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.LWFN": { + "symbolID": "G*MPOWL---****X", + "tag": "LOW WIRE FENCE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.HWFN": { + "symbolID": "G*MPOWH---****X", + "tag": "HIGH WIRE FENCE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.CCTA.S": { + "symbolID": "G*MPOWCS--****X", + "tag": "SINGLE CONCERTINA", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.CCTA.DBLSTD": { + "symbolID": "G*MPOWCD--****X", + "tag": "DOUBLE STRAND CONCERTINA", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.WREOBS.CCTA.TRISTD": { + "symbolID": "G*MPOWCT--****X", + "tag": "TRIPLE STRAND CONCERTINA", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.AVN.OHWIRE": { + "symbolID": "G*MPOHO---****X", + "tag": "OVERHEAD WIRE", + "symbolType": "MultiSegmentLine" + } + }, + + "obstacles": { + "TACGRP.MOBSU.OBST.GNL.LNE": { + "symbolID": "G*MPOGL---****X", + "tag": "LINEAR OBSTACLE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.ABS": { + "symbolID": "G*MPOS----****X", + "tag": "ABATIS", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.ATO.ATD.ATDUC": { + "symbolID": "G*MPOADU--****X", + "tag": "ANTITANK DITCH UNDER CONSTRUCTION", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.ATO.ATD.ATDC": { + "symbolID": "G*MPOADC--****X", + "tag": "ANTITANK DITCH COMPLETE", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.ATO.ATD.ATDATM": { + "symbolID": "G*MPOAR---****X", + "tag": "ANTITANK DITCH REINFORCED WITH MINES", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.ATO.ATD.ATW": { + "symbolID": "G*MPOAW---****X", + "tag": "ANTITANK WALL", + "symbolType": "MultiSegmentLine" + }, + "TACGRP.MOBSU.OBST.GNL.BLT": { + "symbolID": "G*MPOGB---****X", + "tag": "OBSTACLE GENERAL BELT", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2" ] + }, + "TACGRP.MOBSU.OBST.GNL.Z": { + "symbolID": "G*MPOGZ---****X", + "tag": "OBSTACLE GENERAL ZONE", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.MOBSU.OBST.GNL.OFA": { + "symbolID": "G*MPOGF---****X", + "tag": "OBSTACLE FREE AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.MOBSU.OBST.GNL.ORA": { + "symbolID": "G*MPOGR---****X", + "tag": "OBSTACLE RESTRICTED AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.MOBSU.OBST.MNEFLD.MNDARA": { + "symbolID": "G*MPOFA---****X", + "tag": "MINED AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + }, + "TACGRP.MOBSU.OBST.MNE.MCLST": { + "symbolID": "G*MPOMC---****X", + "tag": "MINE CLUSTER", + "symbolType": "SimpleLine" + }, + "TACGRP.C2GM.DCPN.DMA": { + "symbolID": "G*GPPM----****X", + "tag": "DECOY MINED AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + }, + "TACGRP.C2GM.DCPN.DMAF": { + "symbolID": "G*GPPY----****X", + "tag": "DECOY MINED AREA FENCED", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile" ] + }, + "TACGRP.C2GM.DCPN.DMYMD": { + "symbolID": "G*GPPC----****X", + "tag": "DUMMY MINEFIELD", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "hostile", "additionalInfo1" ] + }, + "TACGRP.MOBSU.OBST.MNEFLD.GAP": { + "symbolID": "G*MPOFG---****X", + "tag": "MINEFIELD GAP", + "symbolType": "SimplePath", + "numberPoints": 4, + "width": 40, + "validModifiers": [ "DTG1", "DTG2" ] + }, + "TACGRP.MOBSU.OBST.UXO": { + "symbolID": "G*MPOU----****X", + "tag": "UNEXPLODED ORDNANCE AREA (UXO)", + "symbolType": "MultiSegmentPolygon" + }, + "TACGRP.MOBSU.SU.STRGPT": { + "symbolID": "G*MPSP----****X", + "tag": "STRONG POINT", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1", "echelon" ] + }, + "TACGRP.MOBSU.SU.FEWS": { + "symbolID": "G*MPSW----****X", + "tag": "FOXHOLE, EMPLACEMENT OR WEAPON SITE", + "symbolType": "SimpleLine" + }, + "TACGRP.MOBSU.OBST.RCBB.PLND": { + "symbolID": "G*MPORP---****X", + "tag": "BLOWN BRIDGE PLANNED", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + }, + "TACGRP.MOBSU.OBST.RCBB.SAFE": { + "symbolID": "G*MPORS---****X", + "tag": "BLOWN BRIDGE STATE OF READINESS 1 (SAFE)", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + }, + "TACGRP.MOBSU.OBST.RCBB.ABP": { + "symbolID": "G*MPORA---****X", + "tag": "BLOWN BRIDGE STATE OF READINESS 2 (ARMED BUT PASSABLE)", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + }, + "TACGRP.MOBSU.OBST.RCBB.EXCD": { + "symbolID": "G*MPORC---****X", + "tag": "ROADBLOCK COMPLETE (EXECUTED)", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + }, + "TACGRP.MOBSU.OBST.TRIPWR": { + "symbolID": "G*MPOT----****X", + "tag": "TRIPWIRE", + "symbolType": "SimplePath", + "numberPoints": 3, + "width": 20 + } + }, + + "supply": { + "TACGRP.CSS.LNE.SPLRUT.MSRUT": { + "symbolID": "G*SPLRM---****X", + "tag": "MAIN SUPPLY ROUTE (MSR)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.LNE.SPLRUT.ASRUT": { + "symbolID": "G*SPLRA---****X", + "tag": "ALTERNATE SUPPLY ROUTE (ASR)", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.LNE.SPLRUT.1WYTRFF": { + "symbolID": "G*SPLRO---****X", + "tag": "SUPPLY ROUTE 1 WAY TRAFFIC", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.LNE.SPLRUT.ATRFF": { + "symbolID": "G*SPLRT---****X", + "tag": "SUPPLY ROUTE ALTERNATING TRAFFIC", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.LNE.SPLRUT.2WYTRFF": { + "symbolID": "G*SPLRW---****X", + "tag": "SUPPLY ROUTE 2 WAY TRAFFIC", + "symbolType": "MultiSegmentLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.LNE.CNY.MCNY": { + "symbolID": "G*SPLCM---****X", + "tag": "MOVING CONVOY", + "symbolType": "SimpleArrow", + "validModifiers": [ "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.CSS.LNE.CNY.HCNY": { + "symbolID": "G*SPLCH---****X", + "tag": "HALTED CONVOY", + "symbolType": "SimpleArrow", + "validModifiers": [ "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + } }, - "STBOPS.GRPORG.TERRST": { - "symbolID": "OUGPC-----*****", - "tag": "STBOPS" + + "fireSupport": { + "TACGRP.FSUPP.LNE.LNRTGT": { + "symbolID": "GHFPLT----****X", + "tag": "LINEAR TARGET", + "symbolType": "SimpleLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.LNE.LNRTGT.LSTGT": { + "symbolID": "G*FPLTS---****X", + "tag": "LINEAR SMOKE TARGET", + "symbolType": "SimpleLine", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.LNE.LNRTGT.FPF": { + "symbolID": "G*FPLTF---****X", + "tag": "LINEAR TARGET FINAL PROTECTIVE FIRE (FPF)", + "symbolType": "SimpleLine", + "validModifiers": [ "uniqueDesignation1", "uniqueDesignation2" ] + }, + "TACGRP.FSUPP.ARS.ARATGT.CIRTGT": { + "symbolID": "G*FPATC---****X", + "tag": "AREA TARGET CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "distance" ] + }, + "TACGRP.FSUPP.ARS.ARATGT.RTGTGT": { + "symbolID": "G*FPAT----****X", + "tag": "RECTANGULAR TARGET", + "symbolType": "RectangleMultiPoint", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.ARS.ARATGT": { + "symbolID": "G*FPAT----****X", + "tag": "AREA TARGET IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.ARS.ARATGT.SGTGT": { + "symbolID": "G*FPATG---****X", + "tag": "TARGET SERIES OR GROUP", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.FSUPP.ARS.ARATGT.SMK": { + "symbolID": "G*FPATS---****X", + "tag": "AREA TARGET SMOKE", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.ARATGT.BMARA": { + "symbolID": "G*FPATB---****X", + "tag": "BOMB AREA", + "symbolType": "MultiSegmentPolygon" + }, + "TACGRP.FSUPP.ARS.C2ARS.FSA.RTG": { + "symbolID": "G*FPACSI--****X", + "tag": "FIRE SUPPORT AREA (FSA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.FSA.IRR": { + "symbolID": "G*FPACSI--****X", + "tag": "FIRE SUPPORT AREA (FSA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.FSA.CIRCLR": { + "symbolID": "G*FPACSC--****X", + "tag": "FIRE SUPPORT AREA (FSA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ACA.RTG": { + "symbolID": "G*FPACAI--****X", + "tag": "AIRSPACE COORDINATION AREA (ACA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "additionalInfo3": "Grids", + "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "additionalInfo3", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ACA.IRR": { + "symbolID": "G*FPACAI--****X", + "tag": "AIRSPACE COORDINATION AREA (ACA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "additionalInfo3": "Grids", + "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "additionalInfo3", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ACA.CIRCLR": { + "symbolID": "G*FPACAC--****X", + "tag": "AIRSPACE COORDINATION AREA (ACA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "additionalInfo3": "Grids", + "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "additionalInfo3", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.FFA.RTG": { + "symbolID": "G*FPACFI--****X", + "tag": "FREE FIRE AREA (FFA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.FFA.IRR": { + "symbolID": "G*FPACFI--****X", + "tag": "FREE FIRE AREA (FFA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.FFA.CIRCLR": { + "symbolID": "G*FPACFC--****X", + "tag": "FREE FIRE AREA (FFA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.NFA.RTG": { + "symbolID": "G*FPACNI--****X", + "tag": "NO-FIRE AREA (NFA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.NFA.IRR": { + "symbolID": "G*FPACNI--****X", + "tag": "NO-FIRE AREA (NFA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.NFA.CIRCLR": { + "symbolID": "G*FPACNC--****X", + "tag": "NO-FIRE AREA (NFA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.RFA.RTG": { + "symbolID": "G*FPACRI--****X", + "tag": "RESTRICTIVE FIRE AREA (RFA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.RFA.IRR": { + "symbolID": "G*FPACRI--****X", + "tag": "RESTRICTIVE FIRE AREA (RFA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.RFA.CIRCLR": { + "symbolID": "G*FPACRC--****X", + "tag": "RESTRICTIVE FIRE AREA (RFA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + // TODO: mil-sym currently does not render this graphic. + // Come back to this once mil-sym has corrected this graphic. + // "TACGRP.FSUPP.ARS.C2ARS.PAA.RTG": { + // "symbolID": "G*FPACPR--****X", + // "tag": "POSITION AREA FOR ARTILLERY RECTANGULAR", + // "symbolType": "RectangleMultiPoint" + // }, + "TACGRP.FSUPP.ARS.C2ARS.PAA.CIRCLR": { + "symbolID": "G*FPACPC--****X", + "tag": "POSITION AREA FOR ARTILLERY (PAA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.SNSZ.RTG": { + "symbolID": "G*FPACEI--****X", + "tag": "SENSOR ZONE RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.SNSZ.IRR": { + "symbolID": "G*FPACEI--****X", + "tag": "SENSOR ZONE IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.SNSZ.CIRCLR": { + "symbolID": "G*FPACEI--****X", + "tag": "SENSOR ZONE CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.DA.RTG": { + "symbolID": "G*FPACDI--****X", + "tag": "DEAD SPACE AREA (DA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.DA.IRR": { + "symbolID": "G*FPACDI--****X", + "tag": "DEAD SPACE AREA (DA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.DA.CIRCLR": { + "symbolID": "G*FPACDC--****X", + "tag": "DEAD SPACE AREA (DA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ZOR.RTG": { + "symbolID": "G*FPACZI--****X", + "tag": "ZONE OF RESPONSIBILITY (ZOR) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ZOR.IRR": { + "symbolID": "G*FPACZI--****X", + "tag": "ZONE OF RESPONSIBILITY (ZOR) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.ZOR.CIRCLR": { + "symbolID": "G*FPACZC--****X", + "tag": "ZONE OF RESPONSIBILITY (ZOR) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TBA.RTG": { + "symbolID": "G*FPACBI--****X", + "tag": "TARGET BUILD-UP AREA (TBA) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TBA.IRR": { + "symbolID": "G*FPACBI--****X", + "tag": "TARGET BUILD-UP AREA (TBA) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TBA.CIRCLR": { + "symbolID": "G*FPACBC--****X", + "tag": "TARGET BUILD-UP AREA (TBA) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TVAR.RTG": { + "symbolID": "G*FPACVI--****X", + "tag": "TARGET VALUE AREA (TVAR) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TVAR.IRR": { + "symbolID": "G*FPACVI--****X", + "tag": "TARGET VALUE AREA (TVAR) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TVAR.CIRCLR": { + "symbolID": "G*FPACVC--****X", + "tag": "TARGET VALUE AREA (TVAR) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.RTG": { + "symbolID": "G*FPAZII--****X", + "tag": "ARTILLERY TARGET INTELLIGENCE (ATI) ZONE RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.IRR": { + "symbolID": "G*FPAZII--****X", + "tag": "ARTILLERY TARGET INTELLIGENCE (ATI) ZONE IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.CIRCLR": { + "symbolID": "G*FPAZIC--****X", + "tag": "ARTILLERY TARGET INTELLIGENCE (ATI) ZONE CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.RTG": { + "symbolID": "G*FPAZXI--****X", + "tag": "CALL FOR FIRE ZONE (CFFZ) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.IRR": { + "symbolID": "G*FPAZXI--****X", + "tag": "CALL FOR FIRE ZONE (CFFZ) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.CIRCLR": { + "symbolID": "G*FPAZXC--****X", + "tag": "CALL FOR FIRE ZONE (CFFZ) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CNS.RTG": { + "symbolID": "G*FPAZCI--****X", + "tag": "CENSOR ZONE RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CNS.IRR": { + "symbolID": "G*FPAZCI--****X", + "tag": "CENSOR ZONE IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CNS.CIRCLR": { + "symbolID": "G*FPAZCC--****X", + "tag": "CENSOR ZONE CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFZ.RTG": { + "symbolID": "G*FPAZFI--****X", + "tag": "CRITICAL FRIENDLY ZONE (CFZ) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFZ.IRR": { + "symbolID": "G*FPAZFI--****X", + "tag": "CRITICAL FRIENDLY ZONE (CFZ) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.TGTAQZ.CFZ.CIRCLR": { + "symbolID": "G*FPAZFC--****X", + "tag": "CRITICAL FRIENDLY ZONE (CFZ) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.BLUE.RTG": { + "symbolID": "G*FPAKBI--****X", + "tag": "KILL BOX BLUE (BKB) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.BLUE.IRR": { + "symbolID": "G*FPAKBI--****X", + "tag": "KILL BOX BLUE (BKB) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.BLUE.CIRCLR": { + "symbolID": "G*FPAKBC--****X", + "tag": "KILL BOX BLUE (BKB) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.PURPLE.RTG": { + "symbolID": "G*FPAKPI--****X", + "tag": "KILL BOX PURPLE (PKB) RECTANGULAR", + "symbolType": "RectangleMultiPoint", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.PURPLE.IRR": { + "symbolID": "G*FPAKPI--****X", + "tag": "KILL BOX PURPLE (PKB) IRREGULAR", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + }, + "TACGRP.FSUPP.ARS.KLBOX.PURPLE.CIRCLR": { + "symbolID": "G*FPAKPC--****X", + "tag": "KILL BOX PURPLE (PKB) CIRCULAR", + "symbolType": "SimpleCircle", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End", + "distance": "Radius (m)" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2", "distance" ] + }, + "TACGRP.FSUPP.ARS.C2ARS.TGMF": { + "symbolID": "G*FPACT---****X", + "tag": "TERMINALLY GUIDED MUNITION FOOTPRINT (TGMF)", + "symbolType": "MultiSegmentPolygon" + }, + "TACGRP.FSUPP.LNE.C2LNE.MFP": { + "symbolID": "G*FPLCM---****X", + "tag": "MUNITION FLIGHT PATH (MFP)", + "symbolType": "MultiSegmentLine", + "modifierLabels": { "DTG1": "Eff Start", + "DTG2": "Eff End" }, + "validModifiers": [ "DTG1", "DTG2" ] + } }, - "STBOPS.GRPORG.RELIGS": { - "symbolID": "OUGPD-----*****", - "tag": "STBOPS" + + "combatServiceSupport": { + "TACGRP.CSS.ARA.DHA": { + "symbolID": "G*SPAD----****X", + "tag": "DETAINEE HOLDING AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.EPWHA": { + "symbolID": "G*SPAE----****X", + "tag": "ENEMY PRISONERS OF WAR (EPW) HOLDING AREA", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.FARP": { + "symbolID": "G*SPAR----****X", + "tag": "FORWARD ARMING AND REFUELING AREA (FARP)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.RHA": { + "symbolID": "G*SPAH----****X", + "tag": "REFUGEE HOLDING AREA (RHA)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.BSA": { + "symbolID": "G*SPASB---****X", + "tag": "SUPPORT AREA BRIGADE (BSA)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.DSA": { + "symbolID": "G*SPASD---****X", + "tag": "SUPPORT AREA DIVISION (DSA)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + }, + "TACGRP.CSS.ARA.RSA": { + "symbolID": "G*SPASR---****X", + "tag": "SUPPORT AREA REGIMENTAL (RSA)", + "symbolType": "MultiSegmentPolygon", + "validModifiers": [ "uniqueDesignation1" ] + } }, - "STBOPS.GRPORG.FNFGHT": { - "symbolID": "OUGPE-----*****", - "tag": "STBOPS" + + "airOperations": { + "TACGRP.C2GM.AVN.ARS.ROZ": { + "symbolID": "G*GPAAR---****X", + "tag": "RESTRICTED OPERATIONS ZONE (ROZ)", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.SHRDEZ": { + "symbolID": "G*GPAAF---****X", + "tag": "SHORT-RANGE AIR DEFENSE ENGAGEMENT ZONE", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.HIDACZ": { + "symbolID": "G*GPAAH---****X", + "tag": "HIGH DENSITY AIRSPACE CONTROL ZONE", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.MEZ": { + "symbolID": "G*GPAAM---****X", + "tag": "MISSILE ENGAGEMENT ZONE (MEZ)", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.MEZ.LAMEZ": { + "symbolID": "G*GPAAML--****X", + "tag": "MISSILE ENGAGEMENT ZONE (MEZ) LOW ALTITUDE ZONE", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.MEZ.HAMEZ": { + "symbolID": "G*GPAAMH--****X", + "tag": "MISSILE ENGAGEMENT ZONE (MEZ) HIGH ALTITUDE ZONE", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "additionalInfo1": "Min Alt", + "additionalInfo2": "Max Alt", + "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "additionalInfo1", "additionalInfo2", "DTG1", "DTG2" ] + }, + "TACGRP.C2GM.AVN.ARS.WFZ": { + "symbolID": "G*GPAAW---****X", + "tag": "WEAPONS FREE ZONE", + "symbolType": "MultiSegmentPolygon", + "modifierLabels": { "DTG1": "Time From", + "DTG2": "Time To" }, + "validModifiers": [ "uniqueDesignation1", "DTG1", "DTG2" ] + } }, - "STBOPS.GRPORG.GANG": { - "symbolID": "OUGPF-----*****", - "tag": "STBOPS" - } - }, - - "aliasModifiers": { - "quantity": { modifier: "C_QUANTITY", - type: "ModifiersUnits", - valueType: "Number" }, - "additionalInfo1": { modifier: "H_ADDITIONAL_INFO_1", - type: "ModifiersUnits", - valueType: "Text" }, - "additionalInfo2": { modifier: "H1_ADDITIONAL_INFO_2", - type: "ModifiersUnits", - valueType: "Text" }, - "additionalInfo3": { modifier: "H2_ADDITIONAL_INFO_3", - type: "ModifiersUnits", - valueType: "Text" }, - "altitudeDepth": { modifier: "X_ALTITUDE_DEPTH", - type: "ModifiersUnits", - valueType: "Text" }, - "combatEffectiveness": { modifier: "K_COMBAT_EFFECTIVENESS", - type: "ModifiersUnits", - valueType: "Text" }, - "directionOfMovement": { modifier: "Q_DIRECTION_OF_MOVEMENT", - type: "ModifiersUnits", - valueType: "Text" }, - "evaluationRating": { modifier: "J_EVALUATION_RATING", - type: "ModifiersUnits", - valueType: "Text" }, - "higherFormation": { modifier: "M_HIGHER_FORMATION", - type: "ModifiersUnits", - valueType: "Text" }, - "hostile": { modifier: "N_HOSTILE", - type: "ModifiersUnits", - valueType: "Text" }, - "iffSif": { modifier: "P_IFF_SIF", - type: "ModifiersUnits", - valueType: "Text" }, - "location": { modifier: "Y_LOCATION", - type: "ModifiersUnits", - valueType: "Array" }, - "reinforcedReduced": { modifier: "F_REINFORCED_REDUCED", - type: "ModifiersUnits", - valueType: "Text" }, - "signatureEquip": { modifier: "L_SIGNATURE_EQUIP", - type: "ModifiersUnits", - valueType: "Text" }, - "staffComments": { modifier: "G_STAFF_COMMENTS", - type: "ModifiersUnits", - valueType: "Text" }, - "equipType": { modifier: "V_EQUIP_TYPE", - type: "ModifiersUnits", - valueType: "Text" }, - "uniqueDesignation1": { modifier: "T_UNIQUE_DESIGNATION_1", - type: "ModifiersUnits", - valueType: "Text" }, - "uniqueDesignation2": { modifier: "T1_UNIQUE_DESIGNATION_2", - type: "ModifiersUnits", - valueType: "Text" }, - "speed": { modifier: "Z_SPEED", - type: "ModifiersUnits", - valueType: "Text" }, - "pixelSize": { modifier: "PixelSize", - type: "MilStdAttributes", - valueType: "Number" }, - "icon": { modifier: "Icon", - type: "MilStdAttributes", - valueType: "Boolean" }, - "keepUnitRatio": { modifier: "KeepUnitRatio", - type: "MilStdAttributes", - valueType: "Boolean" }, - "symbologyStandard": { modifier: "SymbologyStandard", - type: "MilStdAttributes", - valueType: "Number" } - }, - "find": function( section, tag ) { - var units = {}; - var sec = undefined; - if ( this[ section ] !== undefined ) { - for ( var fullname in this[ section ] ) { - if ( this[ section ][ fullname ][ tag ] === tag ){ - units[ fullname ] = this[ section ][ fullname ]; - } - } - } - return units; - }, - "findAll": function( section, tag ) { - var units = {}; - var sec = undefined; - if ( this[ section ] !== undefined ) { - for ( var fullname in this[ section ] ) { - if ( fullname.indexOf( tag ) !== -1 ){ - units[ fullname ] = this[ section ][ fullname ]; - } - } - } - return units; - }, - "decode": function( name ){ - var parts = name.split( '.' ); - for ( var i = 0; i < parts.length; i++ ) { - parts[ i ] = ( this.def[ parts[ i ] ] !== undefined ) ? this.def[ parts[ i ] ] : parts[ i ]; - } - return parts.join( '.' ); - }, - "description": function( name, unit ){ - var foundTag = false; - var parts = name.split( '.' ); - var retStr = ""; - var prefix = ""; - for ( var i = 0; i < parts.length; i++ ){ - if ( foundTag ) { - prefix = prefix + " "; - } else if ( parts[ i ] === unit.tag ) { - foundTag = true; - } - if ( this.def[ parts[ i ] ] ) { - retStr = retStr + prefix + this.def[ parts[ i ] ] + "\n"; - } else { - retStr = retStr + prefix + parts[ i ] + "\n"; - } - } - return retStr; - }, - "preTag": function( name, tag ) { - var retStr = ""; - var index = name.indexOf( tag ); - if ( index !== -1 ) { - retStr = name.substr( 0, index - 1 ); - } - return retStr; - }, - "postTag": function( name, tag ) { - var tagLen = tag.length; - var retStr = ""; - var index = name.indexOf( tag ); - if ( index !== -1 ) { - retStr = name.substr( index + tagLen + 1 ); - } - return retStr; - }, - "addEchelonToSymbolId": function( symbolID, value ) { - var retStr = symbolID; - switch( value ) { - - case "team": - case "crew": - retStr = this.team_crew( symbolID ); - break; - case "squad": - retStr = this.squad( symbolID ); - break; - case "section": - retStr = this.section( symbolID ); - break; - case "platoon": - case "detachment": - retStr = this.platoon_detachment( symbolID ); - break; - case "company": - case "battery": - case "troop": - retStr = this.company_battery_troop( symbolID ); - break; - case "battalion": - case "squadron": - retStr = this.battalion_squadron( symbolID ); - break; - case "regiment": - case "group": - retStr = this.regiment_group( symbolID ); - break; - case "brigade": - retStr = this.brigade( symbolID ); - break; - case "division": - retStr = this.division( symbolID ); - break; - case "corps": - case "mef": - retStr = this.corps_mef( symbolID ); - break; - case "army": - retStr = this.army( symbolID ); - break; - case "armyGroup": - case "army group": - case "front": - retStr = this.armyGroup_front( symbolID ); - break; - case "region": - retStr = this.region( symbolID ); - break; - case "null": - case "none": - default: - retStr = this._null( symbolID ); - break; + "aliasModifiers": { + "echelon": { modifier: "B_ECHELON", + type: "ModifiersUnits", + valueType: "Text" }, + "quantity": { modifier: "C_QUANTITY", + type: "ModifiersUnits", + valueType: "Number" }, + "additionalInfo1": { modifier: "H_ADDITIONAL_INFO_1", + type: "ModifiersUnits", + valueType: "Text" }, + "additionalInfo2": { modifier: "H1_ADDITIONAL_INFO_2", + type: "ModifiersUnits", + valueType: "Text" }, + "additionalInfo3": { modifier: "H2_ADDITIONAL_INFO_3", + type: "ModifiersUnits", + valueType: "Text" }, + "altitudeDepth": { modifier: "X_ALTITUDE_DEPTH", + type: "ModifiersUnits", + valueType: "Text" }, + "combatEffectiveness": { modifier: "K_COMBAT_EFFECTIVENESS", + type: "ModifiersUnits", + valueType: "Text" }, + "directionOfMovement": { modifier: "Q_DIRECTION_OF_MOVEMENT", + type: "ModifiersUnits", + valueType: "Text" }, + "evaluationRating": { modifier: "J_EVALUATION_RATING", + type: "ModifiersUnits", + valueType: "Text" }, + "higherFormation": { modifier: "M_HIGHER_FORMATION", + type: "ModifiersUnits", + valueType: "Text" }, + "hostile": { modifier: "N_HOSTILE", + type: "ModifiersUnits", + valueType: "Text" }, + "iffSif": { modifier: "P_IFF_SIF", + type: "ModifiersUnits", + valueType: "Text" }, + "location": { modifier: "Y_LOCATION", + type: "ModifiersUnits", + valueType: "Text" }, + "reinforcedReduced": { modifier: "F_REINFORCED_REDUCED", + type: "ModifiersUnits", + valueType: "Text" }, + "signatureEquip": { modifier: "L_SIGNATURE_EQUIP", + type: "ModifiersUnits", + valueType: "Text" }, + "staffComments": { modifier: "G_STAFF_COMMENTS", + type: "ModifiersUnits", + valueType: "Text" }, + "equipType": { modifier: "V_EQUIP_TYPE", + type: "ModifiersUnits", + valueType: "Text" }, + "uniqueDesignation1": { modifier: "T_UNIQUE_DESIGNATION_1", + type: "ModifiersUnits", + valueType: "Text" }, + "uniqueDesignation2": { modifier: "T1_UNIQUE_DESIGNATION_2", + type: "ModifiersUnits", + valueType: "Text" }, + "speed": { modifier: "Z_SPEED", + type: "ModifiersUnits", + valueType: "Text" }, + "pixelSize": { modifier: "PixelSize", + type: "MilStdAttributes", + valueType: "Number" }, + "fillColor": { modifier: "FillColor", + type: "MilStdAttributes", + valueType: "Text" }, + "lineColor": { modifier: "LineColor", + type: "MilStdAttributes", + valueType: "Text" }, + "lineWidth": { modifier: "LineWidth", + type: "MilStdAttributes", + valueType: "Number" }, + "icon": { modifier: "Icon", + type: "MilStdAttributes", + valueType: "Boolean" }, + "keepUnitRatio": { modifier: "KeepUnitRatio", + type: "MilStdAttributes", + valueType: "Boolean" }, + "symbologyStandard": { modifier: "SymbologyStandard", + type: "MilStdAttributes", + valueType: "Number" }, + "distance": { modifier: "AM_DISTANCE", + type: "ModifiersTG", + valueType: "Array" }, + "azimuth": { modifier: "AN_AZIMUTH", + type: "ModifiersTG", + valueType: "Array" }, + "length": { modifier: "LENGTH", + type: "ModifiersTG", + valueType: "Number" }, + "width": { modifier: "WIDTH", + type: "ModifiersTG", + valueType: "Number" }, + "angle": { modifier: "ANGLE", + type: "ModifiersTG", + valueType: "Number" }, + "DTG1": { modifier: "W_DTG_1", + type: "ModifiersTG", + valueType: "Text" }, + "DTG2": { modifier: "W1_DTG_2", + type: "ModifiersTG", + valueType: "Text" } + }, + "find": function( section, tag ) { + var units = {}; + var sec = undefined; + if ( this[ section ] !== undefined ) { + for ( var fullname in this[ section ] ) { + if ( this[ section ][ fullname ][ tag ] === tag ){ + units[ fullname ] = this[ section ][ fullname ]; + } + } + } + return units; + }, + "findAll": function( section, tag ) { + var units = {}; + var sec = undefined; + if ( this[ section ] !== undefined ) { + for ( var fullname in this[ section ] ) { + if ( fullname.indexOf( tag ) !== -1 ){ + units[ fullname ] = this[ section ][ fullname ]; + } + } + } + return units; + }, + "decode": function( name ){ + var parts = name.split( '.' ); + for ( var i = 0; i < parts.length; i++ ) { + parts[ i ] = ( this.def[ parts[ i ] ] !== undefined ) ? this.def[ parts[ i ] ] : parts[ i ]; + } + return parts.join( '.' ); + }, + "description": function( name, unit ){ + var foundTag = false; + var parts = name.split( '.' ); + var retStr = ""; + var prefix = ""; + for ( var i = 0; i < parts.length; i++ ){ + if ( foundTag ) { + prefix = prefix + " "; + } else if ( parts[ i ] === unit.tag ) { + foundTag = true; + } + if ( this.def[ parts[ i ] ] ) { + retStr = retStr + prefix + this.def[ parts[ i ] ] + "\n"; + } else { + retStr = retStr + prefix + parts[ i ] + "\n"; + } + } - } - return retStr; - }, - "team_crew": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-A" + symbolID.substr( 12 ); - }, - "squad": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-B" + symbolID.substr( 12 ); - }, - "section": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-C" + symbolID.substr( 12 ); - }, - "platoon_detachment": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-D" + symbolID.substr( 12 ); - }, - "company_battery_troop": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-E" + symbolID.substr( 12 ); - }, - "battalion_squadron": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-F" + symbolID.substr( 12 ); - }, - "regiment_group": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-G" + symbolID.substr( 12 ); - }, - "brigade": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-H" + symbolID.substr( 12 ); - }, - "division": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-I" + symbolID.substr( 12 ); - }, - "corps_mef": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-J" + symbolID.substr( 12 ); - }, - "army": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-K" + symbolID.substr( 12 ); - }, - "armyGroup_front": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-L" + symbolID.substr( 12 ); - }, - "region": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "-M" + symbolID.substr( 12 ); - }, - "_null": function( symbolID ) { - return symbolID.substr( 0, 10 ) + "**" + symbolID.substr( 12 ); - }, - "addAffiliationToSymbolId": function( symbolID, value ) { - var retStr = symbolID; - switch ( value ) { - case "unknown": - retStr = this.unknown( symbolID ); - break; - case "friendly": - retStr = this.friendly( symbolID ); - break; - case "neutral": - retStr = this.neutral( symbolID ); - break; - case "hostile": - retStr = this.hostile( symbolID ); - break; - } - return retStr; - }, - "unknown": function( symbolID ) { - return symbolID.substr( 0, 1 ) + "U" + symbolID.substr( 2 ); - }, - "friendly": function( symbolID ) { - return symbolID.substr( 0, 1 ) + "F" + symbolID.substr( 2 ); - }, - "neutral": function( symbolID ) { - return symbolID.substr( 0, 1 ) + "N" + symbolID.substr( 2 ); - }, - "hostile": function( symbolID ) { - return symbolID.substr( 0, 1 ) + "H" + symbolID.substr( 2 ); - }, - "modifierByAlias": function( alias ) { - var modifierObj = undefined; - - if ( this.aliasModifiers[ alias ] ) { - modifierObj = this.aliasModifiers[ alias ]; + return retStr; + }, + "descriptionFromSymbolId": function( symbolId ) { + const rendererUtilities = armyc2.c2sd.renderer.utilities; + const unitDef = rendererUtilities.UnitDefTable; + const symDef = rendererUtilities.SymbolDefTable; + const basicSymbolId = + rendererUtilities.SymbolUtilities.getBasicSymbolID( symbolId, + rendererUtilities.RendererSettings.Symbology_2525C ); + let description = null; + + // Either this is a unit or a symbol, check units, then symbols + if ( unitDef.hasUnitDef( basicSymbolId ) ) { + description = unitDef.getUnitDef( basicSymbolId ).description; + } else if ( symDef.hasSymbolDef( basicSymbolId ) ) { + description = symDef.getSymbolDef( basicSymbolId ).description; + } + + return description; + }, + "preTag": function( name, tag ) { + var retStr = ""; + var index = name.indexOf( tag ); + if ( index !== -1 ) { + retStr = name.substr( 0, index - 1 ); + } + return retStr; + }, + "postTag": function( name, tag ) { + var tagLen = tag.length; + var retStr = ""; + var index = name.indexOf( tag ); + if ( index !== -1 ) { + retStr = name.substr( index + tagLen + 1 ); + } + return retStr; + }, + "addEchelonToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + var echelon = symbolID.charAt(10); + // Override installation + if ( ( echelon === 'H' ) || ( echelon === '*' ) ) { + echelon = '-'; + } + + switch( value ) { + + case "team": + case "crew": + echelon += 'A'; + break; + case "squad": + echelon += 'B'; + break; + case "section": + echelon += 'C'; + break; + case "platoon": + case "detachment": + echelon += 'D'; + break; + case "company": + case "battery": + case "troop": + echelon += 'E'; + break; + case "battalion": + case "squadron": + echelon += 'F'; + break; + case "regiment": + case "group": + echelon += 'G'; + break; + case "brigade": + echelon += 'H'; + break; + case "division": + echelon += 'I'; + break; + case "corps": + case "mef": + echelon += 'J'; + break; + case "army": + echelon += 'K'; + break; + case "armyGroup": + case "army group": + case "front": + echelon += 'L'; + break; + case "region": + echelon += 'M'; + break; + case "null": + case "none": + default: + echelon += '-'; + break; + + } + retStr = symbolID.substr( 0, 10 ) + echelon + symbolID.substr( 12 ); + return retStr; + }, + "addAffiliationToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + switch ( value ) { + case "unknown": + retStr = this.unknown( symbolID ); + break; + case "friendly": + retStr = this.friendly( symbolID ); + break; + case "neutral": + retStr = this.neutral( symbolID ); + break; + case "hostile": + retStr = this.hostile( symbolID ); + break; + } + return retStr; + }, + "symbolCanAcceptAffiliation": function( symbolID ) { + var canAccept = false; + switch ( symbolID.charAt(0) ) { + case 'S': + case 'E': + case 'I': + case 'G': + case 'O': + canAccept = true; + break; + default: + break; + } + return canAccept; + }, + "unknown": function( symbolID ) { + return ( this.symbolCanAcceptAffiliation( symbolID ) ? symbolID.substr( 0, 1 ) + "U" + symbolID.substr( 2 ) : symbolID ); + }, + "friendly": function( symbolID ) { + return ( this.symbolCanAcceptAffiliation( symbolID ) ? symbolID.substr( 0, 1 ) + "F" + symbolID.substr( 2 ) : symbolID ); + }, + "neutral": function( symbolID ) { + return ( this.symbolCanAcceptAffiliation( symbolID ) ? symbolID.substr( 0, 1 ) + "N" + symbolID.substr( 2 ) : symbolID ); + }, + "hostile": function( symbolID ) { + return ( this.symbolCanAcceptAffiliation( symbolID ) ? symbolID.substr( 0, 1 ) + "H" + symbolID.substr( 2 ) : symbolID ); + }, + "addUnitStatusToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + if ( symbolID.charAt(0) === 'S' ) { + var unitStatus = symbolID.charAt(3); + switch ( value ) { + case "anticipated": + unitStatus = "A"; + break; + case "present": + unitStatus = "P"; + break; + case "capable": + unitStatus = "C"; + break; + case "damaged": + unitStatus = "D"; + break; + case "destroyed": + unitStatus = "X"; + break; + case "full": + unitStatus = "F"; + break; + } + retStr = symbolID.substr( 0, 3 ) + unitStatus + symbolID.substr( 4 ); + } + return retStr; + }, + "addMobilityToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + if ( ( symbolID.charAt(0) === 'S' ) && ( symbolID.charAt(4) === 'E' ) ) { + var mobility = symbolID.substr( 10, 2 ); + switch ( value ) { + case "none": + mobility = "**"; + break; + case "wheeled limited cross-country": + mobility = "MO"; + break; + case "cross-country": + mobility = "MP"; + break; + case "tracked": + mobility = "MQ"; + break; + case "wheeled and tracked": + mobility = "MR"; + break; + case "towed": + mobility = "MS"; + break; + case "rail": + mobility = "MT"; + break; + case "over snow": + mobility = "MU"; + break; + case "sled": + mobility = "MV"; + break; + case "pack animals": + mobility = "MW"; + break; + case "barge": + mobility = "MX"; + break; + case "amphibious": + mobility = "MY"; + break; + } + retStr = symbolID.substr( 0, 10 ) + mobility + symbolID.substr( 12 ); + } + return retStr; + }, + "addTaskForceToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + if ( ( symbolID.charAt(0) === 'S' ) && ( symbolID.charAt(4) === 'U' ) ) { + var taskForce = symbolID.charAt(10); + // Override installation + var echelon = symbolID.charAt(11); + if ( symbolID.charAt(10) === "H" ) { + taskForce = '-'; + echelon = '-'; + } + + switch ( value ) { + case "none": + taskForce = "-"; + break; + case "HQ": + taskForce = "A"; + break; + case "TF HQ": + taskForce = "B"; + break; + case "FD HQ": + taskForce = "C"; + break; + case "FD-TF HQ": + taskForce = "D"; + break; + case "TF": + taskForce = "E"; + break; + case "FD": + taskForce = "F"; + break; + case "FD-TF": + taskForce = "G"; + break; + } + retStr = symbolID.substr( 0, 10 ) + taskForce + echelon + symbolID.substr( 12 ); + } + return retStr; + }, + "addInstallationToSymbolId": function( symbolID, value ) { + var retStr = symbolID; + if ( symbolID.charAt(0) === 'S' ) { + var installation = symbolID.substr(10, 2); + switch ( value ) { + case "none": + installation = "--"; + break; + case "installation": + installation = "H-"; + break; + case "feint-dummy": + installation = "HB"; + break; + } + retStr = symbolID.substr( 0, 10 ) + installation + symbolID.substr( 12 ); + } + return retStr; + }, + "modifierByAlias": function( alias ) { + var modifierObj = undefined; + + if ( this.aliasModifiers[ alias ] ) { + modifierObj = this.aliasModifiers[ alias ]; + } + + return modifierObj; } - - return modifierObj; - } - }; + }; - return cws; + return cws; }); diff --git a/support/client/lib/require.js b/support/client/lib/require.js index 24b061e62..0318d83d0 100644 --- a/support/client/lib/require.js +++ b/support/client/lib/require.js @@ -201,7 +201,7 @@ var requirejs, require, define; //Defaults. Do not set a default for map //config to speed up normalize(), which //will run faster if there is no default. - waitSeconds: 7, + waitSeconds: 0, baseUrl: './', paths: {}, bundles: {}, diff --git a/support/client/lib/socket.io-0.6.js b/support/client/lib/socket.io-0.6.js index 21203e146..91b1432dc 100644 --- a/support/client/lib/socket.io-0.6.js +++ b/support/client/lib/socket.io-0.6.js @@ -287,7 +287,7 @@ if (typeof window != 'undefined'){ Transport = io.Transport = function(base, options){ this.base = base; this.options = { - timeout: 15000 // based on heartbeat interval default + timeout: 300000 // based on heartbeat interval default }; io.util.merge(this.options, options); }; @@ -1480,13 +1480,13 @@ if (typeof window != 'undefined'){ transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-multipart', 'xhr-polling', 'jsonp-polling'], transportOptions: { 'xhr-polling': { - timeout: 25000 // based on polling duration default + timeout: 60000 // based on polling duration default }, 'jsonp-polling': { - timeout: 25000 + timeout: 60000 } }, - connectTimeout: 5000, + connectTimeout: 15000, tryTransportsOnConnectTimeout: true, reconnect: true, reconnectionDelay: 500, diff --git a/support/client/lib/socket.io.js b/support/client/lib/socket.io.js index 6ea5dd0a2..27e475b79 100644 --- a/support/client/lib/socket.io.js +++ b/support/client/lib/socket.io.js @@ -1516,7 +1516,7 @@ var io = ('undefined' === typeof module ? {} : module.exports); , document: 'document' in global ? document : false , resource: 'socket.io' , transports: io.transports - , 'connect timeout': 10000 + , 'connect timeout': 30000 , 'try multiple transports': true , 'reconnect': true , 'reconnection delay': 500 diff --git a/support/client/lib/version.js b/support/client/lib/version.js index c29ff9e29..c08e34e9b 100644 --- a/support/client/lib/version.js +++ b/support/client/lib/version.js @@ -12,14 +12,14 @@ // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express // or implied. See the License for the specific language governing permissions and limitations under // the License. - +if (typeof define !== 'function') { var define = require('amdefine')(module) } /// @module version define( function() { /// The version identifier has the following form: /// - /// major, minor, patch, release, build + /// major, minor, patch, release, build, derivative [ app, major, minor, patch ] /// /// Fields are defined according to [SemVer](http://semver.org). The `release` and `build` /// fields are optional, but they are given low-precedence values by default so that official @@ -30,16 +30,21 @@ define( function() { /// particuarly clever about it. Take care to keep the comment and formatting intact when /// bumping the version number. - var version = [ 0, 7, 0, "development", "" ]; // version-identifier + var version = [ 0, 8, 0, "", "", [ "ITDG", 3, 2, 2 ] ]; // version-identifier /// Render the version identifier as a SemVer-style string. version.toString = function() { return this.slice( 0, 3 ).join( "." ) + + ( this[ 5 ] ? "-" + this[ 5 ][0] + "." + this[ 5 ].slice( 1, 4 ).join( "." ) : "" ) + ( this[ 3 ] ? "-" + this[ 3 ] : "" ) + ( this[ 4 ] ? "+" + this[ 4 ] : "" ); }; + version.getDerivativeVersion = function () { + return ( this[ 5 ] ? this[ 5 ][0] + " " + this[ 5 ].slice( 1, 4 ).join( "." ) : "" ); + } + return version; } ); diff --git a/support/client/lib/vwf.js b/support/client/lib/vwf.js index 36e3e758a..b270d264c 100644 --- a/support/client/lib/vwf.js +++ b/support/client/lib/vwf.js @@ -323,6 +323,9 @@ "vwf/model/blockly/msg/js/en": { deps: [ "vwf/model/blockly/blockly_compressed" ] }, + "vwf/view/mocha/mocha": { + exports: "mocha", + }, } }; @@ -367,11 +370,11 @@ { library: "vwf/model/object", active: true }, { library: "vwf/model/stage/log", active: true }, { library: "vwf/model/kineticjs", - linkedLibraries: [ "vwf/model/kinetic/kinetic.min" ], + linkedLibraries: [ "vwf/model/kinetic/konva.min" ], active: false }, { library: "vwf/model/mil-sym", - linkedLibraries: [ "vwf/model/mil-sym/sm-bc.min" ], + linkedLibraries: [ "vwf/model/mil-sym/sm-c.min" ], active: false }, { library: "vwf/model/heightmap", active: false }, @@ -403,9 +406,16 @@ { library: "vwf/view/sound", active: false }, { library: "vwf/view/touch", active: false }, { library: "vwf/view/cesium", active: false }, - { library: "vwf/view/kineticjs", active: false }, { library: "vwf/view/mil-sym", active: false }, + { library: "vwf/view/kineticjs", active: false }, { library: "vwf/view/audio", active: false }, + { library: "vwf/view/mocha", + linkedLibraries: [ + "vwf/view/mocha/mocha", + "vwf/view/chai/chai" + ], + active: false + }, { library: "vwf/kernel/utility", active: true }, { library: "vwf/utility", active: true }, { library: "vwf/model/glge/glge-compiled", active: false }, @@ -423,11 +433,13 @@ { library: "vwf/view/google-earth", active: false }, { library: "vwf/model/cesium/Cesium", active: false }, { library: "vwf/model/blockly/JS-Interpreter/interpreter.js", active: false }, - { library: "vwf/model/kinetic/kinetic.min", active: false }, - { library: "vwf/model/mil-sym/sm-bc.min", active: false }, + { library: "vwf/model/mil-sym/sm-c.min", active: false }, + { library: "vwf/model/kinetic/konva.min", active: false }, { library: "vwf/model/buzz/buzz.min", active: false }, { library: "vwf/model/jPlayer.2.7.1/jquery.jplayer.min", active: false }, - { library: "vwf/admin", active: true } + { library: "vwf/admin", active: true }, + { library: "vwf/view/mocha/mocha", active:false }, + { library: "vwf/view/chai/chai", active:false } ]; var initializers = { @@ -440,8 +452,8 @@ { library: "vwf/model/blockly", active: false }, { library: "vwf/model/graphtool", active: false }, { library: "vwf/model/sound", active: false }, - { library: "vwf/model/kineticjs", active: false }, { library: "vwf/model/mil-sym", active: false }, + { library: "vwf/model/kineticjs", active: false }, { library: "vwf/model/heightmap", active: false }, { library: "vwf/model/buzz", active: false }, { library: "vwf/model/jPlayer", active: false }, @@ -458,10 +470,11 @@ { library: "vwf/view/blockly", active: false }, { library: "vwf/view/sound", active: false }, { library: "vwf/view/touch", active: false }, - { library: "vwf/view/kineticjs", active: false }, { library: "vwf/view/mil-sym", active: false }, + { library: "vwf/view/kineticjs", active: false }, { library: "vwf/view/audio", active: false }, - { library: "vwf/view/webrtc", active: false} + { library: "vwf/view/webrtc", active: false}, + { library: "vwf/view/mocha", active: false } ] }; mapLibraryName(requireArray); @@ -879,7 +892,7 @@ // timeout is controlled by the server.) transportOptions: { - "websocket": { timeout: 90000 }, + "websocket": { timeout: 600000 }, }, } ); @@ -980,9 +993,10 @@ } ); - socket.on( "error", function() { + socket.on( "error", function( error ) { //Overcome by compatibility.js websockets check + console.error( "socket.error:", error ); jQuery('body').html("
WebSockets connections are currently being blocked. Please check your proxy server settings.
"); } ); @@ -1109,7 +1123,7 @@ action: actionName, member: memberName, parameters: require( "vwf/utility" ).transform( parameters, require( "vwf/utility" ).transforms.transit ), - result: require( "vwf/utility" ).transform( result, require( "vwf/utility" ).transforms.transit ), + result: require( "vwf/utility" ).transform( result === undefined ? null : result, require( "vwf/utility" ).transforms.transit ), }; if ( socket ) { @@ -1565,11 +1579,10 @@ if ( componentIsURI( nodeComponent ) ) { // URI // TODO: allow non-vwf URIs (models, images, etc.) to pass through to stage 2 and pass directly to createChild() - // Resolve relative URIs, but leave host-relative, locally-absolute - // references intact. + // Resolve relative URIs, but express local resources as host-relative. - nodeURI = nodeComponent[0] == "/" ? - nodeComponent : require( "vwf/utility" ).resolveURI( nodeComponent, baseURI ); + nodeURI = require( "vwf/utility" ).resolveURI( nodeComponent, baseURI, + document.location.protocol + "//" + document.location.host + "/dummypath/" ); // Load the document if we haven't seen this URI yet. Mark the components // list to indicate that this component is loading. @@ -3379,7 +3392,6 @@ if ( ! childComponent.source ) { // Ignore the result if reentry is disabled and the driver attempted to call // back into the kernel. Kernel reentry is disabled during replication to // prevent coloring from accessor scripts. - if ( this.models.kernel.blocked() ) { // TODO: this might be better handled wholly in vwf/kernel/model by converting to a stage and clearing blocked results on the return value = undefined; } diff --git a/support/client/lib/vwf/configuration.js b/support/client/lib/vwf/configuration.js index b218bd533..b1ac2a8ab 100644 --- a/support/client/lib/vwf/configuration.js +++ b/support/client/lib/vwf/configuration.js @@ -174,13 +174,13 @@ define( function() { "randomize-ids": false, // randomize IDs to discourage assumptions about ID allocation "humanize-ids": false, // append recognizable strings to node IDs "preserve-script-closures": false, // retain method/event closures by not serializing functions (breaks replication, persistence) - "load-timeout": 10, // resource load timeout in seconds + "load-timeout": 60, // resource load timeout in seconds }, /// Changes for production environments. production: { - "load-timeout": 60, + "load-timeout": 120, }, /// Changes for development environments. @@ -189,7 +189,7 @@ define( function() { "log-level": "info", "randomize-ids": true, "humanize-ids": true, - "load-timeout": 30, + "load-timeout": 120, }, /// Changes for testing environments. diff --git a/support/client/lib/vwf/model/cesium.js b/support/client/lib/vwf/model/cesium.js index d47a142dd..cce63cdf5 100644 --- a/support/client/lib/vwf/model/cesium.js +++ b/support/client/lib/vwf/model/cesium.js @@ -1368,7 +1368,7 @@ define( [ "module", } ); if ( node.imageProvider !== undefined ) { - scene.globe.imageryLayers().addImageryProvider( node.imageProvider ); + scene.globe.imageryLayers.addImageryProvider( node.imageProvider ); node.imageryProviderValue = requestedType; } value = undefined; diff --git a/support/client/lib/vwf/model/jPlayer.js b/support/client/lib/vwf/model/jPlayer.js index 6debc886e..7324de2f0 100644 --- a/support/client/lib/vwf/model/jPlayer.js +++ b/support/client/lib/vwf/model/jPlayer.js @@ -397,6 +397,18 @@ define( [ mediaObject = { wav: url }; + } else if ( url.search( "data:audio/mp4" ) === 0 ) { + mediaObject = { + m4a: url + }; + } else if ( url.search( "data:audio/ogg" ) === 0 ) { + mediaObject = { + oga: url + }; + } else if ( url.search( "data:audio/webm" ) === 0 ) { + mediaObject = { + webma: url + }; } else { modelDriver.logger.errorx( "setUrl", "Unsupported sound type for '", url, "'" ); @@ -408,6 +420,16 @@ define( [ m4v: url, poster: node.posterImageUrl }; + } else if ( url.search( "data:video/ogg" ) === 0 ) { + mediaObject = { + ogv: url, + poster: node.posterImageUrl + }; + } else if ( url.search( "data:video/webm" ) === 0 ) { + mediaObject = { + webmv: url, + poster: node.posterImageUrl + }; } else { modelDriver.logger.errorx( "setUrl", "Unsupported video type for '", url, "'" ); diff --git a/support/client/lib/vwf/model/kinetic/README.txt b/support/client/lib/vwf/model/kinetic/README.txt new file mode 100644 index 000000000..9511d818a --- /dev/null +++ b/support/client/lib/vwf/model/kinetic/README.txt @@ -0,0 +1,3 @@ +drawImage in Konva has been modified with a try catch to allow drawing to succeed on some edge cases for iOS devices. +This may cause drawing to fail silently. A warning has been provided. The fix will exist until an official Konva solution +is provided. Any questions: spencer.j.frazier@lmco.com or kevin.j.landers@lmco.com \ No newline at end of file diff --git a/support/client/lib/vwf/model/kinetic/kinetic.min.js b/support/client/lib/vwf/model/kinetic/kinetic.min.js deleted file mode 100644 index 5736ac04c..000000000 --- a/support/client/lib/vwf/model/kinetic/kinetic.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! KineticJS v5.1.1 2014-06-10 http://www.kineticjs.com by Eric Rowell @ericdrowell - MIT License https://github.com/ericdrowell/KineticJS/wiki/License*/ -var Kinetic={};!function(a){var b=Math.PI/180;Kinetic={version:"5.1.1",stages:[],idCounter:0,ids:{},names:{},shapes:{},listenClickTap:!1,inDblClickWindow:!1,enableTrace:!1,traceArrMax:100,dblClickWindow:400,pixelRatio:void 0,dragDistance:0,angleDeg:!0,showWarnings:!0,Filters:{},Node:function(a){this._init(a)},Shape:function(a){this.__init(a)},Container:function(a){this.__init(a)},Stage:function(a){this.___init(a)},BaseLayer:function(a){this.___init(a)},Layer:function(a){this.____init(a)},FastLayer:function(a){this.____init(a)},Group:function(a){this.___init(a)},isDragging:function(){var a=Kinetic.DD;return a?a.isDragging:!1},isDragReady:function(){var a=Kinetic.DD;return a?!!a.node:!1},_addId:function(a,b){void 0!==b&&(this.ids[b]=a)},_removeId:function(a){void 0!==a&&delete this.ids[a]},_addName:function(a,b){void 0!==b&&(void 0===this.names[b]&&(this.names[b]=[]),this.names[b].push(a))},_removeName:function(a,b){if(void 0!==a){var c=this.names[a];if(void 0!==c){for(var d=0;d");Kinetic.document=f,Kinetic.window=Kinetic.document.createWindow(),Kinetic.window.Image=d.Image,Kinetic._nodeCanvas=d}return Kinetic.root=a,void(module.exports=c)}"function"==typeof define&&define.amd&&define(b),Kinetic.document=document,Kinetic.window=window,Kinetic.root=a}(this,function(){return Kinetic}),function(){Kinetic.Collection=function(){var a=[].slice.call(arguments),b=a.length,c=0;for(this.length=b;b>c;c++)this[c]=a[c];return this},Kinetic.Collection.prototype=[],Kinetic.Collection.prototype.each=function(a){for(var b=0;ba;a++)b.push(this[a]);return b},Kinetic.Collection.toCollection=function(a){var b,c=new Kinetic.Collection,d=a.length;for(b=0;d>b;b++)c.push(a[b]);return c},Kinetic.Collection._mapMethod=function(a){Kinetic.Collection.prototype[a]=function(){var b,c=this.length,d=[].slice.call(arguments);for(b=0;c>b;b++)this[b][a].apply(this[b],d);return this}},Kinetic.Collection.mapMethods=function(a){var b=a.prototype;for(var c in b)Kinetic.Collection._mapMethod(c)},Kinetic.Transform=function(a){this.m=a&&a.slice()||[1,0,0,1,0,0]},Kinetic.Transform.prototype={copy:function(){return new Kinetic.Transform(this.m)},point:function(a){var b=this.m;return{x:b[0]*a.x+b[2]*a.y+b[4],y:b[1]*a.x+b[3]*a.y+b[5]}},translate:function(a,b){return this.m[4]+=this.m[0]*a+this.m[2]*b,this.m[5]+=this.m[1]*a+this.m[3]*b,this},scale:function(a,b){return this.m[0]*=a,this.m[1]*=a,this.m[2]*=b,this.m[3]*=b,this},rotate:function(a){var b=Math.cos(a),c=Math.sin(a),d=this.m[0]*b+this.m[2]*c,e=this.m[1]*b+this.m[3]*c,f=this.m[0]*-c+this.m[2]*b,g=this.m[1]*-c+this.m[3]*b;return this.m[0]=d,this.m[1]=e,this.m[2]=f,this.m[3]=g,this},getTranslation:function(){return{x:this.m[4],y:this.m[5]}},skew:function(a,b){var c=this.m[0]+this.m[2]*b,d=this.m[1]+this.m[3]*b,e=this.m[2]+this.m[0]*a,f=this.m[3]+this.m[1]*a;return this.m[0]=c,this.m[1]=d,this.m[2]=e,this.m[3]=f,this},multiply:function(a){var b=this.m[0]*a.m[0]+this.m[2]*a.m[1],c=this.m[1]*a.m[0]+this.m[3]*a.m[1],d=this.m[0]*a.m[2]+this.m[2]*a.m[3],e=this.m[1]*a.m[2]+this.m[3]*a.m[3],f=this.m[0]*a.m[4]+this.m[2]*a.m[5]+this.m[4],g=this.m[1]*a.m[4]+this.m[3]*a.m[5]+this.m[5];return this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g,this},invert:function(){var a=1/(this.m[0]*this.m[3]-this.m[1]*this.m[2]),b=this.m[3]*a,c=-this.m[1]*a,d=-this.m[2]*a,e=this.m[0]*a,f=a*(this.m[2]*this.m[5]-this.m[3]*this.m[4]),g=a*(this.m[1]*this.m[4]-this.m[0]*this.m[5]);return this.m[0]=b,this.m[1]=c,this.m[2]=d,this.m[3]=e,this.m[4]=f,this.m[5]=g,this},getMatrix:function(){return this.m},setAbsolutePosition:function(a,b){var c=this.m[0],d=this.m[1],e=this.m[2],f=this.m[3],g=this.m[4],h=this.m[5],i=(c*(b-h)-d*(a-g))/(c*f-d*e),j=(a-g-e*i)/c;return this.translate(j,i)}};var a="2d",b="[object Array]",c="[object Number]",d="[object String]",e=Math.PI/180,f=180/Math.PI,g="#",h="",i="0",j="Kinetic warning: ",k="Kinetic error: ",l="rgb(",m={aqua:[0,255,255],lime:[0,255,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,255],navy:[0,0,128],white:[255,255,255],fuchsia:[255,0,255],olive:[128,128,0],yellow:[255,255,0],orange:[255,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[255,0,0],pink:[255,192,203],cyan:[0,255,255],transparent:[255,255,255,0]},n=/rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/;Kinetic.Util={_isElement:function(a){return!(!a||1!=a.nodeType)},_isFunction:function(a){return!!(a&&a.constructor&&a.call&&a.apply)},_isObject:function(a){return!!a&&a.constructor==Object},_isArray:function(a){return Object.prototype.toString.call(a)==b},_isNumber:function(a){return Object.prototype.toString.call(a)==c},_isString:function(a){return Object.prototype.toString.call(a)==d},_throttle:function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:(new Date).getTime(),g=null,f=a.apply(d,e),d=e=null};return function(){var j=(new Date).getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),d=e=null):g||c.trailing===!1||(g=setTimeout(i,k)),f}},_hasMethods:function(a){var b,c=[];for(b in a)this._isFunction(a[b])&&c.push(b);return c.length>0},createCanvasElement:function(){var a=Kinetic.document.createElement("canvas");return a.style=a.style||{},a},isBrowser:function(){return"object"!=typeof exports},_isInDocument:function(a){for(;a=a.parentNode;)if(a==Kinetic.document)return!0;return!1},_simplifyArray:function(a){var b,c,d=[],e=a.length,f=Kinetic.Util;for(b=0;e>b;b++)c=a[b],f._isNumber(c)?c=Math.round(1e3*c)/1e3:f._isString(c)||(c=c.toString()),d.push(c);return d},_getImage:function(b,c){var d,e;if(b)if(this._isElement(b))c(b);else if(this._isString(b))d=new Kinetic.window.Image,d.onload=function(){c(d)},d.src=b;else if(b.data){e=Kinetic.Util.createCanvasElement(),e.width=b.width,e.height=b.height;var f=e.getContext(a);f.putImageData(b,0,0),this._getImage(e.toDataURL(),c)}else c(null);else c(null)},_getRGBAString:function(a){var b=a.red||0,c=a.green||0,d=a.blue||0,e=a.alpha||1;return["rgba(",b,",",c,",",d,",",e,")"].join(h)},_rgbToHex:function(a,b,c){return((1<<24)+(a<<16)+(b<<8)+c).toString(16).slice(1)},_hexToRgb:function(a){a=a.replace(g,h);var b=parseInt(a,16);return{r:b>>16&255,g:b>>8&255,b:255&b}},getRandomColor:function(){for(var a=(16777215*Math.random()<<0).toString(16);a.length<6;)a=i+a;return g+a},get:function(a,b){return void 0===a?b:a},getRGB:function(a){var b;return a in m?(b=m[a],{r:b[0],g:b[1],b:b[2]}):a[0]===g?this._hexToRgb(a.substring(1)):a.substr(0,4)===l?(b=n.exec(a.replace(/ /g,"")),{r:parseInt(b[1],10),g:parseInt(b[2],10),b:parseInt(b[3],10)}):{r:0,g:0,b:0}},_merge:function(a,b){var c=this._clone(b);for(var d in a)c[d]=this._isObject(a[d])?this._merge(a[d],c[d]):a[d];return c},cloneObject:function(a){var b={};for(var c in a)b[c]=this._isObject(a[c])?this.cloneObject(a[c]):this._isArray(a[c])?this.cloneArray(a[c]):a[c];return b},cloneArray:function(a){return a.slice(0)},_degToRad:function(a){return a*e},_radToDeg:function(a){return a*f},_capitalize:function(a){return a.charAt(0).toUpperCase()+a.slice(1)},error:function(a){throw new Error(k+a)},warn:function(a){Kinetic.root.console&&console.warn&&Kinetic.showWarnings&&console.warn(j+a)},extend:function(a,b){for(var c in b.prototype)c in a.prototype||(a.prototype[c]=b.prototype[c])},addMethods:function(a,b){var c;for(c in b)a.prototype[c]=b[c]},_getControlPoints:function(a,b,c,d,e,f,g){var h=Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2)),i=Math.sqrt(Math.pow(e-c,2)+Math.pow(f-d,2)),j=g*h/(h+i),k=g*i/(h+i),l=c-j*(e-a),m=d-j*(f-b),n=c+k*(e-a),o=d+k*(f-b);return[l,m,n,o]},_expandPoints:function(a,b){var c,d,e=a.length,f=[];for(c=2;e-2>c;c+=2)d=Kinetic.Util._getControlPoints(a[c-2],a[c-1],a[c],a[c+1],a[c+2],a[c+3],b),f.push(d[0]),f.push(d[1]),f.push(a[c]),f.push(a[c+1]),f.push(d[2]),f.push(d[3]);return f},_removeLastLetter:function(a){return a.substring(0,a.length-1)}}}(),function(){var a=Kinetic.Util.createCanvasElement(),b=a.getContext("2d"),c=Kinetic.UA.mobile?function(){var a=window.devicePixelRatio||1,c=b.webkitBackingStorePixelRatio||b.mozBackingStorePixelRatio||b.msBackingStorePixelRatio||b.oBackingStorePixelRatio||b.backingStorePixelRatio||1;return a/c}():1;Kinetic.Canvas=function(a){this.init(a)},Kinetic.Canvas.prototype={init:function(a){a=a||{};var b=a.pixelRatio||Kinetic.pixelRatio||c;this.pixelRatio=b,this._canvas=Kinetic.Util.createCanvasElement(),this._canvas.style.padding=0,this._canvas.style.margin=0,this._canvas.style.border=0,this._canvas.style.background="transparent",this._canvas.style.position="absolute",this._canvas.style.top=0,this._canvas.style.left=0},getContext:function(){return this.context},getPixelRatio:function(){return this.pixelRatio},setPixelRatio:function(a){this.pixelRatio=a,this.setSize(this.getWidth(),this.getHeight())},setWidth:function(a){this.width=this._canvas.width=a*this.pixelRatio,this._canvas.style.width=a+"px"},setHeight:function(a){this.height=this._canvas.height=a*this.pixelRatio,this._canvas.style.height=a+"px"},getWidth:function(){return this.width},getHeight:function(){return this.height},setSize:function(a,b){this.setWidth(a),this.setHeight(b)},toDataURL:function(a,b){try{return this._canvas.toDataURL(a,b)}catch(c){try{return this._canvas.toDataURL()}catch(d){return Kinetic.Util.warn("Unable to get data URL. "+d.message),""}}}},Kinetic.SceneCanvas=function(a){a=a||{};var b=a.width||0,c=a.height||0;Kinetic.Canvas.call(this,a),this.context=new Kinetic.SceneContext(this),this.setSize(b,c)},Kinetic.SceneCanvas.prototype={setWidth:function(a){var b=this.pixelRatio,c=this.getContext()._context;Kinetic.Canvas.prototype.setWidth.call(this,a),c.scale(b,b)},setHeight:function(a){var b=this.pixelRatio,c=this.getContext()._context;Kinetic.Canvas.prototype.setHeight.call(this,a),c.scale(b,b)}},Kinetic.Util.extend(Kinetic.SceneCanvas,Kinetic.Canvas),Kinetic.HitCanvas=function(a){a=a||{};var b=a.width||0,c=a.height||0;Kinetic.Canvas.call(this,a),this.context=new Kinetic.HitContext(this),this.setSize(b,c)},Kinetic.Util.extend(Kinetic.HitCanvas,Kinetic.Canvas)}(),function(){var a=",",b="(",c=")",d="([",e="])",f=";",g="()",h="=",i=["arc","arcTo","beginPath","bezierCurveTo","clearRect","clip","closePath","createLinearGradient","createPattern","createRadialGradient","drawImage","fill","fillText","getImageData","createImageData","lineTo","moveTo","putImageData","quadraticCurveTo","rect","restore","rotate","save","scale","setLineDash","setTransform","stroke","strokeText","transform","translate"];Kinetic.Context=function(a){this.init(a)},Kinetic.Context.prototype={init:function(a){this.canvas=a,this._context=a._canvas.getContext("2d"),Kinetic.enableTrace&&(this.traceArr=[],this._enableTrace())},fillShape:function(a){a.getFillEnabled()&&this._fill(a)},strokeShape:function(a){a.getStrokeEnabled()&&this._stroke(a)},fillStrokeShape:function(a){var b=a.getFillEnabled();b&&this._fill(a),a.getStrokeEnabled()&&this._stroke(a)},getTrace:function(i){var j,k,l,m,n=this.traceArr,o=n.length,p="";for(j=0;o>j;j++)k=n[j],l=k.method,l?(m=k.args,p+=l,p+=i?g:Kinetic.Util._isArray(m[0])?d+m.join(a)+e:b+m.join(a)+c):(p+=k.property,i||(p+=h+k.val)),p+=f;return p},clearTrace:function(){this.traceArr=[]},_trace:function(a){var b,c=this.traceArr;c.push(a),b=c.length,b>=Kinetic.traceArrMax&&c.shift()},reset:function(){var a=this.getCanvas().getPixelRatio();this.setTransform(1*a,0,0,1*a,0,0)},getCanvas:function(){return this.canvas},clear:function(a){var b=this.getCanvas();a?this.clearRect(a.x||0,a.y||0,a.width||0,a.height||0):this.clearRect(0,0,b.getWidth(),b.getHeight())},_applyLineCap:function(a){var b=a.getLineCap();b&&this.setAttr("lineCap",b)},_applyOpacity:function(a){var b=a.getAbsoluteOpacity();1!==b&&this.setAttr("globalAlpha",b)},_applyLineJoin:function(a){var b=a.getLineJoin();b&&this.setAttr("lineJoin",b)},setAttr:function(a,b){this._context[a]=b},arc:function(){var a=arguments;this._context.arc(a[0],a[1],a[2],a[3],a[4],a[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var a=arguments;this._context.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5])},clearRect:function(){var a=arguments;this._context.clearRect(a[0],a[1],a[2],a[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createImageData:function(){var a=arguments;return 2===a.length?this._context.createImageData(a[0],a[1]):1===a.length?this._context.createImageData(a[0]):void 0},createLinearGradient:function(){var a=arguments;return this._context.createLinearGradient(a[0],a[1],a[2],a[3])},createPattern:function(){var a=arguments;return this._context.createPattern(a[0],a[1])},createRadialGradient:function(){var a=arguments;return this._context.createRadialGradient(a[0],a[1],a[2],a[3],a[4],a[5])},drawImage:function(){var a=arguments,b=this._context;3===a.length?b.drawImage(a[0],a[1],a[2]):5===a.length?b.drawImage(a[0],a[1],a[2],a[3],a[4]):9===a.length&&b.drawImage(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])},fill:function(){this._context.fill()},fillText:function(){var a=arguments;this._context.fillText(a[0],a[1],a[2])},getImageData:function(){var a=arguments;return this._context.getImageData(a[0],a[1],a[2],a[3])},lineTo:function(){var a=arguments;this._context.lineTo(a[0],a[1])},moveTo:function(){var a=arguments;this._context.moveTo(a[0],a[1])},rect:function(){var a=arguments;this._context.rect(a[0],a[1],a[2],a[3])},putImageData:function(){var a=arguments;this._context.putImageData(a[0],a[1],a[2])},quadraticCurveTo:function(){var a=arguments;this._context.quadraticCurveTo(a[0],a[1],a[2],a[3])},restore:function(){this._context.restore()},rotate:function(){var a=arguments;this._context.rotate(a[0])},save:function(){this._context.save()},scale:function(){var a=arguments;this._context.scale(a[0],a[1])},setLineDash:function(){var a=arguments,b=this._context;this._context.setLineDash?b.setLineDash(a[0]):"mozDash"in b?b.mozDash=a[0]:"webkitLineDash"in b&&(b.webkitLineDash=a[0])},setTransform:function(){var a=arguments;this._context.setTransform(a[0],a[1],a[2],a[3],a[4],a[5])},stroke:function(){this._context.stroke()},strokeText:function(){var a=arguments;this._context.strokeText(a[0],a[1],a[2])},transform:function(){var a=arguments;this._context.transform(a[0],a[1],a[2],a[3],a[4],a[5])},translate:function(){var a=arguments;this._context.translate(a[0],a[1])},_enableTrace:function(){var a,b,c=this,d=i.length,e=Kinetic.Util._simplifyArray,f=this.setAttr,g=function(a){var d,f=c[a];c[a]=function(){return b=e(Array.prototype.slice.call(arguments,0)),d=f.apply(c,arguments),c._trace({method:a,args:b}),d}};for(a=0;d>a;a++)g(i[a]);c.setAttr=function(){f.apply(c,arguments),c._trace({property:arguments[0],val:arguments[1]})}}},Kinetic.SceneContext=function(a){Kinetic.Context.call(this,a)},Kinetic.SceneContext.prototype={_fillColor:function(a){var b=a.fill()||Kinetic.Util._getRGBAString({red:a.fillRed(),green:a.fillGreen(),blue:a.fillBlue(),alpha:a.fillAlpha()});this.setAttr("fillStyle",b),a._fillFunc(this)},_fillPattern:function(a){var b=a.getFillPatternImage(),c=a.getFillPatternX(),d=a.getFillPatternY(),e=a.getFillPatternScale(),f=Kinetic.getAngle(a.getFillPatternRotation()),g=a.getFillPatternOffset(),h=a.getFillPatternRepeat();(c||d)&&this.translate(c||0,d||0),f&&this.rotate(f),e&&this.scale(e.x,e.y),g&&this.translate(-1*g.x,-1*g.y),this.setAttr("fillStyle",this.createPattern(b,h||"repeat")),this.fill()},_fillLinearGradient:function(a){var b=a.getFillLinearGradientStartPoint(),c=a.getFillLinearGradientEndPoint(),d=a.getFillLinearGradientColorStops(),e=this.createLinearGradient(b.x,b.y,c.x,c.y);if(d){for(var f=0;fh;h++)i=e[h],a[i]=this.getAttr(d+k(i));return a},c.prototype[m]=function(a){var b,c=this.attrs[d];f&&(a=f.call(this,a));for(b in a)this._setAttr(d+k(b),a[b]);return this._fireChangeEvent(d,c,a),g&&g.call(this),this},this.addOverloadedGetterSetter(c,d)},addOverloadedGetterSetter:function(c,d){var e=Kinetic.Util._capitalize(d),f=b+e,g=a+e;c.prototype[d]=function(){return arguments.length?(this[f](arguments[0]),this):this[g]()}},backCompat:function(a,b){var c;for(c in b)a.prototype[c]=a.prototype[b[c]]},afterSetFilter:function(){this._filterUpToDate=!1}},Kinetic.Validators={RGBComponent:function(a){return a>255?255:0>a?0:Math.round(a)},alphaComponent:function(a){return a>1?1:1e-4>a?1e-4:a}}}(),function(){var a="absoluteOpacity",b="absoluteTransform",c="Change",d="children",e=".",f="",g="get",h="id",i="kinetic",j="listening",k="mouseenter",l="mouseleave",m="name",n="set",o="Shape",p=" ",q="stage",r="transform",s="Stage",t="visible",u=["id"],v=["xChange.kinetic","yChange.kinetic","scaleXChange.kinetic","scaleYChange.kinetic","skewXChange.kinetic","skewYChange.kinetic","rotationChange.kinetic","offsetXChange.kinetic","offsetYChange.kinetic","transformsEnabledChange.kinetic"].join(p);Kinetic.Util.addMethods(Kinetic.Node,{_init:function(c){var d=this;this._id=Kinetic.idCounter++,this.eventListeners={},this.attrs={},this._cache={},this._filterUpToDate=!1,this.setAttrs(c),this.on(v,function(){this._clearCache(r),d._clearSelfAndDescendantCache(b)}),this.on("visibleChange.kinetic",function(){d._clearSelfAndDescendantCache(t)}),this.on("listeningChange.kinetic",function(){d._clearSelfAndDescendantCache(j)}),this.on("opacityChange.kinetic",function(){d._clearSelfAndDescendantCache(a)})},_clearCache:function(a){a?delete this._cache[a]:this._cache={}},_getCache:function(a,b){var c=this._cache[a];return void 0===c&&(this._cache[a]=b.call(this)),this._cache[a]},_clearSelfAndDescendantCache:function(a){this._clearCache(a),this.children&&this.getChildren().each(function(b){b._clearSelfAndDescendantCache(a)})},clearCache:function(){return delete this._cache.canvas,this._filterUpToDate=!1,this},cache:function(a){{var b=a||{},c=b.x||0,d=b.y||0,e=b.width||this.width(),f=b.height||this.height(),g=b.drawBorder||!1;this.getLayer()}if(0===e||0===f)return void Kinetic.Util.warn("Width or height of caching configuration equals 0. Cache is ignored.");var h=new Kinetic.SceneCanvas({pixelRatio:1,width:e,height:f}),i=new Kinetic.SceneCanvas({pixelRatio:1,width:e,height:f}),j=new Kinetic.HitCanvas({width:e,height:f}),k=(this.transformsEnabled(),this.x(),this.y(),h.getContext()),l=j.getContext();return j.isCache=!0,this.clearCache(),k.save(),l.save(),g&&(k.save(),k.beginPath(),k.rect(0,0,e,f),k.closePath(),k.setAttr("strokeStyle","red"),k.setAttr("lineWidth",5),k.stroke(),k.restore()),k.translate(-1*c,-1*d),l.translate(-1*c,-1*d),"Shape"===this.nodeType&&(k.translate(-1*this.x(),-1*this.y()),l.translate(-1*this.x(),-1*this.y())),this.drawScene(h,this),this.drawHit(j,this),k.restore(),l.restore(),this._cache.canvas={scene:h,filter:i,hit:j},this},_drawCachedSceneCanvas:function(a){a.save(),this.getLayer()._applyTransform(this,a),a._applyOpacity(this),a.drawImage(this._getCachedSceneCanvas()._canvas,0,0),a.restore()},_getCachedSceneCanvas:function(){var a,b,c,d,e=this.filters(),f=this._cache.canvas,g=f.scene,h=f.filter,i=h.getContext();if(e){if(!this._filterUpToDate){try{for(a=e.length,i.clear(),i.drawImage(g._canvas,0,0),b=i.getImageData(0,0,h.getWidth(),h.getHeight()),c=0;a>c;c++)d=e[c],d.call(this,b),i.putImageData(b,0,0)}catch(j){Kinetic.Util.warn("Unable to apply filter. "+j.message)}this._filterUpToDate=!0}return h}return g},_drawCachedHitCanvas:function(a){var b=this._cache.canvas,c=b.hit;a.save(),this.getLayer()._applyTransform(this,a),a.drawImage(c._canvas,0,0),a.restore()},on:function(a,b){var c,d,g,h,i,j=a.split(p),k=j.length;for(c=0;k>c;c++)d=j[c],g=d.split(e),h=g[0],i=g[1]||f,this.eventListeners[h]||(this.eventListeners[h]=[]),this.eventListeners[h].push({name:i,handler:b});return this},off:function(a){var b,c,d,f,g,h,i=(a||"").split(p),j=i.length;if(!a)for(c in this.eventListeners)this._off(c);for(b=0;j>b;b++)if(d=i[b],f=d.split(e),g=f[0],h=f[1],g)this.eventListeners[g]&&this._off(g,h);else for(c in this.eventListeners)this._off(c,h);return this},dispatchEvent:function(a){var b={target:this,type:a.type,evt:a};this.fire(a.type,b)},addEventListener:function(a,b){this.on(a,function(a){b.call(this,a.evt)})},removeEventListener:function(a){this.off(a)},remove:function(){var c=this.getParent();return c&&c.children&&(c.children.splice(this.index,1),c._setChildrenIndices(),delete this.parent),this._clearSelfAndDescendantCache(q),this._clearSelfAndDescendantCache(b),this._clearSelfAndDescendantCache(t),this._clearSelfAndDescendantCache(j),this._clearSelfAndDescendantCache(a),this},destroy:function(){Kinetic._removeId(this.getId()),Kinetic._removeName(this.getName(),this._id),this.remove()},getAttr:function(a){var b=g+Kinetic.Util._capitalize(a);return Kinetic.Util._isFunction(this[b])?this[b]():this.attrs[a]},getAncestors:function(){for(var a=this.getParent(),b=new Kinetic.Collection;a;)b.push(a),a=a.getParent();return b},getAttrs:function(){return this.attrs||{}},setAttrs:function(a){var b,c;if(a)for(b in a)b===d||(c=n+Kinetic.Util._capitalize(b),Kinetic.Util._isFunction(this[c])?this[c](a[b]):this._setAttr(b,a[b]));return this},isListening:function(){return this._getCache(j,this._isListening)},_isListening:function(){var a=this.getListening(),b=this.getParent();return"inherit"===a?b?b.isListening():!0:a},isVisible:function(){return this._getCache(t,this._isVisible)},_isVisible:function(){var a=this.getVisible(),b=this.getParent();return"inherit"===a?b?b.isVisible():!0:a},shouldDrawHit:function(a){var b=this.getLayer();return a&&a.isCache||b&&b.hitGraphEnabled()&&this.isListening()&&this.isVisible()&&!Kinetic.isDragging()},show:function(){return this.setVisible(!0),this},hide:function(){return this.setVisible(!1),this},getZIndex:function(){return this.index||0},getAbsoluteZIndex:function(){function a(i){for(b=[],c=i.length,d=0;c>d;d++)e=i[d],h++,e.nodeType!==o&&(b=b.concat(e.getChildren().toArray())),e._id===g._id&&(d=c);b.length>0&&b[0].getDepth()<=f&&a(b)}var b,c,d,e,f=this.getDepth(),g=this,h=0;return g.nodeType!==s&&a(g.getStage().getChildren()),h},getDepth:function(){for(var a=0,b=this.parent;b;)a++,b=b.parent;return a},setPosition:function(a){return this.setX(a.x),this.setY(a.y),this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(){var a=this.getAbsoluteTransform().getMatrix(),b=new Kinetic.Transform,c=this.offset();return b.m=a.slice(),b.translate(c.x,c.y),b.getTranslation()},setAbsolutePosition:function(a){var b,c=this._clearTransform();return this.attrs.x=c.x,this.attrs.y=c.y,delete c.x,delete c.y,b=this.getAbsoluteTransform(),b.invert(),b.translate(a.x,a.y),a={x:this.attrs.x+b.getTranslation().x,y:this.attrs.y+b.getTranslation().y},this.setPosition({x:a.x,y:a.y}),this._setTransform(c),this},_setTransform:function(a){var c;for(c in a)this.attrs[c]=a[c];this._clearCache(r),this._clearSelfAndDescendantCache(b)},_clearTransform:function(){var a={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};return this.attrs.x=0,this.attrs.y=0,this.attrs.rotation=0,this.attrs.scaleX=1,this.attrs.scaleY=1,this.attrs.offsetX=0,this.attrs.offsetY=0,this.attrs.skewX=0,this.attrs.skewY=0,this._clearCache(r),this._clearSelfAndDescendantCache(b),a},move:function(a){var b=a.x,c=a.y,d=this.getX(),e=this.getY();return void 0!==b&&(d+=b),void 0!==c&&(e+=c),this.setPosition({x:d,y:e}),this},_eachAncestorReverse:function(a,b){var c,d,e=[],f=this.getParent();if(b&&b._id===this._id)return a(this),!0;for(e.unshift(this);f&&(!b||f._id!==b._id);)e.unshift(f),f=f.parent;for(c=e.length,d=0;c>d;d++)a(e[d])},rotate:function(a){return this.setRotation(this.getRotation()+a),this},moveToTop:function(){if(!this.parent)return void Kinetic.Util.warn("Node has no parent. moveToTop function is ignored.");var a=this.index;return this.parent.children.splice(a,1),this.parent.children.push(this),this.parent._setChildrenIndices(),!0},moveUp:function(){if(!this.parent)return void Kinetic.Util.warn("Node has no parent. moveUp function is ignored.");var a=this.index,b=this.parent.getChildren().length;return b-1>a?(this.parent.children.splice(a,1),this.parent.children.splice(a+1,0,this),this.parent._setChildrenIndices(),!0):!1},moveDown:function(){if(!this.parent)return void Kinetic.Util.warn("Node has no parent. moveDown function is ignored.");var a=this.index;return a>0?(this.parent.children.splice(a,1),this.parent.children.splice(a-1,0,this),this.parent._setChildrenIndices(),!0):!1},moveToBottom:function(){if(!this.parent)return void Kinetic.Util.warn("Node has no parent. moveToBottom function is ignored.");var a=this.index;return a>0?(this.parent.children.splice(a,1),this.parent.children.unshift(this),this.parent._setChildrenIndices(),!0):!1},setZIndex:function(a){if(!this.parent)return void Kinetic.Util.warn("Node has no parent. zIndex parameter is ignored.");var b=this.index;return this.parent.children.splice(b,1),this.parent.children.splice(a,0,this),this.parent._setChildrenIndices(),this},getAbsoluteOpacity:function(){return this._getCache(a,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var a=this.getOpacity();return this.getParent()&&(a*=this.getParent().getAbsoluteOpacity()),a},moveTo:function(a){return Kinetic.Node.prototype.remove.call(this),a.add(this),this},toObject:function(){var a,b,c,d,e=Kinetic.Util,f={},g=this.getAttrs();f.attrs={};for(a in g)b=g[a],e._isFunction(b)||e._isElement(b)||e._isObject(b)&&e._hasMethods(b)||(c=this[a],delete g[a],d=c?c.call(this):null,g[a]=b,d!==b&&(f.attrs[a]=b));return f.className=this.getClassName(),f},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},getLayer:function(){var a=this.getParent();return a?a.getLayer():null},getStage:function(){return this._getCache(q,this._getStage)},_getStage:function(){var a=this.getParent();return a?a.getStage():void 0},fire:function(a,b,c){return c?this._fireAndBubble(a,b||{}):this._fire(a,b||{}),this},getAbsoluteTransform:function(a){return a?this._getAbsoluteTransform(a):this._getCache(b,this._getAbsoluteTransform)},_getAbsoluteTransform:function(a){var b,c,d=new Kinetic.Transform;return this._eachAncestorReverse(function(a){b=a.transformsEnabled(),c=a.getTransform(),"all"===b?d.multiply(c):"position"===b&&d.translate(a.x(),a.y())},a),d},getTransform:function(){return this._getCache(r,this._getTransform)},_getTransform:function(){var a=new Kinetic.Transform,b=this.getX(),c=this.getY(),d=Kinetic.getAngle(this.getRotation()),e=this.getScaleX(),f=this.getScaleY(),g=this.getSkewX(),h=this.getSkewY(),i=this.getOffsetX(),j=this.getOffsetY();return(0!==b||0!==c)&&a.translate(b,c),0!==d&&a.rotate(d),(0!==g||0!==h)&&a.skew(g,h),(1!==e||1!==f)&&a.scale(e,f),(0!==i||0!==j)&&a.translate(-1*i,-1*j),a},clone:function(a){var b,c,d,e,f,g=this.getClassName(),h=Kinetic.Util.cloneObject(this.attrs);for(var j in u){var k=u[j];delete h[k]}for(b in a)h[b]=a[b];var l=new Kinetic[g](h);for(b in this.eventListeners)for(c=this.eventListeners[b],d=c.length,e=0;d>e;e++)f=c[e],f.name.indexOf(i)<0&&(l.eventListeners[b]||(l.eventListeners[b]=[]),l.eventListeners[b].push(f));return l},toDataURL:function(a){a=a||{};var b=a.mimeType||null,c=a.quality||null,d=this.getStage(),e=a.x||0,f=a.y||0,g=new Kinetic.SceneCanvas({width:a.width||this.getWidth()||(d?d.getWidth():0),height:a.height||this.getHeight()||(d?d.getHeight():0),pixelRatio:1}),h=g.getContext();return h.save(),(e||f)&&h.translate(-1*e,-1*f),this.drawScene(g),h.restore(),g.toDataURL(b,c)},toImage:function(a){Kinetic.Util._getImage(this.toDataURL(a),function(b){a.callback(b)})},setSize:function(a){return this.setWidth(a.width),this.setHeight(a.height),this},getSize:function(){return{width:this.getWidth(),height:this.getHeight()}},getWidth:function(){return this.attrs.width||0},getHeight:function(){return this.attrs.height||0},getClassName:function(){return this.className||this.nodeType},getType:function(){return this.nodeType},getDragDistance:function(){return void 0!==this.attrs.dragDistance?this.attrs.dragDistance:this.parent?this.parent.getDragDistance():Kinetic.dragDistance},_get:function(a){return this.className===a||this.nodeType===a?[this]:[] -},_off:function(a,b){var c,d,e=this.eventListeners[a];for(c=0;ce;e++)c.add(this._createNode(g[e]));return c},Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"position"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"x",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"y",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"opacity",1),Kinetic.Factory.addGetter(Kinetic.Node,"name"),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"name"),Kinetic.Factory.addGetter(Kinetic.Node,"id"),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"id"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"rotation",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Node,"scale",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Node,"scaleX",1),Kinetic.Factory.addGetterSetter(Kinetic.Node,"scaleY",1),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Node,"skew",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Node,"skewX",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"skewY",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Node,"offset",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Node,"offsetX",0),Kinetic.Factory.addGetterSetter(Kinetic.Node,"offsetY",0),Kinetic.Factory.addSetter(Kinetic.Node,"dragDistance"),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"dragDistance"),Kinetic.Factory.addSetter(Kinetic.Node,"width",0),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"width"),Kinetic.Factory.addSetter(Kinetic.Node,"height",0),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"height"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"listening","inherit"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"filters",void 0,function(a){return this._filterUpToDate=!1,a}),Kinetic.Factory.addGetterSetter(Kinetic.Node,"visible","inherit"),Kinetic.Factory.addGetterSetter(Kinetic.Node,"transformsEnabled","all"),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"size"),Kinetic.Factory.backCompat(Kinetic.Node,{rotateDeg:"rotate",setRotationDeg:"setRotation",getRotationDeg:"getRotation"}),Kinetic.Collection.mapMethods(Kinetic.Node)}(),function(){Kinetic.Filters.Grayscale=function(a){var b,c,d=a.data,e=d.length;for(b=0;e>b;b+=4)c=.34*d[b]+.5*d[b+1]+.16*d[b+2],d[b]=c,d[b+1]=c,d[b+2]=c}}(),function(){Kinetic.Filters.Brighten=function(a){var b,c=255*this.brightness(),d=a.data,e=d.length;for(b=0;e>b;b+=4)d[b]+=c,d[b+1]+=c,d[b+2]+=c},Kinetic.Factory.addGetterSetter(Kinetic.Node,"brightness",0,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.Invert=function(a){var b,c=a.data,d=c.length;for(b=0;d>b;b+=4)c[b]=255-c[b],c[b+1]=255-c[b+1],c[b+2]=255-c[b+2]}}(),function(){function a(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}function b(b,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D=b.data,E=b.width,F=b.height,G=e+e+1,H=E-1,I=F-1,J=e+1,K=J*(J+1)/2,L=new a,M=null,N=L,O=null,P=null,Q=c[e],R=d[e];for(h=1;G>h;h++)N=N.next=new a,h==J&&(M=N);for(N.next=L,l=k=0,g=0;F>g;g++){for(u=v=w=x=m=n=o=p=0,q=J*(y=D[k]),r=J*(z=D[k+1]),s=J*(A=D[k+2]),t=J*(B=D[k+3]),m+=K*y,n+=K*z,o+=K*A,p+=K*B,N=L,h=0;J>h;h++)N.r=y,N.g=z,N.b=A,N.a=B,N=N.next;for(h=1;J>h;h++)i=k+((h>H?H:h)<<2),m+=(N.r=y=D[i])*(C=J-h),n+=(N.g=z=D[i+1])*C,o+=(N.b=A=D[i+2])*C,p+=(N.a=B=D[i+3])*C,u+=y,v+=z,w+=A,x+=B,N=N.next;for(O=L,P=M,f=0;E>f;f++)D[k+3]=B=p*Q>>R,0!==B?(B=255/B,D[k]=(m*Q>>R)*B,D[k+1]=(n*Q>>R)*B,D[k+2]=(o*Q>>R)*B):D[k]=D[k+1]=D[k+2]=0,m-=q,n-=r,o-=s,p-=t,q-=O.r,r-=O.g,s-=O.b,t-=O.a,i=l+((i=f+e+1)f;f++){for(v=w=x=u=n=o=p=m=0,k=f<<2,q=J*(y=D[k]),r=J*(z=D[k+1]),s=J*(A=D[k+2]),t=J*(B=D[k+3]),m+=K*y,n+=K*z,o+=K*A,p+=K*B,N=L,h=0;J>h;h++)N.r=y,N.g=z,N.b=A,N.a=B,N=N.next;for(j=E,h=1;e>=h;h++)k=j+f<<2,m+=(N.r=y=D[k])*(C=J-h),n+=(N.g=z=D[k+1])*C,o+=(N.b=A=D[k+2])*C,p+=(N.a=B=D[k+3])*C,u+=y,v+=z,w+=A,x+=B,N=N.next,I>h&&(j+=E);for(k=f,O=L,P=M,g=0;F>g;g++)i=k<<2,D[i+3]=B=p*Q>>R,B>0?(B=255/B,D[i]=(m*Q>>R)*B,D[i+1]=(n*Q>>R)*B,D[i+2]=(o*Q>>R)*B):D[i]=D[i+1]=D[i+2]=0,m-=q,n-=r,o-=s,p-=t,q-=O.r,r-=O.g,s-=O.b,t-=O.a,i=f+((i=g+J)0&&b(a,c)},Kinetic.Factory.addGetterSetter(Kinetic.Node,"blurRadius",0,null,Kinetic.Factory.afterSetFilter)}(),function(){function a(a,b,c){var d=4*(c*a.width+b),e=[];return e.push(a.data[d++],a.data[d++],a.data[d++],a.data[d++]),e}function b(a,b){return Math.sqrt(Math.pow(a[0]-b[0],2)+Math.pow(a[1]-b[1],2)+Math.pow(a[2]-b[2],2))}function c(a){for(var b=[0,0,0],c=0;cn?0:255}return l}}function e(a,b){for(var c=0;ch;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=2040===k?255:0}return g}function g(a,b,c){for(var d=[1,1,1,1,1,1,1,1,1],e=Math.round(Math.sqrt(d.length)),f=Math.floor(e/2),g=[],h=0;c>h;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=k>=1020?255:0}return g}function h(a,b,c){for(var d=[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9],e=Math.round(Math.sqrt(d.length)),f=Math.floor(e/2),g=[],h=0;c>h;h++)for(var i=0;b>i;i++){for(var j=h*b+i,k=0,l=0;e>l;l++)for(var m=0;e>m;m++){var n=h+l-f,o=i+m-f;if(n>=0&&c>n&&o>=0&&b>o){var p=n*b+o,q=d[l*e+m];k+=a[p]*q}}g[j]=k}return g}Kinetic.Filters.Mask=function(a){var b=this.threshold(),c=d(a,b);return c&&(c=f(c,a.width,a.height),c=g(c,a.width,a.height),c=h(c,a.width,a.height),e(a,c)),a},Kinetic.Factory.addGetterSetter(Kinetic.Node,"threshold",0,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.RGB=function(a){var b,c,d=a.data,e=d.length,f=this.red(),g=this.green(),h=this.blue();for(b=0;e>b;b+=4)c=(.34*d[b]+.5*d[b+1]+.16*d[b+2])/255,d[b]=c*f,d[b+1]=c*g,d[b+2]=c*h,d[b+3]=d[b+3]},Kinetic.Factory.addGetterSetter(Kinetic.Node,"red",0,function(a){return this._filterUpToDate=!1,a>255?255:0>a?0:Math.round(a)}),Kinetic.Factory.addGetterSetter(Kinetic.Node,"green",0,function(a){return this._filterUpToDate=!1,a>255?255:0>a?0:Math.round(a)}),Kinetic.Factory.addGetterSetter(Kinetic.Node,"blue",0,Kinetic.Validators.RGBComponent,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.HSV=function(a){var b,c,d,e,f,g=a.data,h=g.length,i=Math.pow(2,this.value()),j=Math.pow(2,this.saturation()),k=Math.abs(this.hue()+360)%360,l=i*j*Math.cos(k*Math.PI/180),m=i*j*Math.sin(k*Math.PI/180),n=.299*i+.701*l+.167*m,o=.587*i-.587*l+.33*m,p=.114*i-.114*l-.497*m,q=.299*i-.299*l-.328*m,r=.587*i+.413*l+.035*m,s=.114*i-.114*l+.293*m,t=.299*i-.3*l+1.25*m,u=.587*i-.586*l-1.05*m,v=.114*i+.886*l-.2*m;for(b=0;h>b;b+=4)c=g[b+0],d=g[b+1],e=g[b+2],f=g[b+3],g[b+0]=n*c+o*d+p*e,g[b+1]=q*c+r*d+s*e,g[b+2]=t*c+u*d+v*e,g[b+3]=f},Kinetic.Factory.addGetterSetter(Kinetic.Node,"hue",0,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"saturation",0,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"value",0,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Factory.addGetterSetter(Kinetic.Node,"hue",0,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"saturation",0,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"luminance",0,null,Kinetic.Factory.afterSetFilter),Kinetic.Filters.HSL=function(a){var b,c,d,e,f,g=a.data,h=g.length,i=1,j=Math.pow(2,this.saturation()),k=Math.abs(this.hue()+360)%360,l=127*this.luminance(),m=i*j*Math.cos(k*Math.PI/180),n=i*j*Math.sin(k*Math.PI/180),o=.299*i+.701*m+.167*n,p=.587*i-.587*m+.33*n,q=.114*i-.114*m-.497*n,r=.299*i-.299*m-.328*n,s=.587*i+.413*m+.035*n,t=.114*i-.114*m+.293*n,u=.299*i-.3*m+1.25*n,v=.587*i-.586*m-1.05*n,w=.114*i+.886*m-.2*n;for(b=0;h>b;b+=4)c=g[b+0],d=g[b+1],e=g[b+2],f=g[b+3],g[b+0]=o*c+p*d+q*e+l,g[b+1]=r*c+s*d+t*e+l,g[b+2]=u*c+v*d+w*e+l,g[b+3]=f}}(),function(){Kinetic.Filters.Emboss=function(a){var b=10*this.embossStrength(),c=255*this.embossWhiteLevel(),d=this.embossDirection(),e=this.embossBlend(),f=0,g=0,h=a.data,i=a.width,j=a.height,k=4*i,l=j;switch(d){case"top-left":f=-1,g=-1;break;case"top":f=-1,g=0;break;case"top-right":f=-1,g=1;break;case"right":f=0,g=1;break;case"bottom-right":f=1,g=1;break;case"bottom":f=1,g=0;break;case"bottom-left":f=1,g=-1;break;case"left":f=0,g=-1}do{var m=(l-1)*k,n=f;1>l+n&&(n=0),l+n>j&&(n=0);var o=(l-1+n)*i*4,p=i;do{var q=m+4*(p-1),r=g;1>p+r&&(r=0),p+r>i&&(r=0);var s=o+4*(p-1+r),t=h[q]-h[s],u=h[q+1]-h[s+1],v=h[q+2]-h[s+2],w=t,x=w>0?w:-w,y=u>0?u:-u,z=v>0?v:-v;if(y>x&&(w=u),z>x&&(w=v),w*=b,e){var A=h[q]+w,B=h[q+1]+w,C=h[q+2]+w;h[q]=A>255?255:0>A?0:A,h[q+1]=B>255?255:0>B?0:B,h[q+2]=C>255?255:0>C?0:C}else{var D=c-w;0>D?D=0:D>255&&(D=255),h[q]=h[q+1]=h[q+2]=D}}while(--p)}while(--l)},Kinetic.Factory.addGetterSetter(Kinetic.Node,"embossStrength",.5,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"embossWhiteLevel",.5,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"embossDirection","top-left",null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"embossBlend",!1,null,Kinetic.Factory.afterSetFilter)}(),function(){function a(a,b,c,d,e){var f,g=c-b,h=e-d;return 0===g?d+h/2:0===h?d:(f=(a-b)/g,f=h*f+d)}Kinetic.Filters.Enhance=function(b){var c,d,e,f,g=b.data,h=g.length,i=g[0],j=i,k=g[1],l=k,m=g[2],n=m,o=g[3],p=o,q=this.enhance();if(0!==q){for(f=0;h>f;f+=4)c=g[f+0],i>c?i=c:c>j&&(j=c),d=g[f+1],k>d?k=d:d>l&&(l=d),e=g[f+2],m>e?m=e:e>n&&(n=e);j===i&&(j=255,i=0),l===k&&(l=255,k=0),n===m&&(n=255,m=0),p===o&&(p=255,o=0);var r,s,t,u,v,w,x,y,z,A,B,C;for(q>0?(s=j+q*(255-j),t=i-q*(i-0),v=l+q*(255-l),w=k-q*(k-0),y=n+q*(255-n),C=m-q*(m-0),B=p+q*(255-p),z=o-q*(o-0)):(r=.5*(j+i),s=j+q*(j-r),t=i+q*(i-r),u=.5*(l+k),v=l+q*(l-u),w=k+q*(k-u),x=.5*(n+m),y=n+q*(n-x),C=m+q*(m-x),A=.5*(p+o),B=p+q*(p-A),z=o+q*(o-A)),f=0;h>f;f+=4)g[f+0]=a(g[f+0],i,j,t,s),g[f+1]=a(g[f+1],k,l,w,v),g[f+2]=a(g[f+2],m,n,C,y)}},Kinetic.Factory.addGetterSetter(Kinetic.Node,"enhance",0,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.Posterize=function(a){var b,c=Math.round(254*this.levels())+1,d=a.data,e=d.length,f=255/c;for(b=0;e>b;b+=1)d[b]=Math.floor(d[b]/f)*f},Kinetic.Factory.addGetterSetter(Kinetic.Node,"levels",.5,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.Noise=function(a){var b,c=255*this.noise(),d=a.data,e=d.length,f=c/2;for(b=0;e>b;b+=4)d[b+0]+=f-2*f*Math.random(),d[b+1]+=f-2*f*Math.random(),d[b+2]+=f-2*f*Math.random()},Kinetic.Factory.addGetterSetter(Kinetic.Node,"noise",.2,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.Pixelate=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p=Math.ceil(this.pixelSize()),q=a.width,r=a.height,s=Math.ceil(q/p),t=Math.ceil(r/p);for(a=a.data,m=0;s>m;m+=1)for(n=0;t>n;n+=1){for(e=0,f=0,g=0,h=0,i=m*p,j=i+p,k=n*p,l=k+p,o=0,b=i;j>b;b+=1)if(!(b>=q))for(c=k;l>c;c+=1)c>=r||(d=4*(q*c+b),e+=a[d+0],f+=a[d+1],g+=a[d+2],h+=a[d+3],o+=1);for(e/=o,f/=o,g/=o,b=i;j>b;b+=1)if(!(b>=q))for(c=k;l>c;c+=1)c>=r||(d=4*(q*c+b),a[d+0]=e,a[d+1]=f,a[d+2]=g,a[d+3]=h)}},Kinetic.Factory.addGetterSetter(Kinetic.Node,"pixelSize",8,null,Kinetic.Factory.afterSetFilter)}(),function(){Kinetic.Filters.Threshold=function(a){var b,c=255*this.threshold(),d=a.data,e=d.length;for(b=0;e>b;b+=1)d[b]=d[b]255?255:h,k[d+1]=i>255?255:i,k[d+2]=j>255?255:j,k[d+3]=k[d+3];while(--c)}while(--m)}}(),function(){Kinetic.Filters.Solarize=function(a){var b=a.data,c=a.width,d=a.height,e=4*c,f=d;do{var g=(f-1)*e,h=c;do{var i=g+4*(h-1),j=b[i],k=b[i+1],l=b[i+2];j>127&&(j=255-j),k>127&&(k=255-k),l>127&&(l=255-l),b[i]=j,b[i+1]=k,b[i+2]=l}while(--h)}while(--f)}}(),function(){var a=function(a,b,c){var d,e,f,g,h=a.data,i=b.data,j=a.width,k=a.height,l=c.polarCenterX||j/2,m=c.polarCenterY||k/2,n=0,o=0,p=0,q=0,r=Math.sqrt(l*l+m*m);e=j-l,f=k-m,g=Math.sqrt(e*e+f*f),r=g>r?g:r;var s,t,u,v,w=k,x=j,y=360/x*Math.PI/180;for(t=0;x>t;t+=1)for(u=Math.sin(t*y),v=Math.cos(t*y),s=0;w>s;s+=1)e=Math.floor(l+r*s/w*v),f=Math.floor(m+r*s/w*u),d=4*(f*j+e),n=h[d+0],o=h[d+1],p=h[d+2],q=h[d+3],d=4*(t+s*j),i[d+0]=n,i[d+1]=o,i[d+2]=p,i[d+3]=q},b=function(a,b,c){var d,e,f,g,h,i,j=a.data,k=b.data,l=a.width,m=a.height,n=c.polarCenterX||l/2,o=c.polarCenterY||m/2,p=0,q=0,r=0,s=0,t=Math.sqrt(n*n+o*o);e=l-n,f=m-o,i=Math.sqrt(e*e+f*f),t=i>t?i:t;var u,v,w,x,y=m,z=l,A=c.polarRotation||0;for(e=0;l>e;e+=1)for(f=0;m>f;f+=1)g=e-n,h=f-o,u=Math.sqrt(g*g+h*h)*y/t,v=(180*Math.atan2(h,g)/Math.PI+360+A)%360,v=v*z/360,w=Math.floor(v),x=Math.floor(u),d=4*(x*l+w),p=j[d+0],q=j[d+1],r=j[d+2],s=j[d+3],d=4*(f*l+e),k[d+0]=p,k[d+1]=q,k[d+2]=r,k[d+3]=s},c=Kinetic.Util.createCanvasElement();Kinetic.Filters.Kaleidoscope=function(d){var e,f,g,h,i,j,k,l,m,n,o=d.width,p=d.height,q=Math.round(this.kaleidoscopePower()),r=Math.round(this.kaleidoscopeAngle()),s=Math.floor(o*(r%360)/360);if(!(1>q)){c.width=o,c.height=p;var t=c.getContext("2d").getImageData(0,0,o,p);a(d,t,{polarCenterX:o/2,polarCenterY:p/2});for(var u=o/Math.pow(2,q);8>=u;)u=2*u,q-=1;u=Math.ceil(u);var v=u,w=0,x=v,y=1;for(s+u>o&&(w=v,x=0,y=-1),f=0;p>f;f+=1)for(e=w;e!==x;e+=y)g=Math.round(e+s)%o,m=4*(o*f+g),i=t.data[m+0],j=t.data[m+1],k=t.data[m+2],l=t.data[m+3],n=4*(o*f+e),t.data[n+0]=i,t.data[n+1]=j,t.data[n+2]=k,t.data[n+3]=l;for(f=0;p>f;f+=1)for(v=Math.floor(u),h=0;q>h;h+=1){for(e=0;v+1>e;e+=1)m=4*(o*f+e),i=t.data[m+0],j=t.data[m+1],k=t.data[m+2],l=t.data[m+3],n=4*(o*f+2*v-e-1),t.data[n+0]=i,t.data[n+1]=j,t.data[n+2]=k,t.data[n+3]=l;v*=2}b(t,d,{polarRotation:0})}},Kinetic.Factory.addGetterSetter(Kinetic.Node,"kaleidoscopePower",2,null,Kinetic.Factory.afterSetFilter),Kinetic.Factory.addGetterSetter(Kinetic.Node,"kaleidoscopeAngle",0,null,Kinetic.Factory.afterSetFilter)}(),function(){function a(a){setTimeout(a,1e3/60)}function b(){return e.apply(Kinetic.root,arguments)}var c=500,d=function(){return Kinetic.root.performance&&Kinetic.root.performance.now?function(){return Kinetic.root.performance.now()}:function(){return(new Date).getTime()}}(),e=function(){return Kinetic.root.requestAnimationFrame||Kinetic.root.webkitRequestAnimationFrame||Kinetic.root.mozRequestAnimationFrame||Kinetic.root.oRequestAnimationFrame||Kinetic.root.msRequestAnimationFrame||a}();Kinetic.Animation=function(a,b){var c=Kinetic.Animation;this.func=a,this.setLayers(b),this.id=c.animIdCounter++,this.frame={time:0,timeDiff:0,lastTime:d()}},Kinetic.Animation.prototype={setLayers:function(a){var b=[];b=a?a.length>0?a:[a]:[],this.layers=b},getLayers:function(){return this.layers},addLayer:function(a){var b,c,d=this.layers;if(d){for(b=d.length,c=0;b>c;c++)if(d[c]._id===a._id)return!1}else this.layers=[];return this.layers.push(a),!0},isRunning:function(){var a,b=Kinetic.Animation,c=b.animations,d=c.length;for(a=0;d>a;a++)if(c[a].id===this.id)return!0;return!1},start:function(){var a=Kinetic.Animation;this.stop(),this.frame.timeDiff=0,this.frame.lastTime=d(),a._addAnimation(this)},stop:function(){Kinetic.Animation._removeAnimation(this)},_updateFrameObject:function(a){this.frame.timeDiff=a-this.frame.lastTime,this.frame.lastTime=a,this.frame.time+=this.frame.timeDiff,this.frame.frameRate=1e3/this.frame.timeDiff}},Kinetic.Animation.animations=[],Kinetic.Animation.animIdCounter=0,Kinetic.Animation.animRunning=!1,Kinetic.Animation._addAnimation=function(a){this.animations.push(a),this._handleAnimation()},Kinetic.Animation._removeAnimation=function(a){var b,c=a.id,d=this.animations,e=d.length;for(b=0;e>b;b++)if(d[b].id===c){this.animations.splice(b,1);break}},Kinetic.Animation._runFrames=function(){var a,b,c,e,f,g,h,i,j={},k=this.animations,l=!1;for(e=0;ef;f++)h=b[f],void 0!==h._id&&(j[h._id]=h);c&&(l=c.call(a,a.frame)!==!1||l)}if(l)for(i in j)j[i].draw()},Kinetic.Animation._animationLoop=function(){var a=Kinetic.Animation;a.animations.length?(b(a._animationLoop),a._runFrames()):a.animRunning=!1},Kinetic.Animation._handleAnimation=function(){var a=this;this.animRunning||(this.animRunning=!0,a._animationLoop())};var f=Kinetic.Node.prototype.moveTo;Kinetic.Node.prototype.moveTo=function(a){f.call(this,a)},Kinetic.BaseLayer.prototype.batchDraw=function(){var a=this,b=Kinetic.Animation;this.batchAnim||(this.batchAnim=new b(function(){a.lastBatchDrawTime&&d()-a.lastBatchDrawTime>c&&a.batchAnim.stop()},this)),this.lastBatchDrawTime=d(),this.batchAnim.isRunning()||(this.draw(),this.batchAnim.start())},Kinetic.Stage.prototype.batchDraw=function(){this.getChildren().each(function(a){a.batchDraw()})}}(this),function(){var a={node:1,duration:1,easing:1,onFinish:1,yoyo:1},b=1,c=2,d=3,e=0;Kinetic.Tween=function(b){var c,d=this,g=b.node,h=g._id,i=b.duration||1,j=b.easing||Kinetic.Easings.Linear,k=!!b.yoyo;this.node=g,this._id=e++,this.anim=new Kinetic.Animation(function(){d.tween.onEnterFrame()},g.getLayer()),this.tween=new f(c,function(a){d._tweenFunc(a)},j,0,1,1e3*i,k),this._addListeners(),Kinetic.Tween.attrs[h]||(Kinetic.Tween.attrs[h]={}),Kinetic.Tween.attrs[h][this._id]||(Kinetic.Tween.attrs[h][this._id]={}),Kinetic.Tween.tweens[h]||(Kinetic.Tween.tweens[h]={});for(c in b)void 0===a[c]&&this._addAttr(c,b[c]);this.reset(),this.onFinish=b.onFinish,this.onReset=b.onReset},Kinetic.Tween.attrs={},Kinetic.Tween.tweens={},Kinetic.Tween.prototype={_addAttr:function(a,b){var c,d,e,f,g,h=this.node,i=h._id;if(e=Kinetic.Tween.tweens[i][a],e&&delete Kinetic.Tween.attrs[i][e][a],c=h.getAttr(a),Kinetic.Util._isArray(b))for(d=[],g=b.length,f=0;g>f;f++)d.push(b[f]-c[f]);else d=b-c;Kinetic.Tween.attrs[i][this._id][a]={start:c,diff:d},Kinetic.Tween.tweens[i][a]=this._id},_tweenFunc:function(a){var b,c,d,e,f,g,h,i=this.node,j=Kinetic.Tween.attrs[i._id][this._id];for(b in j){if(c=j[b],d=c.start,e=c.diff,Kinetic.Util._isArray(d))for(f=[],h=d.length,g=0;h>g;g++)f.push(d[g]+e[g]*a);else f=d+e*a;i.setAttr(b,f)}},_addListeners:function(){var a=this;this.tween.onPlay=function(){a.anim.start()},this.tween.onReverse=function(){a.anim.start()},this.tween.onPause=function(){a.anim.stop()},this.tween.onFinish=function(){a.onFinish&&a.onFinish()},this.tween.onReset=function(){a.onReset&&a.onReset()}},play:function(){return this.tween.play(),this},reverse:function(){return this.tween.reverse(),this},reset:function(){this.node;return this.tween.reset(),this},seek:function(a){this.node;return this.tween.seek(1e3*a),this},pause:function(){return this.tween.pause(),this},finish:function(){this.node;return this.tween.finish(),this},destroy:function(){var a,b=this.node._id,c=this._id,d=Kinetic.Tween.tweens[b];this.pause();for(a in d)delete Kinetic.Tween.tweens[b][a];delete Kinetic.Tween.attrs[b][c]}};var f=function(a,b,c,d,e,f,g){this.prop=a,this.propFunc=b,this.begin=d,this._pos=d,this.duration=f,this._change=0,this.prevPos=0,this.yoyo=g,this._time=0,this._position=0,this._startTime=0,this._finish=0,this.func=c,this._change=e-this.begin,this.pause()};f.prototype={fire:function(a){var b=this[a];b&&b()},setTime:function(a){a>this.duration?this.yoyo?(this._time=this.duration,this.reverse()):this.finish():0>a?this.yoyo?(this._time=0,this.play()):this.reset():(this._time=a,this.update())},getTime:function(){return this._time},setPosition:function(a){this.prevPos=this._pos,this.propFunc(a),this._pos=a},getPosition:function(a){return void 0===a&&(a=this._time),this.func(a,this.begin,this._change,this.duration)},play:function(){this.state=c,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onPlay")},reverse:function(){this.state=d,this._time=this.duration-this._time,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onReverse")},seek:function(a){this.pause(),this._time=a,this.update(),this.fire("onSeek")},reset:function(){this.pause(),this._time=0,this.update(),this.fire("onReset")},finish:function(){this.pause(),this._time=this.duration,this.update(),this.fire("onFinish")},update:function(){this.setPosition(this.getPosition(this._time))},onEnterFrame:function(){var a=this.getTimer()-this._startTime;this.state===c?this.setTime(a):this.state===d&&this.setTime(this.duration-a)},pause:function(){this.state=b,this.fire("onPause")},getTimer:function(){return(new Date).getTime()}},Kinetic.Easings={BackEaseIn:function(a,b,c,d){var e=1.70158;return c*(a/=d)*a*((e+1)*a-e)+b},BackEaseOut:function(a,b,c,d){var e=1.70158;return c*((a=a/d-1)*a*((e+1)*a+e)+1)+b},BackEaseInOut:function(a,b,c,d){var e=1.70158;return(a/=d/2)<1?c/2*a*a*(((e*=1.525)+1)*a-e)+b:c/2*((a-=2)*a*(((e*=1.525)+1)*a+e)+2)+b},ElasticEaseIn:function(a,b,c,d,e,f){var g=0;return 0===a?b:1==(a/=d)?b+c:(f||(f=.3*d),!e||ea?-.5*e*Math.pow(2,10*(a-=1))*Math.sin(2*(a*d-g)*Math.PI/f)+b:e*Math.pow(2,-10*(a-=1))*Math.sin(2*(a*d-g)*Math.PI/f)*.5+c+b)},BounceEaseOut:function(a,b,c,d){return(a/=d)<1/2.75?7.5625*c*a*a+b:2/2.75>a?c*(7.5625*(a-=1.5/2.75)*a+.75)+b:2.5/2.75>a?c*(7.5625*(a-=2.25/2.75)*a+.9375)+b:c*(7.5625*(a-=2.625/2.75)*a+.984375)+b},BounceEaseIn:function(a,b,c,d){return c-Kinetic.Easings.BounceEaseOut(d-a,0,c,d)+b},BounceEaseInOut:function(a,b,c,d){return d/2>a?.5*Kinetic.Easings.BounceEaseIn(2*a,0,c,d)+b:.5*Kinetic.Easings.BounceEaseOut(2*a-d,0,c,d)+.5*c+b},EaseIn:function(a,b,c,d){return c*(a/=d)*a+b},EaseOut:function(a,b,c,d){return-c*(a/=d)*(a-2)+b},EaseInOut:function(a,b,c,d){return(a/=d/2)<1?c/2*a*a+b:-c/2*(--a*(a-2)-1)+b},StrongEaseIn:function(a,b,c,d){return c*(a/=d)*a*a*a*a+b},StrongEaseOut:function(a,b,c,d){return c*((a=a/d-1)*a*a*a*a+1)+b},StrongEaseInOut:function(a,b,c,d){return(a/=d/2)<1?c/2*a*a*a*a*a+b:c/2*((a-=2)*a*a*a*a+2)+b},Linear:function(a,b,c,d){return c*a/d+b}}}(),function(){Kinetic.DD={anim:new Kinetic.Animation(function(){var a=this.dirty;return this.dirty=!1,a}),isDragging:!1,justDragged:!1,offset:{x:0,y:0},node:null,_drag:function(a){var b=Kinetic.DD,c=b.node;if(c){if(!b.isDragging){var d=c.getStage().getPointerPosition(),e=c.dragDistance(),f=Math.max(Math.abs(d.x-b.startPointerPos.x),Math.abs(d.y-b.startPointerPos.y));if(e>f)return}c._setDragPosition(a),b.isDragging||(b.isDragging=!0,c.fire("dragstart",{type:"dragstart",target:c,evt:a},!0)),c.fire("dragmove",{type:"dragmove",target:c,evt:a},!0)}},_endDragBefore:function(a){var b,c,d=Kinetic.DD,e=d.node;e&&(b=e.nodeType,c=e.getLayer(),d.anim.stop(),d.isDragging&&(d.isDragging=!1,d.justDragged=!0,Kinetic.listenClickTap=!1,a&&(a.dragEndNode=e)),delete d.node,(c||e).draw())},_endDragAfter:function(a){a=a||{};var b=a.dragEndNode;a&&b&&b.fire("dragend",{type:"dragend",target:b,evt:a},!0)}},Kinetic.Node.prototype.startDrag=function(){var a=Kinetic.DD,b=this.getStage(),c=this.getLayer(),d=b.getPointerPosition(),e=this.getAbsolutePosition();d&&(a.node&&a.node.stopDrag(),a.node=this,a.startPointerPos=d,a.offset.x=d.x-e.x,a.offset.y=d.y-e.y,a.anim.setLayers(c||this.getLayers()),a.anim.start(),this._setDragPosition())},Kinetic.Node.prototype._setDragPosition=function(a){var b=Kinetic.DD,c=this.getStage().getPointerPosition(),d=this.getDragBoundFunc();if(c){var e={x:c.x-b.offset.x,y:c.y-b.offset.y};void 0!==d&&(e=d.call(this,e,a)),this.setAbsolutePosition(e),this._lastPos&&this._lastPos.x===e.x&&this._lastPos.y===e.y||(b.anim.dirty=!0),this._lastPos=e}},Kinetic.Node.prototype.stopDrag=function(){var a=Kinetic.DD,b={};a._endDragBefore(b),a._endDragAfter(b)},Kinetic.Node.prototype.setDraggable=function(a){this._setAttr("draggable",a),this._dragChange()};var a=Kinetic.Node.prototype.destroy;Kinetic.Node.prototype.destroy=function(){var b=Kinetic.DD;b.node&&b.node._id===this._id&&this.stopDrag(),a.call(this)},Kinetic.Node.prototype.isDragging=function(){var a=Kinetic.DD;return!(!a.node||a.node._id!==this._id||!a.isDragging)},Kinetic.Node.prototype._listenDrag=function(){var a=this;this._dragCleanup(),"Stage"===this.getClassName()?this.on("contentMousedown.kinetic contentTouchstart.kinetic",function(b){Kinetic.DD.node||a.startDrag(b)}):this.on("mousedown.kinetic touchstart.kinetic",function(b){1!==b.evt.button&&2!==b.evt.button&&(Kinetic.DD.node||a.startDrag(b))})},Kinetic.Node.prototype._dragChange=function(){if(this.attrs.draggable)this._listenDrag();else{this._dragCleanup();var a=this.getStage(),b=Kinetic.DD;a&&b.node&&b.node._id===this._id&&b.node.stopDrag()}},Kinetic.Node.prototype._dragCleanup=function(){"Stage"===this.getClassName()?(this.off("contentMousedown.kinetic"),this.off("contentTouchstart.kinetic")):(this.off("mousedown.kinetic"),this.off("touchstart.kinetic"))},Kinetic.Factory.addGetterSetter(Kinetic.Node,"dragBoundFunc"),Kinetic.Factory.addGetter(Kinetic.Node,"draggable",!1),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Node,"draggable");var b=Kinetic.document.documentElement;b.addEventListener("mouseup",Kinetic.DD._endDragBefore,!0),b.addEventListener("touchend",Kinetic.DD._endDragBefore,!0),b.addEventListener("mouseup",Kinetic.DD._endDragAfter,!1),b.addEventListener("touchend",Kinetic.DD._endDragAfter,!1)}(),function(){Kinetic.Util.addMethods(Kinetic.Container,{__init:function(a){this.children=new Kinetic.Collection,Kinetic.Node.call(this,a)},getChildren:function(a){if(a){var b=new Kinetic.Collection;return this.children.each(function(c){a(c)&&b.push(c)}),b}return this.children},hasChildren:function(){return this.getChildren().length>0},removeChildren:function(){for(var a,b=Kinetic.Collection.toCollection(this.children),c=0;c1)){if(a.getParent())return void a.moveTo(this);var b=this.children;return this._validateAdd(a),a.index=b.length,a.parent=this,b.push(a),this._fire("add",{child:a}),this}for(var c=0;cb;b++)if(d=j[b],"#"===d.charAt(0))f=this._getNodeById(d.slice(1)),f&&i.push(f);else if("."===d.charAt(0))e=this._getNodesByName(d.slice(1)),i=i.concat(e);else for(g=this.getChildren(),h=g.length,c=0;h>c;c++)i=i.concat(g[c]._get(d));return Kinetic.Collection.toCollection(i)},_getNodeById:function(a){var b=Kinetic.ids[a];return void 0!==b&&this.isAncestorOf(b)?b:null},_getNodesByName:function(a){var b=Kinetic.names[a]||[];return this._getDescendants(b)},_get:function(a){for(var b=Kinetic.Node.prototype._get.call(this,a),c=this.getChildren(),d=c.length,e=0;d>e;e++)b=b.concat(c[e]._get(a));return b},toObject:function(){var a=Kinetic.Node.prototype.toObject.call(this); -a.children=[];for(var b=this.getChildren(),c=b.length,d=0;c>d;d++){var e=b[d];a.children.push(e.toObject())}return a},_getDescendants:function(a){for(var b=[],c=a.length,d=0;c>d;d++){var e=a[d];this.isAncestorOf(e)&&b.push(e)}return b},isAncestorOf:function(a){for(var b=a.getParent();b;){if(b._id===this._id)return!0;b=b.getParent()}return!1},clone:function(a){var b=Kinetic.Node.prototype.clone.call(this,a);return this.getChildren().each(function(a){b.add(a.clone())}),b},getAllIntersections:function(a){var b=[];return this.find("Shape").each(function(c){c.isVisible()&&c.intersects(a)&&b.push(c)}),b},_setChildrenIndices:function(){this.children.each(function(a,b){a.index=b})},drawScene:function(a,b){var c=this.getLayer(),d=a||c&&c.getCanvas(),e=d&&d.getContext(),f=this._cache.canvas,g=f&&f.scene;return this.isVisible()&&(g?this._drawCachedSceneCanvas(e):this._drawChildren(d,"drawScene",b)),this},drawHit:function(a,b){var c=this.getLayer(),d=a||c&&c.hitCanvas,e=d&&d.getContext(),f=this._cache.canvas,g=f&&f.hit;return this.shouldDrawHit(d)&&(c&&c.clearHitCache(),g?this._drawCachedHitCanvas(e):this._drawChildren(d,"drawHit",b)),this},_drawChildren:function(a,b,c){var d,e,f=this.getLayer(),g=a&&a.getContext(),h=this.getClipWidth(),i=this.getClipHeight(),j=h&&i;j&&f&&(d=this.getClipX(),e=this.getClipY(),g.save(),f._applyTransform(this,g),g.beginPath(),g.rect(d,e,h,i),g.clip(),g.reset()),this.children.each(function(d){d[b](a,c)}),j&&g.restore()},shouldDrawHit:function(a){var b=this.getLayer();return a&&a.isCache||b&&b.hitGraphEnabled()&&this.isVisible()&&!Kinetic.isDragging()}}),Kinetic.Util.extend(Kinetic.Container,Kinetic.Node),Kinetic.Container.prototype.get=Kinetic.Container.prototype.find,Kinetic.Factory.addComponentsGetterSetter(Kinetic.Container,"clip",["x","y","width","height"]),Kinetic.Factory.addGetterSetter(Kinetic.Container,"clipX"),Kinetic.Factory.addGetterSetter(Kinetic.Container,"clipY"),Kinetic.Factory.addGetterSetter(Kinetic.Container,"clipWidth"),Kinetic.Factory.addGetterSetter(Kinetic.Container,"clipHeight"),Kinetic.Collection.mapMethods(Kinetic.Container)}(),function(){function a(a){a.fill()}function b(a){a.stroke()}function c(a){a.fill()}function d(a){a.stroke()}function e(){this._clearCache(f)}var f="hasShadow";Kinetic.Util.addMethods(Kinetic.Shape,{__init:function(f){this.nodeType="Shape",this._fillFunc=a,this._strokeFunc=b,this._fillFuncHit=c,this._strokeFuncHit=d;for(var g,h=Kinetic.shapes;;)if(g=Kinetic.Util.getRandomColor(),g&&!(g in h))break;this.colorKey=g,h[g]=this,Kinetic.Node.call(this,f),this.on("shadowColorChange.kinetic shadowBlurChange.kinetic shadowOffsetChange.kinetic shadowOpacityChange.kinetic shadowEnabledChange.kinetic",e)},hasChildren:function(){return!1},getChildren:function(){return[]},getContext:function(){return this.getLayer().getContext()},getCanvas:function(){return this.getLayer().getCanvas()},hasShadow:function(){return this._getCache(f,this._hasShadow)},_hasShadow:function(){return this.getShadowEnabled()&&0!==this.getShadowOpacity()&&!!(this.getShadowColor()||this.getShadowBlur()||this.getShadowOffsetX()||this.getShadowOffsetY())},hasFill:function(){return!!(this.getFill()||this.getFillPatternImage()||this.getFillLinearGradientColorStops()||this.getFillRadialGradientColorStops())},hasStroke:function(){return!!(this.stroke()||this.strokeRed()||this.strokeGreen()||this.strokeBlue())},intersects:function(a){var b,c=this.getStage(),d=c.bufferHitCanvas;return d.getContext().clear(),this.drawScene(d),b=d.context.getImageData(Math.round(a.x),Math.round(a.y),1,1).data,b[3]>0},destroy:function(){Kinetic.Node.prototype.destroy.call(this),delete Kinetic.shapes[this.colorKey]},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasFill()&&this.hasStroke()&&this.getStage()},drawScene:function(a,b){var c,d,e,f=this.getLayer(),g=a||f.getCanvas(),h=g.getContext(),i=this._cache.canvas,j=this.sceneFunc(),k=this.hasShadow();if(this.isVisible())if(i)this._drawCachedSceneCanvas(h);else if(j){if(h.save(),this._useBufferCanvas()){if(c=this.getStage(),d=c.bufferCanvas,e=d.getContext(),e.clear(),e.save(),e._applyLineJoin(this),f)f._applyTransform(this,e,b);else{var l=this.getAbsoluteTransform(b).getMatrix();h.transform(l[0],l[1],l[2],l[3],l[4],l[5])}j.call(this,e),e.restore(),k&&(h.save(),h._applyShadow(this),h.drawImage(d._canvas,0,0),h.restore()),h._applyOpacity(this),h.drawImage(d._canvas,0,0)}else{if(h._applyLineJoin(this),f)f._applyTransform(this,h,b);else{var l=this.getAbsoluteTransform(b).getMatrix();h.transform(l[0],l[1],l[2],l[3],l[4],l[5])}k&&(h.save(),h._applyShadow(this),j.call(this,h),h.restore()),h._applyOpacity(this),j.call(this,h)}h.restore()}return this},drawHit:function(a,b){var c=this.getLayer(),d=a||c.hitCanvas,e=d.getContext(),f=this.hitFunc()||this.sceneFunc(),g=this._cache.canvas,h=g&&g.hit;if(this.shouldDrawHit(d))if(c&&c.clearHitCache(),h)this._drawCachedHitCanvas(e);else if(f){if(e.save(),e._applyLineJoin(this),c)c._applyTransform(this,e,b);else{var i=this.getAbsoluteTransform(b).getMatrix();e.transform(i[0],i[1],i[2],i[3],i[4],i[5])}f.call(this,e),e.restore()}return this},drawHitFromCache:function(a){var b,c,d,e,f,g,h,i,j=a||0,k=this._cache.canvas,l=this._getCachedSceneCanvas(),m=l.getContext(),n=k.hit,o=n.getContext(),p=l.getWidth(),q=l.getHeight();o.clear();try{for(b=m.getImageData(0,0,p,q),c=b.data,d=o.getImageData(0,0,p,q),e=d.data,f=c.length,g=Kinetic.Util._hexToRgb(this.colorKey),h=0;f>h;h+=4)i=c[h+3],i>j&&(e[h]=g.r,e[h+1]=g.g,e[h+2]=g.b,e[h+3]=255);o.putImageData(d,0,0)}catch(r){Kinetic.Util.warn("Unable to draw hit graph from cached scene canvas. "+r.message)}return this}}),Kinetic.Util.extend(Kinetic.Shape,Kinetic.Node),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"stroke"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeRed",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeGreen",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeBlue",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeAlpha",1,Kinetic.Validators.alphaComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeWidth",2),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"lineJoin"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"lineCap"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"sceneFunc"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"hitFunc"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"dash"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowColor"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowRed",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowGreen",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowBlue",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowAlpha",1,Kinetic.Validators.alphaComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowBlur"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowOpacity"),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"shadowOffset",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowOffsetX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowOffsetY",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternImage"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fill"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRed",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillGreen",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillBlue",0,Kinetic.Validators.RGBComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillAlpha",1,Kinetic.Validators.alphaComponent),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternY",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientColorStops"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientStartRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientEndRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientColorStops"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternRepeat","repeat"),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"shadowEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"dashEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"strokeScaleEnabled",!0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPriority","color"),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillPatternOffset",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternOffsetX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternOffsetY",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillPatternScale",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternScaleX",1),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternScaleY",1),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillLinearGradientStartPoint",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientStartPointX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientStartPointY",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillLinearGradientEndPoint",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientEndPointX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillLinearGradientEndPointY",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillRadialGradientStartPoint",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientStartPointX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientStartPointY",0),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Shape,"fillRadialGradientEndPoint",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientEndPointX",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillRadialGradientEndPointY",0),Kinetic.Factory.addGetterSetter(Kinetic.Shape,"fillPatternRotation",0),Kinetic.Factory.backCompat(Kinetic.Shape,{dashArray:"dash",getDashArray:"getDash",setDashArray:"getDash",drawFunc:"sceneFunc",getDrawFunc:"getSceneFunc",setDrawFunc:"setSceneFunc",drawHitFunc:"hitFunc",getDrawHitFunc:"getHitFunc",setDrawHitFunc:"setHitFunc"}),Kinetic.Collection.mapMethods(Kinetic.Shape)}(),function(){function a(a,b){a.content.addEventListener(b,function(c){a[I+b](c)},!1)}var b="Stage",c="string",d="px",e="mouseout",f="mouseleave",g="mouseover",h="mouseenter",i="mousemove",j="mousedown",k="mouseup",l="click",m="dblclick",n="touchstart",o="touchend",p="tap",q="dbltap",r="touchmove",s="contentMouseout",t="contentMouseover",u="contentMousemove",v="contentMousedown",w="contentMouseup",x="contentClick",y="contentDblclick",z="contentTouchstart",A="contentTouchend",B="contentDbltap",C="contentTouchmove",D="div",E="relative",F="inline-block",G="kineticjs-content",H=" ",I="_",J="container",K="",L=[j,i,k,e,n,r,o,g],M=L.length;Kinetic.Util.addMethods(Kinetic.Stage,{___init:function(a){this.nodeType=b,Kinetic.Container.call(this,a),this._id=Kinetic.idCounter++,this._buildDOM(),this._bindContentEvents(),this._enableNestedTransforms=!1,Kinetic.stages.push(this)},_validateAdd:function(a){"Layer"!==a.getType()&&Kinetic.Util.error("You may only add layers to the stage.")},setContainer:function(a){if(typeof a===c){var b=a;if(a=Kinetic.document.getElementById(a),!a)throw"Can not find container in document with id "+b}return this._setAttr(J,a),this},shouldDrawHit:function(){return!0},draw:function(){return Kinetic.Node.prototype.draw.call(this),this},setHeight:function(a){return Kinetic.Node.prototype.setHeight.call(this,a),this._resizeDOM(),this},setWidth:function(a){return Kinetic.Node.prototype.setWidth.call(this,a),this._resizeDOM(),this},clear:function(){var a,b=this.children,c=b.length;for(a=0;c>a;a++)b[a].clear();return this},clone:function(a){return a||(a={}),a.container=Kinetic.document.createElement(D),Kinetic.Container.prototype.clone.call(this,a)},destroy:function(){var a=this.content;Kinetic.Container.prototype.destroy.call(this),a&&Kinetic.Util._isInDocument(a)&&this.getContainer().removeChild(a);var b=Kinetic.stages.indexOf(this);b>-1&&Kinetic.stages.splice(b,1)},getPointerPosition:function(){return this.pointerPos},getStage:function(){return this},getContent:function(){return this.content},toDataURL:function(a){function b(e){var f=i[e],j=f.toDataURL(),k=new Kinetic.window.Image;k.onload=function(){h.drawImage(k,0,0),e=0;b--)if(c=d[b].getIntersection(a))return c;return null},_resizeDOM:function(){if(this.content){var a,b,c=this.getWidth(),e=this.getHeight(),f=this.getChildren(),g=f.length;for(this.content.style.width=c+d,this.content.style.height=e+d,this.bufferCanvas.setSize(c,e),this.bufferHitCanvas.setSize(c,e),a=0;g>a;a++)b=f[a],b.setSize(c,e),b.draw()}},add:function(a){if(!(arguments.length>1))return Kinetic.Container.prototype.add.call(this,a),a._setCanvasSize(this.width(),this.height()),a.draw(),this.content.appendChild(a.canvas._canvas),this;for(var b=0;bb;b++)a(this,L[b])},_mouseover:function(a){Kinetic.UA.mobile||(this._setPointerPosition(a),this._fire(t,{evt:a}))},_mouseout:function(a){if(!Kinetic.UA.mobile){this._setPointerPosition(a);var b=this.targetShape;b&&!Kinetic.isDragging()&&(b._fireAndBubble(e,{evt:a}),b._fireAndBubble(f,{evt:a}),this.targetShape=null),this.pointerPos=void 0,this._fire(s,{evt:a})}},_mousemove:function(a){if(Kinetic.UA.ieMobile)return this._touchmove(a);if(("undefined"==typeof a.webkitMovementX&&"undefined"==typeof a.webkitMovementY||0!==a.webkitMovementY||0!==a.webkitMovementX)&&!Kinetic.UA.mobile){this._setPointerPosition(a);var b,c=Kinetic.DD;Kinetic.isDragging()||(b=this.getIntersection(this.getPointerPosition()),b&&b.isListening()?Kinetic.isDragging()||this.targetShape&&this.targetShape._id===b._id?b._fireAndBubble(i,{evt:a}):(this.targetShape&&(this.targetShape._fireAndBubble(e,{evt:a},b),this.targetShape._fireAndBubble(f,{evt:a},b)),b._fireAndBubble(g,{evt:a},this.targetShape),b._fireAndBubble(h,{evt:a},this.targetShape),this.targetShape=b):this.targetShape&&!Kinetic.isDragging()&&(this.targetShape._fireAndBubble(e,{evt:a}),this.targetShape._fireAndBubble(f,{evt:a}),this.targetShape=null),this._fire(u,{evt:a})),c&&c._drag(a),a.preventDefault&&a.preventDefault()}},_mousedown:function(a){if(Kinetic.UA.ieMobile)return this._touchstart(a);if(!Kinetic.UA.mobile){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition());Kinetic.listenClickTap=!0,b&&b.isListening()&&(this.clickStartShape=b,b._fireAndBubble(j,{evt:a})),this._fire(v,{evt:a})}a.preventDefault&&a.preventDefault()},_mouseup:function(a){if(Kinetic.UA.ieMobile)return this._touchend(a);if(!Kinetic.UA.mobile){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=this.clickStartShape,d=!1,e=Kinetic.DD;Kinetic.inDblClickWindow?(d=!0,Kinetic.inDblClickWindow=!1):e&&e.justDragged?e&&(e.justDragged=!1):Kinetic.inDblClickWindow=!0,setTimeout(function(){Kinetic.inDblClickWindow=!1},Kinetic.dblClickWindow),b&&b.isListening()&&(b._fireAndBubble(k,{evt:a}),Kinetic.listenClickTap&&c&&c._id===b._id&&(b._fireAndBubble(l,{evt:a}),d&&b._fireAndBubble(m,{evt:a}))),this._fire(w,{evt:a}),Kinetic.listenClickTap&&(this._fire(x,{evt:a}),d&&this._fire(y,{evt:a})),Kinetic.listenClickTap=!1}a.preventDefault&&a.preventDefault()},_touchstart:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition());Kinetic.listenClickTap=!0,b&&b.isListening()&&(this.tapStartShape=b,b._fireAndBubble(n,{evt:a}),b.isListening()&&a.preventDefault&&a.preventDefault()),this._fire(z,{evt:a})},_touchend:function(a){this._setPointerPosition(a);var b=this.getIntersection(this.getPointerPosition()),c=!1;Kinetic.inDblClickWindow?(c=!0,Kinetic.inDblClickWindow=!1):Kinetic.inDblClickWindow=!0,setTimeout(function(){Kinetic.inDblClickWindow=!1},Kinetic.dblClickWindow),b&&b.isListening()&&(b._fireAndBubble(o,{evt:a}),Kinetic.listenClickTap&&b._id===this.tapStartShape._id&&(b._fireAndBubble(p,{evt:a}),c&&b._fireAndBubble(q,{evt:a})),b.isListening()&&a.preventDefault&&a.preventDefault()),Kinetic.listenClickTap&&(this._fire(A,{evt:a}),c&&this._fire(B,{evt:a})),Kinetic.listenClickTap=!1},_touchmove:function(a){this._setPointerPosition(a);var b,c=Kinetic.DD;Kinetic.isDragging()||(b=this.getIntersection(this.getPointerPosition()),b&&b.isListening()&&(b._fireAndBubble(r,{evt:a}),b.isListening()&&a.preventDefault&&a.preventDefault()),this._fire(C,{evt:a})),c&&(c._drag(a),Kinetic.isDragging()&&a.preventDefault())},_setPointerPosition:function(a){var b,c=this._getContentPosition(),d=a.offsetX,e=a.clientX,f=null,g=null;a=a?a:window.event,void 0!==a.touches?a.touches.length>0&&(b=a.touches[0],f=b.clientX-c.left,g=b.clientY-c.top):void 0!==d?(f=d,g=a.offsetY):"mozilla"===Kinetic.UA.browser?(f=a.layerX,g=a.layerY):void 0!==e&&c&&(f=e-c.left,g=a.clientY-c.top),null!==f&&null!==g&&(this.pointerPos={x:f,y:g})},_getContentPosition:function(){var a=this.content.getBoundingClientRect?this.content.getBoundingClientRect():{top:0,left:0};return{top:a.top,left:a.left}},_buildDOM:function(){var a=this.getContainer();if(!a){if(Kinetic.Util.isBrowser())throw"Stage has not container. But container is required";a=Kinetic.document.createElement(D)}a.innerHTML=K,this.content=Kinetic.document.createElement(D),this.content.style.position=E,this.content.style.display=F,this.content.className=G,this.content.setAttribute("role","presentation"),a.appendChild(this.content),this.bufferCanvas=new Kinetic.SceneCanvas({pixelRatio:1}),this.bufferHitCanvas=new Kinetic.HitCanvas,this._resizeDOM()},_onContent:function(a,b){var c,d,e=a.split(H),f=e.length;for(c=0;f>c;c++)d=e[c],this.content.addEventListener(d,b,!1)},cache:function(){Kinetic.Util.warn("Cache function is not allowed for stage. You may use cache only for layers, groups and shapes.")},clearCache:function(){}}),Kinetic.Util.extend(Kinetic.Stage,Kinetic.Container),Kinetic.Factory.addGetter(Kinetic.Stage,"container"),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Stage,"container")}(),function(){Kinetic.Util.addMethods(Kinetic.BaseLayer,{___init:function(a){this.nodeType="Layer",Kinetic.Container.call(this,a)},createPNGStream:function(){return this.canvas._canvas.createPNGStream()},getCanvas:function(){return this.canvas},getHitCanvas:function(){return this.hitCanvas},getContext:function(){return this.getCanvas().getContext()},clear:function(a){return this.getContext().clear(a),this.getHitCanvas().getContext().clear(a),this},clearHitCache:function(){this._hitImageData=void 0},setZIndex:function(a){Kinetic.Node.prototype.setZIndex.call(this,a);var b=this.getStage();return b&&(b.content.removeChild(this.getCanvas()._canvas),ac;c++){if(f=d[c],b=this._getIntersection({x:a.x+f.x*h,y:a.y+f.y*h}),g=b.shape)return g;b.antialiased&&(i=!0)}if(!i)return;h+=1}},_getImageData:function(a,b){var c=this.hitCanvas.width||1,d=this.hitCanvas.height||1,e=Math.round(b)*c+Math.round(a);return this._hitImageData||(this._hitImageData=this.hitCanvas.context.getImageData(0,0,c,d)),[this._hitImageData.data[4*e+0],this._hitImageData.data[4*e+1],this._hitImageData.data[4*e+2],this._hitImageData.data[4*e+3]]},_getIntersection:function(b){var c,d,e=this.hitCanvas.context.getImageData(b.x,b.y,1,1).data,f=e[3];return 255===f?(c=Kinetic.Util._rgbToHex(e[0],e[1],e[2]),d=Kinetic.shapes[a+c],{shape:d}):f>0?{antialiased:!0}:{}},drawScene:function(a,d){var e=this.getLayer(),f=a||e&&e.getCanvas();return this._fire(b,{node:this}),this.getClearBeforeDraw()&&f.getContext().clear(),Kinetic.Container.prototype.drawScene.call(this,f,d),this._fire(c,{node:this}),this},_applyTransform:function(a,b,c){var d=a.getAbsoluteTransform(c).getMatrix();b.transform(d[0],d[1],d[2],d[3],d[4],d[5])},drawHit:function(a,b){var c=this.getLayer(),d=a||c&&c.hitCanvas;return c&&c.getClearBeforeDraw()&&c.getHitCanvas().getContext().clear(),Kinetic.Container.prototype.drawHit.call(this,d,b),this},clear:function(a){return this.getContext().clear(a),this.getHitCanvas().getContext().clear(a),this.imageData=null,this},setVisible:function(a){return Kinetic.Node.prototype.setVisible.call(this,a),a?(this.getCanvas()._canvas.style.display="block",this.hitCanvas._canvas.style.display="block"):(this.getCanvas()._canvas.style.display="none",this.hitCanvas._canvas.style.display="none"),this},enableHitGraph:function(){return this.setHitGraphEnabled(!0),this},disableHitGraph:function(){return this.setHitGraphEnabled(!1),this},setSize:function(a,b){Kinetic.BaseLayer.prototype.setSize.call(this,a,b),this.hitCanvas.setSize(a,b)}}),Kinetic.Util.extend(Kinetic.Layer,Kinetic.BaseLayer),Kinetic.Factory.addGetterSetter(Kinetic.Layer,"hitGraphEnabled",!0),Kinetic.Collection.mapMethods(Kinetic.Layer)}(),function(){Kinetic.Util.addMethods(Kinetic.FastLayer,{____init:function(a){this.nodeType="Layer",this.canvas=new Kinetic.SceneCanvas,Kinetic.BaseLayer.call(this,a)},_validateAdd:function(a){var b=a.getType();"Shape"!==b&&Kinetic.Util.error("You may only add shapes to a fast layer.")},_setCanvasSize:function(a,b){this.canvas.setSize(a,b)},hitGraphEnabled:function(){return!1},getIntersection:function(){return null},drawScene:function(a){var b=this.getLayer(),c=a||b&&b.getCanvas();return this.getClearBeforeDraw()&&c.getContext().clear(),Kinetic.Container.prototype.drawScene.call(this,c),this},_applyTransform:function(a,b,c){if(!c||c._id!==this._id){var d=a.getTransform().getMatrix();b.transform(d[0],d[1],d[2],d[3],d[4],d[5])}},draw:function(){return this.drawScene(),this},clear:function(a){return this.getContext().clear(a),this},setVisible:function(a){return Kinetic.Node.prototype.setVisible.call(this,a),this.getCanvas()._canvas.style.display=a?"block":"none",this}}),Kinetic.Util.extend(Kinetic.FastLayer,Kinetic.BaseLayer),Kinetic.Collection.mapMethods(Kinetic.FastLayer)}(),function(){Kinetic.Util.addMethods(Kinetic.Group,{___init:function(a){this.nodeType="Group",Kinetic.Container.call(this,a)},_validateAdd:function(a){var b=a.getType();"Group"!==b&&"Shape"!==b&&Kinetic.Util.error("You may only add groups and shapes to groups.")}}),Kinetic.Util.extend(Kinetic.Group,Kinetic.Container),Kinetic.Collection.mapMethods(Kinetic.Group)}(),function(){Kinetic.Rect=function(a){this.___init(a)},Kinetic.Rect.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Rect",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b=this.getCornerRadius(),c=this.getWidth(),d=this.getHeight();a.beginPath(),b?(a.moveTo(b,0),a.lineTo(c-b,0),a.arc(c-b,b,b,3*Math.PI/2,0,!1),a.lineTo(c,d-b),a.arc(c-b,d-b,b,0,Math.PI/2,!1),a.lineTo(b,d),a.arc(b,d-b,b,Math.PI/2,Math.PI,!1),a.lineTo(0,b),a.arc(b,b,b,Math.PI,3*Math.PI/2,!1)):a.rect(0,0,c,d),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Rect,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Rect,"cornerRadius",0),Kinetic.Collection.mapMethods(Kinetic.Rect)}(),function(){var a=2*Math.PI-1e-4,b="Circle";Kinetic.Circle=function(a){this.___init(a)},Kinetic.Circle.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className=b,this.sceneFunc(this._sceneFunc)},_sceneFunc:function(b){b.beginPath(),b.arc(0,0,this.getRadius(),0,a,!1),b.closePath(),b.fillStrokeShape(this)},getWidth:function(){return 2*this.getRadius()},getHeight:function(){return 2*this.getRadius()},setWidth:function(a){Kinetic.Node.prototype.setWidth.call(this,a),this.setRadius(a/2)},setHeight:function(a){Kinetic.Node.prototype.setHeight.call(this,a),this.setRadius(a/2)}},Kinetic.Util.extend(Kinetic.Circle,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Circle,"radius",0),Kinetic.Collection.mapMethods(Kinetic.Circle)}(),function(){var a=2*Math.PI-1e-4,b="Ellipse";Kinetic.Ellipse=function(a){this.___init(a)},Kinetic.Ellipse.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className=b,this.sceneFunc(this._sceneFunc)},_sceneFunc:function(b){var c=this.getRadiusX(),d=this.getRadiusY();b.beginPath(),b.save(),c!==d&&b.scale(1,d/c),b.arc(0,0,c,0,a,!1),b.restore(),b.closePath(),b.fillStrokeShape(this)},getWidth:function(){return 2*this.getRadiusX()},getHeight:function(){return 2*this.getRadiusY()},setWidth:function(a){Kinetic.Node.prototype.setWidth.call(this,a),this.setRadius({x:a/2})},setHeight:function(a){Kinetic.Node.prototype.setHeight.call(this,a),this.setRadius({y:a/2})}},Kinetic.Util.extend(Kinetic.Ellipse,Kinetic.Shape),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Ellipse,"radius",["x","y"]),Kinetic.Factory.addGetterSetter(Kinetic.Ellipse,"radiusX",0),Kinetic.Factory.addGetterSetter(Kinetic.Ellipse,"radiusY",0),Kinetic.Collection.mapMethods(Kinetic.Ellipse)}(),function(){var a=2*Math.PI-1e-4;Kinetic.Ring=function(a){this.___init(a)},Kinetic.Ring.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Ring",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(b){b.beginPath(),b.arc(0,0,this.getInnerRadius(),0,a,!1),b.moveTo(this.getOuterRadius(),0),b.arc(0,0,this.getOuterRadius(),a,0,!0),b.closePath(),b.fillStrokeShape(this)},getWidth:function(){return 2*this.getOuterRadius()},getHeight:function(){return 2*this.getOuterRadius()},setWidth:function(a){Kinetic.Node.prototype.setWidth.call(this,a),this.setOuterRadius(a/2)},setHeight:function(a){Kinetic.Node.prototype.setHeight.call(this,a),this.setOuterRadius(a/2)}},Kinetic.Util.extend(Kinetic.Ring,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Ring,"innerRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Ring,"outerRadius",0),Kinetic.Collection.mapMethods(Kinetic.Ring)}(),function(){Kinetic.Wedge=function(a){this.___init(a)},Kinetic.Wedge.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Wedge",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){a.beginPath(),a.arc(0,0,this.getRadius(),0,Kinetic.getAngle(this.getAngle()),this.getClockwise()),a.lineTo(0,0),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Wedge,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Wedge,"radius",0),Kinetic.Factory.addGetterSetter(Kinetic.Wedge,"angle",0),Kinetic.Factory.addGetterSetter(Kinetic.Wedge,"clockwise",!1),Kinetic.Factory.backCompat(Kinetic.Wedge,{angleDeg:"angle",getAngleDeg:"getAngle",setAngleDeg:"setAngle"}),Kinetic.Collection.mapMethods(Kinetic.Wedge)}(),function(){Math.PI/180;Kinetic.Arc=function(a){this.___init(a)},Kinetic.Arc.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Arc",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b=Kinetic.getAngle(this.angle()),c=this.clockwise();a.beginPath(),a.arc(0,0,this.getOuterRadius(),0,b,c),a.arc(0,0,this.getInnerRadius(),b,0,!c),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Arc,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Arc,"innerRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Arc,"outerRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Arc,"angle",0),Kinetic.Factory.addGetterSetter(Kinetic.Arc,"clockwise",!1),Kinetic.Collection.mapMethods(Kinetic.Arc)}(),function(){var a="Image";Kinetic.Image=function(a){this.___init(a)},Kinetic.Image.prototype={___init:function(b){Kinetic.Shape.call(this,b),this.className=a,this.sceneFunc(this._sceneFunc),this.hitFunc(this._hitFunc)},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasStroke()&&this.getStage()},_sceneFunc:function(a){var b,c,d,e=this.getWidth(),f=this.getHeight(),g=this.getImage();g&&(b=this.getCropWidth(),c=this.getCropHeight(),d=b&&c?[g,this.getCropX(),this.getCropY(),b,c,0,0,e,f]:[g,0,0,e,f]),(this.hasFill()||this.hasStroke()||this.hasShadow())&&(a.beginPath(),a.rect(0,0,e,f),a.closePath(),a.fillStrokeShape(this)),g&&a.drawImage.apply(a,d)},_hitFunc:function(a){var b=this.getWidth(),c=this.getHeight();a.beginPath(),a.rect(0,0,b,c),a.closePath(),a.fillStrokeShape(this)},getWidth:function(){var a=this.getImage();return this.attrs.width||(a?a.width:0)},getHeight:function(){var a=this.getImage();return this.attrs.height||(a?a.height:0)}},Kinetic.Util.extend(Kinetic.Image,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Image,"image"),Kinetic.Factory.addComponentsGetterSetter(Kinetic.Image,"crop",["x","y","width","height"]),Kinetic.Factory.addGetterSetter(Kinetic.Image,"cropX",0),Kinetic.Factory.addGetterSetter(Kinetic.Image,"cropY",0),Kinetic.Factory.addGetterSetter(Kinetic.Image,"cropWidth",0),Kinetic.Factory.addGetterSetter(Kinetic.Image,"cropHeight",0),Kinetic.Collection.mapMethods(Kinetic.Image) -}(),function(){function a(a){a.fillText(this.partialText,0,0)}function b(a){a.strokeText(this.partialText,0,0)}var c="auto",d="center",e="Change.kinetic",f="2d",g="-",h="",i="left",j="text",k="Text",l="middle",m="normal",n="px ",o=" ",p="right",q="word",r="char",s="none",t=["fontFamily","fontSize","fontStyle","fontVariant","padding","align","lineHeight","text","width","height","wrap"],u=t.length,v=Kinetic.Util.createCanvasElement().getContext(f);Kinetic.Text=function(a){this.___init(a)},Kinetic.Text.prototype={___init:function(d){var f=this;void 0===d.width&&(d.width=c),void 0===d.height&&(d.height=c),Kinetic.Shape.call(this,d),this._fillFunc=a,this._strokeFunc=b,this.className=k;for(var g=0;u>g;g++)this.on(t[g]+e,f._setTextData);this._setTextData(),this.sceneFunc(this._sceneFunc),this.hitFunc(this._hitFunc)},_sceneFunc:function(a){var b,c=this.getPadding(),e=this.getTextHeight(),f=this.getLineHeight()*e,g=this.textArr,h=g.length,j=this.getWidth();for(a.setAttr("font",this._getContextFont()),a.setAttr("textBaseline",l),a.setAttr("textAlign",i),a.save(),a.translate(c,0),a.translate(0,c+e/2),b=0;h>b;b++){var k=g[b],m=k.text,n=k.width;a.save(),this.getAlign()===p?a.translate(j-n-2*c,0):this.getAlign()===d&&a.translate((j-n-2*c)/2,0),this.partialText=m,a.fillStrokeShape(this),a.restore(),a.translate(0,f)}a.restore()},_hitFunc:function(a){var b=this.getWidth(),c=this.getHeight();a.beginPath(),a.rect(0,0,b,c),a.closePath(),a.fillStrokeShape(this)},setText:function(a){var b=Kinetic.Util._isString(a)?a:a.toString();return this._setAttr(j,b),this},getWidth:function(){return this.attrs.width===c?this.getTextWidth()+2*this.getPadding():this.attrs.width},getHeight:function(){return this.attrs.height===c?this.getTextHeight()*this.textArr.length*this.getLineHeight()+2*this.getPadding():this.attrs.height},getTextWidth:function(){return this.textWidth},getTextHeight:function(){return this.textHeight},_getTextSize:function(a){var b,c=v,d=this.getFontSize();return c.save(),c.font=this._getContextFont(),b=c.measureText(a),c.restore(),{width:b.width,height:parseInt(d,10)}},_getContextFont:function(){return this.getFontStyle()+o+this.getFontVariant()+o+this.getFontSize()+n+this.getFontFamily()},_addTextLine:function(a,b){return this.textArr.push({text:a,width:b})},_getTextWidth:function(a){return v.measureText(a).width},_setTextData:function(){var a=this.getText().split("\n"),b=+this.getFontSize(),d=0,e=this.getLineHeight()*b,f=this.attrs.width,h=this.attrs.height,i=f!==c,j=h!==c,k=this.getPadding(),l=f-2*k,m=h-2*k,n=0,p=this.getWrap(),q=p!==s,t=p!==r&&q;this.textArr=[],v.save(),v.font=this._getContextFont();for(var u=0,w=a.length;w>u;++u){var x=a[u],y=this._getTextWidth(x);if(i&&y>l)for(;x.length>0;){for(var z=0,A=x.length,B="",C=0;A>z;){var D=z+A>>>1,E=x.slice(0,D+1),F=this._getTextWidth(E);l>=F?(z=D+1,B=E,C=F):A=D}if(!B)break;if(t){var G=Math.max(B.lastIndexOf(o),B.lastIndexOf(g))+1;G>0&&(z=G,B=B.slice(0,z),C=this._getTextWidth(B))}if(this._addTextLine(B,C),d=Math.max(d,C),n+=e,!q||j&&n+e>m)break;if(x=x.slice(z),x.length>0&&(y=this._getTextWidth(x),l>=y)){this._addTextLine(x,y),n+=e,d=Math.max(d,y);break}}else this._addTextLine(x,y),n+=e,d=Math.max(d,y);if(j&&n+e>m)break}v.restore(),this.textHeight=b,this.textWidth=d}},Kinetic.Util.extend(Kinetic.Text,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontFamily","Arial"),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontSize",12),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontStyle",m),Kinetic.Factory.addGetterSetter(Kinetic.Text,"fontVariant",m),Kinetic.Factory.addGetterSetter(Kinetic.Text,"padding",0),Kinetic.Factory.addGetterSetter(Kinetic.Text,"align",i),Kinetic.Factory.addGetterSetter(Kinetic.Text,"lineHeight",1),Kinetic.Factory.addGetterSetter(Kinetic.Text,"wrap",q),Kinetic.Factory.addGetter(Kinetic.Text,"text",h),Kinetic.Factory.addOverloadedGetterSetter(Kinetic.Text,"text"),Kinetic.Collection.mapMethods(Kinetic.Text)}(),function(){Kinetic.Line=function(a){this.___init(a)},Kinetic.Line.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Line",this.on("pointsChange.kinetic tensionChange.kinetic closedChange.kinetic",function(){this._clearCache("tensionPoints")}),this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b,c,d,e=this.getPoints(),f=e.length,g=this.getTension(),h=this.getClosed();if(a.beginPath(),a.moveTo(e[0],e[1]),0!==g&&f>4){for(b=this.getTensionPoints(),c=b.length,d=h?0:4,h||a.quadraticCurveTo(b[0],b[1],b[2],b[3]);c-2>d;)a.bezierCurveTo(b[d++],b[d++],b[d++],b[d++],b[d++],b[d++]);h||a.quadraticCurveTo(b[c-2],b[c-1],e[f-2],e[f-1])}else for(d=2;f>d;d+=2)a.lineTo(e[d],e[d+1]);h?(a.closePath(),a.fillStrokeShape(this)):a.strokeShape(this)},getTensionPoints:function(){return this._getCache("tensionPoints",this._getTensionPoints)},_getTensionPoints:function(){return this.getClosed()?this._getTensionPointsClosed():Kinetic.Util._expandPoints(this.getPoints(),this.getTension())},_getTensionPointsClosed:function(){var a=this.getPoints(),b=a.length,c=this.getTension(),d=Kinetic.Util,e=d._getControlPoints(a[b-2],a[b-1],a[0],a[1],a[2],a[3],c),f=d._getControlPoints(a[b-4],a[b-3],a[b-2],a[b-1],a[0],a[1],c),g=Kinetic.Util._expandPoints(a,c),h=[e[2],e[3]].concat(g).concat([f[0],f[1],a[b-2],a[b-1],f[2],f[3],e[0],e[1],a[0],a[1]]);return h}},Kinetic.Util.extend(Kinetic.Line,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Line,"closed",!1),Kinetic.Factory.addGetterSetter(Kinetic.Line,"tension",0),Kinetic.Factory.addGetterSetter(Kinetic.Line,"points"),Kinetic.Collection.mapMethods(Kinetic.Line)}(),function(){Kinetic.Sprite=function(a){this.___init(a)},Kinetic.Sprite.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Sprite",this.anim=new Kinetic.Animation,this.on("animationChange.kinetic",function(){this.frameIndex(0)}),this.on("frameRateChange.kinetic",function(){this.anim.isRunning()&&(clearInterval(this.interval),this._setInterval())}),this.sceneFunc(this._sceneFunc),this.hitFunc(this._hitFunc)},_sceneFunc:function(a){var b=this.getAnimation(),c=this.frameIndex(),d=4*c,e=this.getAnimations()[b],f=e[d+0],g=e[d+1],h=e[d+2],i=e[d+3],j=this.getImage();j&&a.drawImage(j,f,g,h,i,0,0,h,i)},_hitFunc:function(a){var b=this.getAnimation(),c=this.frameIndex(),d=4*c,e=this.getAnimations()[b],f=e[d+2],g=e[d+3];a.beginPath(),a.rect(0,0,f,g),a.closePath(),a.fillShape(this)},_useBufferCanvas:function(){return(this.hasShadow()||1!==this.getAbsoluteOpacity())&&this.hasStroke()},_setInterval:function(){var a=this;this.interval=setInterval(function(){a._updateIndex()},1e3/this.getFrameRate())},start:function(){var a=this.getLayer();this.anim.setLayers(a),this._setInterval(),this.anim.start()},stop:function(){this.anim.stop(),clearInterval(this.interval)},isRunning:function(){return this.anim.isRunning()},_updateIndex:function(){var a=this.frameIndex(),b=this.getAnimation(),c=this.getAnimations(),d=c[b],e=d.length/4;this.frameIndex(e-1>a?a+1:0)}},Kinetic.Util.extend(Kinetic.Sprite,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"animation"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"animations"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"image"),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"frameIndex",0),Kinetic.Factory.addGetterSetter(Kinetic.Sprite,"frameRate",17),Kinetic.Factory.backCompat(Kinetic.Sprite,{index:"frameIndex",getIndex:"getFrameIndex",setIndex:"setFrameIndex"}),Kinetic.Collection.mapMethods(Kinetic.Sprite)}(),function(){Kinetic.Path=function(a){this.___init(a)},Kinetic.Path.prototype={___init:function(a){this.dataArray=[];var b=this;Kinetic.Shape.call(this,a),this.className="Path",this.dataArray=Kinetic.Path.parsePathData(this.getData()),this.on("dataChange.kinetic",function(){b.dataArray=Kinetic.Path.parsePathData(this.getData())}),this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b=this.dataArray,c=!1;a.beginPath();for(var d=0;dj?i:j,p=i>j?1:i/j,q=i>j?j/i:1;a.translate(g,h),a.rotate(m),a.scale(p,q),a.arc(0,0,o,k,k+l,1-n),a.scale(1/p,1/q),a.rotate(-m),a.translate(-g,-h);break;case"z":a.closePath(),c=!0}}c?a.fillStrokeShape(this):a.strokeShape(this)}},Kinetic.Util.extend(Kinetic.Path,Kinetic.Shape),Kinetic.Path.getLineLength=function(a,b,c,d){return Math.sqrt((c-a)*(c-a)+(d-b)*(d-b))},Kinetic.Path.getPointOnLine=function(a,b,c,d,e,f,g){void 0===f&&(f=b),void 0===g&&(g=c);var h=(e-c)/(d-b+1e-8),i=Math.sqrt(a*a/(1+h*h));b>d&&(i*=-1);var j,k=h*i;if(d===b)j={x:f,y:g+k};else if((g-c)/(f-b+1e-8)===h)j={x:f+i,y:g+k};else{var l,m,n=this.getLineLength(b,c,d,e);if(1e-8>n)return void 0;var o=(f-b)*(d-b)+(g-c)*(e-c);o/=n*n,l=b+o*(d-b),m=c+o*(e-c);var p=this.getLineLength(f,g,l,m),q=Math.sqrt(a*a-p*p);i=Math.sqrt(q*q/(1+h*h)),b>d&&(i*=-1),k=h*i,j={x:l+i,y:m+k}}return j},Kinetic.Path.getPointOnCubicBezier=function(a,b,c,d,e,f,g,h,i){function j(a){return a*a*a}function k(a){return 3*a*a*(1-a)}function l(a){return 3*a*(1-a)*(1-a)}function m(a){return(1-a)*(1-a)*(1-a)}var n=h*j(a)+f*k(a)+d*l(a)+b*m(a),o=i*j(a)+g*k(a)+e*l(a)+c*m(a);return{x:n,y:o}},Kinetic.Path.getPointOnQuadraticBezier=function(a,b,c,d,e,f,g){function h(a){return a*a}function i(a){return 2*a*(1-a)}function j(a){return(1-a)*(1-a)}var k=f*h(a)+d*i(a)+b*j(a),l=g*h(a)+e*i(a)+c*j(a);return{x:k,y:l}},Kinetic.Path.getPointOnEllipticalArc=function(a,b,c,d,e,f){var g=Math.cos(f),h=Math.sin(f),i={x:c*Math.cos(e),y:d*Math.sin(e)};return{x:a+(i.x*g-i.y*h),y:b+(i.x*h+i.y*g)}},Kinetic.Path.parsePathData=function(a){if(!a)return[];var b=a,c=["m","M","l","L","v","V","h","H","z","Z","c","C","q","Q","t","T","s","S","a","A"];b=b.replace(new RegExp(" ","g"),",");for(var d=0;d0&&""===k[0]&&k.shift();for(var l=0;l0&&!isNaN(k[0]);){var m,n,o,p,q,r,s,t,u,v,w=null,x=[],y=g,z=h;switch(j){case"l":g+=k.shift(),h+=k.shift(),w="L",x.push(g,h);break;case"L":g=k.shift(),h=k.shift(),x.push(g,h);break;case"m":var A=k.shift(),B=k.shift();if(g+=A,h+=B,w="M",f.length>2&&"z"===f[f.length-1].command)for(var C=f.length-2;C>=0;C--)if("M"===f[C].command){g=f[C].points[0]+A,h=f[C].points[1]+B;break}x.push(g,h),j="l";break;case"M":g=k.shift(),h=k.shift(),w="M",x.push(g,h),j="L";break;case"h":g+=k.shift(),w="L",x.push(g,h);break;case"H":g=k.shift(),w="L",x.push(g,h);break;case"v":h+=k.shift(),w="L",x.push(g,h);break;case"V":h=k.shift(),w="L",x.push(g,h);break;case"C":x.push(k.shift(),k.shift(),k.shift(),k.shift()),g=k.shift(),h=k.shift(),x.push(g,h);break;case"c":x.push(g+k.shift(),h+k.shift(),g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="C",x.push(g,h);break;case"S":n=g,o=h,m=f[f.length-1],"C"===m.command&&(n=g+(g-m.points[2]),o=h+(h-m.points[3])),x.push(n,o,k.shift(),k.shift()),g=k.shift(),h=k.shift(),w="C",x.push(g,h);break;case"s":n=g,o=h,m=f[f.length-1],"C"===m.command&&(n=g+(g-m.points[2]),o=h+(h-m.points[3])),x.push(n,o,g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="C",x.push(g,h);break;case"Q":x.push(k.shift(),k.shift()),g=k.shift(),h=k.shift(),x.push(g,h);break;case"q":x.push(g+k.shift(),h+k.shift()),g+=k.shift(),h+=k.shift(),w="Q",x.push(g,h);break;case"T":n=g,o=h,m=f[f.length-1],"Q"===m.command&&(n=g+(g-m.points[0]),o=h+(h-m.points[1])),g=k.shift(),h=k.shift(),w="Q",x.push(n,o,g,h);break;case"t":n=g,o=h,m=f[f.length-1],"Q"===m.command&&(n=g+(g-m.points[0]),o=h+(h-m.points[1])),g+=k.shift(),h+=k.shift(),w="Q",x.push(n,o,g,h);break;case"A":p=k.shift(),q=k.shift(),r=k.shift(),s=k.shift(),t=k.shift(),u=g,v=h,g=k.shift(),h=k.shift(),w="A",x=this.convertEndpointToCenterParameterization(u,v,g,h,s,t,p,q,r);break;case"a":p=k.shift(),q=k.shift(),r=k.shift(),s=k.shift(),t=k.shift(),u=g,v=h,g+=k.shift(),h+=k.shift(),w="A",x=this.convertEndpointToCenterParameterization(u,v,g,h,s,t,p,q,r)}f.push({command:w||j,points:x,start:{x:y,y:z},pathLength:this.calcLength(y,z,w||j,x)})}("z"===j||"Z"===j)&&f.push({command:"z",points:[],start:void 0,pathLength:0})}return f},Kinetic.Path.calcLength=function(a,b,c,d){var e,f,g,h,i=Kinetic.Path;switch(c){case"L":return i.getLineLength(a,b,d[0],d[1]);case"C":for(e=0,f=i.getPointOnCubicBezier(0,a,b,d[0],d[1],d[2],d[3],d[4],d[5]),h=.01;1>=h;h+=.01)g=i.getPointOnCubicBezier(h,a,b,d[0],d[1],d[2],d[3],d[4],d[5]),e+=i.getLineLength(f.x,f.y,g.x,g.y),f=g;return e;case"Q":for(e=0,f=i.getPointOnQuadraticBezier(0,a,b,d[0],d[1],d[2],d[3]),h=.01;1>=h;h+=.01)g=i.getPointOnQuadraticBezier(h,a,b,d[0],d[1],d[2],d[3]),e+=i.getLineLength(f.x,f.y,g.x,g.y),f=g;return e;case"A":e=0;var j=d[4],k=d[5],l=d[4]+k,m=Math.PI/180;if(Math.abs(j-l)k)for(h=j-m;h>l;h-=m)g=i.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],h,0),e+=i.getLineLength(f.x,f.y,g.x,g.y),f=g;else for(h=j+m;l>h;h+=m)g=i.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],h,0),e+=i.getLineLength(f.x,f.y,g.x,g.y),f=g;return g=i.getPointOnEllipticalArc(d[0],d[1],d[2],d[3],l,0),e+=i.getLineLength(f.x,f.y,g.x,g.y)}return 0},Kinetic.Path.convertEndpointToCenterParameterization=function(a,b,c,d,e,f,g,h,i){var j=i*(Math.PI/180),k=Math.cos(j)*(a-c)/2+Math.sin(j)*(b-d)/2,l=-1*Math.sin(j)*(a-c)/2+Math.cos(j)*(b-d)/2,m=k*k/(g*g)+l*l/(h*h);m>1&&(g*=Math.sqrt(m),h*=Math.sqrt(m));var n=Math.sqrt((g*g*h*h-g*g*l*l-h*h*k*k)/(g*g*l*l+h*h*k*k));e===f&&(n*=-1),isNaN(n)&&(n=0);var o=n*g*l/h,p=n*-h*k/g,q=(a+c)/2+Math.cos(j)*o-Math.sin(j)*p,r=(b+d)/2+Math.sin(j)*o+Math.cos(j)*p,s=function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},t=function(a,b){return(a[0]*b[0]+a[1]*b[1])/(s(a)*s(b))},u=function(a,b){return(a[0]*b[1]=1&&(y=0),0===f&&y>0&&(y-=2*Math.PI),1===f&&0>y&&(y+=2*Math.PI),[q,r,g,h,v,y,j,f]},Kinetic.Factory.addGetterSetter(Kinetic.Path,"data"),Kinetic.Collection.mapMethods(Kinetic.Path)}(),function(){function a(a){a.fillText(this.partialText,0,0)}function b(a){a.strokeText(this.partialText,0,0)}var c="",d="normal";Kinetic.TextPath=function(a){this.___init(a)},Kinetic.TextPath.prototype={___init:function(c){var d=this;this.dummyCanvas=Kinetic.Util.createCanvasElement(),this.dataArray=[],Kinetic.Shape.call(this,c),this._fillFunc=a,this._strokeFunc=b,this._fillFuncHit=a,this._strokeFuncHit=b,this.className="TextPath",this.dataArray=Kinetic.Path.parsePathData(this.attrs.data),this.on("dataChange.kinetic",function(){d.dataArray=Kinetic.Path.parsePathData(this.attrs.data)}),this.on("textChange.kinetic textStroke.kinetic textStrokeWidth.kinetic",d._setTextData),d._setTextData(),this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){a.setAttr("font",this._getContextFont()),a.setAttr("textBaseline","middle"),a.setAttr("textAlign","left"),a.save();for(var b=this.glyphInfo,c=0;c0)return g=d,b[d];"M"==b[d].command&&(c={x:b[d].points[0],y:b[d].points[1]})}return{}},j=function(b){var f=a._getTextSize(b).width,g=0,j=0;for(d=void 0;Math.abs(f-g)/f>.01&&25>j;){j++;for(var k=g;void 0===e;)e=i(),e&&k+e.pathLengthf?d=Kinetic.Path.getPointOnLine(f,c.x,c.y,e.points[0],e.points[1],c.x,c.y):e=void 0;break;case"A":var m=e.points[4],n=e.points[5],o=e.points[4]+n;0===h?h=m+1e-8:f>g?h+=Math.PI/180*n/Math.abs(n):h-=Math.PI/360*n/Math.abs(n),(0>n&&o>h||n>=0&&h>o)&&(h=o,l=!0),d=Kinetic.Path.getPointOnEllipticalArc(e.points[0],e.points[1],e.points[2],e.points[3],h,e.points[6]);break;case"C":0===h?h=f>e.pathLength?1e-8:f/e.pathLength:f>g?h+=(f-g)/e.pathLength:h-=(g-f)/e.pathLength,h>1&&(h=1,l=!0),d=Kinetic.Path.getPointOnCubicBezier(h,e.start.x,e.start.y,e.points[0],e.points[1],e.points[2],e.points[3],e.points[4],e.points[5]);break;case"Q":0===h?h=f/e.pathLength:f>g?h+=(f-g)/e.pathLength:h-=(g-f)/e.pathLength,h>1&&(h=1,l=!0),d=Kinetic.Path.getPointOnQuadraticBezier(h,e.start.x,e.start.y,e.points[0],e.points[1],e.points[2],e.points[3])}void 0!==d&&(g=Kinetic.Path.getLineLength(c.x,c.y,d.x,d.y)),l&&(l=!1,e=void 0)}},k=0;kb;b++)c=f*Math.sin(2*b*Math.PI/e),d=-1*f*Math.cos(2*b*Math.PI/e),a.lineTo(c,d);a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.RegularPolygon,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.RegularPolygon,"radius",0),Kinetic.Factory.addGetterSetter(Kinetic.RegularPolygon,"sides",0),Kinetic.Collection.mapMethods(Kinetic.RegularPolygon)}(),function(){Kinetic.Star=function(a){this.___init(a)},Kinetic.Star.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Star",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b=this.innerRadius(),c=this.outerRadius(),d=this.numPoints();a.beginPath(),a.moveTo(0,0-c);for(var e=1;2*d>e;e++){var f=e%2===0?c:b,g=f*Math.sin(e*Math.PI/d),h=-1*f*Math.cos(e*Math.PI/d);a.lineTo(g,h)}a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Star,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Star,"numPoints",5),Kinetic.Factory.addGetterSetter(Kinetic.Star,"innerRadius",0),Kinetic.Factory.addGetterSetter(Kinetic.Star,"outerRadius",0),Kinetic.Collection.mapMethods(Kinetic.Star)}(),function(){var a=["fontFamily","fontSize","fontStyle","padding","lineHeight","text"],b="Change.kinetic",c="none",d="up",e="right",f="down",g="left",h="Label",i=a.length;Kinetic.Label=function(a){this.____init(a)},Kinetic.Label.prototype={____init:function(a){var b=this;Kinetic.Group.call(this,a),this.className=h,this.on("add.kinetic",function(a){b._addListeners(a.child),b._sync()})},getText:function(){return this.find("Text")[0]},getTag:function(){return this.find("Tag")[0]},_addListeners:function(c){var d,e=this,f=function(){e._sync()};for(d=0;i>d;d++)c.on(a[d]+b,f)},getWidth:function(){return this.getText().getWidth()},getHeight:function(){return this.getText().getHeight()},_sync:function(){var a,b,c,h,i,j,k,l=this.getText(),m=this.getTag();if(l&&m){switch(a=l.getWidth(),b=l.getHeight(),c=m.getPointerDirection(),h=m.getPointerWidth(),k=m.getPointerHeight(),i=0,j=0,c){case d:i=a/2,j=-1*k;break;case e:i=a+h,j=b/2;break;case f:i=a/2,j=b+k;break;case g:i=-1*h,j=b/2}m.setAttrs({x:-1*i,y:-1*j,width:a,height:b}),l.setAttrs({x:-1*i,y:-1*j})}}},Kinetic.Util.extend(Kinetic.Label,Kinetic.Group),Kinetic.Collection.mapMethods(Kinetic.Label),Kinetic.Tag=function(a){this.___init(a)},Kinetic.Tag.prototype={___init:function(a){Kinetic.Shape.call(this,a),this.className="Tag",this.sceneFunc(this._sceneFunc)},_sceneFunc:function(a){var b=this.getWidth(),c=this.getHeight(),h=this.getPointerDirection(),i=this.getPointerWidth(),j=this.getPointerHeight();a.beginPath(),a.moveTo(0,0),h===d&&(a.lineTo((b-i)/2,0),a.lineTo(b/2,-1*j),a.lineTo((b+i)/2,0)),a.lineTo(b,0),h===e&&(a.lineTo(b,(c-j)/2),a.lineTo(b+i,c/2),a.lineTo(b,(c+j)/2)),a.lineTo(b,c),h===f&&(a.lineTo((b+i)/2,c),a.lineTo(b/2,c+j),a.lineTo((b-i)/2,c)),a.lineTo(0,c),h===g&&(a.lineTo(0,(c+j)/2),a.lineTo(-1*i,c/2),a.lineTo(0,(c-j)/2)),a.closePath(),a.fillStrokeShape(this)}},Kinetic.Util.extend(Kinetic.Tag,Kinetic.Shape),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerDirection",c),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerWidth",0),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"pointerHeight",0),Kinetic.Factory.addGetterSetter(Kinetic.Tag,"cornerRadius",0),Kinetic.Collection.mapMethods(Kinetic.Tag)}(); \ No newline at end of file diff --git a/support/client/lib/vwf/model/kinetic/konva.ios.js b/support/client/lib/vwf/model/kinetic/konva.ios.js new file mode 100644 index 000000000..9075e2086 --- /dev/null +++ b/support/client/lib/vwf/model/kinetic/konva.ios.js @@ -0,0 +1,16288 @@ + +/* + * Konva JavaScript Framework v0.15.0 + * http://konvajs.github.io/ + * Licensed under the MIT or GPL Version 2 licenses. + * Date: Fri Jun 24 2016 + * + * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) + * Modified work Copyright (C) 2014 - 2015 by Anton Lavrenov (Konva) + * + * @license + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// runtime check for already included Konva +(function(global){ + 'use strict'; + /** + * @namespace Konva + */ + + var PI_OVER_180 = Math.PI / 180; + + var Konva = { + // public + version: '0.15.0', + + // private + stages: [], + idCounter: 0, + ids: {}, + names: {}, + shapes: {}, + listenClickTap: false, + inDblClickWindow: false, + + // configurations + enableTrace: false, + traceArrMax: 100, + dblClickWindow: 400, + /** + * Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device. + * But you may override such property, if you want to use your value. + * @property pixelRatio + * @default undefined + * @memberof Konva + * @example + * Konva.pixelRatio = 1; + */ + pixelRatio: undefined, + /** + * Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point, + * only then start dragging. + * @property dragDistance + * @default 0 + * @memberof Konva + * @example + * Konva.dragDistance = 10; + */ + dragDistance: 0, + /** + * Use degree values for angle properties. You may set this property to false if you want to use radiant values. + * @property angleDeg + * @default true + * @memberof Konva + * @example + * node.rotation(45); // 45 degrees + * Konva.angleDeg = false; + * node.rotation(Math.PI / 2); // PI/2 radian + */ + angleDeg: true, + /** + * Show different warnings about errors or wrong API usage + * @property showWarnings + * @default true + * @memberof Konva + * @example + * Konva.showWarnings = false; + */ + showWarnings: true, + + + + /** + * @namespace Filters + * @memberof Konva + */ + Filters: {}, + + /** + * returns whether or not drag and drop is currently active + * @method + * @memberof Konva + */ + isDragging: function() { + var dd = Konva.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (dd) { + return dd.isDragging; + } + return false; + }, + /** + * returns whether or not a drag and drop operation is ready, but may + * not necessarily have started + * @method + * @memberof Konva + */ + isDragReady: function() { + var dd = Konva.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (dd) { + return !!dd.node; + } + return false; + }, + _addId: function(node, id) { + if(id !== undefined) { + this.ids[id] = node; + } + }, + _removeId: function(id) { + if(id !== undefined) { + delete this.ids[id]; + } + }, + _addName: function(node, name) { + if(name) { + if(!this.names[name]) { + this.names[name] = []; + } + this.names[name].push(node); + } + }, + _removeName: function(name, _id) { + if(!name) { + return; + } + var nodes = this.names[name]; + if(!nodes) { + return; + } + for(var n = 0; n < nodes.length; n++) { + var no = nodes[n]; + if(no._id === _id) { + nodes.splice(n, 1); + } + } + if(nodes.length === 0) { + delete this.names[name]; + } + }, + getAngle: function(angle) { + return this.angleDeg ? angle * PI_OVER_180 : angle; + }, + _detectIE: function(ua) { + var msie = ua.indexOf('msie '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; + }, + _parseUA: function(userAgent) { + var ua = userAgent.toLowerCase(), + // jQuery UA regex + match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + [], + + // adding mobile flag as well + mobile = !!(userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)), + ieMobile = !!(userAgent.match(/IEMobile/i)); + + return { + browser: match[ 1 ] || '', + version: match[ 2 ] || '0', + isIE: Konva._detectIE(ua), + // adding mobile flab + mobile: mobile, + ieMobile: ieMobile // If this is true (i.e., WP8), then Konva touch events are executed instead of equivalent Konva mouse events + }; + }, + // user agent + UA: undefined + }; + + var glob = + typeof window !== 'undefined' ? window : + typeof global !== 'undefined' ? global : + typeof WorkerGlobalScope !== 'undefined' ? self : {}; + + + Konva.UA = Konva._parseUA((glob.navigator && glob.navigator.userAgent) || ''); + + + if (glob.Konva) { + console.error( + 'Konva instance is already exist in current eviroment. ' + + 'Please use only one instance.' + ); + } + glob.Konva = Konva; + Konva.global = glob; + + + if( typeof exports === 'object') { + // runtime-check for browserify and nw.js (node-webkit) + if(glob.window && glob.window.document) { + Konva.document = glob.window.document; + Konva.window = glob.window; + } else { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + var Canvas = require('canvas'); + var jsdom = require('jsdom').jsdom; + + Konva.window = jsdom('').defaultView; + Konva.document = Konva.window.document; + Konva.window.Image = Canvas.Image; + Konva._nodeCanvas = Canvas; + } + module.exports = Konva; + return; + } + else if( typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(function() { + return Konva; + }); + } + Konva.document = document; + Konva.window = window; +})(typeof window !== 'undefined' ? window : global); + +/*eslint-disable eqeqeq, no-cond-assign, no-empty*/ +(function() { + 'use strict'; + /** + * Collection constructor. Collection extends + * Array. This class is used in conjunction with {@link Konva.Container#get} + * @constructor + * @memberof Konva + */ + Konva.Collection = function() { + var args = [].slice.call(arguments), length = args.length, i = 0; + + this.length = length; + for(; i < length; i++) { + this[i] = args[i]; + } + return this; + }; + Konva.Collection.prototype = []; + /** + * iterate through node array and run a function for each node. + * The node and index is passed into the function + * @method + * @memberof Konva.Collection.prototype + * @param {Function} func + * @example + * // get all nodes with name foo inside layer, and set x to 10 for each + * layer.get('.foo').each(function(shape, n) { + * shape.setX(10); + * }); + */ + Konva.Collection.prototype.each = function(func) { + for(var n = 0; n < this.length; n++) { + func(this[n], n); + } + }; + /** + * convert collection into an array + * @method + * @memberof Konva.Collection.prototype + */ + Konva.Collection.prototype.toArray = function() { + var arr = [], + len = this.length, + n; + + for(n = 0; n < len; n++) { + arr.push(this[n]); + } + return arr; + }; + /** + * convert array into a collection + * @method + * @memberof Konva.Collection + * @param {Array} arr + */ + Konva.Collection.toCollection = function(arr) { + var collection = new Konva.Collection(), + len = arr.length, + n; + + for(n = 0; n < len; n++) { + collection.push(arr[n]); + } + return collection; + }; + + // map one method by it's name + Konva.Collection._mapMethod = function(methodName) { + Konva.Collection.prototype[methodName] = function() { + var len = this.length, + i; + + var args = [].slice.call(arguments); + for(i = 0; i < len; i++) { + this[i][methodName].apply(this[i], args); + } + + return this; + }; + }; + + Konva.Collection.mapMethods = function(constructor) { + var prot = constructor.prototype; + for(var methodName in prot) { + Konva.Collection._mapMethod(methodName); + } + }; + + /* + * Last updated November 2011 + * By Simon Sarris + * www.simonsarris.com + * sarris@acm.org + * + * Free to use and distribute at will + * So long as you are nice to people, etc + */ + + /* + * The usage of this class was inspired by some of the work done by a forked + * project, KineticJS-Ext by Wappworks, which is based on Simon's Transform + * class. Modified by Eric Rowell + */ + + /** + * Transform constructor + * @constructor + * @param {Array} [m] Optional six-element matrix + * @memberof Konva + */ + Konva.Transform = function(m) { + this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0]; + }; + + Konva.Transform.prototype = { + /** + * Copy Konva.Transform object + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + */ + copy: function() { + return new Konva.Transform(this.m); + }, + /** + * Transform point + * @method + * @memberof Konva.Transform.prototype + * @param {Object} point 2D point(x, y) + * @returns {Object} 2D point(x, y) + */ + point: function(point) { + var m = this.m; + return { + x: m[0] * point.x + m[2] * point.y + m[4], + y: m[1] * point.x + m[3] * point.y + m[5] + }; + }, + /** + * Apply translation + * @method + * @memberof Konva.Transform.prototype + * @param {Number} x + * @param {Number} y + * @returns {Konva.Transform} + */ + translate: function(x, y) { + this.m[4] += this.m[0] * x + this.m[2] * y; + this.m[5] += this.m[1] * x + this.m[3] * y; + return this; + }, + /** + * Apply scale + * @method + * @memberof Konva.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Konva.Transform} + */ + scale: function(sx, sy) { + this.m[0] *= sx; + this.m[1] *= sx; + this.m[2] *= sy; + this.m[3] *= sy; + return this; + }, + /** + * Apply rotation + * @method + * @memberof Konva.Transform.prototype + * @param {Number} rad Angle in radians + * @returns {Konva.Transform} + */ + rotate: function(rad) { + var c = Math.cos(rad); + var s = Math.sin(rad); + var m11 = this.m[0] * c + this.m[2] * s; + var m12 = this.m[1] * c + this.m[3] * s; + var m21 = this.m[0] * -s + this.m[2] * c; + var m22 = this.m[1] * -s + this.m[3] * c; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Returns the translation + * @method + * @memberof Konva.Transform.prototype + * @returns {Object} 2D point(x, y) + */ + getTranslation: function() { + return { + x: this.m[4], + y: this.m[5] + }; + }, + /** + * Apply skew + * @method + * @memberof Konva.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Konva.Transform} + */ + skew: function(sx, sy) { + var m11 = this.m[0] + this.m[2] * sy; + var m12 = this.m[1] + this.m[3] * sy; + var m21 = this.m[2] + this.m[0] * sx; + var m22 = this.m[3] + this.m[1] * sx; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Transform multiplication + * @method + * @memberof Konva.Transform.prototype + * @param {Konva.Transform} matrix + * @returns {Konva.Transform} + */ + multiply: function(matrix) { + var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1]; + var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1]; + + var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3]; + var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3]; + + var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4]; + var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5]; + + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + this.m[4] = dx; + this.m[5] = dy; + return this; + }, + /** + * Invert the matrix + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + */ + invert: function() { + var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]); + var m0 = this.m[3] * d; + var m1 = -this.m[1] * d; + var m2 = -this.m[2] * d; + var m3 = this.m[0] * d; + var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]); + var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]); + this.m[0] = m0; + this.m[1] = m1; + this.m[2] = m2; + this.m[3] = m3; + this.m[4] = m4; + this.m[5] = m5; + return this; + }, + /** + * return matrix + * @method + * @memberof Konva.Transform.prototype + */ + getMatrix: function() { + return this.m; + }, + /** + * set to absolute position via translation + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + * @author ericdrowell + */ + setAbsolutePosition: function(x, y) { + var m0 = this.m[0], + m1 = this.m[1], + m2 = this.m[2], + m3 = this.m[3], + m4 = this.m[4], + m5 = this.m[5], + yt = ((m0 * (y - m5)) - (m1 * (x - m4))) / ((m0 * m3) - (m1 * m2)), + xt = (x - m4 - (m2 * yt)) / m0; + + return this.translate(xt, yt); + } + }; + + // CONSTANTS + var CONTEXT_2D = '2d', + OBJECT_ARRAY = '[object Array]', + OBJECT_NUMBER = '[object Number]', + OBJECT_STRING = '[object String]', + PI_OVER_DEG180 = Math.PI / 180, + DEG180_OVER_PI = 180 / Math.PI, + HASH = '#', + EMPTY_STRING = '', + ZERO = '0', + KONVA_WARNING = 'Konva warning: ', + KONVA_ERROR = 'Konva error: ', + RGB_PAREN = 'rgb(', + COLORS = { + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 132, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 255, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + grey: [128, 128, 128], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 203], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + rebeccapurple: [102, 51, 153], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [119, 128, 144], + slategrey: [119, 128, 144], + snow: [255, 255, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + transparent: [255, 255, 255, 0], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 5] + }, + + RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; + + /** + * @namespace Util + * @memberof Konva + */ + Konva.Util = { + /* + * cherry-picked utilities from underscore.js + */ + _isElement: function(obj) { + return !!(obj && obj.nodeType == 1); + }, + _isFunction: function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }, + _isObject: function(obj) { + return (!!obj && obj.constructor === Object); + }, + _isArray: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_ARRAY; + }, + _isNumber: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_NUMBER; + }, + _isString: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_STRING; + }, + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _throttle: function(func, wait, opts) { + var context, args, result; + var timeout = null; + var previous = 0; + var options = opts || {}; + var later = function() { + previous = options.leading === false ? 0 : new Date().getTime(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = new Date().getTime(); + if (!previous && options.leading === false) { + previous = now; + } + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + /* + * other utils + */ + _hasMethods: function(obj) { + var names = [], + key; + + for(key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + if(this._isFunction(obj[key])) { + names.push(key); + } + } + return names.length > 0; + }, + isValidSelector: function(selector) { + if (typeof selector !== 'string') { + return false; + } + var firstChar = selector[0]; + return firstChar === '#' || firstChar === '.' || firstChar === firstChar.toUpperCase(); + }, + createCanvasElement: function() { + var canvas = Konva.document.createElement('canvas'); + // on some environments canvas.style is readonly + try { + canvas.style = canvas.style || {}; + } catch (e) { + } + return canvas; + }, + isBrowser: function() { + return (typeof exports !== 'object'); + }, + _isInDocument: function(el) { + while(el = el.parentNode) { + if(el == Konva.document) { + return true; + } + } + return false; + }, + _simplifyArray: function(arr) { + var retArr = [], + len = arr.length, + util = Konva.Util, + n, val; + + for (n = 0; n < len; n++) { + val = arr[n]; + if (util._isNumber(val)) { + val = Math.round(val * 1000) / 1000; + } + else if (!util._isString(val)) { + val = val.toString(); + } + + retArr.push(val); + } + + return retArr; + }, + /* + * arg can be an image object or image data + */ + _getImage: function(arg, callback) { + var imageObj, canvas; + + // if arg is null or undefined + if(!arg) { + callback(null); + } + + // if arg is already an image object + else if(this._isElement(arg)) { + callback(arg); + } + + // if arg is a string, then it's a data url + else if(this._isString(arg)) { + imageObj = new Konva.window.Image(); + imageObj.onload = function() { + callback(imageObj); + }; + imageObj.src = arg; + } + + //if arg is an object that contains the data property, it's an image object + else if(arg.data) { + canvas = Konva.Util.createCanvasElement(); + canvas.width = arg.width; + canvas.height = arg.height; + var _context = canvas.getContext(CONTEXT_2D); + _context.putImageData(arg, 0, 0); + this._getImage(canvas.toDataURL(), callback); + } + else { + callback(null); + } + }, + _getRGBAString: function(obj) { + var red = obj.red || 0, + green = obj.green || 0, + blue = obj.blue || 0, + alpha = obj.alpha || 1; + + return [ + 'rgba(', + red, + ',', + green, + ',', + blue, + ',', + alpha, + ')' + ].join(EMPTY_STRING); + }, + _rgbToHex: function(r, g, b) { + return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); + }, + _hexToRgb: function(hex) { + hex = hex.replace(HASH, EMPTY_STRING); + var bigint = parseInt(hex, 16); + return { + r: (bigint >> 16) & 255, + g: (bigint >> 8) & 255, + b: bigint & 255 + }; + }, + /** + * return random hex color + * @method + * @memberof Konva.Util.prototype + */ + getRandomColor: function() { + var randColor = (Math.random() * 0xFFFFFF << 0).toString(16); + while (randColor.length < 6) { + randColor = ZERO + randColor; + } + return HASH + randColor; + }, + /** + * return value with default fallback + * @method + * @memberof Konva.Util.prototype + */ + get: function(val, def) { + if (val === undefined) { + return def; + } + else { + return val; + } + }, + /** + * get RGB components of a color + * @method + * @memberof Konva.Util.prototype + * @param {String} color + * @example + * // each of the following examples return {r:0, g:0, b:255} + * var rgb = Konva.Util.getRGB('blue'); + * var rgb = Konva.Util.getRGB('#0000ff'); + * var rgb = Konva.Util.getRGB('rgb(0,0,255)'); + */ + getRGB: function(color) { + var rgb; + // color string + if (color in COLORS) { + rgb = COLORS[color]; + return { + r: rgb[0], + g: rgb[1], + b: rgb[2] + }; + } + // hex + else if (color[0] === HASH) { + return this._hexToRgb(color.substring(1)); + } + // rgb string + else if (color.substr(0, 4) === RGB_PAREN) { + rgb = RGB_REGEX.exec(color.replace(/ /g, '')); + return { + r: parseInt(rgb[1], 10), + g: parseInt(rgb[2], 10), + b: parseInt(rgb[3], 10) + }; + } + // default + else { + return { + r: 0, + g: 0, + b: 0 + }; + } + }, + // convert any color string to RGBA object + // from https://github.com/component/color-parser + colorToRGBA: function(str) { + str = str || 'black'; + return Konva.Util._namedColorToRBA(str) + || Konva.Util._hex3ColorToRGBA(str) + || Konva.Util._hex6ColorToRGBA(str) + || Konva.Util._rgbColorToRGBA(str) + || Konva.Util._rgbaColorToRGBA(str); + }, + // Parse named css color. Like "green" + _namedColorToRBA: function(str) { + var c = COLORS[str.toLowerCase()]; + if (!c) { + return null; + } + return { + r: c[0], + g: c[1], + b: c[2], + a: 1 + }; + }, + // Parse rgb(n, n, n) + _rgbColorToRGBA: function(str) { + if (str.indexOf('rgb(') === 0) { + str = str.match(/rgb\(([^)]+)\)/)[1]; + var parts = str.split(/ *, */).map(Number); + return { + r: parts[0], + g: parts[1], + b: parts[2], + a: 1 + }; + } + }, + // Parse rgba(n, n, n, n) + _rgbaColorToRGBA: function(str) { + if (str.indexOf('rgba(') === 0) { + str = str.match(/rgba\(([^)]+)\)/)[1]; + var parts = str.split(/ *, */).map(Number); + return { + r: parts[0], + g: parts[1], + b: parts[2], + a: parts[3] + }; + } + + }, + // Parse #nnnnnn + _hex6ColorToRGBA: function(str) { + if ((str[0] === '#') && (str.length === 7)) { + return { + r: parseInt(str.slice(1, 3), 16), + g: parseInt(str.slice(3, 5), 16), + b: parseInt(str.slice(5, 7), 16), + a: 1 + }; + } + }, + // Parse #nnn + _hex3ColorToRGBA: function(str) { + if ((str[0] === '#') && (str.length === 4)) { + return { + r: parseInt(str[1] + str[1], 16), + g: parseInt(str[2] + str[2], 16), + b: parseInt(str[3] + str[3], 16), + a: 1 + }; + } + }, + // o1 takes precedence over o2 + _merge: function(o1, o2) { + var retObj = this._clone(o2); + for(var key in o1) { + if(this._isObject(o1[key])) { + retObj[key] = this._merge(o1[key], retObj[key]); + } + else { + retObj[key] = o1[key]; + } + } + return retObj; + }, + cloneObject: function(obj) { + var retObj = {}; + for(var key in obj) { + if(this._isObject(obj[key])) { + retObj[key] = this.cloneObject(obj[key]); + } + else if (this._isArray(obj[key])) { + retObj[key] = this.cloneArray(obj[key]); + } else { + retObj[key] = obj[key]; + } + } + return retObj; + }, + cloneArray: function(arr) { + return arr.slice(0); + }, + _degToRad: function(deg) { + return deg * PI_OVER_DEG180; + }, + _radToDeg: function(rad) { + return rad * DEG180_OVER_PI; + }, + _capitalize: function(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + }, + throw: function(str) { + throw new Error(KONVA_ERROR + str); + }, + error: function(str) { + console.error(KONVA_ERROR + str); + }, + warn: function(str) { + /* + * IE9 on Windows7 64bit will throw a JS error + * if we don't use window.console in the conditional + */ + if(Konva.global.console && console.warn && Konva.showWarnings) { + console.warn(KONVA_WARNING + str); + } + }, + extend: function(child, parent) { + function Ctor() { + this.constructor = child; + } + Ctor.prototype = parent.prototype; + var oldProto = child.prototype; + child.prototype = new Ctor(); + for (var key in oldProto) { + if (oldProto.hasOwnProperty(key)) { + child.prototype[key] = oldProto[key]; + } + } + child.__super__ = parent.prototype; + // create reference to parent + child.super = parent; + }, + /** + * adds methods to a constructor prototype + * @method + * @memberof Konva.Util.prototype + * @param {Function} constructor + * @param {Object} methods + */ + addMethods: function(constructor, methods) { + var key; + + for (key in methods) { + constructor.prototype[key] = methods[key]; + } + }, + _getControlPoints: function(x0, y0, x1, y1, x2, y2, t) { + var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2)), + d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), + fa = t * d01 / (d01 + d12), + fb = t * d12 / (d01 + d12), + p1x = x1 - fa * (x2 - x0), + p1y = y1 - fa * (y2 - y0), + p2x = x1 + fb * (x2 - x0), + p2y = y1 + fb * (y2 - y0); + + return [p1x, p1y, p2x, p2y]; + }, + _expandPoints: function(p, tension) { + var len = p.length, + allPoints = [], + n, cp; + + for (n = 2; n < len - 2; n += 2) { + cp = Konva.Util._getControlPoints(p[n - 2], p[n - 1], p[n], p[n + 1], p[n + 2], p[n + 3], tension); + allPoints.push(cp[0]); + allPoints.push(cp[1]); + allPoints.push(p[n]); + allPoints.push(p[n + 1]); + allPoints.push(cp[2]); + allPoints.push(cp[3]); + } + + return allPoints; + }, + _removeLastLetter: function(str) { + return str.substring(0, str.length - 1); + }, + each: function(obj, func) { + for (var key in obj) { + func(key, obj[key]); + } + }, + _getProjectionToSegment: function(x1, y1, x2, y2, x3, y3) { + var x, y, dist; + + var pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + if(pd2 == 0) { + x = x1; + y = y1; + dist = (x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2); + } else { + var u = ((x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1)) / pd2; + if(u < 0) { + x = x1; + y = y1; + dist = (x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3); + } else if (u > 1.0) { + x = x2; + y = y2; + dist = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3); + } else { + x = x1 + u * (x2 - x1); + y = y1 + u * (y2 - y1); + dist = (x - x3) * (x - x3) + (y - y3) * (y - y3); + } + } + return [x, y, dist]; + }, + // line as array of points. + // line might be closed + _getProjectionToLine: function(pt, line, isClosed) { + var pc = Konva.Util.cloneObject(pt); + var dist = Number.MAX_VALUE; + line.forEach(function(p1, i) { + if (!isClosed && i === line.length - 1) { + return; + } + var p2 = line[(i + 1) % line.length]; + var proj = Konva.Util._getProjectionToSegment(p1.x, p1.y, p2.x, p2.y, pt.x, pt.y); + var px = proj[0], py = proj[1], pdist = proj[2]; + if (pdist < dist) { + pc.x = px; + pc.y = py; + dist = pdist; + } + }); + return pc; + }, + _prepareArrayForTween: function(startArray, endArray, isClosed) { + var n, start = [], end = []; + if (startArray.length > endArray.length) { + var temp = endArray; + endArray = startArray; + startArray = temp; + } + for (n = 0; n < startArray.length; n += 2) { + start.push({ + x: startArray[n], + y: startArray[n + 1] + }); + } + for (n = 0; n < endArray.length; n += 2) { + end.push({ + x: endArray[n], + y: endArray[n + 1] + }); + } + + + var newStart = []; + end.forEach(function(point) { + var pr = Konva.Util._getProjectionToLine(point, start, isClosed); + newStart.push(pr.x); + newStart.push(pr.y); + }); + return newStart; + } + }; +})(); + +(function() { + 'use strict'; + // calculate pixel ratio + var canvas = Konva.Util.createCanvasElement(), + context = canvas.getContext('2d'), + _pixelRatio = (function(){ + var devicePixelRatio = Konva.window.devicePixelRatio || 1, + backingStoreRatio = context.webkitBackingStorePixelRatio + || context.mozBackingStorePixelRatio + || context.msBackingStorePixelRatio + || context.oBackingStorePixelRatio + || context.backingStorePixelRatio + || 1; + return devicePixelRatio / backingStoreRatio; + })(); + + /** + * Canvas Renderer constructor + * @constructor + * @abstract + * @memberof Konva + * @param {Object} config + * @param {Number} config.width + * @param {Number} config.height + * @param {Number} config.pixelRatio KonvaJS automatically handles pixel ratio adjustments in order to render crisp drawings + * on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios + * of 1. Some high end tablets and phones, like iPhones and iPads (not the mini) have a device pixel ratio + * of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel + * ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise + * specified, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel + * ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1. + */ + Konva.Canvas = function(config) { + this.init(config); + }; + + Konva.Canvas.prototype = { + init: function(config) { + var conf = config || {}; + + var pixelRatio = conf.pixelRatio || Konva.pixelRatio || _pixelRatio; + + this.pixelRatio = pixelRatio; + this._canvas = Konva.Util.createCanvasElement(); + + // set inline styles + this._canvas.style.padding = 0; + this._canvas.style.margin = 0; + this._canvas.style.border = 0; + this._canvas.style.background = 'transparent'; + this._canvas.style.position = 'absolute'; + this._canvas.style.top = 0; + this._canvas.style.left = 0; + }, + /** + * get canvas context + * @method + * @memberof Konva.Canvas.prototype + * @returns {CanvasContext} context + */ + getContext: function() { + return this.context; + }, + /** + * get pixel ratio + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} pixel ratio + */ + getPixelRatio: function() { + return this.pixelRatio; + }, + /** + * get pixel ratio + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} pixelRatio KonvaJS automatically handles pixel ratio adustments in order to render crisp drawings + * on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios + * of 1. Some high end tablets and phones, like iPhones and iPads have a device pixel ratio + * of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel + * ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise + * specificed, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel + * ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1. + */ + setPixelRatio: function(pixelRatio) { + var previousRatio = this.pixelRatio; + this.pixelRatio = pixelRatio; + this.setSize(this.getWidth() / previousRatio, this.getHeight() / previousRatio); + }, + /** + * set width + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} width + */ + setWidth: function(width) { + // take into account pixel ratio + this.width = this._canvas.width = width * this.pixelRatio; + this._canvas.style.width = width + 'px'; + + var pixelRatio = this.pixelRatio, + _context = this.getContext()._context; + _context.scale(pixelRatio, pixelRatio); + }, + /** + * set height + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} height + */ + setHeight: function(height) { + // take into account pixel ratio + this.height = this._canvas.height = height * this.pixelRatio; + this._canvas.style.height = height + 'px'; + var pixelRatio = this.pixelRatio, + _context = this.getContext()._context; + _context.scale(pixelRatio, pixelRatio); + }, + /** + * get width + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} width + */ + getWidth: function() { + return this.width; + }, + /** + * get height + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} height + */ + getHeight: function() { + return this.height; + }, + /** + * set size + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} width + * @param {Number} height + */ + setSize: function(width, height) { + this.setWidth(width); + this.setHeight(height); + }, + /** + * to data url + * @method + * @memberof Konva.Canvas.prototype + * @param {String} mimeType + * @param {Number} quality between 0 and 1 for jpg mime types + * @returns {String} data url string + */ + toDataURL: function(mimeType, quality) { + try { + // If this call fails (due to browser bug, like in Firefox 3.6), + // then revert to previous no-parameter image/png behavior + return this._canvas.toDataURL(mimeType, quality); + } + catch(e) { + try { + return this._canvas.toDataURL(); + } + catch(err) { + Konva.Util.warn('Unable to get data URL. ' + err.message); + return ''; + } + } + } + }; + + Konva.SceneCanvas = function(config) { + var conf = config || {}; + var width = conf.width || 0, + height = conf.height || 0; + + Konva.Canvas.call(this, conf); + this.context = new Konva.SceneContext(this); + this.setSize(width, height); + }; + + Konva.Util.extend(Konva.SceneCanvas, Konva.Canvas); + + Konva.HitCanvas = function(config) { + var conf = config || {}; + var width = conf.width || 0, + height = conf.height || 0; + + Konva.Canvas.call(this, conf); + this.context = new Konva.HitContext(this); + this.setSize(width, height); + this.hitCanvas = true; + }; + Konva.Util.extend(Konva.HitCanvas, Konva.Canvas); + +})(); + +(function() { + 'use strict'; + var COMMA = ',', + OPEN_PAREN = '(', + CLOSE_PAREN = ')', + OPEN_PAREN_BRACKET = '([', + CLOSE_BRACKET_PAREN = '])', + SEMICOLON = ';', + DOUBLE_PAREN = '()', + // EMPTY_STRING = '', + EQUALS = '=', + // SET = 'set', + CONTEXT_METHODS = [ + 'arc', + 'arcTo', + 'beginPath', + 'bezierCurveTo', + 'clearRect', + 'clip', + 'closePath', + 'createLinearGradient', + 'createPattern', + 'createRadialGradient', + 'drawImage', + 'fill', + 'fillText', + 'getImageData', + 'createImageData', + 'lineTo', + 'moveTo', + 'putImageData', + 'quadraticCurveTo', + 'rect', + 'restore', + 'rotate', + 'save', + 'scale', + 'setLineDash', + 'setTransform', + 'stroke', + 'strokeText', + 'transform', + 'translate' + ]; + + var CONTEXT_PROPERTIES = ['fillStyle', 'strokeStyle', 'shadowColor', 'shadowBlur', 'shadowOffsetX', + 'shadowOffsetY', 'lineCap', 'lineJoin', 'lineWidth', 'miterLimit', 'font', 'textAlign', 'textBaseline', + 'globalAlpha', 'globalCompositeOperation']; + + /** + * Canvas Context constructor + * @constructor + * @abstract + * @memberof Konva + */ + Konva.Context = function(canvas) { + this.init(canvas); + }; + + Konva.Context.prototype = { + init: function(canvas) { + this.canvas = canvas; + this._context = canvas._canvas.getContext('2d'); + + if (Konva.enableTrace) { + this.traceArr = []; + this._enableTrace(); + } + }, + /** + * fill shape + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + fillShape: function(shape) { + if(shape.getFillEnabled()) { + this._fill(shape); + } + }, + /** + * stroke shape + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + strokeShape: function(shape) { + if(shape.getStrokeEnabled()) { + this._stroke(shape); + } + }, + /** + * fill then stroke + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + fillStrokeShape: function(shape) { + var fillEnabled = shape.getFillEnabled(); + if(fillEnabled) { + this._fill(shape); + } + if(shape.getStrokeEnabled()) { + this._stroke(shape); + } + }, + /** + * get context trace if trace is enabled + * @method + * @memberof Konva.Context.prototype + * @param {Boolean} relaxed if false, return strict context trace, which includes method names, method parameters + * properties, and property values. If true, return relaxed context trace, which only returns method names and + * properites. + * @returns {String} + */ + getTrace: function(relaxed) { + var traceArr = this.traceArr, + len = traceArr.length, + str = '', + n, trace, method, args; + + for (n = 0; n < len; n++) { + trace = traceArr[n]; + method = trace.method; + + // methods + if (method) { + args = trace.args; + str += method; + if (relaxed) { + str += DOUBLE_PAREN; + } + else { + if (Konva.Util._isArray(args[0])) { + str += OPEN_PAREN_BRACKET + args.join(COMMA) + CLOSE_BRACKET_PAREN; + } + else { + str += OPEN_PAREN + args.join(COMMA) + CLOSE_PAREN; + } + } + } + // properties + else { + str += trace.property; + if (!relaxed) { + str += EQUALS + trace.val; + } + } + + str += SEMICOLON; + } + + return str; + }, + /** + * clear trace if trace is enabled + * @method + * @memberof Konva.Context.prototype + */ + clearTrace: function() { + this.traceArr = []; + }, + _trace: function(str) { + var traceArr = this.traceArr, + len; + + traceArr.push(str); + len = traceArr.length; + + if (len >= Konva.traceArrMax) { + traceArr.shift(); + } + }, + /** + * reset canvas context transform + * @method + * @memberof Konva.Context.prototype + */ + reset: function() { + var pixelRatio = this.getCanvas().getPixelRatio(); + this.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0); + }, + /** + * get canvas + * @method + * @memberof Konva.Context.prototype + * @returns {Konva.Canvas} + */ + getCanvas: function() { + return this.canvas; + }, + /** + * clear canvas + * @method + * @memberof Konva.Context.prototype + * @param {Object} [bounds] + * @param {Number} [bounds.x] + * @param {Number} [bounds.y] + * @param {Number} [bounds.width] + * @param {Number} [bounds.height] + */ + clear: function(bounds) { + var canvas = this.getCanvas(); + + if (bounds) { + this.clearRect(bounds.x || 0, bounds.y || 0, bounds.width || 0, bounds.height || 0); + } + else { + this.clearRect(0, 0, canvas.getWidth() / canvas.pixelRatio, canvas.getHeight() / canvas.pixelRatio); + } + }, + _applyLineCap: function(shape) { + var lineCap = shape.getLineCap(); + if(lineCap) { + this.setAttr('lineCap', lineCap); + } + }, + _applyOpacity: function(shape) { + var absOpacity = shape.getAbsoluteOpacity(); + if(absOpacity !== 1) { + this.setAttr('globalAlpha', absOpacity); + } + }, + _applyLineJoin: function(shape) { + var lineJoin = shape.getLineJoin(); + if(lineJoin) { + this.setAttr('lineJoin', lineJoin); + } + }, + setAttr: function(attr, val) { + this._context[attr] = val; + }, + + // context pass through methods + arc: function() { + var a = arguments; + this._context.arc(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + beginPath: function() { + this._context.beginPath(); + }, + bezierCurveTo: function() { + var a = arguments; + this._context.bezierCurveTo(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + clearRect: function() { + var a = arguments; + this._context.clearRect(a[0], a[1], a[2], a[3]); + }, + clip: function() { + this._context.clip(); + }, + closePath: function() { + this._context.closePath(); + }, + createImageData: function() { + var a = arguments; + if(a.length === 2) { + return this._context.createImageData(a[0], a[1]); + } + else if(a.length === 1) { + return this._context.createImageData(a[0]); + } + }, + createLinearGradient: function() { + var a = arguments; + return this._context.createLinearGradient(a[0], a[1], a[2], a[3]); + }, + createPattern: function() { + var a = arguments; + return this._context.createPattern(a[0], a[1]); + }, + createRadialGradient: function() { + var a = arguments; + return this._context.createRadialGradient(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + drawImage: function() { + var a = arguments, + _context = this._context; + + if(a.length === 3) { + _context.drawImage(a[0], a[1], a[2]); + } + else if(a.length === 5) { + // Address iOS/iPad render error temporarily. Questions: spencer.j.frazier@lmco.com + try { + _context.drawImage(a[0], a[1], a[2], a[3], a[4]); + } catch ( e ) { + Konva.Util.warn('Unable to drawImage due to: ' + e.message); + } + } + else if(a.length === 9) { + _context.drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + } + }, + isPointInPath: function(x, y) { + return this._context.isPointInPath(x, y); + }, + fill: function() { + this._context.fill(); + }, + fillRect: function(x, y, width, height) { + this._context.fillRect(x, y, width, height); + }, + strokeRect: function(x, y, width, height) { + this._context.strokeRect(x, y, width, height); + }, + fillText: function() { + var a = arguments; + this._context.fillText(a[0], a[1], a[2]); + }, + measureText: function(text) { + return this._context.measureText(text); + }, + getImageData: function() { + var a = arguments; + return this._context.getImageData(a[0], a[1], a[2], a[3]); + }, + lineTo: function() { + var a = arguments; + this._context.lineTo(a[0], a[1]); + }, + moveTo: function() { + var a = arguments; + this._context.moveTo(a[0], a[1]); + }, + rect: function() { + var a = arguments; + this._context.rect(a[0], a[1], a[2], a[3]); + }, + putImageData: function() { + var a = arguments; + this._context.putImageData(a[0], a[1], a[2]); + }, + quadraticCurveTo: function() { + var a = arguments; + this._context.quadraticCurveTo(a[0], a[1], a[2], a[3]); + }, + restore: function() { + this._context.restore(); + }, + rotate: function() { + var a = arguments; + this._context.rotate(a[0]); + }, + save: function() { + this._context.save(); + }, + scale: function() { + var a = arguments; + this._context.scale(a[0], a[1]); + }, + setLineDash: function() { + var a = arguments, + _context = this._context; + + // works for Chrome and IE11 + if(this._context.setLineDash) { + _context.setLineDash(a[0]); + } + // verified that this works in firefox + else if('mozDash' in _context) { + _context.mozDash = a[0]; + } + // does not currently work for Safari + else if('webkitLineDash' in _context) { + _context.webkitLineDash = a[0]; + } + + // no support for IE9 and IE10 + }, + getLineDash: function() { + return this._context.getLineDash(); + }, + setTransform: function() { + var a = arguments; + this._context.setTransform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + stroke: function() { + this._context.stroke(); + }, + strokeText: function() { + var a = arguments; + this._context.strokeText(a[0], a[1], a[2]); + }, + transform: function() { + var a = arguments; + this._context.transform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + translate: function() { + var a = arguments; + this._context.translate(a[0], a[1]); + }, + _enableTrace: function() { + var that = this, + len = CONTEXT_METHODS.length, + _simplifyArray = Konva.Util._simplifyArray, + origSetter = this.setAttr, + n, args; + + // to prevent creating scope function at each loop + var func = function(methodName) { + var origMethod = that[methodName], + ret; + + that[methodName] = function() { + args = _simplifyArray(Array.prototype.slice.call(arguments, 0)); + ret = origMethod.apply(that, arguments); + + that._trace({ + method: methodName, + args: args + }); + + return ret; + }; + }; + // methods + for (n = 0; n < len; n++) { + func(CONTEXT_METHODS[n]); + } + + // attrs + that.setAttr = function() { + origSetter.apply(that, arguments); + that._trace({ + property: arguments[0], + val: arguments[1] + }); + }; + } + }; + + CONTEXT_PROPERTIES.forEach(function(prop) { + Object.defineProperty(Konva.Context.prototype, prop, { + get: function () { + return this._context[prop]; + }, + set: function (val) { + this._context[prop] = val; + } + }); + }); + + Konva.SceneContext = function(canvas) { + Konva.Context.call(this, canvas); + }; + + Konva.SceneContext.prototype = { + _fillColor: function(shape) { + var fill = shape.fill(); + + this.setAttr('fillStyle', fill); + shape._fillFunc(this); + }, + _fillPattern: function(shape) { + var fillPatternX = shape.getFillPatternX(), + fillPatternY = shape.getFillPatternY(), + fillPatternScale = shape.getFillPatternScale(), + fillPatternRotation = Konva.getAngle(shape.getFillPatternRotation()), + fillPatternOffset = shape.getFillPatternOffset(); + + if(fillPatternX || fillPatternY) { + this.translate(fillPatternX || 0, fillPatternY || 0); + } + if(fillPatternRotation) { + this.rotate(fillPatternRotation); + } + if(fillPatternScale) { + this.scale(fillPatternScale.x, fillPatternScale.y); + } + if(fillPatternOffset) { + this.translate(-1 * fillPatternOffset.x, -1 * fillPatternOffset.y); + } + + this.setAttr('fillStyle', this.createPattern(shape.getFillPatternImage(), shape.getFillPatternRepeat() || 'repeat')); + this.fill(); + }, + _fillLinearGradient: function(shape) { + var start = shape.getFillLinearGradientStartPoint(), + end = shape.getFillLinearGradientEndPoint(), + colorStops = shape.getFillLinearGradientColorStops(), + grd = this.createLinearGradient(start.x, start.y, end.x, end.y); + + if (colorStops) { + // build color stops + for(var n = 0; n < colorStops.length; n += 2) { + grd.addColorStop(colorStops[n], colorStops[n + 1]); + } + this.setAttr('fillStyle', grd); + shape._fillFunc(this); + } + }, + _fillRadialGradient: function(shape) { + var start = shape.getFillRadialGradientStartPoint(), + end = shape.getFillRadialGradientEndPoint(), + startRadius = shape.getFillRadialGradientStartRadius(), + endRadius = shape.getFillRadialGradientEndRadius(), + colorStops = shape.getFillRadialGradientColorStops(), + grd = this.createRadialGradient(start.x, start.y, startRadius, end.x, end.y, endRadius); + + // build color stops + for(var n = 0; n < colorStops.length; n += 2) { + grd.addColorStop(colorStops[n], colorStops[n + 1]); + } + this.setAttr('fillStyle', grd); + this.fill(); + }, + _fill: function(shape) { + var hasColor = shape.fill(), + hasPattern = shape.getFillPatternImage(), + hasLinearGradient = shape.getFillLinearGradientColorStops(), + hasRadialGradient = shape.getFillRadialGradientColorStops(), + fillPriority = shape.getFillPriority(); + + // priority fills + if(hasColor && fillPriority === 'color') { + this._fillColor(shape); + } + else if(hasPattern && fillPriority === 'pattern') { + this._fillPattern(shape); + } + else if(hasLinearGradient && fillPriority === 'linear-gradient') { + this._fillLinearGradient(shape); + } + else if(hasRadialGradient && fillPriority === 'radial-gradient') { + this._fillRadialGradient(shape); + } + // now just try and fill with whatever is available + else if(hasColor) { + this._fillColor(shape); + } + else if(hasPattern) { + this._fillPattern(shape); + } + else if(hasLinearGradient) { + this._fillLinearGradient(shape); + } + else if(hasRadialGradient) { + this._fillRadialGradient(shape); + } + }, + _stroke: function(shape) { + var dash = shape.dash(), + // ignore strokeScaleEnabled for Text + strokeScaleEnabled = (shape.getStrokeScaleEnabled() || (shape instanceof Konva.Text)); + + if(shape.hasStroke()) { + if (!strokeScaleEnabled) { + this.save(); + this.setTransform(1, 0, 0, 1, 0, 0); + } + + this._applyLineCap(shape); + if(dash && shape.dashEnabled()) { + this.setLineDash(dash); + } + + this.setAttr('lineWidth', shape.strokeWidth()); + this.setAttr('strokeStyle', shape.stroke()); + + if (!shape.getShadowForStrokeEnabled()) { + this.setAttr('shadowColor', 'rgba(0,0,0,0)'); + } + shape._strokeFunc(this); + + if (!strokeScaleEnabled) { + this.restore(); + } + } + }, + _applyShadow: function(shape) { + var util = Konva.Util, + color = util.get(shape.getShadowRGBA(), 'black'), + blur = util.get(shape.getShadowBlur(), 5), + offset = util.get(shape.getShadowOffset(), { + x: 0, + y: 0 + }), + // TODO: get this info from transform?? + scale = shape.getAbsoluteScale(), + scaleX = scale.x, + scaleY = scale.y; + + this.setAttr('shadowColor', color); + this.setAttr('shadowBlur', blur); + this.setAttr('shadowOffsetX', offset.x * scaleX); + this.setAttr('shadowOffsetY', offset.y * scaleY); + } + }; + Konva.Util.extend(Konva.SceneContext, Konva.Context); + + Konva.HitContext = function(canvas) { + Konva.Context.call(this, canvas); + }; + + Konva.HitContext.prototype = { + _fill: function(shape) { + this.save(); + this.setAttr('fillStyle', shape.colorKey); + shape._fillFuncHit(this); + this.restore(); + }, + _stroke: function(shape) { + if(shape.hasStroke() && shape.strokeHitEnabled()) { + // ignore strokeScaleEnabled for Text + var strokeScaleEnabled = (shape.getStrokeScaleEnabled() || (shape instanceof Konva.Text)); + if (!strokeScaleEnabled) { + this.save(); + this.setTransform(1, 0, 0, 1, 0, 0); + } + this._applyLineCap(shape); + this.setAttr('lineWidth', shape.strokeWidth()); + this.setAttr('strokeStyle', shape.colorKey); + shape._strokeFuncHit(this); + if (!strokeScaleEnabled) { + this.restore(); + } + } + } + }; + Konva.Util.extend(Konva.HitContext, Konva.Context); +})(); + +(function() { + 'use strict'; + // CONSTANTS + var GET = 'get', + SET = 'set'; + + Konva.Factory = { + addGetterSetter: function(constructor, attr, def, validator, after) { + this.addGetter(constructor, attr, def); + this.addSetter(constructor, attr, validator, after); + this.addOverloadedGetterSetter(constructor, attr); + }, + addGetter: function(constructor, attr, def) { + var method = GET + Konva.Util._capitalize(attr); + + constructor.prototype[method] = function() { + var val = this.attrs[attr]; + return val === undefined ? def : val; + }; + }, + addSetter: function(constructor, attr, validator, after) { + var method = SET + Konva.Util._capitalize(attr); + + constructor.prototype[method] = function(val) { + if (validator) { + val = validator.call(this, val); + } + + this._setAttr(attr, val); + + if (after) { + after.call(this); + } + + return this; + }; + }, + addComponentsGetterSetter: function(constructor, attr, components, validator, after) { + var len = components.length, + capitalize = Konva.Util._capitalize, + getter = GET + capitalize(attr), + setter = SET + capitalize(attr), + n, component; + + // getter + constructor.prototype[getter] = function() { + var ret = {}; + + for (n = 0; n < len; n++) { + component = components[n]; + ret[component] = this.getAttr(attr + capitalize(component)); + } + + return ret; + }; + + // setter + constructor.prototype[setter] = function(val) { + var oldVal = this.attrs[attr], + key; + + if (validator) { + val = validator.call(this, val); + } + + for (key in val) { + if (!val.hasOwnProperty(key)) { + continue; + } + this._setAttr(attr + capitalize(key), val[key]); + } + + this._fireChangeEvent(attr, oldVal, val); + + if (after) { + after.call(this); + } + + return this; + }; + + this.addOverloadedGetterSetter(constructor, attr); + }, + addOverloadedGetterSetter: function(constructor, attr) { + var capitalizedAttr = Konva.Util._capitalize(attr), + setter = SET + capitalizedAttr, + getter = GET + capitalizedAttr; + + constructor.prototype[attr] = function() { + // setting + if (arguments.length) { + this[setter](arguments[0]); + return this; + } + // getting + return this[getter](); + }; + }, + addDeprecatedGetterSetter: function(constructor, attr, def, validator) { + var method = GET + Konva.Util._capitalize(attr); + var message = attr + ' property is deprecated and will be removed soon. Look at Konva change log for more information.'; + constructor.prototype[method] = function() { + Konva.Util.error(message); + var val = this.attrs[attr]; + return val === undefined ? def : val; + }; + this.addSetter(constructor, attr, validator, function() { + Konva.Util.error(message); + }); + this.addOverloadedGetterSetter(constructor, attr); + }, + backCompat: function(constructor, methods) { + Konva.Util.each(methods, function(oldMethodName, newMethodName) { + var method = constructor.prototype[newMethodName]; + constructor.prototype[oldMethodName] = function(){ + method.apply(this, arguments); + Konva.Util.error(oldMethodName + ' method is deprecated and will be removed soon. Use ' + newMethodName + ' instead'); + }; + }); + }, + afterSetFilter: function() { + this._filterUpToDate = false; + } + }; + + Konva.Validators = { + /** + * @return {number} + */ + RGBComponent: function(val) { + if (val > 255) { + return 255; + } else if (val < 0) { + return 0; + } + return Math.round(val); + }, + alphaComponent: function(val) { + if (val > 1) { + return 1; + } + // chrome does not honor alpha values of 0 + else if (val < 0.0001) { + return 0.0001; + } + + return val; + } + }; +})(); + +(function(Konva) { + 'use strict'; + // CONSTANTS + var ABSOLUTE_OPACITY = 'absoluteOpacity', + ABSOLUTE_TRANSFORM = 'absoluteTransform', + ABSOLUTE_SCALE = 'absoluteScale', + CHANGE = 'Change', + CHILDREN = 'children', + DOT = '.', + EMPTY_STRING = '', + GET = 'get', + ID = 'id', + KONVA = 'konva', + LISTENING = 'listening', + MOUSEENTER = 'mouseenter', + MOUSELEAVE = 'mouseleave', + NAME = 'name', + SET = 'set', + SHAPE = 'Shape', + SPACE = ' ', + STAGE = 'stage', + TRANSFORM = 'transform', + UPPER_STAGE = 'Stage', + VISIBLE = 'visible', + CLONE_BLACK_LIST = ['id'], + + TRANSFORM_CHANGE_STR = [ + 'xChange.konva', + 'yChange.konva', + 'scaleXChange.konva', + 'scaleYChange.konva', + 'skewXChange.konva', + 'skewYChange.konva', + 'rotationChange.konva', + 'offsetXChange.konva', + 'offsetYChange.konva', + 'transformsEnabledChange.konva' + ].join(SPACE), + + SCALE_CHANGE_STR = [ + 'scaleXChange.konva', + 'scaleYChange.konva' + ].join(SPACE); + + /** + * Node constructor. Nodes are entities that can be transformed, layered, + * and have bound events. The stage, layers, groups, and shapes all extend Node. + * @constructor + * @memberof Konva + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + */ + Konva.Node = function(config) { + this._init(config); + }; + + Konva.Util.addMethods(Konva.Node, { + _init: function(config) { + var that = this; + this._id = Konva.idCounter++; + this.eventListeners = {}; + this.attrs = {}; + this._cache = {}; + this._filterUpToDate = false; + this.setAttrs(config); + + // event bindings for cache handling + this.on(TRANSFORM_CHANGE_STR, function() { + this._clearCache(TRANSFORM); + that._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + }); + + this.on(SCALE_CHANGE_STR, function() { + that._clearSelfAndDescendantCache(ABSOLUTE_SCALE); + }); + + this.on('visibleChange.konva', function() { + that._clearSelfAndDescendantCache(VISIBLE); + }); + this.on('listeningChange.konva', function() { + that._clearSelfAndDescendantCache(LISTENING); + }); + this.on('opacityChange.konva', function() { + that._clearSelfAndDescendantCache(ABSOLUTE_OPACITY); + }); + }, + _clearCache: function(attr){ + if (attr) { + delete this._cache[attr]; + } + else { + this._cache = {}; + } + }, + _getCache: function(attr, privateGetter){ + var cache = this._cache[attr]; + + // if not cached, we need to set it using the private getter method. + if (cache === undefined) { + this._cache[attr] = privateGetter.call(this); + } + + return this._cache[attr]; + }, + /* + * when the logic for a cached result depends on ancestor propagation, use this + * method to clear self and children cache + */ + _clearSelfAndDescendantCache: function(attr) { + this._clearCache(attr); + + if (this.children) { + this.getChildren().each(function(node) { + node._clearSelfAndDescendantCache(attr); + }); + } + }, + /** + * clear cached canvas + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.clearCache(); + */ + clearCache: function() { + delete this._cache.canvas; + this._filterUpToDate = false; + return this; + }, + /** + * cache node to improve drawing performance, apply filters, or create more accurate + * hit regions. For all basic shapes size of cache canvas will be automatically detected. + * If you need to cache your custom `Konva.Shape` instance you have to pass shape's bounding box + * properties. Look at [link to demo page](link to demo page) for more information. + * @method + * @memberof Konva.Node.prototype + * @param {Object} [config] + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Number} [config.offset] increase canvas size by `offset` pixel in all directions. + * @param {Boolean} [config.drawBorder] when set to true, a red border will be drawn around the cached + * region for debugging purposes + * @returns {Konva.Node} + * @example + * // cache a shape with the x,y position of the bounding box at the center and + * // the width and height of the bounding box equal to the width and height of + * // the shape obtained from shape.width() and shape.height() + * image.cache(); + * + * // cache a node and define the bounding box position and size + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200 + * }); + * + * // cache a node and draw a red border around the bounding box + * // for debugging purposes + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200, + * offset : 10, + * drawBorder: true + * }); + */ + cache: function(config) { + var conf = config || {}, + rect = this.getClientRect(true), + width = conf.width || rect.width, + height = conf.height || rect.height, + x = conf.x || rect.x, + y = conf.y || rect.y, + offset = conf.offset || 0, + drawBorder = conf.drawBorder || false; + + if (!width || !height) { + throw new Error('Width or height of caching configuration equals 0.'); + } + + width += offset * 2; + height += offset * 2; + + x -= offset; + y -= offset; + + + var cachedSceneCanvas = new Konva.SceneCanvas({ + width: width, + height: height + }), + cachedFilterCanvas = new Konva.SceneCanvas({ + width: width, + height: height + }), + cachedHitCanvas = new Konva.HitCanvas({ + pixelRatio: 1, + width: width, + height: height + }), + sceneContext = cachedSceneCanvas.getContext(), + hitContext = cachedHitCanvas.getContext(); + + cachedHitCanvas.isCache = true; + + this.clearCache(); + + sceneContext.save(); + hitContext.save(); + + sceneContext.translate(-x, -y); + hitContext.translate(-x, -y); + + this.drawScene(cachedSceneCanvas, this, true); + this.drawHit(cachedHitCanvas, this, true); + + sceneContext.restore(); + hitContext.restore(); + + // this will draw a red border around the cached box for + // debugging purposes + if (drawBorder) { + sceneContext.save(); + sceneContext.beginPath(); + sceneContext.rect(0, 0, width, height); + sceneContext.closePath(); + sceneContext.setAttr('strokeStyle', 'red'); + sceneContext.setAttr('lineWidth', 5); + sceneContext.stroke(); + sceneContext.restore(); + } + + this._cache.canvas = { + scene: cachedSceneCanvas, + filter: cachedFilterCanvas, + hit: cachedHitCanvas, + x: x, + y: y + }; + + return this; + }, + /** + * Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc). + * The rectangle position is relative to parent container. + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} [skipTransform] flag should we skip transformation to rectangle + * @returns {Object} rect with {x, y, width, height} properties + * @example + * var rect = new Konva.Rect({ + * width : 100, + * height : 100, + * x : 50, + * y : 50, + * strokeWidth : 4, + * stroke : 'black', + * offsetX : 50, + * scaleY : 2 + * }); + * + * // get client rect without think off transformations (position, rotation, scale, offset, etc) + * rect.getClientRect(true); + * // returns { + * // x : -2, // two pixels for stroke / 2 + * // y : -2, + * // width : 104, // increased by 4 for stroke + * // height : 104 + * //} + * + * // get client rect with transformation applied + * rect.getClientRect(); + * // returns Object {x: -2, y: 46, width: 104, height: 208} + */ + getClientRect: function() { + // abstract method + // redefine in Container and Shape + throw new Error('abstract "getClientRect" method call'); + }, + _transformedRect: function(rect) { + var points = [ + {x: rect.x, y: rect.y}, + {x: rect.x + rect.width, y: rect.y}, + {x: rect.x + rect.width, y: rect.y + rect.height}, + {x: rect.x, y: rect.y + rect.height} + ]; + var minX, minY, maxX, maxY; + var trans = this.getTransform(); + points.forEach(function(point) { + var transformed = trans.point(point); + if (minX === undefined) { + minX = maxX = transformed.x; + minY = maxY = transformed.y; + } + minX = Math.min(minX, transformed.x); + minY = Math.min(minY, transformed.y); + maxX = Math.max(maxX, transformed.x); + maxY = Math.max(maxY, transformed.y); + }); + return { + x: minX, + y: minY, + width: maxX - minX, + height: maxY - minY + }; + }, + _drawCachedSceneCanvas: function(context) { + context.save(); + context._applyOpacity(this); + context.translate( + this._cache.canvas.x, + this._cache.canvas.y + ); + + var cacheCanvas = this._getCachedSceneCanvas(); + var ratio = cacheCanvas.pixelRatio; + + context.drawImage(cacheCanvas._canvas, 0, 0, cacheCanvas.width / ratio, cacheCanvas.height / ratio); + context.restore(); + }, + _drawCachedHitCanvas: function(context) { + var cachedCanvas = this._cache.canvas, + hitCanvas = cachedCanvas.hit; + context.save(); + context.translate( + this._cache.canvas.x, + this._cache.canvas.y + ); + context.drawImage(hitCanvas._canvas, 0, 0); + context.restore(); + }, + _getCachedSceneCanvas: function() { + var filters = this.filters(), + cachedCanvas = this._cache.canvas, + sceneCanvas = cachedCanvas.scene, + filterCanvas = cachedCanvas.filter, + filterContext = filterCanvas.getContext(), + len, imageData, n, filter; + + if (filters) { + if (!this._filterUpToDate) { + var ratio = sceneCanvas.pixelRatio; + + try { + len = filters.length; + filterContext.clear(); + + // copy cached canvas onto filter context + filterContext.drawImage(sceneCanvas._canvas, 0, 0, sceneCanvas.getWidth() / ratio, sceneCanvas.getHeight() / ratio); + imageData = filterContext.getImageData(0, 0, filterCanvas.getWidth(), filterCanvas.getHeight()); + + // apply filters to filter context + for (n = 0; n < len; n++) { + filter = filters[n]; + filter.call(this, imageData); + filterContext.putImageData(imageData, 0, 0); + } + } + catch(e) { + Konva.Util.warn('Unable to apply filter. ' + e.message); + } + + this._filterUpToDate = true; + } + + return filterCanvas; + } + return sceneCanvas; + }, + /** + * bind events to the node. KonvaJS supports mouseover, mousemove, + * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, + * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports + * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel + * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, + * and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once + * such as 'mousedown mouseup mousemove'. Include a namespace to bind an + * event by name such as 'click.foobar'. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' + * @param {Function} handler The handler function is passed an event object + * @returns {Konva.Node} + * @example + * // add click listener + * node.on('click', function() { + * console.log('you clicked me!'); + * }); + * + * // get the target node + * node.on('click', function(evt) { + * console.log(evt.target); + * }); + * + * // stop event propagation + * node.on('click', function(evt) { + * evt.cancelBubble = true; + * }); + * + * // bind multiple listeners + * node.on('click touchstart', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // namespace listener + * node.on('click.foo', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // get the event type + * node.on('click tap', function(evt) { + * var eventType = evt.type; + * }); + * + * // get native event object + * node.on('click tap', function(evt) { + * var nativeEvent = evt.evt; + * }); + * + * // for change events, get the old and new val + * node.on('xChange', function(evt) { + * var oldVal = evt.oldVal; + * var newVal = evt.newVal; + * }); + * + * // get event targets + * // with event delegations + * layer.on('click', 'Group', function(evt) { + * var shape = evt.target; + * var group = evtn.currentTarger; + * }); + */ + on: function(evtStr, handler) { + if (arguments.length === 3) { + return this._delegate.apply(this, arguments); + } + var events = evtStr.split(SPACE), + len = events.length, + n, event, parts, baseEvent, name; + + /* + * loop through types and attach event listeners to + * each one. eg. 'click mouseover.namespace mouseout' + * will create three event bindings + */ + for(n = 0; n < len; n++) { + event = events[n]; + parts = event.split(DOT); + baseEvent = parts[0]; + name = parts[1] || EMPTY_STRING; + + // create events array if it doesn't exist + if(!this.eventListeners[baseEvent]) { + this.eventListeners[baseEvent] = []; + } + + this.eventListeners[baseEvent].push({ + name: name, + handler: handler + }); + } + + return this; + }, + /** + * remove event bindings from the node. Pass in a string of + * event types delimmited by a space to remove multiple event + * bindings at once such as 'mousedown mouseup mousemove'. + * include a namespace to remove an event binding by name + * such as 'click.foobar'. If you only give a name like '.foobar', + * all events in that namespace will be removed. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar' + * @returns {Konva.Node} + * @example + * // remove listener + * node.off('click'); + * + * // remove multiple listeners + * node.off('click touchstart'); + * + * // remove listener by name + * node.off('click.foo'); + */ + off: function(evtStr) { + var events = (evtStr || '').split(SPACE), + len = events.length, + n, t, event, parts, baseEvent, name; + + if (!evtStr) { + // remove all events + for(t in this.eventListeners) { + this._off(t); + } + } + for(n = 0; n < len; n++) { + event = events[n]; + parts = event.split(DOT); + baseEvent = parts[0]; + name = parts[1]; + + if(baseEvent) { + if(this.eventListeners[baseEvent]) { + this._off(baseEvent, name); + } + } + else { + for(t in this.eventListeners) { + this._off(t, name); + } + } + } + return this; + }, + // some event aliases for third party integration like HammerJS + dispatchEvent: function(evt) { + var e = { + target: this, + type: evt.type, + evt: evt + }; + this.fire(evt.type, e); + return this; + }, + addEventListener: function(type, handler) { + // we have to pass native event to handler + this.on(type, function(evt){ + handler.call(this, evt.evt); + }); + return this; + }, + removeEventListener: function(type) { + this.off(type); + return this; + }, + // like node.on + _delegate: function(event, selector, handler) { + var stopNode = this; + this.on(event, function(evt) { + var targets = evt.target.findAncestors(selector, true, stopNode); + for(var i = 0; i < targets.length; i++) { + evt = Konva.Util.cloneObject(evt); + evt.currentTarget = targets[i]; + handler.call(targets[i], evt); + } + }); + }, + /** + * remove self from parent, but don't destroy + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.remove(); + */ + remove: function() { + var parent = this.getParent(); + + if(parent && parent.children) { + parent.children.splice(this.index, 1); + parent._setChildrenIndices(); + delete this.parent; + } + + // every cached attr that is calculated via node tree + // traversal must be cleared when removing a node + this._clearSelfAndDescendantCache(STAGE); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + this._clearSelfAndDescendantCache(VISIBLE); + this._clearSelfAndDescendantCache(LISTENING); + this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY); + + return this; + }, + /** + * remove and destroy self + * @method + * @memberof Konva.Node.prototype + * @example + * node.destroy(); + */ + destroy: function() { + // remove from ids and names hashes + Konva._removeId(this.getId()); + Konva._removeName(this.getName(), this._id); + + this.remove(); + return this; + }, + /** + * get attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @returns {Integer|String|Object|Array} + * @example + * var x = node.getAttr('x'); + */ + getAttr: function(attr) { + var method = GET + Konva.Util._capitalize(attr); + if(Konva.Util._isFunction(this[method])) { + return this[method](); + } + // otherwise get directly + return this.attrs[attr]; + }, + /** + * get ancestors + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Collection} + * @example + * shape.getAncestors().each(function(node) { + * console.log(node.getId()); + * }) + */ + getAncestors: function() { + var parent = this.getParent(), + ancestors = new Konva.Collection(); + + while (parent) { + ancestors.push(parent); + parent = parent.getParent(); + } + + return ancestors; + }, + /** + * get attrs object literal + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ + getAttrs: function() { + return this.attrs || {}; + }, + /** + * set multiple attrs at once using an object literal + * @method + * @memberof Konva.Node.prototype + * @param {Object} config object containing key value pairs + * @returns {Konva.Node} + * @example + * node.setAttrs({ + * x: 5, + * fill: 'red' + * }); + */ + setAttrs: function(config) { + var key, method; + + if(!config) { + return this; + } + for(key in config) { + if (key === CHILDREN) { + continue; + } + method = SET + Konva.Util._capitalize(key); + // use setter if available + if(Konva.Util._isFunction(this[method])) { + this[method](config[key]); + } + // otherwise set directly + else { + this._setAttr(key, config[key]); + } + } + return this; + }, + /** + * determine if node is listening for events by taking into account ancestors. + * + * Parent | Self | isListening + * listening | listening | + * ----------+-----------+------------ + * T | T | T + * T | F | F + * F | T | T + * F | F | F + * ----------+-----------+------------ + * T | I | T + * F | I | F + * I | I | T + * + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + isListening: function() { + return this._getCache(LISTENING, this._isListening); + }, + _isListening: function() { + var listening = this.getListening(), + parent = this.getParent(); + + // the following conditions are a simplification of the truth table above. + // please modify carefully + if (listening === 'inherit') { + if (parent) { + return parent.isListening(); + } + else { + return true; + } + } + else { + return listening; + } + }, + /** + * determine if node is visible by taking into account ancestors. + * + * Parent | Self | isVisible + * visible | visible | + * ----------+-----------+------------ + * T | T | T + * T | F | F + * F | T | T + * F | F | F + * ----------+-----------+------------ + * T | I | T + * F | I | F + * I | I | T + + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + isVisible: function() { + return this._getCache(VISIBLE, this._isVisible); + }, + _isVisible: function() { + var visible = this.getVisible(), + parent = this.getParent(); + + // the following conditions are a simplification of the truth table above. + // please modify carefully + if (visible === 'inherit') { + if (parent) { + return parent.isVisible(); + } + else { + return true; + } + } + else { + return visible; + } + }, + /** + * determine if listening is enabled by taking into account descendants. If self or any children + * have _isListeningEnabled set to true, then self also has listening enabled. + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + shouldDrawHit: function(canvas) { + var layer = this.getLayer(); + return (canvas && canvas.isCache) || (layer && layer.hitGraphEnabled()) + && this.isListening() && this.isVisible(); + }, + /** + * show node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + show: function() { + this.setVisible(true); + return this; + }, + /** + * hide node. Hidden nodes are no longer detectable + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + hide: function() { + this.setVisible(false); + return this; + }, + /** + * get zIndex relative to the node's siblings who share the same parent + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getZIndex: function() { + return this.index || 0; + }, + /** + * get absolute z-index which takes into account sibling + * and ancestor indices + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getAbsoluteZIndex: function() { + var depth = this.getDepth(), + that = this, + index = 0, + nodes, len, n, child; + + function addChildren(children) { + nodes = []; + len = children.length; + for(n = 0; n < len; n++) { + child = children[n]; + index++; + + if(child.nodeType !== SHAPE) { + nodes = nodes.concat(child.getChildren().toArray()); + } + + if(child._id === that._id) { + n = len; + } + } + + if(nodes.length > 0 && nodes[0].getDepth() <= depth) { + addChildren(nodes); + } + } + if(that.nodeType !== UPPER_STAGE) { + addChildren(that.getStage().getChildren()); + } + + return index; + }, + /** + * get node depth in node tree. Returns an integer. + * e.g. Stage depth will always be 0. Layers will always be 1. Groups and Shapes will always + * be >= 2 + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getDepth: function() { + var depth = 0, + parent = this.parent; + + while(parent) { + depth++; + parent = parent.parent; + } + return depth; + }, + setPosition: function(pos) { + this.setX(pos.x); + this.setY(pos.y); + return this; + }, + getPosition: function() { + return { + x: this.getX(), + y: this.getY() + }; + }, + /** + * get absolute position relative to the top left corner of the stage container div + * or relative to passed node + * @method + * @param {Object} [top] optional parent node + * @memberof Konva.Node.prototype + * @returns {Object} + */ + getAbsolutePosition: function(top) { + var absoluteMatrix = this.getAbsoluteTransform(top).getMatrix(), + absoluteTransform = new Konva.Transform(), + offset = this.offset(); + + // clone the matrix array + absoluteTransform.m = absoluteMatrix.slice(); + absoluteTransform.translate(offset.x, offset.y); + + return absoluteTransform.getTranslation(); + }, + /** + * set absolute position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Konva.Node} + */ + setAbsolutePosition: function(pos) { + var origTrans = this._clearTransform(), + it; + + // don't clear translation + this.attrs.x = origTrans.x; + this.attrs.y = origTrans.y; + delete origTrans.x; + delete origTrans.y; + + // unravel transform + it = this.getAbsoluteTransform(); + + it.invert(); + it.translate(pos.x, pos.y); + pos = { + x: this.attrs.x + it.getTranslation().x, + y: this.attrs.y + it.getTranslation().y + }; + + this.setPosition({x: pos.x, y: pos.y}); + this._setTransform(origTrans); + + return this; + }, + _setTransform: function(trans) { + var key; + + for(key in trans) { + this.attrs[key] = trans[key]; + } + + this._clearCache(TRANSFORM); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + }, + _clearTransform: function() { + var trans = { + x: this.getX(), + y: this.getY(), + rotation: this.getRotation(), + scaleX: this.getScaleX(), + scaleY: this.getScaleY(), + offsetX: this.getOffsetX(), + offsetY: this.getOffsetY(), + skewX: this.getSkewX(), + skewY: this.getSkewY() + }; + + this.attrs.x = 0; + this.attrs.y = 0; + this.attrs.rotation = 0; + this.attrs.scaleX = 1; + this.attrs.scaleY = 1; + this.attrs.offsetX = 0; + this.attrs.offsetY = 0; + this.attrs.skewX = 0; + this.attrs.skewY = 0; + + this._clearCache(TRANSFORM); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + + // return original transform + return trans; + }, + /** + * move node by an amount relative to its current position + * @method + * @memberof Konva.Node.prototype + * @param {Object} change + * @param {Number} change.x + * @param {Number} change.y + * @returns {Konva.Node} + * @example + * // move node in x direction by 1px and y direction by 2px + * node.move({ + * x: 1, + * y: 2) + * }); + */ + move: function(change) { + var changeX = change.x, + changeY = change.y, + x = this.getX(), + y = this.getY(); + + if(changeX !== undefined) { + x += changeX; + } + + if(changeY !== undefined) { + y += changeY; + } + + this.setPosition({x: x, y: y}); + return this; + }, + _eachAncestorReverse: function(func, top) { + var family = [], + parent = this.getParent(), + len, n; + + // if top node is defined, and this node is top node, + // there's no need to build a family tree. just execute + // func with this because it will be the only node + if (top && top._id === this._id) { + func(this); + return true; + } + + family.unshift(this); + + while(parent && (!top || parent._id !== top._id)) { + family.unshift(parent); + parent = parent.parent; + } + + len = family.length; + for(n = 0; n < len; n++) { + func(family[n]); + } + }, + /** + * rotate node by an amount in degrees relative to its current rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} theta + * @returns {Konva.Node} + */ + rotate: function(theta) { + this.setRotation(this.getRotation() + theta); + return this; + }, + /** + * move node to the top of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveToTop: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveToTop function is ignored.'); + return false; + } + var index = this.index; + this.parent.children.splice(index, 1); + this.parent.children.push(this); + this.parent._setChildrenIndices(); + return true; + }, + /** + * move node up + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} flag is moved or not + */ + moveUp: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveUp function is ignored.'); + return false; + } + var index = this.index, + len = this.parent.getChildren().length; + if(index < len - 1) { + this.parent.children.splice(index, 1); + this.parent.children.splice(index + 1, 0, this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * move node down + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveDown: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveDown function is ignored.'); + return false; + } + var index = this.index; + if(index > 0) { + this.parent.children.splice(index, 1); + this.parent.children.splice(index - 1, 0, this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * move node to the bottom of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveToBottom: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveToBottom function is ignored.'); + return false; + } + var index = this.index; + if(index > 0) { + this.parent.children.splice(index, 1); + this.parent.children.unshift(this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * set zIndex relative to siblings + * @method + * @memberof Konva.Node.prototype + * @param {Integer} zIndex + * @returns {Konva.Node} + */ + setZIndex: function(zIndex) { + if (!this.parent) { + Konva.Util.warn('Node has no parent. zIndex parameter is ignored.'); + return false; + } + var index = this.index; + this.parent.children.splice(index, 1); + this.parent.children.splice(zIndex, 0, this); + this.parent._setChildrenIndices(); + return this; + }, + /** + * get absolute opacity + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + */ + getAbsoluteOpacity: function() { + return this._getCache(ABSOLUTE_OPACITY, this._getAbsoluteOpacity); + }, + _getAbsoluteOpacity: function() { + var absOpacity = this.getOpacity(); + if(this.getParent()) { + absOpacity *= this.getParent().getAbsoluteOpacity(); + } + return absOpacity; + }, + /** + * move node to another container + * @method + * @memberof Konva.Node.prototype + * @param {Container} newContainer + * @returns {Konva.Node} + * @example + * // move node from current layer into layer2 + * node.moveTo(layer2); + */ + moveTo: function(newContainer) { + // do nothing if new container is already parent + if (this.getParent() !== newContainer) { + this.remove(); + newContainer.add(this); + } + return this; + }, + /** + * convert Node into an object for serialization. Returns an object. + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ + toObject: function() { + var obj = {}, + attrs = this.getAttrs(), + key, val, getter, defaultValue; + + obj.attrs = {}; + + for(key in attrs) { + val = attrs[key]; + // serialize only attributes that are not function, image, DOM, or objects with methods + if (Konva.Util._isFunction(val) || Konva.Util._isElement(val) || + (Konva.Util._isObject(val) || Konva.Util._hasMethods(val))) { + continue; + } + getter = this[key]; + // remove attr value so that we can extract the default value from the getter + delete attrs[key]; + defaultValue = getter ? getter.call(this) : null; + // restore attr value + attrs[key] = val; + if (defaultValue !== val) { + obj.attrs[key] = val; + } + } + + obj.className = this.getClassName(); + return obj; + }, + /** + * convert Node into a JSON string. Returns a JSON string. + * @method + * @memberof Konva.Node.prototype + * @returns {String}} + */ + toJSON: function() { + return JSON.stringify(this.toObject()); + }, + /** + * get parent container + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + getParent: function() { + return this.parent; + }, + /** + * get all ancestros (parent then parent of the parent, etc) of the node + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Array} [ancestors] + * @example + * // get one of the parent group + * var parentGroups = node.findAncestors('Group'); + */ + findAncestors: function(selector, includeSelf, stopNode) { + var res = []; + + if (includeSelf && this._isMatch(selector)) { + res.push(this); + } + var ancestor = this.parent; + while(ancestor) { + if (ancestor === stopNode) { + return res; + } + if (ancestor._isMatch(selector)) { + res.push(ancestor); + } + ancestor = ancestor.parent; + } + return res; + }, + /** + * get ancestor (parent or parent of the parent, etc) of the node that match passed selector + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Konva.Node} ancestor + * @example + * // get one of the parent group + * var group = node.findAncestors('.mygroup'); + */ + findAncestor: function(selector, includeSelf, stopNode) { + return this.findAncestors(selector, includeSelf, stopNode)[0]; + }, + // is current node match passed selector? + _isMatch: function(selector) { + if (!selector) { + return false; + } + var selectorArr = selector.replace(/ /g, '').split(','), + len = selectorArr.length, + n, sel; + + for (n = 0; n < len; n++) { + sel = selectorArr[n]; + if (!Konva.Util.isValidSelector(sel)) { + Konva.Util.warn('Selector "' + sel + '" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".'); + Konva.Util.warn('If you have a custom shape with such className, please change it to start with upper letter like "Triangle".'); + Konva.Util.warn('Konva is awesome, right?'); + } + // id selector + if(sel.charAt(0) === '#') { + if (this.id() === sel.slice(1)) { + return true; + } + } + // name selector + else if(sel.charAt(0) === '.') { + if (this.hasName(sel.slice(1))) { + return true; + } + } else if (this._get(sel).length !== 0) { + return true; + } + } + return false; + }, + /** + * get layer ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Layer} + */ + getLayer: function() { + var parent = this.getParent(); + return parent ? parent.getLayer() : null; + }, + /** + * get stage ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Stage} + */ + getStage: function() { + return this._getCache(STAGE, this._getStage); + }, + _getStage: function() { + var parent = this.getParent(); + if(parent) { + return parent.getStage(); + } + else { + return undefined; + } + }, + /** + * fire event + * @method + * @memberof Konva.Node.prototype + * @param {String} eventType event type. can be a regular event, like click, mouseover, or mouseout, or it can be a custom event, like myCustomEvent + * @param {Event} [evt] event object + * @param {Boolean} [bubble] setting the value to false, or leaving it undefined, will result in the event + * not bubbling. Setting the value to true will result in the event bubbling. + * @returns {Konva.Node} + * @example + * // manually fire click event + * node.fire('click'); + * + * // fire custom event + * node.fire('foo'); + * + * // fire custom event with custom event object + * node.fire('foo', { + * bar: 10 + * }); + * + * // fire click event that bubbles + * node.fire('click', null, true); + */ + fire: function(eventType, evt, bubble) { + evt = evt || {}; + evt.target = evt.target || this; + // bubble + if (bubble) { + this._fireAndBubble(eventType, evt); + } + // no bubble + else { + this._fire(eventType, evt); + } + return this; + }, + /** + * get absolute transform of the node which takes into + * account its ancestor transforms + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getAbsoluteTransform: function(top) { + // if using an argument, we can't cache the result. + if (top) { + return this._getAbsoluteTransform(top); + } + // if no argument, we can cache the result + else { + return this._getCache(ABSOLUTE_TRANSFORM, this._getAbsoluteTransform); + } + }, + _getAbsoluteTransform: function(top) { + var at = new Konva.Transform(), + transformsEnabled, trans; + + // start with stage and traverse downwards to self + this._eachAncestorReverse(function(node) { + transformsEnabled = node.transformsEnabled(); + trans = node.getTransform(); + + if (transformsEnabled === 'all') { + at.multiply(trans); + } + else if (transformsEnabled === 'position') { + at.translate(node.x(), node.y()); + } + }, top); + return at; + }, + /** + * get absolute scale of the node which takes into + * account its ancestor scales + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getAbsoluteScale: function(top) { + // if using an argument, we can't cache the result. + if (top) { + return this._getAbsoluteTransform(top); + } + // if no argument, we can cache the result + else { + return this._getCache(ABSOLUTE_SCALE, this._getAbsoluteScale); + } + }, + _getAbsoluteScale: function(top) { + var scaleX = 1, scaleY = 1; + + // start with stage and traverse downwards to self + this._eachAncestorReverse(function(node) { + scaleX *= node.scaleX(); + scaleY *= node.scaleY(); + }, top); + return { + x: scaleX, + y: scaleY + }; + }, + /** + * get transform of the node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getTransform: function() { + return this._getCache(TRANSFORM, this._getTransform); + }, + _getTransform: function() { + var m = new Konva.Transform(), + x = this.getX(), + y = this.getY(), + rotation = Konva.getAngle(this.getRotation()), + scaleX = this.getScaleX(), + scaleY = this.getScaleY(), + skewX = this.getSkewX(), + skewY = this.getSkewY(), + offsetX = this.getOffsetX(), + offsetY = this.getOffsetY(); + + if(x !== 0 || y !== 0) { + m.translate(x, y); + } + if(rotation !== 0) { + m.rotate(rotation); + } + if(skewX !== 0 || skewY !== 0) { + m.skew(skewX, skewY); + } + if(scaleX !== 1 || scaleY !== 1) { + m.scale(scaleX, scaleY); + } + if(offsetX !== 0 || offsetY !== 0) { + m.translate(-1 * offsetX, -1 * offsetY); + } + + return m; + }, + /** + * clone node. Returns a new Node instance with identical attributes. You can also override + * the node properties with an object literal, enabling you to use an existing node as a template + * for another node + * @method + * @memberof Konva.Node.prototype + * @param {Object} obj override attrs + * @returns {Konva.Node} + * @example + * // simple clone + * var clone = node.clone(); + * + * // clone a node and override the x position + * var clone = rect.clone({ + * x: 5 + * }); + */ + clone: function(obj) { + // instantiate new node + var attrs = Konva.Util.cloneObject(this.attrs), + key, allListeners, len, n, listener; + // filter black attrs + for (var i in CLONE_BLACK_LIST) { + var blockAttr = CLONE_BLACK_LIST[i]; + delete attrs[blockAttr]; + } + // apply attr overrides + for (key in obj) { + attrs[key] = obj[key]; + } + + var node = new this.constructor(attrs); + // copy over listeners + for(key in this.eventListeners) { + allListeners = this.eventListeners[key]; + len = allListeners.length; + for(n = 0; n < len; n++) { + listener = allListeners[n]; + /* + * don't include konva namespaced listeners because + * these are generated by the constructors + */ + if(listener.name.indexOf(KONVA) < 0) { + // if listeners array doesn't exist, then create it + if(!node.eventListeners[key]) { + node.eventListeners[key] = []; + } + node.eventListeners[key].push(listener); + } + } + } + return node; + }, + /** + * Creates a composite data URL. If MIME type is not + * specified, then "image/png" will result. For "image/jpeg", specify a quality + * level as quality (range 0.0 - 1.0) + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image url. Default is 1 + * @returns {String} + */ + toDataURL: function(config) { + config = config || {}; + + var mimeType = config.mimeType || null, + quality = config.quality || null, + stage = this.getStage(), + x = config.x || 0, + y = config.y || 0, + pixelRatio = config.pixelRatio || 1, + canvas = new Konva.SceneCanvas({ + width: config.width || this.getWidth() || (stage ? stage.getWidth() : 0), + height: config.height || this.getHeight() || (stage ? stage.getHeight() : 0), + pixelRatio: pixelRatio + }), + context = canvas.getContext(); + + context.save(); + + if(x || y) { + context.translate(-1 * x, -1 * y); + } + + this.drawScene(canvas); + context.restore(); + + return canvas.toDataURL(mimeType, quality); + }, + /** + * converts node into an image. Since the toImage + * method is asynchronous, a callback is required. toImage is most commonly used + * to cache complex drawings as an image so that they don't have to constantly be redrawn + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. + * @example + * var image = node.toImage({ + * callback: function(img) { + * // do stuff with img + * } + * }); + */ + toImage: function(config) { + if (!config || !config.callback) { + throw 'callback required for toImage method config argument'; + } + Konva.Util._getImage(this.toDataURL(config), function(img) { + config.callback(img); + }); + }, + setSize: function(size) { + this.setWidth(size.width); + this.setHeight(size.height); + return this; + }, + getSize: function() { + return { + width: this.getWidth(), + height: this.getHeight() + }; + }, + getWidth: function() { + return this.attrs.width || 0; + }, + getHeight: function() { + return this.attrs.height || 0; + }, + /** + * get class name, which may return Stage, Layer, Group, or shape class names like Rect, Circle, Text, etc. + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ + getClassName: function() { + return this.className || this.nodeType; + }, + /** + * get the node type, which may return Stage, Layer, Group, or Node + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ + getType: function() { + return this.nodeType; + }, + getDragDistance: function() { + // compare with undefined because we need to track 0 value + if (this.attrs.dragDistance !== undefined) { + return this.attrs.dragDistance; + } else if (this.parent) { + return this.parent.getDragDistance(); + } else { + return Konva.dragDistance; + } + }, + _get: function(selector) { + return this.className === selector || this.nodeType === selector ? [this] : []; + }, + _off: function(type, name) { + var evtListeners = this.eventListeners[type], + i, evtName; + + for(i = 0; i < evtListeners.length; i++) { + evtName = evtListeners[i].name; + // the following two conditions must be true in order to remove a handler: + // 1) the current event name cannot be konva unless the event name is konva + // this enables developers to force remove a konva specific listener for whatever reason + // 2) an event name is not specified, or if one is specified, it matches the current event name + if((evtName !== 'konva' || name === 'konva') && (!name || evtName === name)) { + evtListeners.splice(i, 1); + if(evtListeners.length === 0) { + delete this.eventListeners[type]; + break; + } + i--; + } + } + }, + _fireChangeEvent: function(attr, oldVal, newVal) { + this._fire(attr + CHANGE, { + oldVal: oldVal, + newVal: newVal + }); + }, + setId: function(id) { + var oldId = this.getId(); + + Konva._removeId(oldId); + Konva._addId(this, id); + this._setAttr(ID, id); + return this; + }, + setName: function(name) { + var oldNames = (this.getName() || '').split(/\s/g); + var newNames = (name || '').split(/\s/g); + var subname, i; + // remove all subnames + for(i = 0; i < oldNames.length; i++) { + subname = oldNames[i]; + if ((newNames.indexOf(subname)) === -1 && subname) { + Konva._removeName(subname, this._id); + } + } + + // add new names + for(i = 0; i < newNames.length; i++) { + subname = newNames[i]; + if ((oldNames.indexOf(subname) === -1) && subname) { + Konva._addName(this, subname); + } + } + + this._setAttr(NAME, name); + return this; + }, + // naming methods + /** + * add name to node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red'); + * node.addName('selected'); + * node.name(); // return 'red selected' + */ + addName: function(name) { + if (!this.hasName(name)) { + var oldName = this.name(); + var newName = oldName ? (oldName + ' ' + name) : name; + this.setName(newName); + } + return this; + }, + /** + * check is node has name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Boolean} + * @example + * node.name('red'); + * node.hasName('red'); // return true + * node.hasName('selected'); // return false + */ + hasName: function(name) { + var names = (this.name() || '').split(/\s/g); + return names.indexOf(name) !== -1; + }, + /** + * remove name from node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red selected'); + * node.removeName('selected'); + * node.hasName('selected'); // return false + * node.name(); // return 'red' + */ + removeName: function(name) { + var names = (this.name() || '').split(/\s/g); + var index = names.indexOf(name); + if (index !== -1) { + names.splice(index, 1); + this.setName(names.join(' ')); + } + return this; + }, + /** + * set attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @param {*} val + * @returns {Konva.Node} + * @example + * node.setAttr('x', 5); + */ + setAttr: function(attr, val) { + var method = SET + Konva.Util._capitalize(attr), + func = this[method]; + + if(Konva.Util._isFunction(func)) { + func.call(this, val); + } + // otherwise set directly + else { + this._setAttr(attr, val); + } + return this; + }, + _setAttr: function(key, val) { + var oldVal; + if(val !== undefined) { + oldVal = this.attrs[key]; + if (oldVal === val) { + return; + } + this.attrs[key] = val; + this._fireChangeEvent(key, oldVal, val); + } + }, + _setComponentAttr: function(key, component, val) { + var oldVal; + if(val !== undefined) { + oldVal = this.attrs[key]; + + if (!oldVal) { + // set value to default value using getAttr + this.attrs[key] = this.getAttr(key); + } + + this.attrs[key][component] = val; + this._fireChangeEvent(key, oldVal, val); + } + }, + _fireAndBubble: function(eventType, evt, compareShape) { + var okayToRun = true; + + if(evt && this.nodeType === SHAPE) { + evt.target = this; + } + + if(eventType === MOUSEENTER && compareShape && (this._id === compareShape._id || (this.isAncestorOf && this.isAncestorOf(compareShape)))) { + okayToRun = false; + } + else if(eventType === MOUSELEAVE && compareShape && (this._id === compareShape._id || (this.isAncestorOf && this.isAncestorOf(compareShape)))) { + okayToRun = false; + } + if(okayToRun) { + this._fire(eventType, evt); + + // simulate event bubbling + var stopBubble = + (eventType === MOUSEENTER || eventType === MOUSELEAVE) && + ((compareShape && compareShape.isAncestorOf && compareShape.isAncestorOf(this) && !compareShape.isAncestorOf(this.parent))); + if((evt && !evt.cancelBubble || !evt) && this.parent && this.parent.isListening() && (!stopBubble)) { + if (compareShape && compareShape.parent) { + this._fireAndBubble.call(this.parent, eventType, evt, compareShape.parent); + } + else { + this._fireAndBubble.call(this.parent, eventType, evt); + } + } + } + }, + _fire: function(eventType, evt) { + var events = this.eventListeners[eventType], + i; + + evt = evt || {}; + evt.currentTarget = this; + evt.type = eventType; + + if (events) { + for(i = 0; i < events.length; i++) { + events[i].handler.call(this, evt); + } + } + }, + /** + * draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redrawn + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + draw: function() { + this.drawScene(); + this.drawHit(); + return this; + } + }); + + /** + * create node with JSON string or an Object. De-serializtion does not generate custom + * shape drawing functions, images, or event handlers (this would make the + * serialized object huge). If your app uses custom shapes, images, and + * event handlers (it probably does), then you need to select the appropriate + * shapes after loading the stage and set these properties via on(), setDrawFunc(), + * and setImage() methods + * @method + * @memberof Konva.Node + * @param {String|Object} json string or object + * @param {Element} [container] optional container dom element used only if you're + * creating a stage node + */ + Konva.Node.create = function(data, container) { + if (Konva.Util._isString(data)) { + data = JSON.parse(data); + } + return this._createNode(data, container); + }; + Konva.Node._createNode = function(obj, container) { + var className = Konva.Node.prototype.getClassName.call(obj), + children = obj.children, + no, len, n; + + // if container was passed in, add it to attrs + if(container) { + obj.attrs.container = container; + } + + no = new Konva[className](obj.attrs); + if(children) { + len = children.length; + for(n = 0; n < len; n++) { + no.add(this._createNode(children[n])); + } + } + + return no; + }; + + + // =========================== add getters setters =========================== + + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'position'); + /** + * get/set node position relative to parent + * @name position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Object} + * @example + * // get position + * var position = node.position(); + * + * // set position + * node.position({ + * x: 5 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'x', 0); + + /** + * get/set x position + * @name x + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Object} + * @example + * // get x + * var x = node.x(); + * + * // set x + * node.x(5); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'y', 0); + + /** + * get/set y position + * @name y + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Integer} + * @example + * // get y + * var y = node.y(); + * + * // set y + * node.y(5); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'opacity', 1); + + /** + * get/set opacity. Opacity values range from 0 to 1. + * A node with an opacity of 0 is fully transparent, and a node + * with an opacity of 1 is fully opaque + * @name opacity + * @method + * @memberof Konva.Node.prototype + * @param {Object} opacity + * @returns {Number} + * @example + * // get opacity + * var opacity = node.opacity(); + * + * // set opacity + * node.opacity(0.5); + */ + + Konva.Factory.addGetter(Konva.Node, 'name'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'name'); + + /** + * get/set name + * @name name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {String} + * @example + * // get name + * var name = node.name(); + * + * // set name + * node.name('foo'); + * + * // also node may have multiple names (as css classes) + * node.name('foo bar'); + */ + + Konva.Factory.addGetter(Konva.Node, 'id'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'id'); + + /** + * get/set id. Id is global for whole page. + * @name id + * @method + * @memberof Konva.Node.prototype + * @param {String} id + * @returns {String} + * @example + * // get id + * var name = node.id(); + * + * // set id + * node.id('foo'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'rotation', 0); + + /** + * get/set rotation in degrees + * @name rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} rotation + * @returns {Number} + * @example + * // get rotation in degrees + * var rotation = node.rotation(); + * + * // set rotation in degrees + * node.rotation(45); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'scale', ['x', 'y']); + + /** + * get/set scale + * @name scale + * @param {Object} scale + * @param {Number} scale.x + * @param {Number} scale.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get scale + * var scale = node.scale(); + * + * // set scale + * shape.scale({ + * x: 2 + * y: 3 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'scaleX', 1); + + /** + * get/set scale x + * @name scaleX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale x + * var scaleX = node.scaleX(); + * + * // set scale x + * node.scaleX(2); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'scaleY', 1); + + /** + * get/set scale y + * @name scaleY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale y + * var scaleY = node.scaleY(); + * + * // set scale y + * node.scaleY(2); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'skew', ['x', 'y']); + + /** + * get/set skew + * @name skew + * @param {Object} skew + * @param {Number} skew.x + * @param {Number} skew.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get skew + * var skew = node.skew(); + * + * // set skew + * node.skew({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'skewX', 0); + + /** + * get/set skew x + * @name skewX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew x + * var skewX = node.skewX(); + * + * // set skew x + * node.skewX(3); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'skewY', 0); + + /** + * get/set skew y + * @name skewY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew y + * var skewY = node.skewY(); + * + * // set skew y + * node.skewY(3); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'offset', ['x', 'y']); + + /** + * get/set offset. Offsets the default position and rotation point + * @method + * @memberof Konva.Node.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get offset + * var offset = node.offset(); + * + * // set offset + * node.offset({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'offsetX', 0); + + /** + * get/set offset x + * @name offsetX + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get offset x + * var offsetX = node.offsetX(); + * + * // set offset x + * node.offsetX(3); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'offsetY', 0); + + /** + * get/set offset y + * @name offsetY + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get offset y + * var offsetY = node.offsetY(); + * + * // set offset y + * node.offsetY(3); + */ + + Konva.Factory.addSetter(Konva.Node, 'dragDistance'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'dragDistance'); + + /** + * get/set drag distance + * @name dragDistance + * @method + * @memberof Konva.Node.prototype + * @param {Number} distance + * @returns {Number} + * @example + * // get drag distance + * var dragDistance = node.dragDistance(); + * + * // set distance + * // node starts dragging only if pointer moved more then 3 pixels + * node.dragDistance(3); + * // or set globally + * Konva.dragDistance = 3; + */ + + + Konva.Factory.addSetter(Konva.Node, 'width', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'width'); + /** + * get/set width + * @name width + * @method + * @memberof Konva.Node.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get width + * var width = node.width(); + * + * // set width + * node.width(100); + */ + + Konva.Factory.addSetter(Konva.Node, 'height', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'height'); + /** + * get/set height + * @name height + * @method + * @memberof Konva.Node.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get height + * var height = node.height(); + * + * // set height + * node.height(100); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'listening', 'inherit'); + /** + * get/set listenig attr. If you need to determine if a node is listening or not + * by taking into account its parents, use the isListening() method + * @name listening + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} listening Can be "inherit", true, or false. The default is "inherit". + * @returns {Boolean|String} + * @example + * // get listening attr + * var listening = node.listening(); + * + * // stop listening for events + * node.listening(false); + * + * // listen for events + * node.listening(true); + * + * // listen to events according to the parent + * node.listening('inherit'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'filters', undefined, function(val) {this._filterUpToDate = false; return val; }); + /** + * get/set filters. Filters are applied to cached canvases + * @name filters + * @method + * @memberof Konva.Node.prototype + * @param {Array} filters array of filters + * @returns {Array} + * @example + * // get filters + * var filters = node.filters(); + * + * // set a single filter + * node.cache(); + * node.filters([Konva.Filters.Blur]); + * + * // set multiple filters + * node.cache(); + * node.filters([ + * Konva.Filters.Blur, + * Konva.Filters.Sepia, + * Konva.Filters.Invert + * ]); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'visible', 'inherit'); + /** + * get/set visible attr. Can be "inherit", true, or false. The default is "inherit". + * If you need to determine if a node is visible or not + * by taking into account its parents, use the isVisible() method + * @name visible + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} visible + * @returns {Boolean|String} + * @example + * // get visible attr + * var visible = node.visible(); + * + * // make invisible + * node.visible(false); + * + * // make visible + * node.visible(true); + * + * // make visible according to the parent + * node.visible('inherit'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'transformsEnabled', 'all'); + + /** + * get/set transforms that are enabled. Can be "all", "none", or "position". The default + * is "all" + * @name transformsEnabled + * @method + * @memberof Konva.Node.prototype + * @param {String} enabled + * @returns {String} + * @example + * // enable position transform only to improve draw performance + * node.transformsEnabled('position'); + * + * // enable all transforms + * node.transformsEnabled('all'); + */ + + + + /** + * get/set node size + * @name size + * @method + * @memberof Konva.Node.prototype + * @param {Object} size + * @param {Number} size.width + * @param {Number} size.height + * @returns {Object} + * @example + * // get node size + * var size = node.size(); + * var x = size.x; + * var y = size.y; + * + * // set size + * node.size({ + * width: 100, + * height: 200 + * }); + */ + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'size'); + + Konva.Factory.backCompat(Konva.Node, { + rotateDeg: 'rotate', + setRotationDeg: 'setRotation', + getRotationDeg: 'getRotation' + }); + + Konva.Collection.mapMethods(Konva.Node); +})(Konva); + +(function() { + 'use strict'; + /** + * Grayscale Filter + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Grayscale]); + */ + Konva.Filters.Grayscale = function(imageData) { + var data = imageData.data, + len = data.length, + i, brightness; + + for(i = 0; i < len; i += 4) { + brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; + // red + data[i] = brightness; + // green + data[i + 1] = brightness; + // blue + data[i + 2] = brightness; + } + }; +})(); + +(function() { + 'use strict'; + /** + * Brighten Filter. + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Brighten]); + * node.brightness(0.8); + */ + Konva.Filters.Brighten = function(imageData) { + var brightness = this.brightness() * 255, + data = imageData.data, + len = data.length, + i; + + for(i = 0; i < len; i += 4) { + // red + data[i] += brightness; + // green + data[i + 1] += brightness; + // blue + data[i + 2] += brightness; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'brightness', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set filter brightness. The brightness is a number between -1 and 1.  Positive values + * brighten the pixels and negative values darken them. Use with {@link Konva.Filters.Brighten} filter. + * @name brightness + * @method + * @memberof Konva.Node.prototype + * @param {Number} brightness value between -1 and 1 + * @returns {Number} + */ + +})(); + +(function() { + 'use strict'; + /** + * Invert Filter + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Invert]); + */ + Konva.Filters.Invert = function(imageData) { + var data = imageData.data, + len = data.length, + i; + + for(i = 0; i < len; i += 4) { + // red + data[i] = 255 - data[i]; + // green + data[i + 1] = 255 - data[i + 1]; + // blue + data[i + 2] = 255 - data[i + 2]; + } + }; +})(); + +/* + the Gauss filter + master repo: https://github.com/pavelpower/kineticjsGaussFilter +*/ +(function() { + 'use strict'; + /* + + StackBlur - a fast almost Gaussian Blur For Canvas + + Version: 0.5 + Author: Mario Klingemann + Contact: mario@quasimondo.com + Website: http://www.quasimondo.com/StackBlurForCanvas + Twitter: @quasimondo + + In case you find this class useful - especially in commercial projects - + I am not totally unhappy for a small donation to my PayPal account + mario@quasimondo.de + + Or support me on flattr: + https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript + + Copyright (c) 2010 Mario Klingemann + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + */ + + function BlurStack() { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 0; + this.next = null; + } + + var mul_table = [ + 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, + 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, + 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, + 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, + 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, + 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, + 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, + 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, + 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, + 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, + 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, + 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, + 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, + 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, + 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, + 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259 + ]; + + var shg_table = [ + 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + ]; + + function filterGaussBlurRGBA( imageData, radius) { + + var pixels = imageData.data, + width = imageData.width, + height = imageData.height; + + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, + r_out_sum, g_out_sum, b_out_sum, a_out_sum, + r_in_sum, g_in_sum, b_in_sum, a_in_sum, + pr, pg, pb, pa, rbs; + + var div = radius + radius + 1, + widthMinus1 = width - 1, + heightMinus1 = height - 1, + radiusPlus1 = radius + 1, + sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2, + stackStart = new BlurStack(), + stackEnd = null, + stack = stackStart, + stackIn = null, + stackOut = null, + mul_sum = mul_table[radius], + shg_sum = shg_table[radius]; + + for ( i = 1; i < div; i++ ) { + stack = stack.next = new BlurStack(); + if ( i === radiusPlus1 ){ + stackEnd = stack; + } + } + + stack.next = stackStart; + + yw = yi = 0; + + for ( y = 0; y < height; y++ ) + { + r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; + + r_out_sum = radiusPlus1 * ( pr = pixels[yi] ); + g_out_sum = radiusPlus1 * ( pg = pixels[yi + 1] ); + b_out_sum = radiusPlus1 * ( pb = pixels[yi + 2] ); + a_out_sum = radiusPlus1 * ( pa = pixels[yi + 3] ); + + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; + + stack = stackStart; + + for( i = 0; i < radiusPlus1; i++ ) + { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } + + for( i = 1; i < radiusPlus1; i++ ) + { + p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 ); + r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i ); + g_sum += ( stack.g = ( pg = pixels[p + 1])) * rbs; + b_sum += ( stack.b = ( pb = pixels[p + 2])) * rbs; + a_sum += ( stack.a = ( pa = pixels[p + 3])) * rbs; + + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; + + stack = stack.next; + } + + + stackIn = stackStart; + stackOut = stackEnd; + for ( x = 0; x < width; x++ ) + { + pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum; + if ( pa !== 0 ) + { + pa = 255 / pa; + pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; + pixels[yi + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; + pixels[yi + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; + } else { + pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; + } + + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; + + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; + + p = (yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2; + + r_in_sum += ( stackIn.r = pixels[p]); + g_in_sum += ( stackIn.g = pixels[p + 1]); + b_in_sum += ( stackIn.b = pixels[p + 2]); + a_in_sum += ( stackIn.a = pixels[p + 3]); + + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; + a_sum += a_in_sum; + + stackIn = stackIn.next; + + r_out_sum += ( pr = stackOut.r ); + g_out_sum += ( pg = stackOut.g ); + b_out_sum += ( pb = stackOut.b ); + a_out_sum += ( pa = stackOut.a ); + + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; + + stackOut = stackOut.next; + + yi += 4; + } + yw += width; + } + + + for ( x = 0; x < width; x++ ) + { + g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; + + yi = x << 2; + r_out_sum = radiusPlus1 * ( pr = pixels[yi]); + g_out_sum = radiusPlus1 * ( pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * ( pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * ( pa = pixels[yi + 3]); + + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; + + stack = stackStart; + + for( i = 0; i < radiusPlus1; i++ ) + { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } + + yp = width; + + for( i = 1; i <= radius; i++ ) + { + yi = ( yp + x ) << 2; + + r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i ); + g_sum += ( stack.g = ( pg = pixels[yi + 1])) * rbs; + b_sum += ( stack.b = ( pb = pixels[yi + 2])) * rbs; + a_sum += ( stack.a = ( pa = pixels[yi + 3])) * rbs; + + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; + + stack = stack.next; + + if( i < heightMinus1 ) + { + yp += width; + } + } + + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for ( y = 0; y < height; y++ ) + { + p = yi << 2; + pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum; + if ( pa > 0 ) + { + pa = 255 / pa; + pixels[p] = ((r_sum * mul_sum) >> shg_sum ) * pa; + pixels[p + 1] = ((g_sum * mul_sum) >> shg_sum ) * pa; + pixels[p + 2] = ((b_sum * mul_sum) >> shg_sum ) * pa; + } else { + pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; + } + + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; + + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; + + p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2; + + r_sum += ( r_in_sum += ( stackIn.r = pixels[p])); + g_sum += ( g_in_sum += ( stackIn.g = pixels[p + 1])); + b_sum += ( b_in_sum += ( stackIn.b = pixels[p + 2])); + a_sum += ( a_in_sum += ( stackIn.a = pixels[p + 3])); + + stackIn = stackIn.next; + + r_out_sum += ( pr = stackOut.r ); + g_out_sum += ( pg = stackOut.g ); + b_out_sum += ( pb = stackOut.b ); + a_out_sum += ( pa = stackOut.a ); + + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; + + stackOut = stackOut.next; + + yi += width; + } + } + } + + /** + * Blur Filter + * @function + * @name Blur + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Blur]); + * node.blurRadius(10); + */ + Konva.Filters.Blur = function Blur(imageData) { + var radius = Math.round(this.blurRadius()); + + if (radius > 0) { + filterGaussBlurRGBA(imageData, radius); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'blurRadius', 0, null, Konva.Factory.afterSetFilter); + + /** + * get/set blur radius. Use with {@link Konva.Filters.Blur} filter + * @name blurRadius + * @method + * @memberof Konva.Node.prototype + * @param {Integer} radius + * @returns {Integer} + */ +})(); + +/*eslint-disable max-depth */ +(function() { + 'use strict'; + function pixelAt(idata, x, y) { + var idx = (y * idata.width + x) * 4; + var d = []; + d.push(idata.data[idx++], idata.data[idx++], idata.data[idx++], idata.data[idx++]); + return d; + } + + function rgbDistance(p1, p2) { + return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2)); + } + + function rgbMean(pTab) { + var m = [0, 0, 0]; + + for (var i = 0; i < pTab.length; i++) { + m[0] += pTab[i][0]; + m[1] += pTab[i][1]; + m[2] += pTab[i][2]; + } + + m[0] /= pTab.length; + m[1] /= pTab.length; + m[2] /= pTab.length; + + return m; + } + + function backgroundMask(idata, threshold) { + var rgbv_no = pixelAt(idata, 0, 0); + var rgbv_ne = pixelAt(idata, idata.width - 1, 0); + var rgbv_so = pixelAt(idata, 0, idata.height - 1); + var rgbv_se = pixelAt(idata, idata.width - 1, idata.height - 1); + + + var thres = threshold || 10; + if (rgbDistance(rgbv_no, rgbv_ne) < thres && rgbDistance(rgbv_ne, rgbv_se) < thres && rgbDistance(rgbv_se, rgbv_so) < thres && rgbDistance(rgbv_so, rgbv_no) < thres) { + + // Mean color + var mean = rgbMean([rgbv_ne, rgbv_no, rgbv_se, rgbv_so]); + + // Mask based on color distance + var mask = []; + for (var i = 0; i < idata.width * idata.height; i++) { + var d = rgbDistance(mean, [idata.data[i * 4], idata.data[i * 4 + 1], idata.data[i * 4 + 2]]); + mask[i] = (d < thres) ? 0 : 255; + } + + return mask; + } + } + + function applyMask(idata, mask) { + for (var i = 0; i < idata.width * idata.height; i++) { + idata.data[4 * i + 3] = mask[i]; + } + } + + function erodeMask(mask, sw, sh) { + + var weights = [1, 1, 1, 1, 0, 1, 1, 1, 1]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = (a === 255 * 8) ? 255 : 0; + } + } + + return maskResult; + } + + function dilateMask(mask, sw, sh) { + + var weights = [1, 1, 1, 1, 1, 1, 1, 1, 1]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = (a >= 255 * 4) ? 255 : 0; + } + } + + return maskResult; + } + + function smoothEdgeMask(mask, sw, sh) { + + var weights = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = a; + } + } + + return maskResult; + } + + /** + * Mask Filter + * @function + * @name Mask + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Mask]); + * node.threshold(200); + */ + Konva.Filters.Mask = function(imageData) { + // Detect pixels close to the background color + var threshold = this.threshold(), + mask = backgroundMask(imageData, threshold); + if (mask) { + // Erode + mask = erodeMask(mask, imageData.width, imageData.height); + + // Dilate + mask = dilateMask(mask, imageData.width, imageData.height); + + // Gradient + mask = smoothEdgeMask(mask, imageData.width, imageData.height); + + // Apply mask + applyMask(imageData, mask); + + // todo : Update hit region function according to mask + } + + return imageData; + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'threshold', 0, null, Konva.Factory.afterSetFilter); +})(); + +(function () { + 'use strict'; + /** + * RGB Filter + * @function + * @name RGB + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.RGB]); + * node.blue(120); + * node.green(200); + */ + Konva.Filters.RGB = function (imageData) { + var data = imageData.data, + nPixels = data.length, + red = this.red(), + green = this.green(), + blue = this.blue(), + i, brightness; + + for (i = 0; i < nPixels; i += 4) { + brightness = (0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]) / 255; + data[i] = brightness * red; // r + data[i + 1] = brightness * green; // g + data[i + 2] = brightness * blue; // b + data[i + 3] = data[i + 3]; // alpha + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'red', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter red value. Use with {@link Konva.Filters.RGB} filter. + * @name red + * @method + * @memberof Konva.Node.prototype + * @param {Integer} red value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'green', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter green value. Use with {@link Konva.Filters.RGB} filter. + * @name green + * @method + * @memberof Konva.Node.prototype + * @param {Integer} green value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'blue', 0, Konva.Validators.RGBComponent, Konva.Factory.afterSetFilter); + /** + * get/set filter blue value. Use with {@link Konva.Filters.RGB} filter. + * @name blue + * @method + * @memberof Konva.Node.prototype + * @param {Integer} blue value between 0 and 255 + * @returns {Integer} + */ +})(); + +(function () { + 'use strict'; + /** + * RGBA Filter + * @function + * @name RGBA + * @memberof Konva.Filters + * @param {Object} imageData + * @author codefo + * @example + * node.cache(); + * node.filters([Konva.Filters.RGBA]); + * node.blue(120); + * node.green(200); + * node.alpha(0.3); + */ + Konva.Filters.RGBA = function (imageData) { + var data = imageData.data, + nPixels = data.length, + red = this.red(), + green = this.green(), + blue = this.blue(), + alpha = this.alpha(), + i, ia; + + for (i = 0; i < nPixels; i += 4) { + ia = 1 - alpha; + + data[i] = red * alpha + data[i] * ia; // r + data[i + 1] = green * alpha + data[i + 1] * ia; // g + data[i + 2] = blue * alpha + data[i + 2] * ia; // b + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'red', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter red value. Use with {@link Konva.Filters.RGBA} filter. + * @name red + * @method + * @memberof Konva.Node.prototype + * @param {Integer} red value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'green', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter green value. Use with {@link Konva.Filters.RGBA} filter. + * @name green + * @method + * @memberof Konva.Node.prototype + * @param {Integer} green value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'blue', 0, Konva.Validators.RGBComponent, Konva.Factory.afterSetFilter); + /** + * get/set filter blue value. Use with {@link Konva.Filters.RGBA} filter. + * @name blue + * @method + * @memberof Konva.Node.prototype + * @param {Integer} blue value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'alpha', 1, function(val) { + this._filterUpToDate = false; + if (val > 1) { + return 1; + } + else if (val < 0) { + return 0; + } + else { + return val; + } + }); + /** + * get/set filter alpha value. Use with {@link Konva.Filters.RGBA} filter. + * @name alpha + * @method + * @memberof Konva.Node.prototype + * @param {Float} alpha value between 0 and 1 + * @returns {Float} + */ +})(); + +(function () { + 'use strict'; + /** + * HSV Filter. Adjusts the hue, saturation and value + * @function + * @name HSV + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * image.filters([Konva.Filters.HSV]); + * image.value(200); + */ + + Konva.Filters.HSV = function (imageData) { + var data = imageData.data, + nPixels = data.length, + v = Math.pow(2, this.value()), + s = Math.pow(2, this.saturation()), + h = Math.abs((this.hue()) + 360) % 360, + i; + + // Basis for the technique used: + // http://beesbuzz.biz/code/hsv_color_transforms.php + // V is the value multiplier (1 for none, 2 for double, 0.5 for half) + // S is the saturation multiplier (1 for none, 2 for double, 0.5 for half) + // H is the hue shift in degrees (0 to 360) + // vsu = V*S*cos(H*PI/180); + // vsw = V*S*sin(H*PI/180); + //[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R] + //[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G] + //[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B] + + // Precompute the values in the matrix: + var vsu = v * s * Math.cos(h * Math.PI / 180), + vsw = v * s * Math.sin(h * Math.PI / 180); + // (result spot)(source spot) + var rr = 0.299 * v + 0.701 * vsu + 0.167 * vsw, + rg = 0.587 * v - 0.587 * vsu + 0.330 * vsw, + rb = 0.114 * v - 0.114 * vsu - 0.497 * vsw; + var gr = 0.299 * v - 0.299 * vsu - 0.328 * vsw, + gg = 0.587 * v + 0.413 * vsu + 0.035 * vsw, + gb = 0.114 * v - 0.114 * vsu + 0.293 * vsw; + var br = 0.299 * v - 0.300 * vsu + 1.250 * vsw, + bg = 0.587 * v - 0.586 * vsu - 1.050 * vsw, + bb = 0.114 * v + 0.886 * vsu - 0.200 * vsw; + + var r, g, b, a; + + for (i = 0; i < nPixels; i += 4) { + r = data[i + 0]; + g = data[i + 1]; + b = data[i + 2]; + a = data[i + 3]; + + data[i + 0] = rr * r + rg * g + rb * b; + data[i + 1] = gr * r + gg * g + gb * b; + data[i + 2] = br * r + bg * g + bb * b; + data[i + 3] = a; // alpha + } + + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'hue', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv hue in degrees. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name hue + * @method + * @memberof Konva.Node.prototype + * @param {Number} hue value between 0 and 359 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'saturation', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv saturation. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name saturation + * @method + * @memberof Konva.Node.prototype + * @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc.. + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'value', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv value. Use with {@link Konva.Filters.HSV} filter. + * @name value + * @method + * @memberof Konva.Node.prototype + * @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc.. + * @returns {Number} + */ + +})(); + +(function () { + 'use strict'; + + Konva.Factory.addGetterSetter(Konva.Node, 'hue', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv hue in degrees. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name hue + * @method + * @memberof Konva.Node.prototype + * @param {Number} hue value between 0 and 359 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'saturation', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv saturation. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name saturation + * @method + * @memberof Konva.Node.prototype + * @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc.. + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'luminance', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsl luminance. Use with {@link Konva.Filters.HSL} filter. + * @name value + * @method + * @memberof Konva.Node.prototype + * @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc.. + * @returns {Number} + */ + + /** + * HSL Filter. Adjusts the hue, saturation and luminance (or lightness) + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * image.filters([Konva.Filters.HSL]); + * image.luminance(200); + */ + + Konva.Filters.HSL = function (imageData) { + var data = imageData.data, + nPixels = data.length, + v = 1, + s = Math.pow(2, this.saturation()), + h = Math.abs((this.hue()) + 360) % 360, + l = this.luminance() * 127, + i; + + // Basis for the technique used: + // http://beesbuzz.biz/code/hsv_color_transforms.php + // V is the value multiplier (1 for none, 2 for double, 0.5 for half) + // S is the saturation multiplier (1 for none, 2 for double, 0.5 for half) + // H is the hue shift in degrees (0 to 360) + // vsu = V*S*cos(H*PI/180); + // vsw = V*S*sin(H*PI/180); + //[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R] + //[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G] + //[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B] + + // Precompute the values in the matrix: + var vsu = v * s * Math.cos(h * Math.PI / 180), + vsw = v * s * Math.sin(h * Math.PI / 180); + // (result spot)(source spot) + var rr = 0.299 * v + 0.701 * vsu + 0.167 * vsw, + rg = 0.587 * v - 0.587 * vsu + 0.330 * vsw, + rb = 0.114 * v - 0.114 * vsu - 0.497 * vsw; + var gr = 0.299 * v - 0.299 * vsu - 0.328 * vsw, + gg = 0.587 * v + 0.413 * vsu + 0.035 * vsw, + gb = 0.114 * v - 0.114 * vsu + 0.293 * vsw; + var br = 0.299 * v - 0.300 * vsu + 1.250 * vsw, + bg = 0.587 * v - 0.586 * vsu - 1.050 * vsw, + bb = 0.114 * v + 0.886 * vsu - 0.200 * vsw; + + var r, g, b, a; + + for (i = 0; i < nPixels; i += 4) { + r = data[i + 0]; + g = data[i + 1]; + b = data[i + 2]; + a = data[i + 3]; + + data[i + 0] = rr * r + rg * g + rb * b + l; + data[i + 1] = gr * r + gg * g + gb * b + l; + data[i + 2] = br * r + bg * g + bb * b + l; + data[i + 3] = a; // alpha + } + }; +})(); + +(function () { + 'use strict'; + /** + * Emboss Filter. + * Pixastic Lib - Emboss filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * License: [http://www.pixastic.com/lib/license.txt] + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Emboss]); + * node.embossStrength(0.8); + * node.embossWhiteLevel(0.3); + * node.embossDirection('right'); + * node.embossBlend(true); + */ + Konva.Filters.Emboss = function (imageData) { + + // pixastic strength is between 0 and 10. I want it between 0 and 1 + // pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also, + // a max value of greyLevel yields a white emboss, and the min value yields a black + // emboss. Therefore, I changed greyLevel to whiteLevel + var strength = this.embossStrength() * 10, + greyLevel = this.embossWhiteLevel() * 255, + direction = this.embossDirection(), + blend = this.embossBlend(), + dirY = 0, + dirX = 0, + data = imageData.data, + w = imageData.width, + h = imageData.height, + w4 = w * 4, + y = h; + + switch (direction) { + case 'top-left': + dirY = -1; + dirX = -1; + break; + case 'top': + dirY = -1; + dirX = 0; + break; + case 'top-right': + dirY = -1; + dirX = 1; + break; + case 'right': + dirY = 0; + dirX = 1; + break; + case 'bottom-right': + dirY = 1; + dirX = 1; + break; + case 'bottom': + dirY = 1; + dirX = 0; + break; + case 'bottom-left': + dirY = 1; + dirX = -1; + break; + case 'left': + dirY = 0; + dirX = -1; + break; + } + + do { + var offsetY = (y - 1) * w4; + + var otherY = dirY; + if (y + otherY < 1){ + otherY = 0; + } + if (y + otherY > h) { + otherY = 0; + } + + var offsetYOther = (y - 1 + otherY) * w * 4; + + var x = w; + do { + var offset = offsetY + (x - 1) * 4; + + var otherX = dirX; + if (x + otherX < 1){ + otherX = 0; + } + if (x + otherX > w) { + otherX = 0; + } + + var offsetOther = offsetYOther + (x - 1 + otherX) * 4; + + var dR = data[offset] - data[offsetOther]; + var dG = data[offset + 1] - data[offsetOther + 1]; + var dB = data[offset + 2] - data[offsetOther + 2]; + + var dif = dR; + var absDif = dif > 0 ? dif : -dif; + + var absG = dG > 0 ? dG : -dG; + var absB = dB > 0 ? dB : -dB; + + if (absG > absDif) { + dif = dG; + } + if (absB > absDif) { + dif = dB; + } + + dif *= strength; + + if (blend) { + var r = data[offset] + dif; + var g = data[offset + 1] + dif; + var b = data[offset + 2] + dif; + + data[offset] = (r > 255) ? 255 : (r < 0 ? 0 : r); + data[offset + 1] = (g > 255) ? 255 : (g < 0 ? 0 : g); + data[offset + 2] = (b > 255) ? 255 : (b < 0 ? 0 : b); + } else { + var grey = greyLevel - dif; + if (grey < 0) { + grey = 0; + } else if (grey > 255) { + grey = 255; + } + + data[offset] = data[offset + 1] = data[offset + 2] = grey; + } + + } while (--x); + } while (--y); + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'embossStrength', 0.5, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss strength. Use with {@link Konva.Filters.Emboss} filter. + * @name embossStrength + * @method + * @memberof Konva.Node.prototype + * @param {Number} level between 0 and 1. Default is 0.5 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossWhiteLevel', 0.5, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss white level. Use with {@link Konva.Filters.Emboss} filter. + * @name embossWhiteLevel + * @method + * @memberof Konva.Node.prototype + * @param {Number} embossWhiteLevel between 0 and 1. Default is 0.5 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossDirection', 'top-left', null, Konva.Factory.afterSetFilter); + /** + * get/set emboss direction. Use with {@link Konva.Filters.Emboss} filter. + * @name embossDirection + * @method + * @memberof Konva.Node.prototype + * @param {String} embossDirection can be top-left, top, top-right, right, bottom-right, bottom, bottom-left or left + * The default is top-left + * @returns {String} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossBlend', false, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss blend. Use with {@link Konva.Filters.Emboss} filter. + * @name embossBlend + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} embossBlend + * @returns {Boolean} + */ +})(); + +(function () { + 'use strict'; + function remap(fromValue, fromMin, fromMax, toMin, toMax) { + // Compute the range of the data + var fromRange = fromMax - fromMin, + toRange = toMax - toMin, + toValue; + + // If either range is 0, then the value can only be mapped to 1 value + if (fromRange === 0) { + return toMin + toRange / 2; + } + if (toRange === 0) { + return toMin; + } + + // (1) untranslate, (2) unscale, (3) rescale, (4) retranslate + toValue = (fromValue - fromMin) / fromRange; + toValue = (toRange * toValue) + toMin; + + return toValue; + } + + + /** + * Enhance Filter. Adjusts the colors so that they span the widest + * possible range (ie 0-255). Performs w*h pixel reads and w*h pixel + * writes. + * @function + * @name Enhance + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Enhance]); + * node.enhance(0.4); + */ + Konva.Filters.Enhance = function (imageData) { + var data = imageData.data, + nSubPixels = data.length, + rMin = data[0], rMax = rMin, r, + gMin = data[1], gMax = gMin, g, + bMin = data[2], bMax = bMin, b, + i; + + // If we are not enhancing anything - don't do any computation + var enhanceAmount = this.enhance(); + if( enhanceAmount === 0 ){ return; } + + // 1st Pass - find the min and max for each channel: + for (i = 0; i < nSubPixels; i += 4) { + r = data[i + 0]; + if (r < rMin) { rMin = r; } + else if (r > rMax) { rMax = r; } + g = data[i + 1]; + if (g < gMin) { gMin = g; } else + if (g > gMax) { gMax = g; } + b = data[i + 2]; + if (b < bMin) { bMin = b; } else + if (b > bMax) { bMax = b; } + //a = data[i + 3]; + //if (a < aMin) { aMin = a; } else + //if (a > aMax) { aMax = a; } + } + + // If there is only 1 level - don't remap + if( rMax === rMin ){ rMax = 255; rMin = 0; } + if( gMax === gMin ){ gMax = 255; gMin = 0; } + if( bMax === bMin ){ bMax = 255; bMin = 0; } + + var rMid, rGoalMax, rGoalMin, + gMid, gGoalMax, gGoalMin, + bMid, bGoalMax, bGoalMin; + + // If the enhancement is positive - stretch the histogram + if ( enhanceAmount > 0 ){ + rGoalMax = rMax + enhanceAmount * (255 - rMax); + rGoalMin = rMin - enhanceAmount * (rMin - 0); + gGoalMax = gMax + enhanceAmount * (255 - gMax); + gGoalMin = gMin - enhanceAmount * (gMin - 0); + bGoalMax = bMax + enhanceAmount * (255 - bMax); + bGoalMin = bMin - enhanceAmount * (bMin - 0); + // If the enhancement is negative - compress the histogram + } else { + rMid = (rMax + rMin) * 0.5; + rGoalMax = rMax + enhanceAmount * (rMax - rMid); + rGoalMin = rMin + enhanceAmount * (rMin - rMid); + gMid = (gMax + gMin) * 0.5; + gGoalMax = gMax + enhanceAmount * (gMax - gMid); + gGoalMin = gMin + enhanceAmount * (gMin - gMid); + bMid = (bMax + bMin) * 0.5; + bGoalMax = bMax + enhanceAmount * (bMax - bMid); + bGoalMin = bMin + enhanceAmount * (bMin - bMid); + } + + // Pass 2 - remap everything, except the alpha + for (i = 0; i < nSubPixels; i += 4) { + data[i + 0] = remap(data[i + 0], rMin, rMax, rGoalMin, rGoalMax); + data[i + 1] = remap(data[i + 1], gMin, gMax, gGoalMin, gGoalMax); + data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax); + //data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'enhance', 0, null, Konva.Factory.afterSetFilter); + + /** + * get/set enhance. Use with {@link Konva.Filters.Enhance} filter. + * @name enhance + * @method + * @memberof Konva.Node.prototype + * @param {Float} amount + * @returns {Float} + */ +})(); + +(function () { + 'use strict'; + /** + * Posterize Filter. Adjusts the channels so that there are no more + * than n different values for that channel. This is also applied + * to the alpha channel. + * @function + * @name Posterize + * @author ippo615 + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Posterize]); + * node.levels(0.8); + */ + + Konva.Filters.Posterize = function (imageData) { + // level must be between 1 and 255 + var levels = Math.round(this.levels() * 254) + 1, + data = imageData.data, + len = data.length, + scale = (255 / levels), + i; + + for (i = 0; i < len; i += 1) { + data[i] = Math.floor(data[i] / scale) * scale; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'levels', 0.5, null, Konva.Factory.afterSetFilter); + + /** + * get/set levels. Must be a number between 0 and 1. Use with {@link Konva.Filters.Posterize} filter. + * @name levels + * @method + * @memberof Konva.Node.prototype + * @param {Number} level between 0 and 1 + * @returns {Number} + */ +})(); + +(function () { + 'use strict'; + + /** + * Noise Filter. Randomly adds or substracts to the color channels + * @function + * @name Noise + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Noise]); + * node.noise(0.8); + */ + Konva.Filters.Noise = function (imageData) { + var amount = this.noise() * 255, + data = imageData.data, + nPixels = data.length, + half = amount / 2, + i; + + for (i = 0; i < nPixels; i += 4) { + data[i + 0] += half - 2 * half * Math.random(); + data[i + 1] += half - 2 * half * Math.random(); + data[i + 2] += half - 2 * half * Math.random(); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'noise', 0.2, null, Konva.Factory.afterSetFilter); + + /** + * get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter. + * @name noise + * @method + * @memberof Konva.Node.prototype + * @param {Number} noise + * @returns {Number} + */ +})(); + +/*eslint-disable max-depth */ +(function () { + 'use strict'; + /** + * Pixelate Filter. Averages groups of pixels and redraws + * them as larger pixels + * @function + * @name Pixelate + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Pixelate]); + * node.pixelSize(10); + */ + + Konva.Filters.Pixelate = function (imageData) { + + var pixelSize = Math.ceil(this.pixelSize()), + width = imageData.width, + height = imageData.height, + x, y, i, + //pixelsPerBin = pixelSize * pixelSize, + red, green, blue, alpha, + nBinsX = Math.ceil(width / pixelSize), + nBinsY = Math.ceil(height / pixelSize), + xBinStart, xBinEnd, yBinStart, yBinEnd, + xBin, yBin, pixelsInBin; + imageData = imageData.data; + + for (xBin = 0; xBin < nBinsX; xBin += 1) { + for (yBin = 0; yBin < nBinsY; yBin += 1) { + + // Initialize the color accumlators to 0 + red = 0; + green = 0; + blue = 0; + alpha = 0; + + // Determine which pixels are included in this bin + xBinStart = xBin * pixelSize; + xBinEnd = xBinStart + pixelSize; + yBinStart = yBin * pixelSize; + yBinEnd = yBinStart + pixelSize; + + // Add all of the pixels to this bin! + pixelsInBin = 0; + for (x = xBinStart; x < xBinEnd; x += 1) { + if( x >= width ){ continue; } + for (y = yBinStart; y < yBinEnd; y += 1) { + if( y >= height ){ continue; } + i = (width * y + x) * 4; + red += imageData[i + 0]; + green += imageData[i + 1]; + blue += imageData[i + 2]; + alpha += imageData[i + 3]; + pixelsInBin += 1; + } + } + + // Make sure the channels are between 0-255 + red = red / pixelsInBin; + green = green / pixelsInBin; + blue = blue / pixelsInBin; + + // Draw this bin + for (x = xBinStart; x < xBinEnd; x += 1) { + if( x >= width ){ continue; } + for (y = yBinStart; y < yBinEnd; y += 1) { + if( y >= height ){ continue; } + i = (width * y + x) * 4; + imageData[i + 0] = red; + imageData[i + 1] = green; + imageData[i + 2] = blue; + imageData[i + 3] = alpha; + } + } + } + } + + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'pixelSize', 8, null, Konva.Factory.afterSetFilter); + + /** + * get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter. + * @name pixelSize + * @method + * @memberof Konva.Node.prototype + * @param {Integer} pixelSize + * @returns {Integer} + */ +})(); + +(function () { + 'use strict'; + /** + * Threshold Filter. Pushes any value above the mid point to + * the max and any value below the mid point to the min. + * This affects the alpha channel. + * @function + * @name Threshold + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Threshold]); + * node.threshold(0.1); + */ + + Konva.Filters.Threshold = function (imageData) { + var level = this.threshold() * 255, + data = imageData.data, + len = data.length, + i; + + for (i = 0; i < len; i += 1) { + data[i] = data[i] < level ? 0 : 255; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'threshold', 0.5, null, Konva.Factory.afterSetFilter); + + /** + * get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter. + * @name threshold + * @method + * @memberof Konva.Node.prototype + * @param {Number} threshold + * @returns {Number} + */ +})(); + +(function() { + 'use strict'; + /** + * Sepia Filter + * Based on: Pixastic Lib - Sepia filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * @function + * @name Sepia + * @memberof Konva.Filters + * @param {Object} imageData + * @author Jacob Seidelin + * @license MPL v1.1 [http://www.pixastic.com/lib/license.txt] + * @example + * node.cache(); + * node.filters([Konva.Filters.Sepia]); + */ + Konva.Filters.Sepia = function (imageData) { + var data = imageData.data, + w = imageData.width, + y = imageData.height, + w4 = w * 4, + offsetY, x, offset, or, og, ob, r, g, b; + + do { + offsetY = (y - 1) * w4; + x = w; + do { + offset = offsetY + (x - 1) * 4; + + or = data[offset]; + og = data[offset + 1]; + ob = data[offset + 2]; + + r = or * 0.393 + og * 0.769 + ob * 0.189; + g = or * 0.349 + og * 0.686 + ob * 0.168; + b = or * 0.272 + og * 0.534 + ob * 0.131; + + data[offset] = r > 255 ? 255 : r; + data[offset + 1] = g > 255 ? 255 : g; + data[offset + 2] = b > 255 ? 255 : b; + data[offset + 3] = data[offset + 3]; + } while (--x); + } while (--y); + }; +})(); + +(function () { + 'use strict'; + /** + * Solarize Filter + * Pixastic Lib - Solarize filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * License: [http://www.pixastic.com/lib/license.txt] + * @function + * @name Solarize + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Solarize]); + */ + Konva.Filters.Solarize = function (imageData) { + var data = imageData.data, + w = imageData.width, + h = imageData.height, + w4 = w * 4, + y = h; + + do { + var offsetY = (y - 1) * w4; + var x = w; + do { + var offset = offsetY + (x - 1) * 4; + var r = data[offset]; + var g = data[offset + 1]; + var b = data[offset + 2]; + + if (r > 127) { + r = 255 - r; + } + if (g > 127) { + g = 255 - g; + } + if (b > 127) { + b = 255 - b; + } + + data[offset] = r; + data[offset + 1] = g; + data[offset + 2] = b; + } while (--x); + } while (--y); + }; +})(); + + + +(function () { + 'use strict'; + + /* + * ToPolar Filter. Converts image data to polar coordinates. Performs + * w*h*4 pixel reads and w*h pixel writes. The r axis is placed along + * what would be the y axis and the theta axis along the x axis. + * @function + * @author ippo615 + * @memberof Konva.Filters + * @param {ImageData} src, the source image data (what will be transformed) + * @param {ImageData} dst, the destination image data (where it will be saved) + * @param {Object} opt + * @param {Number} [opt.polarCenterX] horizontal location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarCenterY] vertical location for the center of the circle, + * default is in the middle + */ + + var ToPolar = function(src, dst, opt){ + + var srcPixels = src.data, + dstPixels = dst.data, + xSize = src.width, + ySize = src.height, + xMid = opt.polarCenterX || xSize / 2, + yMid = opt.polarCenterY || ySize / 2, + i, x, y, r = 0, g = 0, b = 0, a = 0; + + // Find the largest radius + var rad, rMax = Math.sqrt( xMid * xMid + yMid * yMid ); + x = xSize - xMid; + y = ySize - yMid; + rad = Math.sqrt( x * x + y * y ); + rMax = (rad > rMax) ? rad : rMax; + + // We'll be uisng y as the radius, and x as the angle (theta=t) + var rSize = ySize, + tSize = xSize, + radius, theta; + + // We want to cover all angles (0-360) and we need to convert to + // radians (*PI/180) + var conversion = 360 / tSize * Math.PI / 180, sin, cos; + + // var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale; + + for( theta = 0; theta < tSize; theta += 1 ){ + sin = Math.sin(theta * conversion); + cos = Math.cos(theta * conversion); + for( radius = 0; radius < rSize; radius += 1 ){ + x = Math.floor(xMid + rMax * radius / rSize * cos); + y = Math.floor(yMid + rMax * radius / rSize * sin); + i = (y * xSize + x) * 4; + r = srcPixels[i + 0]; + g = srcPixels[i + 1]; + b = srcPixels[i + 2]; + a = srcPixels[i + 3]; + + // Store it + //i = (theta * xSize + radius) * 4; + i = (theta + radius * xSize) * 4; + dstPixels[i + 0] = r; + dstPixels[i + 1] = g; + dstPixels[i + 2] = b; + dstPixels[i + 3] = a; + + } + } + }; + + /* + * FromPolar Filter. Converts image data from polar coordinates back to rectangular. + * Performs w*h*4 pixel reads and w*h pixel writes. + * @function + * @author ippo615 + * @memberof Konva.Filters + * @param {ImageData} src, the source image data (what will be transformed) + * @param {ImageData} dst, the destination image data (where it will be saved) + * @param {Object} opt + * @param {Number} [opt.polarCenterX] horizontal location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarCenterY] vertical location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarRotation] amount to rotate the image counterclockwis, + * 0 is no rotation, 360 degrees is a full rotation + */ + + var FromPolar = function(src, dst, opt){ + + var srcPixels = src.data, + dstPixels = dst.data, + xSize = src.width, + ySize = src.height, + xMid = opt.polarCenterX || xSize / 2, + yMid = opt.polarCenterY || ySize / 2, + i, x, y, dx, dy, r = 0, g = 0, b = 0, a = 0; + + + // Find the largest radius + var rad, rMax = Math.sqrt( xMid * xMid + yMid * yMid ); + x = xSize - xMid; + y = ySize - yMid; + rad = Math.sqrt( x * x + y * y ); + rMax = (rad > rMax) ? rad : rMax; + + // We'll be uisng x as the radius, and y as the angle (theta=t) + var rSize = ySize, + tSize = xSize, + radius, theta, + phaseShift = opt.polarRotation || 0; + + // We need to convert to degrees and we need to make sure + // it's between (0-360) + // var conversion = tSize/360*180/Math.PI; + //var conversion = tSize/360*180/Math.PI; + + var x1, y1; + + for( x = 0; x < xSize; x += 1 ){ + for( y = 0; y < ySize; y += 1 ){ + dx = x - xMid; + dy = y - yMid; + radius = Math.sqrt(dx * dx + dy * dy) * rSize / rMax; + theta = (Math.atan2(dy, dx) * 180 / Math.PI + 360 + phaseShift) % 360; + theta = theta * tSize / 360; + x1 = Math.floor(theta); + y1 = Math.floor(radius); + i = (y1 * xSize + x1) * 4; + r = srcPixels[i + 0]; + g = srcPixels[i + 1]; + b = srcPixels[i + 2]; + a = srcPixels[i + 3]; + + // Store it + i = (y * xSize + x) * 4; + dstPixels[i + 0] = r; + dstPixels[i + 1] = g; + dstPixels[i + 2] = b; + dstPixels[i + 3] = a; + } + } + + }; + + //Konva.Filters.ToPolar = Konva.Util._FilterWrapDoubleBuffer(ToPolar); + //Konva.Filters.FromPolar = Konva.Util._FilterWrapDoubleBuffer(FromPolar); + + // create a temporary canvas for working - shared between multiple calls + var tempCanvas = Konva.Util.createCanvasElement(); + + /* + * Kaleidoscope Filter. + * @function + * @name Kaleidoscope + * @author ippo615 + * @memberof Konva.Filters + * @example + * node.cache(); + * node.filters([Konva.Filters.Kaleidoscope]); + * node.kaleidoscopePower(3); + * node.kaleidoscopeAngle(45); + */ + Konva.Filters.Kaleidoscope = function(imageData){ + var xSize = imageData.width, + ySize = imageData.height; + + var x, y, xoff, i, r, g, b, a, srcPos, dstPos; + var power = Math.round( this.kaleidoscopePower() ); + var angle = Math.round( this.kaleidoscopeAngle() ); + var offset = Math.floor(xSize * (angle % 360) / 360); + + if( power < 1 ){return; } + + // Work with our shared buffer canvas + tempCanvas.width = xSize; + tempCanvas.height = ySize; + var scratchData = tempCanvas.getContext('2d').getImageData(0, 0, xSize, ySize); + + // Convert thhe original to polar coordinates + ToPolar( imageData, scratchData, { + polarCenterX: xSize / 2, + polarCenterY: ySize / 2 + }); + + // Determine how big each section will be, if it's too small + // make it bigger + var minSectionSize = xSize / Math.pow(2, power); + while( minSectionSize <= 8){ + minSectionSize = minSectionSize * 2; + power -= 1; + } + minSectionSize = Math.ceil(minSectionSize); + var sectionSize = minSectionSize; + + // Copy the offset region to 0 + // Depending on the size of filter and location of the offset we may need + // to copy the section backwards to prevent it from rewriting itself + var xStart = 0, + xEnd = sectionSize, + xDelta = 1; + if( offset + minSectionSize > xSize ){ + xStart = sectionSize; + xEnd = 0; + xDelta = -1; + } + for( y = 0; y < ySize; y += 1 ){ + for( x = xStart; x !== xEnd; x += xDelta ){ + xoff = Math.round(x + offset) % xSize; + srcPos = (xSize * y + xoff) * 4; + r = scratchData.data[srcPos + 0]; + g = scratchData.data[srcPos + 1]; + b = scratchData.data[srcPos + 2]; + a = scratchData.data[srcPos + 3]; + dstPos = (xSize * y + x) * 4; + scratchData.data[dstPos + 0] = r; + scratchData.data[dstPos + 1] = g; + scratchData.data[dstPos + 2] = b; + scratchData.data[dstPos + 3] = a; + } + } + + // Perform the actual effect + for( y = 0; y < ySize; y += 1 ){ + sectionSize = Math.floor( minSectionSize ); + for( i = 0; i < power; i += 1 ){ + for( x = 0; x < sectionSize + 1; x += 1 ){ + srcPos = (xSize * y + x) * 4; + r = scratchData.data[srcPos + 0]; + g = scratchData.data[srcPos + 1]; + b = scratchData.data[srcPos + 2]; + a = scratchData.data[srcPos + 3]; + dstPos = (xSize * y + sectionSize * 2 - x - 1) * 4; + scratchData.data[dstPos + 0] = r; + scratchData.data[dstPos + 1] = g; + scratchData.data[dstPos + 2] = b; + scratchData.data[dstPos + 3] = a; + } + sectionSize *= 2; + } + } + + // Convert back from polar coordinates + FromPolar(scratchData, imageData, {polarRotation: 0}); + }; + + /** + * get/set kaleidoscope power. Use with {@link Konva.Filters.Kaleidoscope} filter. + * @name kaleidoscopePower + * @method + * @memberof Konva.Node.prototype + * @param {Integer} power of kaleidoscope + * @returns {Integer} + */ + Konva.Factory.addGetterSetter(Konva.Node, 'kaleidoscopePower', 2, null, Konva.Factory.afterSetFilter); + + /** + * get/set kaleidoscope angle. Use with {@link Konva.Filters.Kaleidoscope} filter. + * @name kaleidoscopeAngle + * @method + * @memberof Konva.Node.prototype + * @param {Integer} degrees + * @returns {Integer} + */ + Konva.Factory.addGetterSetter(Konva.Node, 'kaleidoscopeAngle', 0, null, Konva.Factory.afterSetFilter); + +})(); + +(function() { + 'use strict'; + /** + * Container constructor.  Containers are used to contain nodes or other containers + * @constructor + * @memberof Konva + * @augments Konva.Node + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + */ + Konva.Container = function(config) { + this.__init(config); + }; + + Konva.Util.addMethods(Konva.Container, { + __init: function(config) { + this.children = new Konva.Collection(); + Konva.Node.call(this, config); + }, + /** + * returns a {@link Konva.Collection} of direct descendant nodes + * @method + * @memberof Konva.Container.prototype + * @param {Function} [filterFunc] filter function + * @returns {Konva.Collection} + * @example + * // get all children + * var children = layer.getChildren(); + * + * // get only circles + * var circles = layer.getChildren(function(node){ + * return node.getClassName() === 'Circle'; + * }); + */ + getChildren: function(filterFunc) { + if (!filterFunc) { + return this.children; + } + + var results = new Konva.Collection(); + this.children.each(function(child){ + if (filterFunc(child)) { + results.push(child); + } + }); + return results; + }, + /** + * determine if node has children + * @method + * @memberof Konva.Container.prototype + * @returns {Boolean} + */ + hasChildren: function() { + return this.getChildren().length > 0; + }, + /** + * remove all children + * @method + * @memberof Konva.Container.prototype + */ + removeChildren: function() { + var children = Konva.Collection.toCollection(this.children); + var child; + for (var i = 0; i < children.length; i++) { + child = children[i]; + // reset parent to prevent many _setChildrenIndices calls + delete child.parent; + child.index = 0; + child.remove(); + } + children = null; + this.children = new Konva.Collection(); + return this; + }, + /** + * destroy all children + * @method + * @memberof Konva.Container.prototype + */ + destroyChildren: function() { + var children = Konva.Collection.toCollection(this.children); + var child; + for (var i = 0; i < children.length; i++) { + child = children[i]; + // reset parent to prevent many _setChildrenIndices calls + delete child.parent; + child.index = 0; + child.destroy(); + } + children = null; + this.children = new Konva.Collection(); + return this; + }, + /** + * Add node or nodes to container. + * @method + * @memberof Konva.Container.prototype + * @param {...Konva.Node} child + * @returns {Container} + * @example + * layer.add(shape1, shape2, shape3); + */ + add: function(child) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.add(arguments[i]); + } + return this; + } + if (child.getParent()) { + child.moveTo(this); + return this; + } + var children = this.children; + this._validateAdd(child); + child.index = children.length; + child.parent = this; + children.push(child); + this._fire('add', { + child: child + }); + + // if node under drag we need to update drag animation + if (Konva.DD && child.isDragging()) { + Konva.DD.anim.setLayers(child.getLayer()); + } + + // chainable + return this; + }, + destroy: function() { + // destroy children + if (this.hasChildren()) { + this.destroyChildren(); + } + // then destroy self + Konva.Node.prototype.destroy.call(this); + return this; + }, + /** + * return a {@link Konva.Collection} of nodes that match the selector. Use '#' for id selections + * and '.' for name selections. You can also select by type or class name. Pass multiple selectors + * separated by a space. + * @method + * @memberof Konva.Container.prototype + * @param {String} selector + * @returns {Collection} + * @example + * // select node with id foo + * var node = stage.find('#foo'); + * + * // select nodes with name bar inside layer + * var nodes = layer.find('.bar'); + * + * // select all groups inside layer + * var nodes = layer.find('Group'); + * + * // select all rectangles inside layer + * var nodes = layer.find('Rect'); + * + * // select node with an id of foo or a name of bar inside layer + * var nodes = layer.find('#foo, .bar'); + */ + find: function(selector) { + var retArr = [], + selectorArr = selector.replace(/ /g, '').split(','), + len = selectorArr.length, + n, i, sel, arr, node, children, clen; + + for (n = 0; n < len; n++) { + sel = selectorArr[n]; + if (!Konva.Util.isValidSelector(sel)) { + Konva.Util.warn('Selector "' + sel + '" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".'); + Konva.Util.warn('If you have a custom shape with such className, please change it to start with upper letter like "Triangle".'); + Konva.Util.warn('Konva is awesome, right?'); + } + // id selector + if(sel.charAt(0) === '#') { + node = this._getNodeById(sel.slice(1)); + if(node) { + retArr.push(node); + } + } + // name selector + else if(sel.charAt(0) === '.') { + arr = this._getNodesByName(sel.slice(1)); + retArr = retArr.concat(arr); + } + // unrecognized selector, pass to children + else { + children = this.getChildren(); + clen = children.length; + for(i = 0; i < clen; i++) { + retArr = retArr.concat(children[i]._get(sel)); + } + } + } + + return Konva.Collection.toCollection(retArr); + }, + /** + * return a first node from `find` method + * @method + * @memberof Konva.Container.prototype + * @param {String} selector + * @returns {Konva.Node} + * @example + * // select node with id foo + * var node = stage.findOne('#foo'); + * + * // select node with name bar inside layer + * var nodes = layer.findOne('.bar'); + */ + findOne: function(selector) { + return this.find(selector)[0]; + }, + _getNodeById: function(key) { + var node = Konva.ids[key]; + + if(node !== undefined && this.isAncestorOf(node)) { + return node; + } + return null; + }, + _getNodesByName: function(key) { + var arr = Konva.names[key] || []; + return this._getDescendants(arr); + }, + _get: function(selector) { + var retArr = Konva.Node.prototype._get.call(this, selector); + var children = this.getChildren(); + var len = children.length; + for(var n = 0; n < len; n++) { + retArr = retArr.concat(children[n]._get(selector)); + } + return retArr; + }, + // extenders + toObject: function() { + var obj = Konva.Node.prototype.toObject.call(this); + + obj.children = []; + + var children = this.getChildren(); + var len = children.length; + for(var n = 0; n < len; n++) { + var child = children[n]; + obj.children.push(child.toObject()); + } + + return obj; + }, + _getDescendants: function(arr) { + var retArr = []; + var len = arr.length; + for(var n = 0; n < len; n++) { + var node = arr[n]; + if(this.isAncestorOf(node)) { + retArr.push(node); + } + } + + return retArr; + }, + /** + * determine if node is an ancestor + * of descendant + * @method + * @memberof Konva.Container.prototype + * @param {Konva.Node} node + */ + isAncestorOf: function(node) { + var parent = node.getParent(); + while(parent) { + if(parent._id === this._id) { + return true; + } + parent = parent.getParent(); + } + + return false; + }, + clone: function(obj) { + // call super method + var node = Konva.Node.prototype.clone.call(this, obj); + + this.getChildren().each(function(no) { + node.add(no.clone()); + }); + return node; + }, + /** + * get all shapes that intersect a point. Note: because this method must clear a temporary + * canvas and redraw every shape inside the container, it should only be used for special sitations + * because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible + * because it performs much better + * @method + * @memberof Konva.Container.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Array} array of shapes + */ + getAllIntersections: function(pos) { + var arr = []; + + this.find('Shape').each(function(shape) { + if(shape.isVisible() && shape.intersects(pos)) { + arr.push(shape); + } + }); + + return arr; + }, + _setChildrenIndices: function() { + this.children.each(function(child, n) { + child.index = n; + }); + }, + drawScene: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()), + context = canvas && canvas.getContext(), + cachedCanvas = this._cache.canvas, + cachedSceneCanvas = cachedCanvas && cachedCanvas.scene; + + if (this.isVisible()) { + if (!caching && cachedSceneCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedSceneCanvas(context); + context.restore(); + } + else { + this._drawChildren(canvas, 'drawScene', top, false, caching); + } + } + return this; + }, + drawHit: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || (layer && layer.hitCanvas), + context = canvas && canvas.getContext(), + cachedCanvas = this._cache.canvas, + cachedHitCanvas = cachedCanvas && cachedCanvas.hit; + + if (this.shouldDrawHit(canvas)) { + if (layer) { + layer.clearHitCache(); + } + if (!caching && cachedHitCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedHitCanvas(context); + context.restore(); + } + else { + this._drawChildren(canvas, 'drawHit', top); + } + } + return this; + }, + _drawChildren: function(canvas, drawMethod, top, caching, skipBuffer) { + var layer = this.getLayer(), + context = canvas && canvas.getContext(), + clipWidth = this.getClipWidth(), + clipHeight = this.getClipHeight(), + clipFunc = this.getClipFunc(), + hasClip = clipWidth && clipHeight || clipFunc, + clipX, clipY; + + if (hasClip && layer) { + context.save(); + layer._applyTransform(this, context); + context.beginPath(); + if (clipFunc) { + clipFunc.call(this, context, this); + } else { + clipX = this.getClipX(); + clipY = this.getClipY(); + context.rect(clipX, clipY, clipWidth, clipHeight); + } + context.clip(); + context.reset(); + } + + this.children.each(function(child) { + child[drawMethod](canvas, top, caching, skipBuffer); + }); + + if (hasClip) { + context.restore(); + } + }, + shouldDrawHit: function(canvas) { + var layer = this.getLayer(); + var dd = Konva.DD; + var layerUnderDrag = dd && Konva.isDragging() && (Konva.DD.anim.getLayers().indexOf(layer) !== -1); + return (canvas && canvas.isCache) || (layer && layer.hitGraphEnabled()) + && this.isVisible() && !layerUnderDrag; + }, + getClientRect: function(skipTransform) { + var minX, minY, maxX, maxY; + var selfRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + this.children.each(function(child) { + var rect = child.getClientRect(); + + // skip invisible children (like empty groups) + // or don't skip... hmmm... + // if (rect.width === 0 && rect.height === 0) { + // return; + // } + + if (minX === undefined) { // initial value for first child + minX = rect.x; + minY = rect.y; + maxX = rect.x + rect.width; + maxY = rect.y + rect.height; + } else { + minX = Math.min(minX, rect.x); + minY = Math.min(minY, rect.y); + maxX = Math.max(maxX, rect.x + rect.width); + maxY = Math.max(maxY, rect.y + rect.height); + } + + }); + + if (this.children.length !== 0) { + selfRect = { + x: minX, + y: minY, + width: maxX - minX, + height: maxY - minY + }; + } + + if (!skipTransform) { + return this._transformedRect(selfRect); + } + return selfRect; + } + }); + + Konva.Util.extend(Konva.Container, Konva.Node); + // deprecated methods + Konva.Container.prototype.get = Konva.Container.prototype.find; + + // add getters setters + Konva.Factory.addComponentsGetterSetter(Konva.Container, 'clip', ['x', 'y', 'width', 'height']); + /** + * get/set clip + * @method + * @name clip + * @memberof Konva.Container.prototype + * @param {Object} clip + * @param {Number} clip.x + * @param {Number} clip.y + * @param {Number} clip.width + * @param {Number} clip.height + * @returns {Object} + * @example + * // get clip + * var clip = container.clip(); + * + * // set clip + * container.setClip({ + * x: 20, + * y: 20, + * width: 20, + * height: 20 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipX'); + /** + * get/set clip x + * @name clipX + * @method + * @memberof Konva.Container.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get clip x + * var clipX = container.clipX(); + * + * // set clip x + * container.clipX(10); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipY'); + /** + * get/set clip y + * @name clipY + * @method + * @memberof Konva.Container.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get clip y + * var clipY = container.clipY(); + * + * // set clip y + * container.clipY(10); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipWidth'); + /** + * get/set clip width + * @name clipWidth + * @method + * @memberof Konva.Container.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get clip width + * var clipWidth = container.clipWidth(); + * + * // set clip width + * container.clipWidth(100); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipHeight'); + /** + * get/set clip height + * @name clipHeight + * @method + * @memberof Konva.Container.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get clip height + * var clipHeight = container.clipHeight(); + * + * // set clip height + * container.clipHeight(100); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipFunc'); + /** + * get/set clip function + * @name clipFunc + * @method + * @memberof Konva.Container.prototype + * @param {Function} function + * @returns {Function} + * @example + * // get clip function + * var clipFunction = container.clipFunc(); + * + * // set clip height + * container.clipFunc(function(ctx) { + * ctx.rect(0, 0, 100, 100); + * }); + */ + + Konva.Collection.mapMethods(Konva.Container); +})(); + +(function(Konva) { + 'use strict'; + var HAS_SHADOW = 'hasShadow'; + var SHADOW_RGBA = 'shadowRGBA'; + + function _fillFunc(context) { + context.fill(); + } + function _strokeFunc(context) { + context.stroke(); + } + function _fillFuncHit(context) { + context.fill(); + } + function _strokeFuncHit(context) { + context.stroke(); + } + + function _clearHasShadowCache() { + this._clearCache(HAS_SHADOW); + } + + function _clearGetShadowRGBACache() { + this._clearCache(SHADOW_RGBA); + } + + /** + * Shape constructor. Shapes are primitive objects such as rectangles, + * circles, text, lines, etc. + * @constructor + * @memberof Konva + * @augments Konva.Node + * @param {Object} config + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var customShape = new Konva.Shape({ + * x: 5, + * y: 10, + * fill: 'red', + * // a Konva.Canvas renderer is passed into the drawFunc function + * drawFunc: function(context) { + * context.beginPath(); + * context.moveTo(200, 50); + * context.lineTo(420, 80); + * context.quadraticCurveTo(300, 100, 260, 170); + * context.closePath(); + * context.fillStrokeShape(this); + * } + *}); + */ + Konva.Shape = function(config) { + this.__init(config); + }; + + Konva.Util.addMethods(Konva.Shape, { + __init: function(config) { + this.nodeType = 'Shape'; + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this._fillFuncHit = _fillFuncHit; + this._strokeFuncHit = _strokeFuncHit; + + // set colorKey + var shapes = Konva.shapes; + var key; + + while(true) { + key = Konva.Util.getRandomColor(); + if(key && !( key in shapes)) { + break; + } + } + + this.colorKey = key; + shapes[key] = this; + + // call super constructor + Konva.Node.call(this, config); + + this.on('shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearHasShadowCache); + + this.on('shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearGetShadowRGBACache); + }, + hasChildren: function() { + return false; + }, + getChildren: function() { + return []; + }, + /** + * get canvas context tied to the layer + * @method + * @memberof Konva.Shape.prototype + * @returns {Konva.Context} + */ + getContext: function() { + return this.getLayer().getContext(); + }, + /** + * get canvas renderer tied to the layer. Note that this returns a canvas renderer, not a canvas element + * @method + * @memberof Konva.Shape.prototype + * @returns {Konva.Canvas} + */ + getCanvas: function() { + return this.getLayer().getCanvas(); + }, + /** + * returns whether or not a shadow will be rendered + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasShadow: function() { + return this._getCache(HAS_SHADOW, this._hasShadow); + }, + _hasShadow: function() { + return this.getShadowEnabled() && (this.getShadowOpacity() !== 0 && !!(this.getShadowColor() || this.getShadowBlur() || this.getShadowOffsetX() || this.getShadowOffsetY())); + }, + getShadowRGBA: function() { + return this._getCache(SHADOW_RGBA, this._getShadowRGBA); + }, + _getShadowRGBA: function() { + if (this.hasShadow()) { + var rgba = Konva.Util.colorToRGBA(this.shadowColor()); + return 'rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + (rgba.a * (this.getShadowOpacity() || 1)) + ')'; + } + }, + /** + * returns whether or not the shape will be filled + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasFill: function() { + return !!(this.getFill() || this.getFillPatternImage() || this.getFillLinearGradientColorStops() || this.getFillRadialGradientColorStops()); + }, + /** + * returns whether or not the shape will be stroked + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasStroke: function() { + return !!(this.stroke()); + }, + /** + * determines if point is in the shape, regardless if other shapes are on top of it. Note: because + * this method clears a temporary canvas and then redraws the shape, it performs very poorly if executed many times + * consecutively. Please use the {@link Konva.Stage#getIntersection} method if at all possible + * because it performs much better + * @method + * @memberof Konva.Shape.prototype + * @param {Object} point + * @param {Number} point.x + * @param {Number} point.y + * @returns {Boolean} + */ + intersects: function(point) { + var stage = this.getStage(), + bufferHitCanvas = stage.bufferHitCanvas, + p; + + bufferHitCanvas.getContext().clear(); + this.drawScene(bufferHitCanvas); + p = bufferHitCanvas.context.getImageData(Math.round(point.x), Math.round(point.y), 1, 1).data; + return p[3] > 0; + }, + // extends Node.prototype.destroy + destroy: function() { + Konva.Node.prototype.destroy.call(this); + delete Konva.shapes[this.colorKey]; + return this; + }, + _useBufferCanvas: function(caching) { + return !caching && (this.perfectDrawEnabled() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()) || + (this.perfectDrawEnabled() && this.hasShadow() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()); + }, + /** + * return self rectangle (x, y, width, height) of shape. + * This method are not taken into account transformation and styles. + * @method + * @memberof Konva.Node.prototype + * @returns {Object} rect with {x, y, width, height} properties + * @example + * + * rect.getSelfRect(); // return {x:0, y:0, width:rect.width(), height:rect.height()} + * circle.getSelfRect(); // return {x: - circle.width() / 2, y: - circle.height() / 2, width:circle.width(), height:circle.height()} + * + */ + getSelfRect: function() { + var size = this.getSize(); + return { + x: this._centroid ? Math.round(-size.width / 2) : 0, + y: this._centroid ? Math.round(-size.height / 2) : 0, + width: size.width, + height: size.height + }; + }, + getClientRect: function(skipTransform) { + var fillRect = this.getSelfRect(); + + var strokeWidth = (this.hasStroke() && this.strokeWidth()) || 0; + var fillAndStrokeWidth = fillRect.width + strokeWidth; + var fillAndStrokeHeight = fillRect.height + strokeWidth; + + var shadowOffsetX = this.shadowOffsetX(); + var shadowOffsetY = this.shadowOffsetY(); + + var preWidth = fillAndStrokeWidth + Math.abs(shadowOffsetX); + var preHeight = fillAndStrokeHeight + Math.abs(shadowOffsetY); + + var blurRadius = (this.hasShadow() && this.shadowBlur() || 0); + + var width = preWidth + blurRadius * 2; + var height = preHeight + blurRadius * 2; + + // if stroke, for example = 3 + // we need to set x to 1.5, but after Math.round it will be 2 + // as we have additional offset we need to increase width and height by 1 pixel + var roundingOffset = 0; + if (Math.round(strokeWidth / 2) !== strokeWidth / 2) { + roundingOffset = 1; + } + var rect = { + width: width + roundingOffset, + height: height + roundingOffset, + x: -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetX, 0) + fillRect.x, + y: -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetY, 0) + fillRect.y + }; + if (!skipTransform) { + return this._transformedRect(rect); + } + return rect; + }, + drawScene: function(can, top, caching, skipBuffer) { + var layer = this.getLayer(), + canvas = can || layer.getCanvas(), + context = canvas.getContext(), + cachedCanvas = this._cache.canvas, + drawFunc = this.sceneFunc(), + hasShadow = this.hasShadow(), + hasStroke = this.hasStroke(), + stage, bufferCanvas, bufferContext; + + if(!this.isVisible()) { + return this; + } + if (cachedCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedSceneCanvas(context); + context.restore(); + return this; + } + if (!drawFunc) { + return this; + } + context.save(); + // if buffer canvas is needed + if (this._useBufferCanvas(caching) && !skipBuffer) { + stage = this.getStage(); + bufferCanvas = stage.bufferCanvas; + bufferContext = bufferCanvas.getContext(); + bufferContext.clear(); + bufferContext.save(); + bufferContext._applyLineJoin(this); + // layer might be undefined if we are using cache before adding to layer + if (!caching) { + if (layer) { + layer._applyTransform(this, bufferContext, top); + } else { + var m = this.getAbsoluteTransform(top).getMatrix(); + context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + } + + drawFunc.call(this, bufferContext); + bufferContext.restore(); + + var ratio = bufferCanvas.pixelRatio; + if (hasShadow && !canvas.hitCanvas) { + context.save(); + context._applyShadow(this); + context._applyOpacity(this); + context.drawImage(bufferCanvas._canvas, 0, 0, bufferCanvas.width / ratio, bufferCanvas.height / ratio); + context.restore(); + } else { + context._applyOpacity(this); + context.drawImage(bufferCanvas._canvas, 0, 0, bufferCanvas.width / ratio, bufferCanvas.height / ratio); + } + } + // if buffer canvas is not needed + else { + context._applyLineJoin(this); + // layer might be undefined if we are using cache before adding to layer + if (!caching) { + if (layer) { + layer._applyTransform(this, context, top); + } else { + var o = this.getAbsoluteTransform(top).getMatrix(); + context.transform(o[0], o[1], o[2], o[3], o[4], o[5]); + } + } + + if (hasShadow && hasStroke && !canvas.hitCanvas) { + context.save(); + // apply shadow + if (!caching) { + context._applyOpacity(this); + } + context._applyShadow(this); + drawFunc.call(this, context); + context.restore(); + // if shape has stroke we need to redraw shape + // otherwise we will see a shadow under stroke (and over fill) + // but I think this is unexpected behavior + if (this.hasFill() && this.getShadowForStrokeEnabled()) { + drawFunc.call(this, context); + } + } else if (hasShadow && !canvas.hitCanvas) { + context.save(); + if (!caching) { + context._applyOpacity(this); + } + context._applyShadow(this); + drawFunc.call(this, context); + context.restore(); + } else { + if (!caching) { + context._applyOpacity(this); + } + drawFunc.call(this, context); + } + } + context.restore(); + return this; + }, + drawHit: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || layer.hitCanvas, + context = canvas.getContext(), + drawFunc = this.hitFunc() || this.sceneFunc(), + cachedCanvas = this._cache.canvas, + cachedHitCanvas = cachedCanvas && cachedCanvas.hit; + + if(!this.shouldDrawHit(canvas)) { + return this; + } + if (layer) { + layer.clearHitCache(); + } + if (cachedHitCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedHitCanvas(context); + context.restore(); + return this; + } + if (!drawFunc) { + return this; + } + context.save(); + context._applyLineJoin(this); + if (!caching) { + if (layer) { + layer._applyTransform(this, context, top); + } else { + var o = this.getAbsoluteTransform(top).getMatrix(); + context.transform(o[0], o[1], o[2], o[3], o[4], o[5]); + } + } + drawFunc.call(this, context); + context.restore(); + return this; + }, + /** + * draw hit graph using the cached scene canvas + * @method + * @memberof Konva.Shape.prototype + * @param {Integer} alphaThreshold alpha channel threshold that determines whether or not + * a pixel should be drawn onto the hit graph. Must be a value between 0 and 255. + * The default is 0 + * @returns {Konva.Shape} + * @example + * shape.cache(); + * shape.drawHitFromCache(); + */ + drawHitFromCache: function(alphaThreshold) { + var threshold = alphaThreshold || 0, + cachedCanvas = this._cache.canvas, + sceneCanvas = this._getCachedSceneCanvas(), + hitCanvas = cachedCanvas.hit, + hitContext = hitCanvas.getContext(), + hitWidth = hitCanvas.getWidth(), + hitHeight = hitCanvas.getHeight(), + hitImageData, hitData, len, rgbColorKey, i, alpha; + + hitContext.clear(); + hitContext.drawImage(sceneCanvas._canvas, 0, 0, hitWidth, hitHeight); + + try { + hitImageData = hitContext.getImageData(0, 0, hitWidth, hitHeight); + hitData = hitImageData.data; + len = hitData.length; + rgbColorKey = Konva.Util._hexToRgb(this.colorKey); + + // replace non transparent pixels with color key + for(i = 0; i < len; i += 4) { + alpha = hitData[i + 3]; + if (alpha > threshold) { + hitData[i] = rgbColorKey.r; + hitData[i + 1] = rgbColorKey.g; + hitData[i + 2] = rgbColorKey.b; + hitData[i + 3] = 255; + } + else { + hitData[i + 3] = 0; + } + } + hitContext.putImageData(hitImageData, 0, 0); + } + catch(e) { + Konva.Util.error('Unable to draw hit graph from cached scene canvas. ' + e.message); + } + + return this; + } + }); + Konva.Util.extend(Konva.Shape, Konva.Node); + + // add getters and setters + Konva.Factory.addGetterSetter(Konva.Shape, 'stroke'); + + /** + * get/set stroke color + * @name stroke + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get stroke color + * var stroke = shape.stroke(); + * + * // set stroke color with color string + * shape.stroke('green'); + * + * // set stroke color with hex + * shape.stroke('#00ff00'); + * + * // set stroke color with rgb + * shape.stroke('rgb(0,255,0)'); + * + * // set stroke color with rgba and make it 50% opaque + * shape.stroke('rgba(0,255,0,0.5'); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeAlpha', 1, Konva.Validators.alphaComponent); + + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeWidth', 2); + + /** + * get/set stroke width + * @name strokeWidth + * @method + * @memberof Konva.Shape.prototype + * @param {Number} strokeWidth + * @returns {Number} + * @example + * // get stroke width + * var strokeWidth = shape.strokeWidth(); + * + * // set stroke width + * shape.strokeWidth(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeHitEnabled', true); + + /** + * get/set strokeHitEnabled property. Useful for performance optimization. + * You may set `shape.strokeHitEnabled(false)`. In this case stroke will be no draw on hit canvas, so hit area + * of shape will be decreased (by lineWidth / 2). Remember that non closed line with `strokeHitEnabled = false` + * will be not drawn on hit canvas, that is mean line will no trigger pointer events (like mouseover) + * Default value is true + * @name strokeHitEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} strokeHitEnabled + * @returns {Boolean} + * @example + * // get strokeHitEnabled + * var strokeHitEnabled = shape.strokeHitEnabled(); + * + * // set strokeHitEnabled + * shape.strokeHitEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'perfectDrawEnabled', true); + + /** + * get/set perfectDrawEnabled. If a shape has fill, stroke and opacity you may set `perfectDrawEnabled` to improve performance. + * See http://konvajs.github.io/docs/performance/Disable_Perfect_Draw.html for more information. + * Default value is true + * @name perfectDrawEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} perfectDrawEnabled + * @returns {Boolean} + * @example + * // get perfectDrawEnabled + * var perfectDrawEnabled = shape.perfectDrawEnabled(); + * + * // set perfectDrawEnabled + * shape.perfectDrawEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowForStrokeEnabled', true); + + /** + * get/set shadowForStrokeEnabled. Useful for performance optimization. + * You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will be no draw shadow for stroke. + * Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line with have no shadow!. + * Default value is true + * @name shadowForStrokeEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} shadowForStrokeEnabled + * @returns {Boolean} + * @example + * // get shadowForStrokeEnabled + * var shadowForStrokeEnabled = shape.shadowForStrokeEnabled(); + * + * // set shadowForStrokeEnabled + * shape.shadowForStrokeEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'lineJoin'); + + /** + * get/set line join. Can be miter, round, or bevel. The + * default is miter + * @name lineJoin + * @method + * @memberof Konva.Shape.prototype + * @param {String} lineJoin + * @returns {String} + * @example + * // get line join + * var lineJoin = shape.lineJoin(); + * + * // set line join + * shape.lineJoin('round'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'lineCap'); + + /** + * get/set line cap. Can be butt, round, or square + * @name lineCap + * @method + * @memberof Konva.Shape.prototype + * @param {String} lineCap + * @returns {String} + * @example + * // get line cap + * var lineCap = shape.lineCap(); + * + * // set line cap + * shape.lineCap('round'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'sceneFunc'); + + /** + * get/set scene draw function + * @name sceneFunc + * @method + * @memberof Konva.Shape.prototype + * @param {Function} drawFunc drawing function + * @returns {Function} + * @example + * // get scene draw function + * var sceneFunc = shape.sceneFunc(); + * + * // set scene draw function + * shape.sceneFunc(function(context) { + * context.beginPath(); + * context.rect(0, 0, this.width(), this.height()); + * context.closePath(); + * context.fillStrokeShape(this); + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'hitFunc'); + + /** + * get/set hit draw function + * @name hitFunc + * @method + * @memberof Konva.Shape.prototype + * @param {Function} drawFunc drawing function + * @returns {Function} + * @example + * // get hit draw function + * var hitFunc = shape.hitFunc(); + * + * // set hit draw function + * shape.hitFunc(function(context) { + * context.beginPath(); + * context.rect(0, 0, this.width(), this.height()); + * context.closePath(); + * context.fillStrokeShape(this); + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'dash'); + + /** + * get/set dash array for stroke. + * @name dash + * @method + * @memberof Konva.Shape.prototype + * @param {Array} dash + * @returns {Array} + * @example + * // apply dashed stroke that is 10px long and 5 pixels apart + * line.dash([10, 5]); + * // apply dashed stroke that is made up of alternating dashed + * // lines that are 10px long and 20px apart, and dots that have + * // a radius of 5px and are 20px apart + * line.dash([10, 20, 0.001, 20]); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowColor'); + + /** + * get/set shadow color + * @name shadowColor + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get shadow color + * var shadow = shape.shadowColor(); + * + * // set shadow color with color string + * shape.shadowColor('green'); + * + * // set shadow color with hex + * shape.shadowColor('#00ff00'); + * + * // set shadow color with rgb + * shape.shadowColor('rgb(0,255,0)'); + * + * // set shadow color with rgba and make it 50% opaque + * shape.shadowColor('rgba(0,255,0,0.5'); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowAlpha', 1, Konva.Validators.alphaComponent); + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowBlur'); + + /** + * get/set shadow blur + * @name shadowBlur + * @method + * @memberof Konva.Shape.prototype + * @param {Number} blur + * @returns {Number} + * @example + * // get shadow blur + * var shadowBlur = shape.shadowBlur(); + * + * // set shadow blur + * shape.shadowBlur(10); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOpacity'); + + /** + * get/set shadow opacity. must be a value between 0 and 1 + * @name shadowOpacity + * @method + * @memberof Konva.Shape.prototype + * @param {Number} opacity + * @returns {Number} + * @example + * // get shadow opacity + * var shadowOpacity = shape.shadowOpacity(); + * + * // set shadow opacity + * shape.shadowOpacity(0.5); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'shadowOffset', ['x', 'y']); + + /** + * get/set shadow offset + * @name shadowOffset + * @method + * @memberof Konva.Shape.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get shadow offset + * var shadowOffset = shape.shadowOffset(); + * + * // set shadow offset + * shape.shadowOffset({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOffsetX', 0); + + /** + * get/set shadow offset x + * @name shadowOffsetX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get shadow offset x + * var shadowOffsetX = shape.shadowOffsetX(); + * + * // set shadow offset x + * shape.shadowOffsetX(5); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOffsetY', 0); + + /** + * get/set shadow offset y + * @name shadowOffsetY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get shadow offset y + * var shadowOffsetY = shape.shadowOffsetY(); + * + * // set shadow offset y + * shape.shadowOffsetY(5); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternImage'); + + /** + * get/set fill pattern image + * @name fillPatternImage + * @method + * @memberof Konva.Shape.prototype + * @param {Image} image object + * @returns {Image} + * @example + * // get fill pattern image + * var fillPatternImage = shape.fillPatternImage(); + * + * // set fill pattern image + * var imageObj = new Image(); + * imageObj.onload = function() { + * shape.fillPatternImage(imageObj); + * }; + * imageObj.src = 'path/to/image/jpg'; + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fill'); + + /** + * get/set fill color + * @name fill + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get fill color + * var fill = shape.fill(); + * + * // set fill color with color string + * shape.fill('green'); + * + * // set fill color with hex + * shape.fill('#00ff00'); + * + * // set fill color with rgb + * shape.fill('rgb(0,255,0)'); + * + * // set fill color with rgba and make it 50% opaque + * shape.fill('rgba(0,255,0,0.5'); + * + * // shape without fill + * shape.fill(null); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillAlpha', 1, Konva.Validators.alphaComponent); + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternX', 0); + + /** + * get/set fill pattern x + * @name fillPatternX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern x + * var fillPatternX = shape.fillPatternX(); + * // set fill pattern x + * shape.fillPatternX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternY', 0); + + /** + * get/set fill pattern y + * @name fillPatternY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern y + * var fillPatternY = shape.fillPatternY(); + * // set fill pattern y + * shape.fillPatternY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientColorStops'); + + /** + * get/set fill linear gradient color stops + * @name fillLinearGradientColorStops + * @method + * @memberof Konva.Shape.prototype + * @param {Array} colorStops + * @returns {Array} colorStops + * @example + * // get fill linear gradient color stops + * var colorStops = shape.fillLinearGradientColorStops(); + * + * // create a linear gradient that starts with red, changes to blue + * // halfway through, and then changes to green + * shape.fillLinearGradientColorStops(0, 'red', 0.5, 'blue', 1, 'green'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartRadius', 0); + + /** + * get/set fill radial gradient start radius + * @name fillRadialGradientStartRadius + * @method + * @memberof Konva.Shape.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radial gradient start radius + * var startRadius = shape.fillRadialGradientStartRadius(); + * + * // set radial gradient start radius + * shape.fillRadialGradientStartRadius(0); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndRadius', 0); + + /** + * get/set fill radial gradient end radius + * @name fillRadialGradientEndRadius + * @method + * @memberof Konva.Shape.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radial gradient end radius + * var endRadius = shape.fillRadialGradientEndRadius(); + * + * // set radial gradient end radius + * shape.fillRadialGradientEndRadius(100); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientColorStops'); + + /** + * get/set fill radial gradient color stops + * @name fillRadialGradientColorStops + * @method + * @memberof Konva.Shape.prototype + * @param {Number} colorStops + * @returns {Array} + * @example + * // get fill radial gradient color stops + * var colorStops = shape.fillRadialGradientColorStops(); + * + * // create a radial gradient that starts with red, changes to blue + * // halfway through, and then changes to green + * shape.fillRadialGradientColorStops(0, 'red', 0.5, 'blue', 1, 'green'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternRepeat', 'repeat'); + + /** + * get/set fill pattern repeat. Can be 'repeat', 'repeat-x', 'repeat-y', or 'no-repeat'. The default is 'repeat' + * @name fillPatternRepeat + * @method + * @memberof Konva.Shape.prototype + * @param {String} repeat + * @returns {String} + * @example + * // get fill pattern repeat + * var repeat = shape.fillPatternRepeat(); + * + * // repeat pattern in x direction only + * shape.fillPatternRepeat('repeat-x'); + * + * // do not repeat the pattern + * shape.fillPatternRepeat('no repeat'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillEnabled', true); + + /** + * get/set fill enabled flag + * @name fillEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get fill enabled flag + * var fillEnabled = shape.fillEnabled(); + * + * // disable fill + * shape.fillEnabled(false); + * + * // enable fill + * shape.fillEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeEnabled', true); + + /** + * get/set stroke enabled flag + * @name strokeEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get stroke enabled flag + * var strokeEnabled = shape.strokeEnabled(); + * + * // disable stroke + * shape.strokeEnabled(false); + * + * // enable stroke + * shape.strokeEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowEnabled', true); + + /** + * get/set shadow enabled flag + * @name shadowEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get shadow enabled flag + * var shadowEnabled = shape.shadowEnabled(); + * + * // disable shadow + * shape.shadowEnabled(false); + * + * // enable shadow + * shape.shadowEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'dashEnabled', true); + + /** + * get/set dash enabled flag + * @name dashEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get dash enabled flag + * var dashEnabled = shape.dashEnabled(); + * + * // disable dash + * shape.dashEnabled(false); + * + * // enable dash + * shape.dashEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeScaleEnabled', true); + + /** + * get/set strokeScale enabled flag + * @name strokeScaleEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get stroke scale enabled flag + * var strokeScaleEnabled = shape.strokeScaleEnabled(); + * + * // disable stroke scale + * shape.strokeScaleEnabled(false); + * + * // enable stroke scale + * shape.strokeScaleEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPriority', 'color'); + + /** + * get/set fill priority. can be color, pattern, linear-gradient, or radial-gradient. The default is color. + * This is handy if you want to toggle between different fill types. + * @name fillPriority + * @method + * @memberof Konva.Shape.prototype + * @param {String} priority + * @returns {String} + * @example + * // get fill priority + * var fillPriority = shape.fillPriority(); + * + * // set fill priority + * shape.fillPriority('linear-gradient'); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillPatternOffset', ['x', 'y']); + + /** + * get/set fill pattern offset + * @name fillPatternOffset + * @method + * @memberof Konva.Shape.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get fill pattern offset + * var patternOffset = shape.fillPatternOffset(); + * + * // set fill pattern offset + * shape.fillPatternOffset({ + * x: 20 + * y: 10 + * }); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternOffsetX', 0); + /** + * get/set fill pattern offset x + * @name fillPatternOffsetX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern offset x + * var patternOffsetX = shape.fillPatternOffsetX(); + * + * // set fill pattern offset x + * shape.fillPatternOffsetX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternOffsetY', 0); + /** + * get/set fill pattern offset y + * @name fillPatternOffsetY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern offset y + * var patternOffsetY = shape.fillPatternOffsetY(); + * + * // set fill pattern offset y + * shape.fillPatternOffsetY(10); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillPatternScale', ['x', 'y']); + + /** + * get/set fill pattern scale + * @name fillPatternScale + * @method + * @memberof Konva.Shape.prototype + * @param {Object} scale + * @param {Number} scale.x + * @param {Number} scale.y + * @returns {Object} + * @example + * // get fill pattern scale + * var patternScale = shape.fillPatternScale(); + * + * // set fill pattern scale + * shape.fillPatternScale({ + * x: 2 + * y: 2 + * }); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternScaleX', 1); + /** + * get/set fill pattern scale x + * @name fillPatternScaleX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern scale x + * var patternScaleX = shape.fillPatternScaleX(); + * + * // set fill pattern scale x + * shape.fillPatternScaleX(2); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternScaleY', 1); + /** + * get/set fill pattern scale y + * @name fillPatternScaleY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern scale y + * var patternScaleY = shape.fillPatternScaleY(); + * + * // set fill pattern scale y + * shape.fillPatternScaleY(2); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillLinearGradientStartPoint', ['x', 'y']); + + /** + * get/set fill linear gradient start point + * @name fillLinearGradientStartPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} startPoint + * @param {Number} startPoint.x + * @param {Number} startPoint.y + * @returns {Object} + * @example + * // get fill linear gradient start point + * var startPoint = shape.fillLinearGradientStartPoint(); + * + * // set fill linear gradient start point + * shape.fillLinearGradientStartPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientStartPointX', 0); + /** + * get/set fill linear gradient start point x + * @name fillLinearGradientStartPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill linear gradient start point x + * var startPointX = shape.fillLinearGradientStartPointX(); + * + * // set fill linear gradient start point x + * shape.fillLinearGradientStartPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientStartPointY', 0); + /** + * get/set fill linear gradient start point y + * @name fillLinearGradientStartPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill linear gradient start point y + * var startPointY = shape.fillLinearGradientStartPointY(); + * + * // set fill linear gradient start point y + * shape.fillLinearGradientStartPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillLinearGradientEndPoint', ['x', 'y']); + + /** + * get/set fill linear gradient end point + * @name fillLinearGradientEndPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} endPoint + * @param {Number} endPoint.x + * @param {Number} endPoint.y + * @returns {Object} + * @example + * // get fill linear gradient end point + * var endPoint = shape.fillLinearGradientEndPoint(); + * + * // set fill linear gradient end point + * shape.fillLinearGradientEndPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientEndPointX', 0); + /** + * get/set fill linear gradient end point x + * @name fillLinearGradientEndPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill linear gradient end point x + * var endPointX = shape.fillLinearGradientEndPointX(); + * + * // set fill linear gradient end point x + * shape.fillLinearGradientEndPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientEndPointY', 0); + /** + * get/set fill linear gradient end point y + * @name fillLinearGradientEndPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill linear gradient end point y + * var endPointY = shape.fillLinearGradientEndPointY(); + * + * // set fill linear gradient end point y + * shape.fillLinearGradientEndPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillRadialGradientStartPoint', ['x', 'y']); + + /** + * get/set fill radial gradient start point + * @name fillRadialGradientStartPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} startPoint + * @param {Number} startPoint.x + * @param {Number} startPoint.y + * @returns {Object} + * @example + * // get fill radial gradient start point + * var startPoint = shape.fillRadialGradientStartPoint(); + * + * // set fill radial gradient start point + * shape.fillRadialGradientStartPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartPointX', 0); + /** + * get/set fill radial gradient start point x + * @name fillRadialGradientStartPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill radial gradient start point x + * var startPointX = shape.fillRadialGradientStartPointX(); + * + * // set fill radial gradient start point x + * shape.fillRadialGradientStartPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartPointY', 0); + /** + * get/set fill radial gradient start point y + * @name fillRadialGradientStartPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill radial gradient start point y + * var startPointY = shape.fillRadialGradientStartPointY(); + * + * // set fill radial gradient start point y + * shape.fillRadialGradientStartPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillRadialGradientEndPoint', ['x', 'y']); + + /** + * get/set fill radial gradient end point + * @name fillRadialGradientEndPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} endPoint + * @param {Number} endPoint.x + * @param {Number} endPoint.y + * @returns {Object} + * @example + * // get fill radial gradient end point + * var endPoint = shape.fillRadialGradientEndPoint(); + * + * // set fill radial gradient end point + * shape.fillRadialGradientEndPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndPointX', 0); + /** + * get/set fill radial gradient end point x + * @name fillRadialGradientEndPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill radial gradient end point x + * var endPointX = shape.fillRadialGradientEndPointX(); + * + * // set fill radial gradient end point x + * shape.fillRadialGradientEndPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndPointY', 0); + /** + * get/set fill radial gradient end point y + * @name fillRadialGradientEndPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill radial gradient end point y + * var endPointY = shape.fillRadialGradientEndPointY(); + * + * // set fill radial gradient end point y + * shape.fillRadialGradientEndPointY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternRotation', 0); + + /** + * get/set fill pattern rotation in degrees + * @name fillPatternRotation + * @method + * @memberof Konva.Shape.prototype + * @param {Number} rotation + * @returns {Konva.Shape} + * @example + * // get fill pattern rotation + * var patternRotation = shape.fillPatternRotation(); + * + * // set fill pattern rotation + * shape.fillPatternRotation(20); + */ + + + Konva.Factory.backCompat(Konva.Shape, { + dashArray: 'dash', + getDashArray: 'getDash', + setDashArray: 'getDash', + + drawFunc: 'sceneFunc', + getDrawFunc: 'getSceneFunc', + setDrawFunc: 'setSceneFunc', + + drawHitFunc: 'hitFunc', + getDrawHitFunc: 'getHitFunc', + setDrawHitFunc: 'setHitFunc' + }); + + Konva.Collection.mapMethods(Konva.Shape); +})(Konva); + +(function() { + 'use strict'; + // CONSTANTS + var STAGE = 'Stage', + STRING = 'string', + PX = 'px', + + MOUSEOUT = 'mouseout', + MOUSELEAVE = 'mouseleave', + MOUSEOVER = 'mouseover', + MOUSEENTER = 'mouseenter', + MOUSEMOVE = 'mousemove', + MOUSEDOWN = 'mousedown', + MOUSEUP = 'mouseup', + CLICK = 'click', + DBL_CLICK = 'dblclick', + TOUCHSTART = 'touchstart', + TOUCHEND = 'touchend', + TAP = 'tap', + DBL_TAP = 'dbltap', + TOUCHMOVE = 'touchmove', + DOMMOUSESCROLL = 'DOMMouseScroll', + MOUSEWHEEL = 'mousewheel', + WHEEL = 'wheel', + + CONTENT_MOUSEOUT = 'contentMouseout', + CONTENT_MOUSEOVER = 'contentMouseover', + CONTENT_MOUSEMOVE = 'contentMousemove', + CONTENT_MOUSEDOWN = 'contentMousedown', + CONTENT_MOUSEUP = 'contentMouseup', + CONTENT_CLICK = 'contentClick', + CONTENT_DBL_CLICK = 'contentDblclick', + CONTENT_TOUCHSTART = 'contentTouchstart', + CONTENT_TOUCHEND = 'contentTouchend', + CONTENT_DBL_TAP = 'contentDbltap', + CONTENT_TAP = 'contentTap', + CONTENT_TOUCHMOVE = 'contentTouchmove', + CONTENT_WHEEL = 'contentWheel', + + DIV = 'div', + RELATIVE = 'relative', + KONVA_CONTENT = 'konvajs-content', + SPACE = ' ', + UNDERSCORE = '_', + CONTAINER = 'container', + EMPTY_STRING = '', + EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER, DOMMOUSESCROLL, MOUSEWHEEL, WHEEL], + + // cached variables + eventsLength = EVENTS.length; + + function addEvent(ctx, eventName) { + ctx.content.addEventListener(eventName, function(evt) { + ctx[UNDERSCORE + eventName](evt); + }, false); + } + + /** + * Stage constructor. A stage is used to contain multiple layers + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {String|Element} config.container Container selector or DOM element + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var stage = new Konva.Stage({ + * width: 500, + * height: 800, + * container: 'containerId' // or "#containerId" or ".containerClass" + * }); + */ + Konva.Stage = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.Stage, { + ___init: function(config) { + this.nodeType = STAGE; + // call super constructor + Konva.Container.call(this, config); + this._id = Konva.idCounter++; + this._buildDOM(); + this._bindContentEvents(); + this._enableNestedTransforms = false; + Konva.stages.push(this); + }, + _validateAdd: function(child) { + if (child.getType() !== 'Layer') { + Konva.Util.throw('You may only add layers to the stage.'); + } + }, + /** + * set container dom element which contains the stage wrapper div element + * @method + * @memberof Konva.Stage.prototype + * @param {DomElement} container can pass in a dom element or id string + */ + setContainer: function (container) { + if (typeof container === STRING) { + if (container.charAt(0) === '.') { + var className = container.slice(1); + container = Konva.document.getElementsByClassName(className)[0]; + } else { + var id; + if (container.charAt(0) !== '#') { + id = container; + } else { + id = container.slice(1); + } + container = Konva.document.getElementById(id); + } + if (!container) { + throw 'Can not find container in document with id ' + id; + } + } + this._setAttr(CONTAINER, container); + return this; + }, + shouldDrawHit: function() { + return true; + }, + draw: function() { + Konva.Node.prototype.draw.call(this); + return this; + }, + /** + * draw layer scene graphs + * @name draw + * @method + * @memberof Konva.Stage.prototype + */ + + /** + * draw layer hit graphs + * @name drawHit + * @method + * @memberof Konva.Stage.prototype + */ + + /** + * set height + * @method + * @memberof Konva.Stage.prototype + * @param {Number} height + */ + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + this._resizeDOM(); + return this; + }, + /** + * set width + * @method + * @memberof Konva.Stage.prototype + * @param {Number} width + */ + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + this._resizeDOM(); + return this; + }, + /** + * clear all layers + * @method + * @memberof Konva.Stage.prototype + */ + clear: function() { + var layers = this.children, + len = layers.length, + n; + + for(n = 0; n < len; n++) { + layers[n].clear(); + } + return this; + }, + clone: function(obj) { + if (!obj) { + obj = {}; + } + obj.container = Konva.document.createElement(DIV); + return Konva.Container.prototype.clone.call(this, obj); + }, + /** + * destroy stage + * @method + * @memberof Konva.Stage.prototype + */ + destroy: function() { + var content = this.content; + Konva.Container.prototype.destroy.call(this); + + if(content && Konva.Util._isInDocument(content)) { + this.getContainer().removeChild(content); + } + var index = Konva.stages.indexOf(this); + if (index > -1) { + Konva.stages.splice(index, 1); + } + return this; + }, + /** + * get pointer position which can be a touch position or mouse position + * @method + * @memberof Konva.Stage.prototype + * @returns {Object} + */ + getPointerPosition: function() { + return this.pointerPos; + }, + getStage: function() { + return this; + }, + /** + * get stage content div element which has the + * the class name "konvajs-content" + * @method + * @memberof Konva.Stage.prototype + */ + getContent: function() { + return this.content; + }, + /** + * Creates a composite data URL + * @method + * @memberof Konva.Stage.prototype + * @param {Object} config + * @param {Function} [config.callback] function executed when the composite has completed. Deprecated as method is sync now. + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + */ + toDataURL: function(config) { + config = config || {}; + + var mimeType = config.mimeType || null, + quality = config.quality || null, + x = config.x || 0, + y = config.y || 0, + canvas = new Konva.SceneCanvas({ + width: config.width || this.getWidth(), + height: config.height || this.getHeight(), + pixelRatio: config.pixelRatio + }), + _context = canvas.getContext()._context, + layers = this.children; + + if(x || y) { + _context.translate(-1 * x, -1 * y); + } + + + layers.each(function(layer) { + var width = layer.getCanvas().getWidth(); + var height = layer.getCanvas().getHeight(); + var ratio = layer.getCanvas().getPixelRatio(); + _context.drawImage(layer.getCanvas()._canvas, 0, 0, width / ratio, height / ratio); + }); + var src = canvas.toDataURL(mimeType, quality); + + if (config.callback) { + config.callback(src); + } + + return src; + }, + /** + * converts stage into an image. + * @method + * @memberof Konva.Stage.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + */ + toImage: function(config) { + var cb = config.callback; + + config.callback = function(dataUrl) { + Konva.Util._getImage(dataUrl, function(img) { + cb(img); + }); + }; + this.toDataURL(config); + }, + /** + * get visible intersection shape. This is the preferred + * method for determining if a point intersects a shape or not + * @method + * @memberof Konva.Stage.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @param {String} [selector] + * @returns {Konva.Node} + * @example + * var shape = stage.getIntersection({x: 50, y: 50}); + * // or if you interested in shape parent: + * var group = stage.getIntersection({x: 50, y: 50}, 'Group'); + */ + getIntersection: function(pos, selector) { + var layers = this.getChildren(), + len = layers.length, + end = len - 1, + n, shape; + + for(n = end; n >= 0; n--) { + shape = layers[n].getIntersection(pos, selector); + if (shape) { + return shape; + } + } + + return null; + }, + _resizeDOM: function() { + if(this.content) { + var width = this.getWidth(), + height = this.getHeight(), + layers = this.getChildren(), + len = layers.length, + n, layer; + + // set content dimensions + this.content.style.width = width + PX; + this.content.style.height = height + PX; + + this.bufferCanvas.setSize(width, height); + this.bufferHitCanvas.setSize(width, height); + + // set layer dimensions + for(n = 0; n < len; n++) { + layer = layers[n]; + layer.setSize(width, height); + layer.draw(); + } + } + }, + /** + * add layer or layers to stage + * @method + * @memberof Konva.Stage.prototype + * @param {...Konva.Layer} layer + * @example + * stage.add(layer1, layer2, layer3); + */ + add: function(layer) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.add(arguments[i]); + } + return this; + } + Konva.Container.prototype.add.call(this, layer); + layer._setCanvasSize(this.width(), this.height()); + + // draw layer and append canvas to container + layer.draw(); + this.content.appendChild(layer.canvas._canvas); + + // chainable + return this; + }, + getParent: function() { + return null; + }, + getLayer: function() { + return null; + }, + /** + * returns a {@link Konva.Collection} of layers + * @method + * @memberof Konva.Stage.prototype + */ + getLayers: function() { + return this.getChildren(); + }, + _bindContentEvents: function() { + for (var n = 0; n < eventsLength; n++) { + addEvent(this, EVENTS[n]); + } + }, + _mouseover: function(evt) { + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + this._fire(CONTENT_MOUSEOVER, {evt: evt}); + } + }, + _mouseout: function(evt) { + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var targetShape = this.targetShape; + + if(targetShape && !Konva.isDragging()) { + targetShape._fireAndBubble(MOUSEOUT, {evt: evt}); + targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}); + this.targetShape = null; + } + this.pointerPos = undefined; + + this._fire(CONTENT_MOUSEOUT, {evt: evt}); + } + }, + _mousemove: function(evt) { + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchmove(evt); + } + // workaround fake mousemove event in chrome browser https://code.google.com/p/chromium/issues/detail?id=161464 + if ((typeof evt.movementX !== 'undefined' || typeof evt.movementY !== 'undefined') && evt.movementY === 0 && evt.movementX === 0) { + return null; + } + if (Konva.UA.mobile) { + return null; + } + this._setPointerPosition(evt); + var dd = Konva.DD, shape; + + if (!Konva.isDragging()) { + shape = this.getIntersection(this.getPointerPosition()); + if(shape && shape.isListening()) { + if(!Konva.isDragging() && (!this.targetShape || this.targetShape._id !== shape._id)) { + if(this.targetShape) { + this.targetShape._fireAndBubble(MOUSEOUT, {evt: evt}, shape); + this.targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}, shape); + } + shape._fireAndBubble(MOUSEOVER, {evt: evt}, this.targetShape); + shape._fireAndBubble(MOUSEENTER, {evt: evt}, this.targetShape); + this.targetShape = shape; + } + else { + shape._fireAndBubble(MOUSEMOVE, {evt: evt}); + } + } + /* + * if no shape was detected, clear target shape and try + * to run mouseout from previous target shape + */ + else { + if(this.targetShape && !Konva.isDragging()) { + this.targetShape._fireAndBubble(MOUSEOUT, {evt: evt}); + this.targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}); + this.targetShape = null; + } + + } + + // content event + this._fire(CONTENT_MOUSEMOVE, {evt: evt}); + } + if(dd) { + dd._drag(evt); + } + + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _mousedown: function(evt) { + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchstart(evt); + } + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + Konva.listenClickTap = true; + + if (shape && shape.isListening()) { + this.clickStartShape = shape; + shape._fireAndBubble(MOUSEDOWN, {evt: evt}); + } + + // content event + this._fire(CONTENT_MOUSEDOWN, {evt: evt}); + } + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _mouseup: function(evt) { + + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchend(evt); + } + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()), + clickStartShape = this.clickStartShape, + fireDblClick = false, + dd = Konva.DD; + + if(Konva.inDblClickWindow) { + fireDblClick = true; + Konva.inDblClickWindow = false; + } + // don't set inDblClickWindow after dragging + else if (!dd || !dd.justDragged) { + Konva.inDblClickWindow = true; + } else if (dd) { + dd.justDragged = false; + } + + setTimeout(function() { + Konva.inDblClickWindow = false; + }, Konva.dblClickWindow); + + if (shape && shape.isListening()) { + shape._fireAndBubble(MOUSEUP, {evt: evt}); + + // detect if click or double click occurred + if(Konva.listenClickTap && clickStartShape && clickStartShape._id === shape._id) { + shape._fireAndBubble(CLICK, {evt: evt}); + + if(fireDblClick) { + shape._fireAndBubble(DBL_CLICK, {evt: evt}); + } + } + } + // content events + this._fire(CONTENT_MOUSEUP, {evt: evt}); + if (Konva.listenClickTap) { + this._fire(CONTENT_CLICK, {evt: evt}); + if(fireDblClick) { + this._fire(CONTENT_DBL_CLICK, {evt: evt}); + } + } + + Konva.listenClickTap = false; + } + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _touchstart: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + Konva.listenClickTap = true; + + if (shape && shape.isListening()) { + this.tapStartShape = shape; + shape._fireAndBubble(TOUCHSTART, {evt: evt}); + + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + // content event + this._fire(CONTENT_TOUCHSTART, {evt: evt}); + }, + _touchend: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()), + fireDblClick = false; + + if(Konva.inDblClickWindow) { + fireDblClick = true; + Konva.inDblClickWindow = false; + } + else { + Konva.inDblClickWindow = true; + } + + setTimeout(function() { + Konva.inDblClickWindow = false; + }, Konva.dblClickWindow); + + if (shape && shape.isListening()) { + shape._fireAndBubble(TOUCHEND, {evt: evt}); + + // detect if tap or double tap occurred + if(Konva.listenClickTap && shape._id === this.tapStartShape._id) { + shape._fireAndBubble(TAP, {evt: evt}); + + if(fireDblClick) { + shape._fireAndBubble(DBL_TAP, {evt: evt}); + } + } + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + // content events + this._fire(CONTENT_TOUCHEND, {evt: evt}); + if (Konva.listenClickTap) { + this._fire(CONTENT_TAP, {evt: evt}); + if(fireDblClick) { + this._fire(CONTENT_DBL_TAP, {evt: evt}); + } + } + + Konva.listenClickTap = false; + }, + _touchmove: function(evt) { + this._setPointerPosition(evt); + var dd = Konva.DD, + shape; + if (!Konva.isDragging()) { + shape = this.getIntersection(this.getPointerPosition()); + if (shape && shape.isListening()) { + shape._fireAndBubble(TOUCHMOVE, {evt: evt}); + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + this._fire(CONTENT_TOUCHMOVE, {evt: evt}); + } + if(dd) { + dd._drag(evt); + if (Konva.isDragging()) { + evt.preventDefault(); + } + } + }, + _DOMMouseScroll: function(evt) { + this._mousewheel(evt); + }, + _mousewheel: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + if (shape && shape.isListening()) { + shape._fireAndBubble(WHEEL, {evt: evt}); + } + this._fire(CONTENT_WHEEL, {evt: evt}); + }, + _wheel: function(evt) { + this._mousewheel(evt); + }, + _setPointerPosition: function(evt) { + var contentPosition = this._getContentPosition(), + x = null, + y = null; + evt = evt ? evt : window.event; + + // touch events + if(evt.touches !== undefined) { + // currently, only handle one finger + if (evt.touches.length > 0) { + + var touch = evt.touches[0]; + // get the information for finger #1 + x = touch.clientX - contentPosition.left; + y = touch.clientY - contentPosition.top; + } + } + // mouse events + else { + x = evt.clientX - contentPosition.left; + y = evt.clientY - contentPosition.top; + } + if (x !== null && y !== null) { + this.pointerPos = { + x: x, + y: y + }; + } + }, + _getContentPosition: function() { + var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top: 0, left: 0 }; + return { + top: rect.top, + left: rect.left + }; + }, + _buildDOM: function() { + var container = this.getContainer(); + if (!container) { + if (Konva.Util.isBrowser()) { + throw 'Stage has no container. A container is required.'; + } else { + // automatically create element for jsdom in nodejs env + container = Konva.document.createElement(DIV); + } + } + // clear content inside container + container.innerHTML = EMPTY_STRING; + + // content + this.content = Konva.document.createElement(DIV); + this.content.style.position = RELATIVE; + this.content.className = KONVA_CONTENT; + this.content.setAttribute('role', 'presentation'); + container.appendChild(this.content); + + // the buffer canvas pixel ratio must be 1 because it is used as an + // intermediate canvas before copying the result onto a scene canvas. + // not setting it to 1 will result in an over compensation + this.bufferCanvas = new Konva.SceneCanvas(); + this.bufferHitCanvas = new Konva.HitCanvas({pixelRatio: 1}); + + this._resizeDOM(); + }, + _onContent: function(typesStr, handler) { + var types = typesStr.split(SPACE), + len = types.length, + n, baseEvent; + + for(n = 0; n < len; n++) { + baseEvent = types[n]; + this.content.addEventListener(baseEvent, handler, false); + } + }, + // currently cache function is now working for stage, because stage has no its own canvas element + // TODO: may be it is better to cache all children layers? + cache: function() { + Konva.Util.warn('Cache function is not allowed for stage. You may use cache only for layers, groups and shapes.'); + }, + clearCache: function() { + } + }); + Konva.Util.extend(Konva.Stage, Konva.Container); + + // add getters and setters + Konva.Factory.addGetter(Konva.Stage, 'container'); + Konva.Factory.addOverloadedGetterSetter(Konva.Stage, 'container'); + + /** + * get container DOM element + * @name container + * @method + * @memberof Konva.Stage.prototype + * @returns {DomElement} container + * @example + * // get container + * var container = stage.container(); + * // set container + * var container = document.createElement('div'); + * body.appendChild(container); + * stage.container(container); + */ + +})(); + +(function() { + 'use strict'; + /** + * BaseLayer constructor. + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.Layer(); + */ + Konva.BaseLayer = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.BaseLayer, { + ___init: function(config) { + this.nodeType = 'Layer'; + Konva.Container.call(this, config); + }, + createPNGStream: function() { + return this.canvas._canvas.createPNGStream(); + }, + /** + * get layer canvas + * @method + * @memberof Konva.BaseLayer.prototype + */ + getCanvas: function() { + return this.canvas; + }, + /** + * get layer hit canvas + * @method + * @memberof Konva.BaseLayer.prototype + */ + getHitCanvas: function() { + return this.hitCanvas; + }, + /** + * get layer canvas context + * @method + * @memberof Konva.BaseLayer.prototype + */ + getContext: function() { + return this.getCanvas().getContext(); + }, + /** + * clear scene and hit canvas contexts tied to the layer + * @method + * @memberof Konva.BaseLayer.prototype + * @param {Object} [bounds] + * @param {Number} [bounds.x] + * @param {Number} [bounds.y] + * @param {Number} [bounds.width] + * @param {Number} [bounds.height] + * @example + * layer.clear(); + * layer.clear({ + * x : 0, + * y : 0, + * width : 100, + * height : 100 + * }); + */ + clear: function(bounds) { + this.getContext().clear(bounds); + return this; + }, + clearHitCache: function() { + this._hitImageData = undefined; + }, + // extend Node.prototype.setZIndex + setZIndex: function(index) { + Konva.Node.prototype.setZIndex.call(this, index); + var stage = this.getStage(); + if(stage) { + stage.content.removeChild(this.getCanvas()._canvas); + + if(index < stage.getChildren().length - 1) { + stage.content.insertBefore(this.getCanvas()._canvas, stage.getChildren()[index + 1].getCanvas()._canvas); + } + else { + stage.content.appendChild(this.getCanvas()._canvas); + } + } + return this; + }, + // extend Node.prototype.moveToTop + moveToTop: function() { + Konva.Node.prototype.moveToTop.call(this); + var stage = this.getStage(); + if(stage) { + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.appendChild(this.getCanvas()._canvas); + } + return this; + }, + // extend Node.prototype.moveUp + moveUp: function() { + var moved = Konva.Node.prototype.moveUp.call(this); + if (!moved){ + return this; + } + var stage = this.getStage(); + if(!stage) { + return this; + } + stage.content.removeChild(this.getCanvas()._canvas); + + if(this.index < stage.getChildren().length - 1) { + stage.content.insertBefore(this.getCanvas()._canvas, stage.getChildren()[this.index + 1].getCanvas()._canvas); + } else { + stage.content.appendChild(this.getCanvas()._canvas); + } + return this; + }, + // extend Node.prototype.moveDown + moveDown: function() { + if(Konva.Node.prototype.moveDown.call(this)) { + var stage = this.getStage(); + if(stage) { + var children = stage.getChildren(); + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.insertBefore(this.getCanvas()._canvas, children[this.index + 1].getCanvas()._canvas); + } + } + return this; + }, + // extend Node.prototype.moveToBottom + moveToBottom: function() { + if(Konva.Node.prototype.moveToBottom.call(this)) { + var stage = this.getStage(); + if(stage) { + var children = stage.getChildren(); + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.insertBefore(this.getCanvas()._canvas, children[1].getCanvas()._canvas); + } + } + return this; + }, + getLayer: function() { + return this; + }, + remove: function() { + var _canvas = this.getCanvas()._canvas; + + Konva.Node.prototype.remove.call(this); + + if(_canvas && _canvas.parentNode && Konva.Util._isInDocument(_canvas)) { + _canvas.parentNode.removeChild(_canvas); + } + return this; + }, + getStage: function() { + return this.parent; + }, + setSize: function(width, height) { + this.canvas.setSize(width, height); + return this; + }, + /** + * get/set width of layer.getter return width of stage. setter doing nothing. + * if you want change width use `stage.width(value);` + * @name width + * @method + * @memberof Konva.BaseLayer.prototype + * @returns {Number} + * @example + * var width = layer.width(); + */ + getWidth: function() { + if (this.parent) { + return this.parent.getWidth(); + } + }, + setWidth: function() { + Konva.Util.warn('Can not change width of layer. Use "stage.width(value)" function instead.'); + }, + /** + * get/set height of layer.getter return height of stage. setter doing nothing. + * if you want change height use `stage.height(value);` + * @name height + * @method + * @memberof Konva.BaseLayer.prototype + * @returns {Number} + * @example + * var height = layer.height(); + */ + getHeight: function() { + if (this.parent) { + return this.parent.getHeight(); + } + }, + setHeight: function() { + Konva.Util.warn('Can not change height of layer. Use "stage.height(value)" function instead.'); + }, + // the apply transform method is handled by the Layer and FastLayer class + // because it is up to the layer to decide if an absolute or relative transform + // should be used + _applyTransform: function(shape, context, top) { + var m = shape.getAbsoluteTransform(top).getMatrix(); + context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + }); + Konva.Util.extend(Konva.BaseLayer, Konva.Container); + + // add getters and setters + Konva.Factory.addGetterSetter(Konva.BaseLayer, 'clearBeforeDraw', true); + /** + * get/set clearBeforeDraw flag which determines if the layer is cleared or not + * before drawing + * @name clearBeforeDraw + * @method + * @memberof Konva.BaseLayer.prototype + * @param {Boolean} clearBeforeDraw + * @returns {Boolean} + * @example + * // get clearBeforeDraw flag + * var clearBeforeDraw = layer.clearBeforeDraw(); + * + * // disable clear before draw + * layer.clearBeforeDraw(false); + * + * // enable clear before draw + * layer.clearBeforeDraw(true); + */ + + Konva.Collection.mapMethods(Konva.BaseLayer); +})(); + +(function() { + 'use strict'; + // constants + var HASH = '#', + BEFORE_DRAW = 'beforeDraw', + DRAW = 'draw', + + /* + * 2 - 3 - 4 + * | | + * 1 - 0 5 + * | + * 8 - 7 - 6 + */ + INTERSECTION_OFFSETS = [ + {x: 0, y: 0}, // 0 + {x: -1, y: 0}, // 1 + {x: -1, y: -1}, // 2 + {x: 0, y: -1}, // 3 + {x: 1, y: -1}, // 4 + {x: 1, y: 0}, // 5 + {x: 1, y: 1}, // 6 + {x: 0, y: 1}, // 7 + {x: -1, y: 1} // 8 + ], + INTERSECTION_OFFSETS_LEN = INTERSECTION_OFFSETS.length; + + /** + * Layer constructor. Layers are tied to their own canvas element and are used + * to contain groups or shapes. + * @constructor + * @memberof Konva + * @augments Konva.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.Layer(); + */ + Konva.Layer = function(config) { + this.____init(config); + }; + + Konva.Util.addMethods(Konva.Layer, { + ____init: function(config) { + this.nodeType = 'Layer'; + this.canvas = new Konva.SceneCanvas(); + this.hitCanvas = new Konva.HitCanvas({ + pixelRatio: 1 + }); + // call super constructor + Konva.BaseLayer.call(this, config); + }, + _setCanvasSize: function(width, height) { + this.canvas.setSize(width, height); + this.hitCanvas.setSize(width, height); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Group' && type !== 'Shape') { + Konva.Util.throw('You may only add groups and shapes to a layer.'); + } + }, + /** + * get visible intersection shape. This is the preferred + * method for determining if a point intersects a shape or not + * also you may pass optional selector parametr to return ancestor of intersected shape + * @method + * @memberof Konva.Layer.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @param {String} [selector] + * @returns {Konva.Node} + * @example + * var shape = layer.getIntersection({x: 50, y: 50}); + * // or if you interested in shape parent: + * var group = layer.getIntersection({x: 50, y: 50}, 'Group'); + */ + getIntersection: function(pos, selector) { + var obj, i, intersectionOffset, shape; + + if(!this.hitGraphEnabled() || !this.isVisible()) { + return null; + } + // in some cases antialiased area may be bigger than 1px + // it is possible if we will cache node, then scale it a lot + // TODO: check { 0; 0 } point before loop, and remove it from INTERSECTION_OFFSETS. + var spiralSearchDistance = 1; + var continueSearch = false; + while (true) { + for (i = 0; i < INTERSECTION_OFFSETS_LEN; i++) { + intersectionOffset = INTERSECTION_OFFSETS[i]; + obj = this._getIntersection({ + x: pos.x + intersectionOffset.x * spiralSearchDistance, + y: pos.y + intersectionOffset.y * spiralSearchDistance + }); + shape = obj.shape; + if (shape && selector) { + return shape.findAncestor(selector, true); + } else if (shape) { + return shape; + } + // we should continue search if we found antialiased pixel + // that means our node somewhere very close + continueSearch = !!obj.antialiased; + // stop search if found empty pixel + if (!obj.antialiased) { + break; + } + } + // if no shape, and no antialiased pixel, we should end searching + if (continueSearch) { + spiralSearchDistance += 1; + } else { + return null; + } + } + }, + _getImageData: function(x, y) { + var width = this.hitCanvas.width || 1, + height = this.hitCanvas.height || 1, + index = (Math.round(y) * width ) + Math.round(x); + + if (!this._hitImageData) { + this._hitImageData = this.hitCanvas.context.getImageData(0, 0, width, height); + } + + return [ + this._hitImageData.data[4 * index + 0], // Red + this._hitImageData.data[4 * index + 1], // Green + this._hitImageData.data[4 * index + 2], // Blue + this._hitImageData.data[4 * index + 3] // Alpha + ]; + }, + _getIntersection: function(pos) { + var ratio = this.hitCanvas.pixelRatio; + var p = this.hitCanvas.context.getImageData(Math.round(pos.x * ratio), Math.round(pos.y * ratio), 1, 1).data, + p3 = p[3], + colorKey, shape; + // fully opaque pixel + if(p3 === 255) { + colorKey = Konva.Util._rgbToHex(p[0], p[1], p[2]); + shape = Konva.shapes[HASH + colorKey]; + if (shape) { + return { + shape: shape + }; + } + return { + antialiased: true + }; + } + // antialiased pixel + else if(p3 > 0) { + return { + antialiased: true + }; + } + // empty pixel + return {}; + }, + drawScene: function(can, top) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()); + + this._fire(BEFORE_DRAW, { + node: this + }); + + if(this.getClearBeforeDraw()) { + canvas.getContext().clear(); + } + + Konva.Container.prototype.drawScene.call(this, canvas, top); + + this._fire(DRAW, { + node: this + }); + + return this; + }, + drawHit: function(can, top) { + var layer = this.getLayer(), + canvas = can || (layer && layer.hitCanvas); + + if(layer && layer.getClearBeforeDraw()) { + layer.getHitCanvas().getContext().clear(); + } + + Konva.Container.prototype.drawHit.call(this, canvas, top); + this.imageData = null; // Clear imageData cache + return this; + }, + clear: function(bounds) { + Konva.BaseLayer.prototype.clear.call(this, bounds); + this.getHitCanvas().getContext().clear(bounds); + this.imageData = null; // Clear getImageData cache + return this; + }, + // extend Node.prototype.setVisible + setVisible: function(visible) { + Konva.Node.prototype.setVisible.call(this, visible); + if(visible) { + this.getCanvas()._canvas.style.display = 'block'; + this.hitCanvas._canvas.style.display = 'block'; + } + else { + this.getCanvas()._canvas.style.display = 'none'; + this.hitCanvas._canvas.style.display = 'none'; + } + return this; + }, + /** + * enable hit graph + * @name enableHitGraph + * @method + * @memberof Konva.Layer.prototype + * @returns {Layer} + */ + enableHitGraph: function() { + this.setHitGraphEnabled(true); + return this; + }, + /** + * disable hit graph + * @name disableHitGraph + * @method + * @memberof Konva.Layer.prototype + * @returns {Layer} + */ + disableHitGraph: function() { + this.setHitGraphEnabled(false); + return this; + }, + setSize: function(width, height) { + Konva.BaseLayer.prototype.setSize.call(this, width, height); + this.hitCanvas.setSize(width, height); + return this; + } + }); + Konva.Util.extend(Konva.Layer, Konva.BaseLayer); + + Konva.Factory.addGetterSetter(Konva.Layer, 'hitGraphEnabled', true); + /** + * get/set hitGraphEnabled flag. Disabling the hit graph will greatly increase + * draw performance because the hit graph will not be redrawn each time the layer is + * drawn. This, however, also disables mouse/touch event detection + * @name hitGraphEnabled + * @method + * @memberof Konva.Layer.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get hitGraphEnabled flag + * var hitGraphEnabled = layer.hitGraphEnabled(); + * + * // disable hit graph + * layer.hitGraphEnabled(false); + * + * // enable hit graph + * layer.hitGraphEnabled(true); + */ + Konva.Collection.mapMethods(Konva.Layer); +})(); + +(function() { + 'use strict'; + /** + * FastLayer constructor. Layers are tied to their own canvas element and are used + * to contain shapes only. If you don't need node nesting, mouse and touch interactions, + * or event pub/sub, you should use FastLayer instead of Layer to create your layers. + * It renders about 2x faster than normal layers. + * @constructor + * @memberof Konva + * @augments Konva.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Boolean} [config.visible] + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.FastLayer(); + */ + Konva.FastLayer = function(config) { + this.____init(config); + }; + + Konva.Util.addMethods(Konva.FastLayer, { + ____init: function(config) { + this.nodeType = 'Layer'; + this.canvas = new Konva.SceneCanvas(); + // call super constructor + Konva.BaseLayer.call(this, config); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Shape') { + Konva.Util.throw('You may only add shapes to a fast layer.'); + } + }, + _setCanvasSize: function(width, height) { + this.canvas.setSize(width, height); + }, + hitGraphEnabled: function() { + return false; + }, + getIntersection: function() { + return null; + }, + drawScene: function(can) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()); + + if(this.getClearBeforeDraw()) { + canvas.getContext().clear(); + } + + Konva.Container.prototype.drawScene.call(this, canvas); + + return this; + }, + draw: function() { + this.drawScene(); + return this; + }, + // extend Node.prototype.setVisible + setVisible: function(visible) { + Konva.Node.prototype.setVisible.call(this, visible); + if(visible) { + this.getCanvas()._canvas.style.display = 'block'; + } + else { + this.getCanvas()._canvas.style.display = 'none'; + } + return this; + } + }); + Konva.Util.extend(Konva.FastLayer, Konva.BaseLayer); + + Konva.Collection.mapMethods(Konva.FastLayer); +})(); + +(function() { + 'use strict'; + /** + * Group constructor. Groups are used to contain shapes or other groups. + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var group = new Konva.Group(); + */ + Konva.Group = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.Group, { + ___init: function(config) { + this.nodeType = 'Group'; + // call super constructor + Konva.Container.call(this, config); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Group' && type !== 'Shape') { + Konva.Util.throw('You may only add groups and shapes to groups.'); + } + } + }); + Konva.Util.extend(Konva.Group, Konva.Container); + + Konva.Collection.mapMethods(Konva.Group); +})(); + +(function(Konva) { + 'use strict'; + + var now = (function() { + if (Konva.global.performance && Konva.global.performance.now) { + return function() { + return Konva.global.performance.now(); + }; + } + + return function() { + return new Date().getTime(); + }; + })(); + + function FRAF(callback) { + setTimeout(callback, 1000 / 60); + } + + var RAF = (function(){ + return Konva.global.requestAnimationFrame + || Konva.global.webkitRequestAnimationFrame + || Konva.global.mozRequestAnimationFrame + || Konva.global.oRequestAnimationFrame + || Konva.global.msRequestAnimationFrame + || FRAF; + })(); + + + + function requestAnimFrame() { + return RAF.apply(Konva.global, arguments); + } + + /** + * Animation constructor. A stage is used to contain multiple layers and handle + * @constructor + * @memberof Konva + * @param {Function} func function executed on each animation frame. The function is passed a frame object, which contains + * timeDiff, lastTime, time, and frameRate properties. The timeDiff property is the number of milliseconds that have passed + * since the last animation frame. The lastTime property is time in milliseconds that elapsed from the moment the animation started + * to the last animation frame. The time property is the time in milliseconds that ellapsed from the moment the animation started + * to the current animation frame. The frameRate property is the current frame rate in frames / second. Return false from function, + * if you don't need to redraw layer/layers on some frames. + * @param {Konva.Layer|Array} [layers] layer(s) to be redrawn on each animation frame. Can be a layer, an array of layers, or null. + * Not specifying a node will result in no redraw. + * @example + * // move a node to the right at 50 pixels / second + * var velocity = 50; + * + * var anim = new Konva.Animation(function(frame) { + * var dist = velocity * (frame.timeDiff / 1000); + * node.move(dist, 0); + * }, layer); + * + * anim.start(); + */ + Konva.Animation = function(func, layers) { + var Anim = Konva.Animation; + this.func = func; + this.setLayers(layers); + this.id = Anim.animIdCounter++; + this.frame = { + time: 0, + timeDiff: 0, + lastTime: now() + }; + }; + /* + * Animation methods + */ + Konva.Animation.prototype = { + /** + * set layers to be redrawn on each animation frame + * @method + * @memberof Konva.Animation.prototype + * @param {Konva.Layer|Array} [layers] layer(s) to be redrawn.  Can be a layer, an array of layers, or null. Not specifying a node will result in no redraw. + * @return {Konva.Animation} this + */ + setLayers: function(layers) { + var lays = []; + // if passing in no layers + if (!layers) { + lays = []; + } + // if passing in an array of Layers + // NOTE: layers could be an array or Konva.Collection. for simplicity, I'm just inspecting + // the length property to check for both cases + else if (layers.length > 0) { + lays = layers; + } + // if passing in a Layer + else { + lays = [layers]; + } + + this.layers = lays; + return this; + }, + /** + * get layers + * @method + * @memberof Konva.Animation.prototype + * @return {Array} Array of Konva.Layer + */ + getLayers: function() { + return this.layers; + }, + /** + * add layer. Returns true if the layer was added, and false if it was not + * @method + * @memberof Konva.Animation.prototype + * @param {Konva.Layer} layer to add + * @return {Bool} true if layer is added to animation, otherwise false + */ + addLayer: function(layer) { + var layers = this.layers, + len = layers.length, n; + + // don't add the layer if it already exists + for (n = 0; n < len; n++) { + if (layers[n]._id === layer._id){ + return false; + } + } + + this.layers.push(layer); + return true; + }, + /** + * determine if animation is running or not. returns true or false + * @method + * @memberof Konva.Animation.prototype + * @return {Bool} is animation running? + */ + isRunning: function() { + var a = Konva.Animation, + animations = a.animations, + len = animations.length, + n; + + for (n = 0; n < len; n++) { + if (animations[n].id === this.id) { + return true; + } + } + return false; + }, + /** + * start animation + * @method + * @memberof Konva.Animation.prototype + * @return {Konva.Animation} this + */ + start: function() { + var Anim = Konva.Animation; + this.stop(); + this.frame.timeDiff = 0; + this.frame.lastTime = now(); + Anim._addAnimation(this); + return this; + }, + /** + * stop animation + * @method + * @memberof Konva.Animation.prototype + * @return {Konva.Animation} this + */ + stop: function() { + Konva.Animation._removeAnimation(this); + return this; + }, + _updateFrameObject: function(time) { + this.frame.timeDiff = time - this.frame.lastTime; + this.frame.lastTime = time; + this.frame.time += this.frame.timeDiff; + this.frame.frameRate = 1000 / this.frame.timeDiff; + } + }; + Konva.Animation.animations = []; + Konva.Animation.animIdCounter = 0; + Konva.Animation.animRunning = false; + + Konva.Animation._addAnimation = function(anim) { + this.animations.push(anim); + this._handleAnimation(); + }; + Konva.Animation._removeAnimation = function(anim) { + var id = anim.id, + animations = this.animations, + len = animations.length, + n; + + for(n = 0; n < len; n++) { + if(animations[n].id === id) { + this.animations.splice(n, 1); + break; + } + } + }; + + Konva.Animation._runFrames = function() { + var layerHash = {}, + animations = this.animations, + anim, layers, func, n, i, layersLen, layer, key, needRedraw; + /* + * loop through all animations and execute animation + * function. if the animation object has specified node, + * we can add the node to the nodes hash to eliminate + * drawing the same node multiple times. The node property + * can be the stage itself or a layer + */ + /* + * WARNING: don't cache animations.length because it could change while + * the for loop is running, causing a JS error + */ + + for(n = 0; n < animations.length; n++) { + anim = animations[n]; + layers = anim.layers; + func = anim.func; + + + anim._updateFrameObject(now()); + layersLen = layers.length; + + // if animation object has a function, execute it + if (func) { + // allow anim bypassing drawing + needRedraw = (func.call(anim, anim.frame) !== false); + } else { + needRedraw = true; + } + if (!needRedraw) { + continue; + } + for (i = 0; i < layersLen; i++) { + layer = layers[i]; + + if (layer._id !== undefined) { + layerHash[layer._id] = layer; + } + } + } + + for (key in layerHash) { + if (!layerHash.hasOwnProperty(key)) { + continue; + } + layerHash[key].draw(); + } + }; + Konva.Animation._animationLoop = function() { + var Anim = Konva.Animation; + if(Anim.animations.length) { + Anim._runFrames(); + requestAnimFrame(Anim._animationLoop); + } + else { + Anim.animRunning = false; + } + }; + Konva.Animation._handleAnimation = function() { + if(!this.animRunning) { + this.animRunning = true; + requestAnimFrame(this._animationLoop); + } + }; + + /** + * batch draw. this function will not do immediate draw + * but it will schedule drawing to next tick (requestAnimFrame) + * @method + * @return {Konva.Layer} this + * @memberof Konva.Base.prototype + */ + Konva.BaseLayer.prototype.batchDraw = function() { + var that = this, + Anim = Konva.Animation; + + if (!this.batchAnim) { + this.batchAnim = new Anim(function() { + // stop animation after first tick + that.batchAnim.stop(); + }, this); + } + + this.lastBatchDrawTime = now(); + + if (!this.batchAnim.isRunning()) { + this.batchAnim.start(); + } + return this; + }; + + /** + * batch draw + * @method + * @return {Konva.Stage} this + * @memberof Konva.Stage.prototype + */ + Konva.Stage.prototype.batchDraw = function() { + this.getChildren().each(function(layer) { + layer.batchDraw(); + }); + return this; + }; +})(Konva); + +(function() { + 'use strict'; + var blacklist = { + node: 1, + duration: 1, + easing: 1, + onFinish: 1, + yoyo: 1 + }, + + PAUSED = 1, + PLAYING = 2, + REVERSING = 3, + + idCounter = 0, + colorAttrs = ['fill', 'stroke', 'shadowColor']; + + var Tween = function(prop, propFunc, func, begin, finish, duration, yoyo) { + this.prop = prop; + this.propFunc = propFunc; + this.begin = begin; + this._pos = begin; + this.duration = duration; + this._change = 0; + this.prevPos = 0; + this.yoyo = yoyo; + this._time = 0; + this._position = 0; + this._startTime = 0; + this._finish = 0; + this.func = func; + this._change = finish - this.begin; + this.pause(); + }; + /* + * Tween methods + */ + Tween.prototype = { + fire: function(str) { + var handler = this[str]; + if (handler) { + handler(); + } + }, + setTime: function(t) { + if(t > this.duration) { + if(this.yoyo) { + this._time = this.duration; + this.reverse(); + } + else { + this.finish(); + } + } + else if(t < 0) { + if(this.yoyo) { + this._time = 0; + this.play(); + } + else { + this.reset(); + } + } + else { + this._time = t; + this.update(); + } + }, + getTime: function() { + return this._time; + }, + setPosition: function(p) { + this.prevPos = this._pos; + this.propFunc(p); + this._pos = p; + }, + getPosition: function(t) { + if(t === undefined) { + t = this._time; + } + return this.func(t, this.begin, this._change, this.duration); + }, + play: function() { + this.state = PLAYING; + this._startTime = this.getTimer() - this._time; + this.onEnterFrame(); + this.fire('onPlay'); + }, + reverse: function() { + this.state = REVERSING; + this._time = this.duration - this._time; + this._startTime = this.getTimer() - this._time; + this.onEnterFrame(); + this.fire('onReverse'); + }, + seek: function(t) { + this.pause(); + this._time = t; + this.update(); + this.fire('onSeek'); + }, + reset: function() { + this.pause(); + this._time = 0; + this.update(); + this.fire('onReset'); + }, + finish: function() { + this.pause(); + this._time = this.duration; + this.update(); + this.fire('onFinish'); + }, + update: function() { + this.setPosition(this.getPosition(this._time)); + }, + onEnterFrame: function() { + var t = this.getTimer() - this._startTime; + if(this.state === PLAYING) { + this.setTime(t); + } + else if (this.state === REVERSING) { + this.setTime(this.duration - t); + } + }, + pause: function() { + this.state = PAUSED; + this.fire('onPause'); + }, + getTimer: function() { + return new Date().getTime(); + } + }; + + /** + * Tween constructor. Tweens enable you to animate a node between the current state and a new state. + * You can play, pause, reverse, seek, reset, and finish tweens. By default, tweens are animated using + * a linear easing. For more tweening options, check out {@link Konva.Easings} + * @constructor + * @memberof Konva + * @example + * // instantiate new tween which fully rotates a node in 1 second + * var tween = new Konva.Tween({ + * node: node, + * rotationDeg: 360, + * duration: 1, + * easing: Konva.Easings.EaseInOut + * }); + * + * // play tween + * tween.play(); + * + * // pause tween + * tween.pause(); + */ + Konva.Tween = function(config) { + var that = this, + node = config.node, + nodeId = node._id, + duration, + easing = config.easing || Konva.Easings.Linear, + yoyo = !!config.yoyo, + key; + + if (typeof config.duration === 'undefined') { + duration = 1; + } else if (config.duration === 0) { // zero is bad value for duration + duration = 0.001; + } else { + duration = config.duration; + } + this.node = node; + this._id = idCounter++; + + var layers = node.getLayer() || ((node instanceof Konva.Stage) ? node.getLayers() : null); + if (!layers) { + Konva.Util.error( + 'Tween constructor have `node` that is not in a layer. Please add node into layer first.' + ); + } + this.anim = new Konva.Animation(function() { + that.tween.onEnterFrame(); + }, layers); + + this.tween = new Tween(key, function(i) { + that._tweenFunc(i); + }, easing, 0, 1, duration * 1000, yoyo); + + this._addListeners(); + + // init attrs map + if (!Konva.Tween.attrs[nodeId]) { + Konva.Tween.attrs[nodeId] = {}; + } + if (!Konva.Tween.attrs[nodeId][this._id]) { + Konva.Tween.attrs[nodeId][this._id] = {}; + } + // init tweens map + if (!Konva.Tween.tweens[nodeId]) { + Konva.Tween.tweens[nodeId] = {}; + } + + for (key in config) { + if (blacklist[key] === undefined) { + this._addAttr(key, config[key]); + } + } + + this.reset(); + + // callbacks + this.onFinish = config.onFinish; + this.onReset = config.onReset; + }; + + // start/diff object = attrs.nodeId.tweenId.attr + Konva.Tween.attrs = {}; + // tweenId = tweens.nodeId.attr + Konva.Tween.tweens = {}; + + Konva.Tween.prototype = { + _addAttr: function(key, end) { + var node = this.node, + nodeId = node._id, + start, diff, tweenId, n, len, trueEnd, trueStart; + + // remove conflict from tween map if it exists + tweenId = Konva.Tween.tweens[nodeId][key]; + + if (tweenId) { + delete Konva.Tween.attrs[nodeId][tweenId][key]; + } + + // add to tween map + start = node.getAttr(key); + + if (Konva.Util._isArray(end)) { + diff = []; + len = Math.max(end.length, start.length); + + if (key === 'points' && end.length !== start.length) { + // before tweening points we need to make sure that start.length === end.length + // Konva.Util._prepareArrayForTween thinking that end.length > start.length + + if (end.length > start.length) { + // so in this case we will increase number of starting points + trueStart = start; + start = Konva.Util._prepareArrayForTween(start, end, node.closed()); + } else { + // in this case we will increase number of eding points + trueEnd = end; + end = Konva.Util._prepareArrayForTween(end, start, node.closed()); + } + } + + for (n = 0; n < len; n++) { + diff.push((end[n]) - (start[n])); + } + + } else if (colorAttrs.indexOf(key) !== -1) { + start = Konva.Util.colorToRGBA(start); + var endRGBA = Konva.Util.colorToRGBA(end); + diff = { + r: endRGBA.r - start.r, + g: endRGBA.g - start.g, + b: endRGBA.b - start.b, + a: endRGBA.a - start.a + }; + } else { + diff = end - start; + } + + Konva.Tween.attrs[nodeId][this._id][key] = { + start: start, + diff: diff, + end: end, + trueEnd: trueEnd, + trueStart: trueStart + }; + Konva.Tween.tweens[nodeId][key] = this._id; + }, + _tweenFunc: function(i) { + var node = this.node, + attrs = Konva.Tween.attrs[node._id][this._id], + key, attr, start, diff, newVal, n, len, end; + + for (key in attrs) { + attr = attrs[key]; + start = attr.start; + diff = attr.diff; + end = attr.end; + + if (Konva.Util._isArray(start)) { + newVal = []; + len = Math.max(start.length, end.length); + for (n = 0; n < len; n++) { + newVal.push((start[n] || 0) + (diff[n] * i)); + } + } else if (colorAttrs.indexOf(key) !== -1) { + newVal = 'rgba(' + + Math.round(start.r + diff.r * i) + ',' + + Math.round(start.g + diff.g * i) + ',' + + Math.round(start.b + diff.b * i) + ',' + + (start.a + diff.a * i) + ')'; + } else { + newVal = start + (diff * i); + } + + node.setAttr(key, newVal); + } + }, + _addListeners: function() { + var that = this; + + // start listeners + this.tween.onPlay = function() { + that.anim.start(); + }; + this.tween.onReverse = function() { + that.anim.start(); + }; + + // stop listeners + this.tween.onPause = function() { + that.anim.stop(); + }; + this.tween.onFinish = function() { + var node = that.node; + + // after tweening points of line we need to set original end + var attrs = Konva.Tween.attrs[node._id][that._id]; + if (attrs.points && attrs.points.trueEnd) { + node.points(attrs.points.trueEnd); + } + + if (that.onFinish) { + that.onFinish.call(that); + } + }; + this.tween.onReset = function() { + var node = that.node; + // after tweening points of line we need to set original start + var attrs = Konva.Tween.attrs[node._id][that._id]; + if (attrs.points && attrs.points.trueStart) { + node.points(attrs.points.trueStart); + } + + if (that.onReset) { + that.onReset(); + } + }; + }, + /** + * play + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + play: function() { + this.tween.play(); + return this; + }, + /** + * reverse + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + reverse: function() { + this.tween.reverse(); + return this; + }, + /** + * reset + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + reset: function() { + this.tween.reset(); + return this; + }, + /** + * seek + * @method + * @memberof Konva.Tween.prototype + * @param {Integer} t time in seconds between 0 and the duration + * @returns {Tween} + */ + seek: function(t) { + this.tween.seek(t * 1000); + return this; + }, + /** + * pause + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + pause: function() { + this.tween.pause(); + return this; + }, + /** + * finish + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + finish: function() { + this.tween.finish(); + return this; + }, + /** + * destroy + * @method + * @memberof Konva.Tween.prototype + */ + destroy: function() { + var nodeId = this.node._id, + thisId = this._id, + attrs = Konva.Tween.tweens[nodeId], + key; + + this.pause(); + + for (key in attrs) { + delete Konva.Tween.tweens[nodeId][key]; + } + + delete Konva.Tween.attrs[nodeId][thisId]; + } + }; + + /** + * Tween node properties. Shorter usage of {@link Konva.Tween} object. + * + * @method Konva.Node#to + * @memberof Konva.Node + * @param {Object} [params] tween params + * @example + * + * circle.to({ + * x : 50, + * duration : 0.5 + * }); + */ + Konva.Node.prototype.to = function(params) { + var onFinish = params.onFinish; + params.node = this; + params.onFinish = function() { + this.destroy(); + if (onFinish) { + onFinish(); + } + }; + var tween = new Konva.Tween(params); + tween.play(); + }; + + /* + * These eases were ported from an Adobe Flash tweening library to JavaScript + * by Xaric + */ + + /** + * @namespace Easings + * @memberof Konva + */ + Konva.Easings = { + /** + * back ease in + * @function + * @memberof Konva.Easings + */ + 'BackEaseIn': function(t, b, c, d) { + var s = 1.70158; + return c * (t /= d) * t * ((s + 1) * t - s) + b; + }, + /** + * back ease out + * @function + * @memberof Konva.Easings + */ + 'BackEaseOut': function(t, b, c, d) { + var s = 1.70158; + return c * (( t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + }, + /** + * back ease in out + * @function + * @memberof Konva.Easings + */ + 'BackEaseInOut': function(t, b, c, d) { + var s = 1.70158; + if((t /= d / 2) < 1) { + return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; + } + return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + }, + /** + * elastic ease in + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseIn': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d) === 1) { + return b + c; + } + if(!p) { + p = d * 0.3; + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; + }, + /** + * elastic ease out + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseOut': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d) === 1) { + return b + c; + } + if(!p) { + p = d * 0.3; + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b); + }, + /** + * elastic ease in out + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseInOut': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d / 2) === 2) { + return b + c; + } + if(!p) { + p = d * (0.3 * 1.5); + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + if(t < 1) { + return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; + } + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b; + }, + /** + * bounce ease out + * @function + * @memberof Konva.Easings + */ + 'BounceEaseOut': function(t, b, c, d) { + if((t /= d) < (1 / 2.75)) { + return c * (7.5625 * t * t) + b; + } + else if(t < (2 / 2.75)) { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; + } + else if(t < (2.5 / 2.75)) { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; + } + else { + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; + } + }, + /** + * bounce ease in + * @function + * @memberof Konva.Easings + */ + 'BounceEaseIn': function(t, b, c, d) { + return c - Konva.Easings.BounceEaseOut(d - t, 0, c, d) + b; + }, + /** + * bounce ease in out + * @function + * @memberof Konva.Easings + */ + 'BounceEaseInOut': function(t, b, c, d) { + if(t < d / 2) { + return Konva.Easings.BounceEaseIn(t * 2, 0, c, d) * 0.5 + b; + } + else { + return Konva.Easings.BounceEaseOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; + } + }, + /** + * ease in + * @function + * @memberof Konva.Easings + */ + 'EaseIn': function(t, b, c, d) { + return c * (t /= d) * t + b; + }, + /** + * ease out + * @function + * @memberof Konva.Easings + */ + 'EaseOut': function(t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + }, + /** + * ease in out + * @function + * @memberof Konva.Easings + */ + 'EaseInOut': function(t, b, c, d) { + if((t /= d / 2) < 1) { + return c / 2 * t * t + b; + } + return -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + /** + * strong ease in + * @function + * @memberof Konva.Easings + */ + 'StrongEaseIn': function(t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + }, + /** + * strong ease out + * @function + * @memberof Konva.Easings + */ + 'StrongEaseOut': function(t, b, c, d) { + return c * (( t = t / d - 1) * t * t * t * t + 1) + b; + }, + /** + * strong ease in out + * @function + * @memberof Konva.Easings + */ + 'StrongEaseInOut': function(t, b, c, d) { + if((t /= d / 2) < 1) { + return c / 2 * t * t * t * t * t + b; + } + return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + }, + /** + * linear + * @function + * @memberof Konva.Easings + */ + 'Linear': function(t, b, c, d) { + return c * t / d + b; + } + }; +})(); + +(function() { + 'use strict'; + Konva.DD = { + // properties + anim: new Konva.Animation(function() { + var b = this.dirty; + this.dirty = false; + return b; + }), + isDragging: false, + justDragged: false, + offset: { + x: 0, + y: 0 + }, + node: null, + + // methods + _drag: function(evt) { + var dd = Konva.DD, + node = dd.node; + + if(node) { + if(!dd.isDragging) { + var pos = node.getStage().getPointerPosition(); + var dragDistance = node.dragDistance(); + var distance = Math.max( + Math.abs(pos.x - dd.startPointerPos.x), + Math.abs(pos.y - dd.startPointerPos.y) + ); + if (distance < dragDistance) { + return; + } + } + + + node.getStage()._setPointerPosition(evt); + node._setDragPosition(evt); + if(!dd.isDragging) { + dd.isDragging = true; + node.fire('dragstart', { + type: 'dragstart', + target: node, + evt: evt + }, true); + } + + // execute ondragmove if defined + node.fire('dragmove', { + type: 'dragmove', + target: node, + evt: evt + }, true); + } + }, + _endDragBefore: function(evt) { + var dd = Konva.DD, + node = dd.node, + layer; + + if(node) { + layer = node.getLayer(); + dd.anim.stop(); + + // only fire dragend event if the drag and drop + // operation actually started. + if(dd.isDragging) { + dd.isDragging = false; + dd.justDragged = true; + Konva.listenClickTap = false; + + if (evt) { + evt.dragEndNode = node; + } + } + + delete dd.node; + + (layer || node).draw(); + } + }, + _endDragAfter: function(evt) { + evt = evt || {}; + var dragEndNode = evt.dragEndNode; + + if (evt && dragEndNode) { + dragEndNode.fire('dragend', { + type: 'dragend', + target: dragEndNode, + evt: evt + }, true); + } + } + }; + + // Node extenders + + /** + * initiate drag and drop + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.startDrag = function() { + var dd = Konva.DD, + stage = this.getStage(), + layer = this.getLayer(), + pos = stage.getPointerPosition(), + ap = this.getAbsolutePosition(); + + if(pos) { + if (dd.node) { + dd.node.stopDrag(); + } + + dd.node = this; + dd.startPointerPos = pos; + dd.offset.x = pos.x - ap.x; + dd.offset.y = pos.y - ap.y; + dd.anim.setLayers(layer || this.getLayers()); + dd.anim.start(); + + this._setDragPosition(); + } + }; + + Konva.Node.prototype._setDragPosition = function(evt) { + var dd = Konva.DD, + pos = this.getStage().getPointerPosition(), + dbf = this.getDragBoundFunc(); + if (!pos) { + return; + } + var newNodePos = { + x: pos.x - dd.offset.x, + y: pos.y - dd.offset.y + }; + + if(dbf !== undefined) { + newNodePos = dbf.call(this, newNodePos, evt); + } + this.setAbsolutePosition(newNodePos); + + if (!this._lastPos || this._lastPos.x !== newNodePos.x || + this._lastPos.y !== newNodePos.y) { + dd.anim.dirty = true; + } + + this._lastPos = newNodePos; + }; + + /** + * stop drag and drop + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.stopDrag = function() { + var dd = Konva.DD, + evt = {}; + dd._endDragBefore(evt); + dd._endDragAfter(evt); + }; + + Konva.Node.prototype.setDraggable = function(draggable) { + this._setAttr('draggable', draggable); + this._dragChange(); + }; + + var origDestroy = Konva.Node.prototype.destroy; + + Konva.Node.prototype.destroy = function() { + var dd = Konva.DD; + + // stop DD + if(dd.node && dd.node._id === this._id) { + + this.stopDrag(); + } + + origDestroy.call(this); + }; + + /** + * determine if node is currently in drag and drop mode + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.isDragging = function() { + var dd = Konva.DD; + return !!(dd.node && dd.node._id === this._id && dd.isDragging); + }; + + Konva.Node.prototype._listenDrag = function() { + var that = this; + + this._dragCleanup(); + + if (this.getClassName() === 'Stage') { + this.on('contentMousedown.konva contentTouchstart.konva', function(evt) { + if(!Konva.DD.node) { + that.startDrag(evt); + } + }); + } + else { + this.on('mousedown.konva touchstart.konva', function(evt) { + // ignore right and middle buttons + if (evt.evt.button === 1 || evt.evt.button === 2) { + return; + } + if(!Konva.DD.node) { + that.startDrag(evt); + } + }); + } + + // listening is required for drag and drop + /* + this._listeningEnabled = true; + this._clearSelfAndAncestorCache('listeningEnabled'); + */ + }; + + Konva.Node.prototype._dragChange = function() { + if(this.attrs.draggable) { + this._listenDrag(); + } + else { + // remove event listeners + this._dragCleanup(); + + /* + * force drag and drop to end + * if this node is currently in + * drag and drop mode + */ + var stage = this.getStage(); + var dd = Konva.DD; + if(stage && dd.node && dd.node._id === this._id) { + dd.node.stopDrag(); + } + } + }; + + Konva.Node.prototype._dragCleanup = function() { + if (this.getClassName() === 'Stage') { + this.off('contentMousedown.konva'); + this.off('contentTouchstart.konva'); + } else { + this.off('mousedown.konva'); + this.off('touchstart.konva'); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'dragBoundFunc'); + + /** + * get/set drag bound function. This is used to override the default + * drag and drop position + * @name dragBoundFunc + * @method + * @memberof Konva.Node.prototype + * @param {Function} dragBoundFunc + * @returns {Function} + * @example + * // get drag bound function + * var dragBoundFunc = node.dragBoundFunc(); + * + * // create vertical drag and drop + * node.dragBoundFunc(function(pos){ + * return { + * x: this.getAbsolutePosition().x, + * y: pos.y + * }; + * }); + */ + + Konva.Factory.addGetter(Konva.Node, 'draggable', false); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'draggable'); + + /** + * get/set draggable flag + * @name draggable + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} draggable + * @returns {Boolean} + * @example + * // get draggable flag + * var draggable = node.draggable(); + * + * // enable drag and drop + * node.draggable(true); + * + * // disable drag and drop + * node.draggable(false); + */ + + var html = Konva.document.documentElement; + html.addEventListener('mouseup', Konva.DD._endDragBefore, true); + html.addEventListener('touchend', Konva.DD._endDragBefore, true); + + // html.addEventListener('mousemove', Konva.DD._drag); + // html.addEventListener('touchmove', Konva.DD._drag); + + html.addEventListener('mouseup', Konva.DD._endDragAfter, false); + html.addEventListener('touchend', Konva.DD._endDragAfter, false); + +})(); + +(function() { + 'use strict'; + /** + * Rect constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} [config.cornerRadius] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var rect = new Konva.Rect({ + * width: 100, + * height: 50, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 5 + * }); + */ + Konva.Rect = function(config) { + this.___init(config); + }; + + Konva.Rect.prototype = { + ___init: function(config) { + Konva.Shape.call(this, config); + this.className = 'Rect'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var cornerRadius = this.getCornerRadius(), + width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + + if(!cornerRadius) { + // simple rect - don't bother doing all that complicated maths stuff. + context.rect(0, 0, width, height); + } else { + // arcTo would be nicer, but browser support is patchy (Opera) + cornerRadius = Math.min(cornerRadius, width / 2, height / 2); + context.moveTo(cornerRadius, 0); + context.lineTo(width - cornerRadius, 0); + context.arc(width - cornerRadius, cornerRadius, cornerRadius, Math.PI * 3 / 2, 0, false); + context.lineTo(width, height - cornerRadius); + context.arc(width - cornerRadius, height - cornerRadius, cornerRadius, 0, Math.PI / 2, false); + context.lineTo(cornerRadius, height); + context.arc(cornerRadius, height - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false); + context.lineTo(0, cornerRadius); + context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false); + } + context.closePath(); + context.fillStrokeShape(this); + } + }; + + Konva.Util.extend(Konva.Rect, Konva.Shape); + + Konva.Factory.addGetterSetter(Konva.Rect, 'cornerRadius', 0); + /** + * get/set corner radius + * @name cornerRadius + * @method + * @memberof Konva.Rect.prototype + * @param {Number} cornerRadius + * @returns {Number} + * @example + * // get corner radius + * var cornerRadius = rect.cornerRadius(); + * + * // set corner radius + * rect.cornerRadius(10); + */ + + Konva.Collection.mapMethods(Konva.Rect); +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001, + CIRCLE = 'Circle'; + + /** + * Circle constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // create circle + * var circle = new Konva.Circle({ + * radius: 40, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5 + * }); + */ + Konva.Circle = function(config) { + this.___init(config); + }; + + Konva.Circle.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = CIRCLE; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getRadius(), 0, PIx2, false); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Circle, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Circle, 'radius', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Circle, 'radius'); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Circle.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radius + * var radius = circle.radius(); + * + * // set radius + * circle.radius(10); + */ + + Konva.Collection.mapMethods(Konva.Circle); +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001, + ELLIPSE = 'Ellipse'; + + /** + * Ellipse constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Object} config.radius defines x and y radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var ellipse = new Konva.Ellipse({ + * radius : { + * x : 50, + * y : 50 + * }, + * fill: 'red' + * }); + */ + Konva.Ellipse = function(config) { + this.___init(config); + }; + + Konva.Ellipse.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = ELLIPSE; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var rx = this.getRadiusX(), + ry = this.getRadiusY(); + + context.beginPath(); + context.save(); + if(rx !== ry) { + context.scale(1, ry / rx); + } + context.arc(0, 0, rx, 0, PIx2, false); + context.restore(); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadiusX() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadiusY() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + this.setRadius({ + x: width / 2 + }); + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + this.setRadius({ + y: height / 2 + }); + } + }; + Konva.Util.extend(Konva.Ellipse, Konva.Shape); + + // add getters setters + Konva.Factory.addComponentsGetterSetter(Konva.Ellipse, 'radius', ['x', 'y']); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Ellipse.prototype + * @param {Object} radius + * @param {Number} radius.x + * @param {Number} radius.y + * @returns {Object} + * @example + * // get radius + * var radius = ellipse.radius(); + * + * // set radius + * ellipse.radius({ + * x: 200, + * y: 100 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Ellipse, 'radiusX', 0); + /** + * get/set radius x + * @name radiusX + * @method + * @memberof Konva.Ellipse.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get radius x + * var radiusX = ellipse.radiusX(); + * + * // set radius x + * ellipse.radiusX(200); + */ + + Konva.Factory.addGetterSetter(Konva.Ellipse, 'radiusY', 0); + /** + * get/set radius y + * @name radiusY + * @method + * @memberof Konva.Ellipse.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get radius y + * var radiusY = ellipse.radiusY(); + * + * // set radius y + * ellipse.radiusY(200); + */ + + Konva.Collection.mapMethods(Konva.Ellipse); + +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001; + /** + * Ring constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var ring = new Konva.Ring({ + * innerRadius: 40, + * outerRadius: 80, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 5 + * }); + */ + Konva.Ring = function(config) { + this.___init(config); + }; + + Konva.Ring.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Ring'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getInnerRadius(), 0, PIx2, false); + context.moveTo(this.getOuterRadius(), 0); + context.arc(0, 0, this.getOuterRadius(), PIx2, 0, true); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.outerRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.outerRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + }, + setOuterRadius: function(val) { + this._setAttr('outerRadius', val); + this.setWidth(val * 2); + this.setHeight(val * 2); + } + }; + Konva.Util.extend(Konva.Ring, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Ring, 'innerRadius', 0); + + /** + * get/set innerRadius + * @name innerRadius + * @method + * @memberof Konva.Ring.prototype + * @param {Number} innerRadius + * @returns {Number} + * @example + * // get inner radius + * var innerRadius = ring.innerRadius(); + * + * // set inner radius + * ring.innerRadius(20); + */ + Konva.Factory.addGetter(Konva.Ring, 'outerRadius', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Ring, 'outerRadius'); + + /** + * get/set outerRadius + * @name outerRadius + * @method + * @memberof Konva.Ring.prototype + * @param {Number} outerRadius + * @returns {Number} + * @example + * // get outer radius + * var outerRadius = ring.outerRadius(); + * + * // set outer radius + * ring.outerRadius(20); + */ + + Konva.Collection.mapMethods(Konva.Ring); +})(); + +(function() { + 'use strict'; + /** + * Wedge constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.angle in degrees + * @param {Number} config.radius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // draw a wedge that's pointing downwards + * var wedge = new Konva.Wedge({ + * radius: 40, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5, + * angleDeg: 60, + * rotationDeg: -120 + * }); + */ + Konva.Wedge = function(config) { + this.___init(config); + }; + + Konva.Wedge.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Wedge'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getRadius(), 0, Konva.getAngle(this.getAngle()), this.getClockwise()); + context.lineTo(0, 0); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Wedge, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Wedge, 'radius', 0); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radius + * var radius = wedge.radius(); + * + * // set radius + * wedge.radius(10); + */ + + Konva.Factory.addGetterSetter(Konva.Wedge, 'angle', 0); + + /** + * get/set angle in degrees + * @name angle + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} angle + * @returns {Number} + * @example + * // get angle + * var angle = wedge.angle(); + * + * // set angle + * wedge.angle(20); + */ + + Konva.Factory.addGetterSetter(Konva.Wedge, 'clockwise', false); + + /** + * get/set clockwise flag + * @name clockwise + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} clockwise + * @returns {Number} + * @example + * // get clockwise flag + * var clockwise = wedge.clockwise(); + * + * // draw wedge counter-clockwise + * wedge.clockwise(false); + * + * // draw wedge clockwise + * wedge.clockwise(true); + */ + + Konva.Factory.backCompat(Konva.Wedge, { + angleDeg: 'angle', + getAngleDeg: 'getAngle', + setAngleDeg: 'setAngle' + }); + + Konva.Collection.mapMethods(Konva.Wedge); +})(); + +(function() { + 'use strict'; + /** + * Arc constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.angle in degrees + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // draw a Arc that's pointing downwards + * var arc = new Konva.Arc({ + * innerRadius: 40, + * outerRadius: 80, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5, + * angle: 60, + * rotationDeg: -120 + * }); + */ + Konva.Arc = function(config) { + this.___init(config); + }; + + Konva.Arc.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Arc'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var angle = Konva.getAngle(this.angle()), + clockwise = this.clockwise(); + + context.beginPath(); + context.arc(0, 0, this.getOuterRadius(), 0, angle, clockwise); + context.arc(0, 0, this.getInnerRadius(), angle, 0, !clockwise); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.getOuterRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.getOuterRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Arc, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Arc, 'innerRadius', 0); + + /** + * get/set innerRadius + * @name innerRadius + * @method + * @memberof Konva.Arc.prototype + * @param {Number} innerRadius + * @returns {Number} + * @example + * // get inner radius + * var innerRadius = arc.innerRadius(); + * + * // set inner radius + * arc.innerRadius(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'outerRadius', 0); + + /** + * get/set outerRadius + * @name outerRadius + * @method + * @memberof Konva.Arc.prototype + * @param {Number} outerRadius + * @returns {Number} + * @example + * // get outer radius + * var outerRadius = arc.outerRadius(); + * + * // set outer radius + * arc.outerRadius(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'angle', 0); + + /** + * get/set angle in degrees + * @name angle + * @method + * @memberof Konva.Arc.prototype + * @param {Number} angle + * @returns {Number} + * @example + * // get angle + * var angle = arc.angle(); + * + * // set angle + * arc.angle(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'clockwise', false); + + /** + * get/set clockwise flag + * @name clockwise + * @method + * @memberof Konva.Arc.prototype + * @param {Boolean} clockwise + * @returns {Boolean} + * @example + * // get clockwise flag + * var clockwise = arc.clockwise(); + * + * // draw arc counter-clockwise + * arc.clockwise(false); + * + * // draw arc clockwise + * arc.clockwise(true); + */ + + Konva.Collection.mapMethods(Konva.Arc); +})(); + +(function() { + 'use strict'; + // CONSTANTS + var IMAGE = 'Image'; + + /** + * Image constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Image} config.image + * @param {Object} [config.crop] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var imageObj = new Image(); + * imageObj.onload = function() { + * var image = new Konva.Image({ + * x: 200, + * y: 50, + * image: imageObj, + * width: 100, + * height: 100 + * }); + * }; + * imageObj.src = '/path/to/image.jpg' + */ + Konva.Image = function(config) { + this.___init(config); + }; + + Konva.Image.prototype = { + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = IMAGE; + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _useBufferCanvas: function() { + return (this.hasShadow() || this.getAbsoluteOpacity() !== 1) && this.hasStroke() && this.getStage(); + }, + _sceneFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(), + image = this.getImage(), + cropWidth, cropHeight, params; + + if (image) { + cropWidth = this.getCropWidth(); + cropHeight = this.getCropHeight(); + if (cropWidth && cropHeight) { + params = [image, this.getCropX(), this.getCropY(), cropWidth, cropHeight, 0, 0, width, height]; + } else { + params = [image, 0, 0, width, height]; + } + } + + if (this.hasFill() || this.hasStroke()) { + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + } + + if (image) { + context.drawImage.apply(context, params); + } + }, + _hitFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + }, + getWidth: function() { + var image = this.getImage(); + return this.attrs.width || (image ? image.width : 0); + }, + getHeight: function() { + var image = this.getImage(); + return this.attrs.height || (image ? image.height : 0); + } + }; + Konva.Util.extend(Konva.Image, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Image, 'image'); + + /** + * set image + * @name setImage + * @method + * @memberof Konva.Image.prototype + * @param {Image} image + */ + + /** + * get image + * @name getImage + * @method + * @memberof Konva.Image.prototype + * @returns {Image} + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Image, 'crop', ['x', 'y', 'width', 'height']); + /** + * get/set crop + * @method + * @name crop + * @memberof Konva.Image.prototype + * @param {Object} crop + * @param {Number} crop.x + * @param {Number} crop.y + * @param {Number} crop.width + * @param {Number} crop.height + * @returns {Object} + * @example + * // get crop + * var crop = image.crop(); + * + * // set crop + * image.crop({ + * x: 20, + * y: 20, + * width: 20, + * height: 20 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropX', 0); + /** + * get/set crop x + * @method + * @name cropX + * @memberof Konva.Image.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get crop x + * var cropX = image.cropX(); + * + * // set crop x + * image.cropX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropY', 0); + /** + * get/set crop y + * @name cropY + * @method + * @memberof Konva.Image.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get crop y + * var cropY = image.cropY(); + * + * // set crop y + * image.cropY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropWidth', 0); + /** + * get/set crop width + * @name cropWidth + * @method + * @memberof Konva.Image.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get crop width + * var cropWidth = image.cropWidth(); + * + * // set crop width + * image.cropWidth(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropHeight', 0); + /** + * get/set crop height + * @name cropHeight + * @method + * @memberof Konva.Image.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get crop height + * var cropHeight = image.cropHeight(); + * + * // set crop height + * image.cropHeight(20); + */ + + Konva.Collection.mapMethods(Konva.Image); + + /** + * load image from given url and create `Konva.Image` instance + * @method + * @memberof Konva.Image + * @param {String} url image source + * @param {Function} callback with Konva.Image instance as first argument + * @example + * Konva.Image.fromURL(imageURL, function(image){ + * // image is Konva.Image instance + * layer.add(image); + * layer.draw(); + * }); + */ + Konva.Image.fromURL = function(url, callback) { + var img = new Image(); + img.onload = function() { + var image = new Konva.Image({ + image: img + }); + callback(image); + }; + img.src = url; + }; +})(); + +/*eslint-disable max-depth */ +(function() { + 'use strict'; + // constants + var AUTO = 'auto', + //CANVAS = 'canvas', + CENTER = 'center', + CHANGE_KONVA = 'Change.konva', + CONTEXT_2D = '2d', + DASH = '-', + EMPTY_STRING = '', + LEFT = 'left', + TEXT = 'text', + TEXT_UPPER = 'Text', + MIDDLE = 'middle', + NORMAL = 'normal', + PX_SPACE = 'px ', + SPACE = ' ', + RIGHT = 'right', + WORD = 'word', + CHAR = 'char', + NONE = 'none', + ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'fontVariant', 'padding', 'align', 'lineHeight', 'text', 'width', 'height', 'wrap'], + + // cached variables + attrChangeListLen = ATTR_CHANGE_LIST.length, + dummyContext = Konva.Util.createCanvasElement().getContext(CONTEXT_2D); + + /** + * Text constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} [config.fontFamily] default is Arial + * @param {Number} [config.fontSize] in pixels. Default is 12 + * @param {String} [config.fontStyle] can be normal, bold, or italic. Default is normal + * @param {String} [config.fontVariant] can be normal or small-caps. Default is normal + * @param {String} config.text + * @param {String} [config.align] can be left, center, or right + * @param {Number} [config.padding] + * @param {Number} [config.width] default is auto + * @param {Number} [config.height] default is auto + * @param {Number} [config.lineHeight] default is 1 + * @param {String} [config.wrap] can be word, char, or none. Default is word + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var text = new Konva.Text({ + * x: 10, + * y: 15, + * text: 'Simple Text', + * fontSize: 30, + * fontFamily: 'Calibri', + * fill: 'green' + * }); + */ + Konva.Text = function(config) { + this.___init(config); + }; + function _fillFunc(context) { + context.fillText(this.partialText, 0, 0); + } + function _strokeFunc(context) { + context.strokeText(this.partialText, 0, 0); + } + + Konva.Text.prototype = { + ___init: function(config) { + config = config || {}; + + // set default color to black + if (!config.fillLinearGradientColorStops && !config.fillRadialGradientColorStops) { + config.fill = config.fill || 'black'; + } + + if (config.width === undefined) { + config.width = AUTO; + } + if (config.height === undefined) { + config.height = AUTO; + } + + // call super constructor + Konva.Shape.call(this, config); + + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this.className = TEXT_UPPER; + + // update text data for certain attr changes + for(var n = 0; n < attrChangeListLen; n++) { + this.on(ATTR_CHANGE_LIST[n] + CHANGE_KONVA, this._setTextData); + } + + this._setTextData(); + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _sceneFunc: function(context) { + var p = this.getPadding(), + textHeight = this.getTextHeight(), + lineHeightPx = this.getLineHeight() * textHeight, + textArr = this.textArr, + textArrLen = textArr.length, + totalWidth = this.getWidth(), + n; + + context.setAttr('font', this._getContextFont()); + + context.setAttr('textBaseline', MIDDLE); + context.setAttr('textAlign', LEFT); + context.save(); + if (p) { + context.translate(p, 0); + context.translate(0, p + textHeight / 2); + } else { + context.translate(0, textHeight / 2); + } + + + // draw text lines + for(n = 0; n < textArrLen; n++) { + var obj = textArr[n], + text = obj.text, + width = obj.width; + + // horizontal alignment + context.save(); + if(this.getAlign() === RIGHT) { + context.translate(totalWidth - width - p * 2, 0); + } + else if(this.getAlign() === CENTER) { + context.translate((totalWidth - width - p * 2) / 2, 0); + } + + this.partialText = text; + + context.fillStrokeShape(this); + context.restore(); + context.translate(0, lineHeightPx); + } + context.restore(); + }, + _hitFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + }, + setText: function(text) { + var str = Konva.Util._isString(text) ? text : text.toString(); + this._setAttr(TEXT, str); + return this; + }, + /** + * get width of text area, which includes padding + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getWidth: function() { + return this.attrs.width === AUTO ? this.getTextWidth() + this.getPadding() * 2 : this.attrs.width; + }, + /** + * get the height of the text area, which takes into account multi-line text, line heights, and padding + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getHeight: function() { + return this.attrs.height === AUTO ? (this.getTextHeight() * this.textArr.length * this.getLineHeight()) + this.getPadding() * 2 : this.attrs.height; + }, + /** + * get text width + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getTextWidth: function() { + return this.textWidth; + }, + /** + * get text height + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getTextHeight: function() { + return this.textHeight; + }, + _getTextSize: function(text) { + var _context = dummyContext, + fontSize = this.getFontSize(), + metrics; + + _context.save(); + _context.font = this._getContextFont(); + + metrics = _context.measureText(text); + _context.restore(); + return { + width: metrics.width, + height: parseInt(fontSize, 10) + }; + }, + _getContextFont: function() { + // IE don't want to work with usual font style + // bold was not working + // removing font variant will solve + // fix for: https://github.com/konvajs/konva/issues/94 + if (Konva.UA.isIE) { + return this.getFontStyle() + SPACE + this.getFontSize() + PX_SPACE + this.getFontFamily(); + } + return this.getFontStyle() + SPACE + + this.getFontVariant() + SPACE + + this.getFontSize() + PX_SPACE + + this.getFontFamily(); + }, + _addTextLine: function (line, width) { + return this.textArr.push({text: line, width: width}); + }, + _getTextWidth: function (text) { + return dummyContext.measureText(text).width; + }, + _setTextData: function () { + var lines = this.getText().split('\n'), + fontSize = +this.getFontSize(), + textWidth = 0, + lineHeightPx = this.getLineHeight() * fontSize, + width = this.attrs.width, + height = this.attrs.height, + fixedWidth = width !== AUTO, + fixedHeight = height !== AUTO, + padding = this.getPadding(), + maxWidth = width - padding * 2, + maxHeightPx = height - padding * 2, + currentHeightPx = 0, + wrap = this.getWrap(), + shouldWrap = wrap !== NONE, + wrapAtWord = wrap !== CHAR && shouldWrap; + + this.textArr = []; + dummyContext.save(); + dummyContext.font = this._getContextFont(); + for (var i = 0, max = lines.length; i < max; ++i) { + var line = lines[i], + lineWidth = this._getTextWidth(line); + if (fixedWidth && lineWidth > maxWidth) { + /* + * if width is fixed and line does not fit entirely + * break the line into multiple fitting lines + */ + while (line.length > 0) { + /* + * use binary search to find the longest substring that + * that would fit in the specified width + */ + var low = 0, high = line.length, + match = '', matchWidth = 0; + while (low < high) { + var mid = (low + high) >>> 1, + substr = line.slice(0, mid + 1), + substrWidth = this._getTextWidth(substr); + if (substrWidth <= maxWidth) { + low = mid + 1; + match = substr; + matchWidth = substrWidth; + } else { + high = mid; + } + } + /* + * 'low' is now the index of the substring end + * 'match' is the substring + * 'matchWidth' is the substring width in px + */ + if (match) { + // a fitting substring was found + if (wrapAtWord) { + // try to find a space or dash where wrapping could be done + var wrapIndex = Math.max(match.lastIndexOf(SPACE), + match.lastIndexOf(DASH)) + 1; + if (wrapIndex > 0) { + // re-cut the substring found at the space/dash position + low = wrapIndex; + match = match.slice(0, low); + matchWidth = this._getTextWidth(match); + } + } + this._addTextLine(match, matchWidth); + textWidth = Math.max(textWidth, matchWidth); + currentHeightPx += lineHeightPx; + if (!shouldWrap || + (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)) { + /* + * stop wrapping if wrapping is disabled or if adding + * one more line would overflow the fixed height + */ + break; + } + line = line.slice(low); + if (line.length > 0) { + // Check if the remaining text would fit on one line + lineWidth = this._getTextWidth(line); + if (lineWidth <= maxWidth) { + // if it does, add the line and break out of the loop + this._addTextLine(line, lineWidth); + currentHeightPx += lineHeightPx; + textWidth = Math.max(textWidth, lineWidth); + break; + } + } + } else { + // not even one character could fit in the element, abort + break; + } + } + } else { + // element width is automatically adjusted to max line width + this._addTextLine(line, lineWidth); + currentHeightPx += lineHeightPx; + textWidth = Math.max(textWidth, lineWidth); + } + // if element height is fixed, abort if adding one more line would overflow + if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) { + break; + } + } + dummyContext.restore(); + this.textHeight = fontSize; + this.textWidth = textWidth; + } + }; + Konva.Util.extend(Konva.Text, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Text, 'fontFamily', 'Arial'); + + /** + * get/set font family + * @name fontFamily + * @method + * @memberof Konva.Text.prototype + * @param {String} fontFamily + * @returns {String} + * @example + * // get font family + * var fontFamily = text.fontFamily(); + * + * // set font family + * text.fontFamily('Arial'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontSize', 12); + + /** + * get/set font size in pixels + * @name fontSize + * @method + * @memberof Konva.Text.prototype + * @param {Number} fontSize + * @returns {Number} + * @example + * // get font size + * var fontSize = text.fontSize(); + * + * // set font size to 22px + * text.fontSize(22); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontStyle', NORMAL); + + /** + * set font style. Can be 'normal', 'italic', or 'bold'. 'normal' is the default. + * @name fontStyle + * @method + * @memberof Konva.Text.prototype + * @param {String} fontStyle + * @returns {String} + * @example + * // get font style + * var fontStyle = text.fontStyle(); + * + * // set font style + * text.fontStyle('bold'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontVariant', NORMAL); + + /** + * set font variant. Can be 'normal' or 'small-caps'. 'normal' is the default. + * @name fontVariant + * @method + * @memberof Konva.Text.prototype + * @param {String} fontVariant + * @returns {String} + * @example + * // get font variant + * var fontVariant = text.fontVariant(); + * + * // set font variant + * text.fontVariant('small-caps'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'padding', 0); + + /** + * set padding + * @name padding + * @method + * @memberof Konva.Text.prototype + * @param {Number} padding + * @returns {Number} + * @example + * // get padding + * var padding = text.padding(); + * + * // set padding to 10 pixels + * text.padding(10); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'align', LEFT); + + /** + * get/set horizontal align of text. Can be 'left', 'center', or 'right' + * @name align + * @method + * @memberof Konva.Text.prototype + * @param {String} align + * @returns {String} + * @example + * // get text align + * var align = text.align(); + * + * // center text + * text.align('center'); + * + * // align text to right + * text.align('right'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'lineHeight', 1); + + /** + * get/set line height. The default is 1. + * @name lineHeight + * @method + * @memberof Konva.Text.prototype + * @param {Number} lineHeight + * @returns {Number} + * @example + * // get line height + * var lineHeight = text.lineHeight(); + * + * // set the line height + * text.lineHeight(2); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'wrap', WORD); + + /** + * get/set wrap. Can be word, char, or none. Default is word. + * @name wrap + * @method + * @memberof Konva.Text.prototype + * @param {String} wrap + * @returns {String} + * @example + * // get wrap + * var wrap = text.wrap(); + * + * // set wrap + * text.wrap('word'); + */ + + Konva.Factory.addGetter(Konva.Text, 'text', EMPTY_STRING); + Konva.Factory.addOverloadedGetterSetter(Konva.Text, 'text'); + + /** + * get/set text + * @name getText + * @method + * @memberof Konva.Text.prototype + * @param {String} text + * @returns {String} + * @example + * // get text + * var text = text.text(); + * + * // set text + * text.text('Hello world!'); + */ + + Konva.Collection.mapMethods(Konva.Text); +})(); + +(function () { + 'use strict'; + /** + * Line constructor.  Lines are defined by an array of points and + * a tension + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Array} config.points + * @param {Number} [config.tension] Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @param {Boolean} [config.closed] defines whether or not the line shape is closed, creating a polygon or blob + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var line = new Konva.Line({ + * x: 100, + * y: 50, + * points: [73, 70, 340, 23, 450, 60, 500, 20], + * stroke: 'red', + * tension: 1 + * }); + */ + Konva.Line = function (config) { + this.___init(config); + }; + + Konva.Line.prototype = { + ___init: function (config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Line'; + + this.on('pointsChange.konva tensionChange.konva closedChange.konva', function () { + this._clearCache('tensionPoints'); + }); + + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function (context) { + var points = this.getPoints(), + length = points.length, + tension = this.getTension(), + closed = this.getClosed(), + tp, len, n; + + if (!length) { + return; + } + + context.beginPath(); + context.moveTo(points[0], points[1]); + + // tension + if (tension !== 0 && length > 4) { + tp = this.getTensionPoints(); + len = tp.length; + n = closed ? 0 : 4; + + if (!closed) { + context.quadraticCurveTo(tp[0], tp[1], tp[2], tp[3]); + } + + while (n < len - 2) { + context.bezierCurveTo(tp[n++], tp[n++], tp[n++], tp[n++], tp[n++], tp[n++]); + } + + if (!closed) { + context.quadraticCurveTo(tp[len - 2], tp[len - 1], points[length - 2], points[length - 1]); + } + } + // no tension + else { + for (n = 2; n < length; n += 2) { + context.lineTo(points[n], points[n + 1]); + } + } + + // closed e.g. polygons and blobs + if (closed) { + context.closePath(); + context.fillStrokeShape(this); + } + // open e.g. lines and splines + else { + context.strokeShape(this); + } + }, + getTensionPoints: function () { + return this._getCache('tensionPoints', this._getTensionPoints); + }, + _getTensionPoints: function () { + if (this.getClosed()) { + return this._getTensionPointsClosed(); + } else { + return Konva.Util._expandPoints(this.getPoints(), this.getTension()); + } + }, + _getTensionPointsClosed: function () { + var p = this.getPoints(), + len = p.length, + tension = this.getTension(), + util = Konva.Util, + firstControlPoints = util._getControlPoints( + p[len - 2], + p[len - 1], + p[0], + p[1], + p[2], + p[3], + tension + ), + lastControlPoints = util._getControlPoints( + p[len - 4], + p[len - 3], + p[len - 2], + p[len - 1], + p[0], + p[1], + tension + ), + middle = Konva.Util._expandPoints(p, tension), + tp = [ + firstControlPoints[2], + firstControlPoints[3] + ] + .concat(middle) + .concat([ + lastControlPoints[0], + lastControlPoints[1], + p[len - 2], + p[len - 1], + lastControlPoints[2], + lastControlPoints[3], + firstControlPoints[0], + firstControlPoints[1], + p[0], + p[1] + ]); + + return tp; + }, + getWidth: function () { + return this.getSelfRect().width; + }, + getHeight: function () { + return this.getSelfRect().height; + }, + // overload size detection + getSelfRect: function () { + var points; + if (this.getTension() !== 0) { + points = this._getTensionPoints(); + } else { + points = this.getPoints(); + } + var minX = points[0]; + var maxX = points[0]; + var minY = points[1]; + var maxY = points[1]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; + y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX), + y: Math.round(minY), + width: Math.round(maxX - minX), + height: Math.round(maxY - minY) + }; + } + }; + Konva.Util.extend(Konva.Line, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Line, 'closed', false); + + /** + * get/set closed flag. The default is false + * @name closed + * @method + * @memberof Konva.Line.prototype + * @param {Boolean} closed + * @returns {Boolean} + * @example + * // get closed flag + * var closed = line.closed(); + * + * // close the shape + * line.closed(true); + * + * // open the shape + * line.closed(false); + */ + + Konva.Factory.addGetterSetter(Konva.Line, 'tension', 0); + + /** + * get/set tension + * @name tension + * @method + * @memberof Konva.Line.prototype + * @param {Number} Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @returns {Number} + * @example + * // get tension + * var tension = line.tension(); + * + * // set tension + * line.tension(3); + */ + + Konva.Factory.addGetterSetter(Konva.Line, 'points', []); + /** + * get/set points array + * @name points + * @method + * @memberof Konva.Line.prototype + * @param {Array} points + * @returns {Array} + * @example + * // get points + * var points = line.points(); + * + * // set points + * line.points([10, 20, 30, 40, 50, 60]); + * + * // push a new point + * line.points(line.points().concat([70, 80])); + */ + + Konva.Collection.mapMethods(Konva.Line); +})(); + +(function() { + 'use strict'; + /** + * Sprite constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} config.animation animation key + * @param {Object} config.animations animation map + * @param {Integer} [config.frameIndex] animation frame index + * @param {Image} config.image image object + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var imageObj = new Image(); + * imageObj.onload = function() { + * var sprite = new Konva.Sprite({ + * x: 200, + * y: 100, + * image: imageObj, + * animation: 'standing', + * animations: { + * standing: [ + * // x, y, width, height (6 frames) + * 0, 0, 49, 109, + * 52, 0, 49, 109, + * 105, 0, 49, 109, + * 158, 0, 49, 109, + * 210, 0, 49, 109, + * 262, 0, 49, 109 + * ], + * kicking: [ + * // x, y, width, height (6 frames) + * 0, 109, 45, 98, + * 45, 109, 45, 98, + * 95, 109, 63, 98, + * 156, 109, 70, 98, + * 229, 109, 60, 98, + * 287, 109, 41, 98 + * ] + * }, + * frameRate: 7, + * frameIndex: 0 + * }); + * }; + * imageObj.src = '/path/to/image.jpg' + */ + Konva.Sprite = function(config) { + this.___init(config); + }; + + Konva.Sprite.prototype = { + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Sprite'; + + this._updated = true; + var that = this; + this.anim = new Konva.Animation(function() { + // if we don't need to redraw layer we should return false + var updated = that._updated; + that._updated = false; + return updated; + }); + this.on('animationChange.konva', function() { + // reset index when animation changes + this.frameIndex(0); + }); + this.on('frameIndexChange.konva', function() { + this._updated = true; + }); + // smooth change for frameRate + this.on('frameRateChange.konva', function() { + if (!this.anim.isRunning()) { + return; + } + clearInterval(this.interval); + this._setInterval(); + }); + + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _sceneFunc: function(context) { + var anim = this.getAnimation(), + index = this.frameIndex(), + ix4 = index * 4, + set = this.getAnimations()[anim], + offsets = this.frameOffsets(), + x = set[ix4 + 0], + y = set[ix4 + 1], + width = set[ix4 + 2], + height = set[ix4 + 3], + image = this.getImage(); + + if (this.hasFill() || this.hasStroke()) { + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + } + + if(image) { + if (offsets) { + var offset = offsets[anim], + ix2 = index * 2; + context.drawImage(image, x, y, width, height, offset[ix2 + 0], offset[ix2 + 1], width, height); + } else { + context.drawImage(image, x, y, width, height, 0, 0, width, height); + } + } + }, + _hitFunc: function(context) { + var anim = this.getAnimation(), + index = this.frameIndex(), + ix4 = index * 4, + set = this.getAnimations()[anim], + offsets = this.frameOffsets(), + width = set[ix4 + 2], + height = set[ix4 + 3]; + + context.beginPath(); + if (offsets) { + var offset = offsets[anim]; + var ix2 = index * 2; + context.rect(offset[ix2 + 0], offset[ix2 + 1], width, height); + } else { + context.rect(0, 0, width, height); + } + context.closePath(); + context.fillShape(this); + }, + _useBufferCanvas: function() { + return (this.hasShadow() || this.getAbsoluteOpacity() !== 1) && this.hasStroke(); + }, + _setInterval: function() { + var that = this; + this.interval = setInterval(function() { + that._updateIndex(); + }, 1000 / this.getFrameRate()); + }, + /** + * start sprite animation + * @method + * @memberof Konva.Sprite.prototype + */ + start: function() { + var layer = this.getLayer(); + + /* + * animation object has no executable function because + * the updates are done with a fixed FPS with the setInterval + * below. The anim object only needs the layer reference for + * redraw + */ + this.anim.setLayers(layer); + this._setInterval(); + this.anim.start(); + }, + /** + * stop sprite animation + * @method + * @memberof Konva.Sprite.prototype + */ + stop: function() { + this.anim.stop(); + clearInterval(this.interval); + }, + /** + * determine if animation of sprite is running or not. returns true or false + * @method + * @memberof Konva.Animation.prototype + * @returns {Boolean} + */ + isRunning: function() { + return this.anim.isRunning(); + }, + _updateIndex: function() { + var index = this.frameIndex(), + animation = this.getAnimation(), + animations = this.getAnimations(), + anim = animations[animation], + len = anim.length / 4; + + if(index < len - 1) { + this.frameIndex(index + 1); + } + else { + this.frameIndex(0); + } + } + }; + Konva.Util.extend(Konva.Sprite, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Sprite, 'animation'); + + /** + * get/set animation key + * @name animation + * @method + * @memberof Konva.Sprite.prototype + * @param {String} anim animation key + * @returns {String} + * @example + * // get animation key + * var animation = sprite.animation(); + * + * // set animation key + * sprite.animation('kicking'); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'animations'); + + /** + * get/set animations map + * @name animations + * @method + * @memberof Konva.Sprite.prototype + * @param {Object} animations + * @returns {Object} + * @example + * // get animations map + * var animations = sprite.animations(); + * + * // set animations map + * sprite.animations({ + * standing: [ + * // x, y, width, height (6 frames) + * 0, 0, 49, 109, + * 52, 0, 49, 109, + * 105, 0, 49, 109, + * 158, 0, 49, 109, + * 210, 0, 49, 109, + * 262, 0, 49, 109 + * ], + * kicking: [ + * // x, y, width, height (6 frames) + * 0, 109, 45, 98, + * 45, 109, 45, 98, + * 95, 109, 63, 98, + * 156, 109, 70, 98, + * 229, 109, 60, 98, + * 287, 109, 41, 98 + * ] + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameOffsets'); + + /** + * get/set offsets map + * @name offsets + * @method + * @memberof Konva.Sprite.prototype + * @param {Object} offsets + * @returns {Object} + * @example + * // get offsets map + * var offsets = sprite.offsets(); + * + * // set offsets map + * sprite.offsets({ + * standing: [ + * // x, y (6 frames) + * 0, 0, + * 0, 0, + * 5, 0, + * 0, 0, + * 0, 3, + * 2, 0 + * ], + * kicking: [ + * // x, y (6 frames) + * 0, 5, + * 5, 0, + * 10, 0, + * 0, 0, + * 2, 1, + * 0, 0 + * ] + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'image'); + + /** + * get/set image + * @name image + * @method + * @memberof Konva.Sprite.prototype + * @param {Image} image + * @returns {Image} + * @example + * // get image + * var image = sprite.image(); + * + * // set image + * sprite.image(imageObj); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameIndex', 0); + + /** + * set/set animation frame index + * @name frameIndex + * @method + * @memberof Konva.Sprite.prototype + * @param {Integer} frameIndex + * @returns {Integer} + * @example + * // get animation frame index + * var frameIndex = sprite.frameIndex(); + * + * // set animation frame index + * sprite.frameIndex(3); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameRate', 17); + + /** + * get/set frame rate in frames per second. Increase this number to make the sprite + * animation run faster, and decrease the number to make the sprite animation run slower + * The default is 17 frames per second + * @name frameRate + * @method + * @memberof Konva.Sprite.prototype + * @param {Integer} frameRate + * @returns {Integer} + * @example + * // get frame rate + * var frameRate = sprite.frameRate(); + * + * // set frame rate to 2 frames per second + * sprite.frameRate(2); + */ + + Konva.Factory.backCompat(Konva.Sprite, { + index: 'frameIndex', + getIndex: 'getFrameIndex', + setIndex: 'setFrameIndex' + }); + + Konva.Collection.mapMethods(Konva.Sprite); +})(); + +/*eslint-disable no-shadow, max-len, max-depth */ +(function () { + 'use strict'; + /** + * Path constructor. + * @author Jason Follas + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} config.data SVG data string + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var path = new Konva.Path({ + * x: 240, + * y: 40, + * data: 'M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z', + * fill: 'green', + * scale: 2 + * }); + */ + Konva.Path = function (config) { + this.___init(config); + }; + + Konva.Path.prototype = { + ___init: function (config) { + this.dataArray = []; + var that = this; + + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Path'; + + this.dataArray = Konva.Path.parsePathData(this.getData()); + this.on('dataChange.konva', function () { + that.dataArray = Konva.Path.parsePathData(this.getData()); + }); + + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var ca = this.dataArray; + + // context position + context.beginPath(); + for (var n = 0; n < ca.length; n++) { + var c = ca[n].command; + var p = ca[n].points; + switch (c) { + case 'L': + context.lineTo(p[0], p[1]); + break; + case 'M': + context.moveTo(p[0], p[1]); + break; + case 'C': + context.bezierCurveTo(p[0], p[1], p[2], p[3], p[4], p[5]); + break; + case 'Q': + context.quadraticCurveTo(p[0], p[1], p[2], p[3]); + break; + case 'A': + var cx = p[0], cy = p[1], rx = p[2], ry = p[3], theta = p[4], dTheta = p[5], psi = p[6], fs = p[7]; + + var r = (rx > ry) ? rx : ry; + var scaleX = (rx > ry) ? 1 : rx / ry; + var scaleY = (rx > ry) ? ry / rx : 1; + + context.translate(cx, cy); + context.rotate(psi); + context.scale(scaleX, scaleY); + context.arc(0, 0, r, theta, theta + dTheta, 1 - fs); + context.scale(1 / scaleX, 1 / scaleY); + context.rotate(-psi); + context.translate(-cx, -cy); + + break; + case 'z': + context.closePath(); + break; + } + } + + context.fillStrokeShape(this); + }, + getSelfRect: function() { + var points = []; + this.dataArray.forEach(function(data) { + points = points.concat(data.points); + }); + var minX = points[0]; + var maxX = points[0]; + var minY = points[1]; + var maxY = points[1]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX), + y: Math.round(minY), + width: Math.round(maxX - minX), + height: Math.round(maxY - minY) + }; + } + }; + Konva.Util.extend(Konva.Path, Konva.Shape); + + Konva.Path.getLineLength = function(x1, y1, x2, y2) { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + }; + Konva.Path.getPointOnLine = function(dist, P1x, P1y, P2x, P2y, fromX, fromY) { + if(fromX === undefined) { + fromX = P1x; + } + if(fromY === undefined) { + fromY = P1y; + } + + var m = (P2y - P1y) / ((P2x - P1x) + 0.00000001); + var run = Math.sqrt(dist * dist / (1 + m * m)); + if(P2x < P1x) { + run *= -1; + } + var rise = m * run; + var pt; + + if (P2x === P1x) { // vertical line + pt = { + x: fromX, + y: fromY + rise + }; + } else if((fromY - P1y) / ((fromX - P1x) + 0.00000001) === m) { + pt = { + x: fromX + run, + y: fromY + rise + }; + } + else { + var ix, iy; + + var len = this.getLineLength(P1x, P1y, P2x, P2y); + if(len < 0.00000001) { + return undefined; + } + var u = (((fromX - P1x) * (P2x - P1x)) + ((fromY - P1y) * (P2y - P1y))); + u = u / (len * len); + ix = P1x + u * (P2x - P1x); + iy = P1y + u * (P2y - P1y); + + var pRise = this.getLineLength(fromX, fromY, ix, iy); + var pRun = Math.sqrt(dist * dist - pRise * pRise); + run = Math.sqrt(pRun * pRun / (1 + m * m)); + if(P2x < P1x) { + run *= -1; + } + rise = m * run; + pt = { + x: ix + run, + y: iy + rise + }; + } + + return pt; + }; + + Konva.Path.getPointOnCubicBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y, P4x, P4y) { + function CB1(t) { + return t * t * t; + } + function CB2(t) { + return 3 * t * t * (1 - t); + } + function CB3(t) { + return 3 * t * (1 - t) * (1 - t); + } + function CB4(t) { + return (1 - t) * (1 - t) * (1 - t); + } + var x = P4x * CB1(pct) + P3x * CB2(pct) + P2x * CB3(pct) + P1x * CB4(pct); + var y = P4y * CB1(pct) + P3y * CB2(pct) + P2y * CB3(pct) + P1y * CB4(pct); + + return { + x: x, + y: y + }; + }; + Konva.Path.getPointOnQuadraticBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y) { + function QB1(t) { + return t * t; + } + function QB2(t) { + return 2 * t * (1 - t); + } + function QB3(t) { + return (1 - t) * (1 - t); + } + var x = P3x * QB1(pct) + P2x * QB2(pct) + P1x * QB3(pct); + var y = P3y * QB1(pct) + P2y * QB2(pct) + P1y * QB3(pct); + + return { + x: x, + y: y + }; + }; + Konva.Path.getPointOnEllipticalArc = function(cx, cy, rx, ry, theta, psi) { + var cosPsi = Math.cos(psi), sinPsi = Math.sin(psi); + var pt = { + x: rx * Math.cos(theta), + y: ry * Math.sin(theta) + }; + return { + x: cx + (pt.x * cosPsi - pt.y * sinPsi), + y: cy + (pt.x * sinPsi + pt.y * cosPsi) + }; + }; + /* + * get parsed data array from the data + * string. V, v, H, h, and l data are converted to + * L data for the purpose of high performance Path + * rendering + */ + Konva.Path.parsePathData = function(data) { + // Path Data Segment must begin with a moveTo + //m (x y)+ Relative moveTo (subsequent points are treated as lineTo) + //M (x y)+ Absolute moveTo (subsequent points are treated as lineTo) + //l (x y)+ Relative lineTo + //L (x y)+ Absolute LineTo + //h (x)+ Relative horizontal lineTo + //H (x)+ Absolute horizontal lineTo + //v (y)+ Relative vertical lineTo + //V (y)+ Absolute vertical lineTo + //z (closepath) + //Z (closepath) + //c (x1 y1 x2 y2 x y)+ Relative Bezier curve + //C (x1 y1 x2 y2 x y)+ Absolute Bezier curve + //q (x1 y1 x y)+ Relative Quadratic Bezier + //Q (x1 y1 x y)+ Absolute Quadratic Bezier + //t (x y)+ Shorthand/Smooth Relative Quadratic Bezier + //T (x y)+ Shorthand/Smooth Absolute Quadratic Bezier + //s (x2 y2 x y)+ Shorthand/Smooth Relative Bezier curve + //S (x2 y2 x y)+ Shorthand/Smooth Absolute Bezier curve + //a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ Relative Elliptical Arc + //A (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ Absolute Elliptical Arc + + // return early if data is not defined + if(!data) { + return []; + } + + // command string + var cs = data; + + // command chars + var cc = ['m', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z', 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A']; + // convert white spaces to commas + cs = cs.replace(new RegExp(' ', 'g'), ','); + // create pipes so that we can split the data + for(var n = 0; n < cc.length; n++) { + cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]); + } + // create array + var arr = cs.split('|'); + var ca = []; + // init context point + var cpx = 0; + var cpy = 0; + for( n = 1; n < arr.length; n++) { + var str = arr[n]; + var c = str.charAt(0); + str = str.slice(1); + // remove ,- for consistency + str = str.replace(new RegExp(',-', 'g'), '-'); + // add commas so that it's easy to split + str = str.replace(new RegExp('-', 'g'), ',-'); + str = str.replace(new RegExp('e,-', 'g'), 'e-'); + var p = str.split(','); + if(p.length > 0 && p[0] === '') { + p.shift(); + } + // convert strings to floats + for(var i = 0; i < p.length; i++) { + p[i] = parseFloat(p[i]); + } + while(p.length > 0) { + if(isNaN(p[0])) {// case for a trailing comma before next command + break; + } + + var cmd = null; + var points = []; + var startX = cpx, startY = cpy; + // Move var from within the switch to up here (jshint) + var prevCmd, ctlPtx, ctlPty; // Ss, Tt + var rx, ry, psi, fa, fs, x1, y1; // Aa + + + // convert l, H, h, V, and v to L + switch (c) { + + // Note: Keep the lineTo's above the moveTo's in this switch + case 'l': + cpx += p.shift(); + cpy += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'L': + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + + // Note: lineTo handlers need to be above this point + case 'm': + var dx = p.shift(); + var dy = p.shift(); + cpx += dx; + cpy += dy; + cmd = 'M'; + // After closing the path move the current position + // to the the first point of the path (if any). + if(ca.length > 2 && ca[ca.length - 1].command === 'z'){ + for(var idx = ca.length - 2; idx >= 0; idx--){ + if(ca[idx].command === 'M'){ + cpx = ca[idx].points[0] + dx; + cpy = ca[idx].points[1] + dy; + break; + } + } + } + points.push(cpx, cpy); + c = 'l'; + // subsequent points are treated as relative lineTo + break; + case 'M': + cpx = p.shift(); + cpy = p.shift(); + cmd = 'M'; + points.push(cpx, cpy); + c = 'L'; + // subsequent points are treated as absolute lineTo + break; + + case 'h': + cpx += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'H': + cpx = p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'v': + cpy += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'V': + cpy = p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'C': + points.push(p.shift(), p.shift(), p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + case 'c': + points.push(cpx + p.shift(), cpy + p.shift(), cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 'S': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'C') { + ctlPtx = cpx + (cpx - prevCmd.points[2]); + ctlPty = cpy + (cpy - prevCmd.points[3]); + } + points.push(ctlPtx, ctlPty, p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 's': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'C') { + ctlPtx = cpx + (cpx - prevCmd.points[2]); + ctlPty = cpy + (cpy - prevCmd.points[3]); + } + points.push(ctlPtx, ctlPty, cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 'Q': + points.push(p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + case 'q': + points.push(cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'Q'; + points.push(cpx, cpy); + break; + case 'T': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'Q') { + ctlPtx = cpx + (cpx - prevCmd.points[0]); + ctlPty = cpy + (cpy - prevCmd.points[1]); + } + cpx = p.shift(); + cpy = p.shift(); + cmd = 'Q'; + points.push(ctlPtx, ctlPty, cpx, cpy); + break; + case 't': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'Q') { + ctlPtx = cpx + (cpx - prevCmd.points[0]); + ctlPty = cpy + (cpy - prevCmd.points[1]); + } + cpx += p.shift(); + cpy += p.shift(); + cmd = 'Q'; + points.push(ctlPtx, ctlPty, cpx, cpy); + break; + case 'A': + rx = p.shift(); + ry = p.shift(); + psi = p.shift(); + fa = p.shift(); + fs = p.shift(); + x1 = cpx; + y1 = cpy; + cpx = p.shift(); + cpy = p.shift(); + cmd = 'A'; + points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); + break; + case 'a': + rx = p.shift(); + ry = p.shift(); + psi = p.shift(); + fa = p.shift(); + fs = p.shift(); + x1 = cpx; + y1 = cpy; cpx += p.shift(); + cpy += p.shift(); + cmd = 'A'; + points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); + break; + } + + ca.push({ + command: cmd || c, + points: points, + start: { + x: startX, + y: startY + }, + pathLength: this.calcLength(startX, startY, cmd || c, points) + }); + } + + if(c === 'z' || c === 'Z') { + ca.push({ + command: 'z', + points: [], + start: undefined, + pathLength: 0 + }); + } + } + + return ca; + }; + Konva.Path.calcLength = function(x, y, cmd, points) { + var len, p1, p2, t; + var path = Konva.Path; + + switch (cmd) { + case 'L': + return path.getLineLength(x, y, points[0], points[1]); + case 'C': + // Approximates by breaking curve into 100 line segments + len = 0.0; + p1 = path.getPointOnCubicBezier(0, x, y, points[0], points[1], points[2], points[3], points[4], points[5]); + for( t = 0.01; t <= 1; t += 0.01) { + p2 = path.getPointOnCubicBezier(t, x, y, points[0], points[1], points[2], points[3], points[4], points[5]); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + return len; + case 'Q': + // Approximates by breaking curve into 100 line segments + len = 0.0; + p1 = path.getPointOnQuadraticBezier(0, x, y, points[0], points[1], points[2], points[3]); + for( t = 0.01; t <= 1; t += 0.01) { + p2 = path.getPointOnQuadraticBezier(t, x, y, points[0], points[1], points[2], points[3]); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + return len; + case 'A': + // Approximates by breaking curve into line segments + len = 0.0; + var start = points[4]; + // 4 = theta + var dTheta = points[5]; + // 5 = dTheta + var end = points[4] + dTheta; + var inc = Math.PI / 180.0; + // 1 degree resolution + if(Math.abs(start - end) < inc) { + inc = Math.abs(start - end); + } + // Note: for purpose of calculating arc length, not going to worry about rotating X-axis by angle psi + p1 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], start, 0); + if(dTheta < 0) {// clockwise + for( t = start - inc; t > end; t -= inc) { + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + } + else {// counter-clockwise + for( t = start + inc; t < end; t += inc) { + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + } + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], end, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + + return len; + } + + return 0; + }; + Konva.Path.convertEndpointToCenterParameterization = function(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg) { + // Derived from: http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes + var psi = psiDeg * (Math.PI / 180.0); + var xp = Math.cos(psi) * (x1 - x2) / 2.0 + Math.sin(psi) * (y1 - y2) / 2.0; + var yp = -1 * Math.sin(psi) * (x1 - x2) / 2.0 + Math.cos(psi) * (y1 - y2) / 2.0; + + var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); + + if(lambda > 1) { + rx *= Math.sqrt(lambda); + ry *= Math.sqrt(lambda); + } + + var f = Math.sqrt((((rx * rx) * (ry * ry)) - ((rx * rx) * (yp * yp)) - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp) + (ry * ry) * (xp * xp))); + + if(fa === fs) { + f *= -1; + } + if(isNaN(f)) { + f = 0; + } + + var cxp = f * rx * yp / ry; + var cyp = f * -ry * xp / rx; + + var cx = (x1 + x2) / 2.0 + Math.cos(psi) * cxp - Math.sin(psi) * cyp; + var cy = (y1 + y2) / 2.0 + Math.sin(psi) * cxp + Math.cos(psi) * cyp; + + var vMag = function(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1]); + }; + var vRatio = function(u, v) { + return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)); + }; + var vAngle = function(u, v) { + return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v)); + }; + var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]); + var u = [(xp - cxp) / rx, (yp - cyp) / ry]; + var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; + var dTheta = vAngle(u, v); + + if(vRatio(u, v) <= -1) { + dTheta = Math.PI; + } + if(vRatio(u, v) >= 1) { + dTheta = 0; + } + if(fs === 0 && dTheta > 0) { + dTheta = dTheta - 2 * Math.PI; + } + if(fs === 1 && dTheta < 0) { + dTheta = dTheta + 2 * Math.PI; + } + return [cx, cy, rx, ry, theta, dTheta, psi, fs]; + }; + // add getters setters + Konva.Factory.addGetterSetter(Konva.Path, 'data'); + + /** + * set SVG path data string. This method + * also automatically parses the data string + * into a data array. Currently supported SVG data: + * M, m, L, l, H, h, V, v, Q, q, T, t, C, c, S, s, A, a, Z, z + * @name setData + * @method + * @memberof Konva.Path.prototype + * @param {String} SVG path command string + */ + + /** + * get SVG path data string + * @name getData + * @method + * @memberof Konva.Path.prototype + */ + + Konva.Collection.mapMethods(Konva.Path); +})(); + +(function() { + 'use strict'; + var EMPTY_STRING = '', + //CALIBRI = 'Calibri', + NORMAL = 'normal'; + + /** + * Path constructor. + * @author Jason Follas + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} [config.fontFamily] default is Calibri + * @param {Number} [config.fontSize] default is 12 + * @param {String} [config.fontStyle] can be normal, bold, or italic. Default is normal + * @param {String} [config.fontVariant] can be normal or small-caps. Default is normal + * @param {String} config.text + * @param {String} config.data SVG data string + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var textpath = new Konva.TextPath({ + * x: 100, + * y: 50, + * fill: '#333', + * fontSize: '24', + * fontFamily: 'Arial', + * text: 'All the world\'s a stage, and all the men and women merely players.', + * data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50' + * }); + */ + Konva.TextPath = function(config) { + this.___init(config); + }; + + function _fillFunc(context) { + context.fillText(this.partialText, 0, 0); + } + function _strokeFunc(context) { + context.strokeText(this.partialText, 0, 0); + } + + Konva.TextPath.prototype = { + ___init: function(config) { + var that = this; + this.dummyCanvas = Konva.Util.createCanvasElement(); + this.dataArray = []; + + // call super constructor + Konva.Shape.call(this, config); + + // overrides + // TODO: shouldn't this be on the prototype? + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this._fillFuncHit = _fillFunc; + this._strokeFuncHit = _strokeFunc; + + this.className = 'TextPath'; + + this.dataArray = Konva.Path.parsePathData(this.attrs.data); + this.on('dataChange.konva', function() { + that.dataArray = Konva.Path.parsePathData(this.attrs.data); + }); + + // update text data for certain attr changes + this.on('textChange.konva textStroke.konva textStrokeWidth.konva', that._setTextData); + that._setTextData(); + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.setAttr('font', this._getContextFont()); + context.setAttr('textBaseline', 'middle'); + context.setAttr('textAlign', 'left'); + context.save(); + + var glyphInfo = this.glyphInfo; + for(var i = 0; i < glyphInfo.length; i++) { + context.save(); + + var p0 = glyphInfo[i].p0; + + context.translate(p0.x, p0.y); + context.rotate(glyphInfo[i].rotation); + this.partialText = glyphInfo[i].text; + + context.fillStrokeShape(this); + context.restore(); + + //// To assist with debugging visually, uncomment following + // context.beginPath(); + // if (i % 2) + // context.strokeStyle = 'cyan'; + // else + // context.strokeStyle = 'green'; + // var p1 = glyphInfo[i].p1; + // context.moveTo(p0.x, p0.y); + // context.lineTo(p1.x, p1.y); + // context.stroke(); + } + context.restore(); + }, + /** + * get text width in pixels + * @method + * @memberof Konva.TextPath.prototype + */ + getTextWidth: function() { + return this.textWidth; + }, + /** + * get text height in pixels + * @method + * @memberof Konva.TextPath.prototype + */ + getTextHeight: function() { + return this.textHeight; + }, + /** + * set text + * @method + * @memberof Konva.TextPath.prototype + * @param {String} text + */ + setText: function(text) { + Konva.Text.prototype.setText.call(this, text); + }, + _getTextSize: function(text) { + var dummyCanvas = this.dummyCanvas; + var _context = dummyCanvas.getContext('2d'); + + _context.save(); + + _context.font = this._getContextFont(); + var metrics = _context.measureText(text); + + _context.restore(); + + return { + width: metrics.width, + height: parseInt(this.attrs.fontSize, 10) + }; + }, + _setTextData: function() { + + var that = this; + var size = this._getTextSize(this.attrs.text); + this.textWidth = size.width; + this.textHeight = size.height; + + this.glyphInfo = []; + + var charArr = this.attrs.text.split(''); + + var p0, p1, pathCmd; + + var pIndex = -1; + var currentT = 0; + + var getNextPathSegment = function() { + currentT = 0; + var pathData = that.dataArray; + + for(var j = pIndex + 1; j < pathData.length; j++) { + if(pathData[j].pathLength > 0) { + pIndex = j; + + return pathData[j]; + } + else if(pathData[j].command === 'M') { + p0 = { + x: pathData[j].points[0], + y: pathData[j].points[1] + }; + } + } + + return {}; + }; + var findSegmentToFitCharacter = function(c) { + + var glyphWidth = that._getTextSize(c).width; + + var currLen = 0; + var attempts = 0; + + p1 = undefined; + while(Math.abs(glyphWidth - currLen) / glyphWidth > 0.01 && attempts < 25) { + attempts++; + var cumulativePathLength = currLen; + while(pathCmd === undefined) { + pathCmd = getNextPathSegment(); + + if(pathCmd && cumulativePathLength + pathCmd.pathLength < glyphWidth) { + cumulativePathLength += pathCmd.pathLength; + pathCmd = undefined; + } + } + + if(pathCmd === {} || p0 === undefined) { + return undefined; + } + + var needNewSegment = false; + + switch (pathCmd.command) { + case 'L': + if(Konva.Path.getLineLength(p0.x, p0.y, pathCmd.points[0], pathCmd.points[1]) > glyphWidth) { + p1 = Konva.Path.getPointOnLine(glyphWidth, p0.x, p0.y, pathCmd.points[0], pathCmd.points[1], p0.x, p0.y); + } + else { + pathCmd = undefined; + } + break; + case 'A': + + var start = pathCmd.points[4]; + // 4 = theta + var dTheta = pathCmd.points[5]; + // 5 = dTheta + var end = pathCmd.points[4] + dTheta; + + if(currentT === 0){ + currentT = start + 0.00000001; + } + // Just in case start is 0 + else if(glyphWidth > currLen) { + currentT += (Math.PI / 180.0) * dTheta / Math.abs(dTheta); + } + else { + currentT -= Math.PI / 360.0 * dTheta / Math.abs(dTheta); + } + + // Credit for bug fix: @therth https://github.com/ericdrowell/KonvaJS/issues/249 + // Old code failed to render text along arc of this path: "M 50 50 a 150 50 0 0 1 250 50 l 50 0" + if(dTheta < 0 && currentT < end || dTheta >= 0 && currentT > end) { + currentT = end; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnEllipticalArc(pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], currentT, pathCmd.points[6]); + break; + case 'C': + if(currentT === 0) { + if(glyphWidth > pathCmd.pathLength) { + currentT = 0.00000001; + } + else { + currentT = glyphWidth / pathCmd.pathLength; + } + } + else if(glyphWidth > currLen) { + currentT += (glyphWidth - currLen) / pathCmd.pathLength; + } + else { + currentT -= (currLen - glyphWidth) / pathCmd.pathLength; + } + + if(currentT > 1.0) { + currentT = 1.0; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnCubicBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], pathCmd.points[4], pathCmd.points[5]); + break; + case 'Q': + if(currentT === 0) { + currentT = glyphWidth / pathCmd.pathLength; + } + else if(glyphWidth > currLen) { + currentT += (glyphWidth - currLen) / pathCmd.pathLength; + } + else { + currentT -= (currLen - glyphWidth) / pathCmd.pathLength; + } + + if(currentT > 1.0) { + currentT = 1.0; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnQuadraticBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3]); + break; + + } + + if(p1 !== undefined) { + currLen = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y); + } + + if(needNewSegment) { + needNewSegment = false; + pathCmd = undefined; + } + } + }; + for(var i = 0; i < charArr.length; i++) { + + // Find p1 such that line segment between p0 and p1 is approx. width of glyph + findSegmentToFitCharacter(charArr[i]); + + if(p0 === undefined || p1 === undefined) { + break; + } + + var width = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y); + + // Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used. + // Can foresee having a rough pair table built in that the developer can override as needed. + + var kern = 0; + // placeholder for future implementation + + var midpoint = Konva.Path.getPointOnLine(kern + width / 2.0, p0.x, p0.y, p1.x, p1.y); + + var rotation = Math.atan2((p1.y - p0.y), (p1.x - p0.x)); + this.glyphInfo.push({ + transposeX: midpoint.x, + transposeY: midpoint.y, + text: charArr[i], + rotation: rotation, + p0: p0, + p1: p1 + }); + p0 = p1; + } + }, + getSelfRect: function() { + var points = []; + var fontSize = this.fontSize(); + + this.glyphInfo.forEach(function(info) { + points.push(info.p0.x); + points.push(info.p0.y); + points.push(info.p1.x); + points.push(info.p1.y); + }); + var minX = points[0]; + var maxX = points[0]; + var minY = points[0]; + var maxY = points[0]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX) - fontSize, + y: Math.round(minY) - fontSize, + width: Math.round(maxX - minX) + fontSize * 2, + height: Math.round(maxY - minY) + fontSize * 2 + }; + } + }; + + // map TextPath methods to Text + Konva.TextPath.prototype._getContextFont = Konva.Text.prototype._getContextFont; + + Konva.Util.extend(Konva.TextPath, Konva.Shape); + + // add setters and getters + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontFamily', 'Arial'); + + /** + * set font family + * @name setFontFamily + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontFamily + */ + + /** + * get font family + * @name getFontFamily + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontSize', 12); + + /** + * set font size + * @name setFontSize + * @method + * @memberof Konva.TextPath.prototype + * @param {int} fontSize + */ + + /** + * get font size + * @name getFontSize + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontStyle', NORMAL); + + /** + * set font style. Can be 'normal', 'italic', or 'bold'. 'normal' is the default. + * @name setFontStyle + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontStyle + */ + + /** + * get font style + * @name getFontStyle + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontVariant', NORMAL); + + /** + * set font variant. Can be 'normal' or 'small-caps'. 'normal' is the default. + * @name setFontVariant + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontVariant + */ + + /** + * @get font variant + * @name getFontVariant + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetter(Konva.TextPath, 'text', EMPTY_STRING); + + /** + * get text + * @name getText + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Collection.mapMethods(Konva.TextPath); +})(); + +(function() { + 'use strict'; + /** + * RegularPolygon constructor.  Examples include triangles, squares, pentagons, hexagons, etc. + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.sides + * @param {Number} config.radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var hexagon = new Konva.RegularPolygon({ + * x: 100, + * y: 200, + * sides: 6, + * radius: 70, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 4 + * }); + */ + Konva.RegularPolygon = function(config) { + this.___init(config); + }; + + Konva.RegularPolygon.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'RegularPolygon'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var sides = this.attrs.sides, + radius = this.attrs.radius, + n, x, y; + + context.beginPath(); + context.moveTo(0, 0 - radius); + + for(n = 1; n < sides; n++) { + x = radius * Math.sin(n * 2 * Math.PI / sides); + y = -1 * radius * Math.cos(n * 2 * Math.PI / sides); + context.lineTo(x, y); + } + context.closePath(); + context.fillStrokeShape(this); + }, + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.RegularPolygon, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.RegularPolygon, 'radius', 0); + + /** + * set radius + * @name setRadius + * @method + * @memberof Konva.RegularPolygon.prototype + * @param {Number} radius + */ + + /** + * get radius + * @name getRadius + * @method + * @memberof Konva.RegularPolygon.prototype + */ + + Konva.Factory.addGetterSetter(Konva.RegularPolygon, 'sides', 0); + + /** + * set number of sides + * @name setSides + * @method + * @memberof Konva.RegularPolygon.prototype + * @param {int} sides + */ + + /** + * get number of sides + * @name getSides + * @method + * @memberof Konva.RegularPolygon.prototype + */ + + Konva.Collection.mapMethods(Konva.RegularPolygon); +})(); + +(function() { + 'use strict'; + /** + * Star constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Integer} config.numPoints + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var star = new Konva.Star({ + * x: 100, + * y: 200, + * numPoints: 5, + * innerRadius: 70, + * outerRadius: 70, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 4 + * }); + */ + Konva.Star = function(config) { + this.___init(config); + }; + + Konva.Star.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Star'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var innerRadius = this.innerRadius(), + outerRadius = this.outerRadius(), + numPoints = this.numPoints(); + + context.beginPath(); + context.moveTo(0, 0 - outerRadius); + + for(var n = 1; n < numPoints * 2; n++) { + var radius = n % 2 === 0 ? outerRadius : innerRadius; + var x = radius * Math.sin(n * Math.PI / numPoints); + var y = -1 * radius * Math.cos(n * Math.PI / numPoints); + context.lineTo(x, y); + } + context.closePath(); + + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.outerRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.outerRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Star, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Star, 'numPoints', 5); + + /** + * set number of points + * @name setNumPoints + * @method + * @memberof Konva.Star.prototype + * @param {Integer} points + */ + + /** + * get number of points + * @name getNumPoints + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Star, 'innerRadius', 0); + + /** + * set inner radius + * @name setInnerRadius + * @method + * @memberof Konva.Star.prototype + * @param {Number} radius + */ + + /** + * get inner radius + * @name getInnerRadius + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Star, 'outerRadius', 0); + + /** + * set outer radius + * @name setOuterRadius + * @method + * @memberof Konva.Star.prototype + * @param {Number} radius + */ + + /** + * get outer radius + * @name getOuterRadius + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Collection.mapMethods(Konva.Star); +})(); + +(function() { + 'use strict'; + // constants + var ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'padding', 'lineHeight', 'text'], + CHANGE_KONVA = 'Change.konva', + NONE = 'none', + UP = 'up', + RIGHT = 'right', + DOWN = 'down', + LEFT = 'left', + LABEL = 'Label', + + // cached variables + attrChangeListLen = ATTR_CHANGE_LIST.length; + + /** + * Label constructor.  Labels are groups that contain a Text and Tag shape + * @constructor + * @memberof Konva + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // create label + * var label = new Konva.Label({ + * x: 100, + * y: 100, + * draggable: true + * }); + * + * // add a tag to the label + * label.add(new Konva.Tag({ + * fill: '#bbb', + * stroke: '#333', + * shadowColor: 'black', + * shadowBlur: 10, + * shadowOffset: [10, 10], + * shadowOpacity: 0.2, + * lineJoin: 'round', + * pointerDirection: 'up', + * pointerWidth: 20, + * pointerHeight: 20, + * cornerRadius: 5 + * })); + * + * // add text to the label + * label.add(new Konva.Text({ + * text: 'Hello World!', + * fontSize: 50, + * lineHeight: 1.2, + * padding: 10, + * fill: 'green' + * })); + */ + Konva.Label = function(config) { + this.____init(config); + }; + + Konva.Label.prototype = { + ____init: function(config) { + var that = this; + + Konva.Group.call(this, config); + this.className = LABEL; + + this.on('add.konva', function(evt) { + that._addListeners(evt.child); + that._sync(); + }); + }, + /** + * get Text shape for the label. You need to access the Text shape in order to update + * the text properties + * @name getText + * @method + * @memberof Konva.Label.prototype + */ + getText: function() { + return this.find('Text')[0]; + }, + /** + * get Tag shape for the label. You need to access the Tag shape in order to update + * the pointer properties and the corner radius + * @name getTag + * @method + * @memberof Konva.Label.prototype + */ + getTag: function() { + return this.find('Tag')[0]; + }, + _addListeners: function(text) { + var that = this, + n; + var func = function(){ + that._sync(); + }; + + // update text data for certain attr changes + for(n = 0; n < attrChangeListLen; n++) { + text.on(ATTR_CHANGE_LIST[n] + CHANGE_KONVA, func); + } + }, + getWidth: function() { + return this.getText().getWidth(); + }, + getHeight: function() { + return this.getText().getHeight(); + }, + _sync: function() { + var text = this.getText(), + tag = this.getTag(), + width, height, pointerDirection, pointerWidth, x, y, pointerHeight; + + if (text && tag) { + width = text.getWidth(); + height = text.getHeight(); + pointerDirection = tag.getPointerDirection(); + pointerWidth = tag.getPointerWidth(); + pointerHeight = tag.getPointerHeight(); + x = 0; + y = 0; + + switch(pointerDirection) { + case UP: + x = width / 2; + y = -1 * pointerHeight; + break; + case RIGHT: + x = width + pointerWidth; + y = height / 2; + break; + case DOWN: + x = width / 2; + y = height + pointerHeight; + break; + case LEFT: + x = -1 * pointerWidth; + y = height / 2; + break; + } + + tag.setAttrs({ + x: -1 * x, + y: -1 * y, + width: width, + height: height + }); + + text.setAttrs({ + x: -1 * x, + y: -1 * y + }); + } + } + }; + + Konva.Util.extend(Konva.Label, Konva.Group); + + Konva.Collection.mapMethods(Konva.Label); + + /** + * Tag constructor.  A Tag can be configured + * to have a pointer element that points up, right, down, or left + * @constructor + * @memberof Konva + * @param {Object} config + * @param {String} [config.pointerDirection] can be up, right, down, left, or none; the default + * is none. When a pointer is present, the positioning of the label is relative to the tip of the pointer. + * @param {Number} [config.pointerWidth] + * @param {Number} [config.pointerHeight] + * @param {Number} [config.cornerRadius] + */ + Konva.Tag = function(config) { + this.___init(config); + }; + + Konva.Tag.prototype = { + ___init: function(config) { + Konva.Shape.call(this, config); + this.className = 'Tag'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(), + pointerDirection = this.getPointerDirection(), + pointerWidth = this.getPointerWidth(), + pointerHeight = this.getPointerHeight(), + cornerRadius = Math.min(this.getCornerRadius(), width / 2, height / 2); + + context.beginPath(); + if (!cornerRadius) { + context.moveTo(0, 0); + } else { + context.moveTo(cornerRadius, 0); + } + + if (pointerDirection === UP) { + context.lineTo((width - pointerWidth) / 2, 0); + context.lineTo(width / 2, -1 * pointerHeight); + context.lineTo((width + pointerWidth) / 2, 0); + } + + if(!cornerRadius) { + context.lineTo(width, 0); + } else { + context.lineTo(width - cornerRadius, 0); + context.arc(width - cornerRadius, cornerRadius, cornerRadius, Math.PI * 3 / 2, 0, false); + } + + if (pointerDirection === RIGHT) { + context.lineTo(width, (height - pointerHeight) / 2); + context.lineTo(width + pointerWidth, height / 2); + context.lineTo(width, (height + pointerHeight) / 2); + } + + if(!cornerRadius) { + context.lineTo(width, height); + } else { + context.lineTo(width, height - cornerRadius); + context.arc(width - cornerRadius, height - cornerRadius, cornerRadius, 0, Math.PI / 2, false); + } + + if (pointerDirection === DOWN) { + context.lineTo((width + pointerWidth) / 2, height); + context.lineTo(width / 2, height + pointerHeight); + context.lineTo((width - pointerWidth) / 2, height); + } + + if(!cornerRadius) { + context.lineTo(0, height); + } else { + context.lineTo(cornerRadius, height); + context.arc(cornerRadius, height - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false); + } + + if (pointerDirection === LEFT) { + context.lineTo(0, (height + pointerHeight) / 2); + context.lineTo(-1 * pointerWidth, height / 2); + context.lineTo(0, (height - pointerHeight) / 2); + } + + if(cornerRadius) { + context.lineTo(0, cornerRadius); + context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false); + } + + context.closePath(); + context.fillStrokeShape(this); + }, + getSelfRect: function() { + var x = 0, + y = 0, + pointerWidth = this.getPointerWidth(), + pointerHeight = this.getPointerHeight(), + direction = this.pointerDirection(), + width = this.getWidth(), + height = this.getHeight(); + + if (direction === UP) { + y -= pointerHeight; + height += pointerHeight; + } else if (direction === DOWN) { + height += pointerHeight; + } else if (direction === LEFT) { + // ARGH!!! I have no idea why should I used magic 1.5!!!!!!!!! + x -= pointerWidth * 1.5; + width += pointerWidth; + } else if (direction === RIGHT) { + width += pointerWidth * 1.5; + } + return { + x: x, + y: y, + width: width, + height: height + }; + } + }; + + Konva.Util.extend(Konva.Tag, Konva.Shape); + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerDirection', NONE); + + /** + * set pointer Direction + * @name setPointerDirection + * @method + * @memberof Konva.Tag.prototype + * @param {String} pointerDirection can be up, right, down, left, or none. The + * default is none + */ + + /** + * get pointer Direction + * @name getPointerDirection + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerWidth', 0); + + /** + * set pointer width + * @name setPointerWidth + * @method + * @memberof Konva.Tag.prototype + * @param {Number} pointerWidth + */ + + /** + * get pointer width + * @name getPointerWidth + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerHeight', 0); + + /** + * set pointer height + * @name setPointerHeight + * @method + * @memberof Konva.Tag.prototype + * @param {Number} pointerHeight + */ + + /** + * get pointer height + * @name getPointerHeight + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'cornerRadius', 0); + + /** + * set corner radius + * @name setCornerRadius + * @method + * @memberof Konva.Tag.prototype + * @param {Number} corner radius + */ + + /** + * get corner radius + * @name getCornerRadius + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Collection.mapMethods(Konva.Tag); +})(); + +(function() { + 'use strict'; + /** + * Arrow constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Array} config.points + * @param {Number} [config.tension] Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @param {Number} config.pointerLength + * @param {Number} config.pointerWidth + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var line = new Konva.Line({ + * points: [73, 70, 340, 23, 450, 60, 500, 20], + * stroke: 'red', + * tension: 1, + * pointerLength : 10, + * pointerWidth : 12 + * }); + */ + Konva.Arrow = function(config) { + this.____init(config); + }; + + Konva.Arrow.prototype = { + ____init: function(config) { + // call super constructor + Konva.Line.call(this, config); + this.className = 'Arrow'; + }, + _sceneFunc: function(ctx) { + Konva.Line.prototype._sceneFunc.apply(this, arguments); + var PI2 = Math.PI * 2; + var points = this.points(); + var n = points.length; + var dx = points[n - 2] - points[n - 4]; + var dy = points[n - 1] - points[n - 3]; + var radians = (Math.atan2(dy, dx) + PI2) % PI2; + var length = this.pointerLength(); + var width = this.pointerWidth(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(points[n - 2], points[n - 1]); + ctx.rotate(radians); + ctx.moveTo(0, 0); + ctx.lineTo(-length, width / 2); + ctx.lineTo(-length, -width / 2); + ctx.closePath(); + ctx.restore(); + + if (this.pointerAtBeginning()) { + ctx.save(); + ctx.translate(points[0], points[1]); + dx = points[2] - points[0]; + dy = points[3] - points[1]; + ctx.rotate((Math.atan2(-dy, -dx) + PI2) % PI2); + ctx.moveTo(0, 0); + ctx.lineTo(-length, width / 2); + ctx.lineTo(-length, -width / 2); + ctx.closePath(); + ctx.restore(); + } + ctx.fillStrokeShape(this); + } + }; + + Konva.Util.extend(Konva.Arrow, Konva.Line); + /** + * get/set pointerLength + * @name pointerLength + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Length of pointer of arrow. + * The default is 10. + * @returns {Number} + * @example + * // get tension + * var pointerLength = line.pointerLength(); + * + * // set tension + * line.pointerLength(15); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerLength', 10); + /** + * get/set pointerWidth + * @name pointerWidth + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Width of pointer of arrow. + * The default is 10. + * @returns {Number} + * @example + * // get tension + * var pointerWidth = line.pointerWidth(); + * + * // set tension + * line.pointerWidth(15); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerWidth', 10); + /** + * get/set pointerAtBeginning + * @name pointerAtBeginning + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Should pointer displayed at beginning of arrow. + * The default is false. + * @returns {Boolean} + * @example + * // get tension + * var pointerAtBeginning = line.pointerAtBeginning(); + * + * // set tension + * line.pointerAtBeginning(true); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerAtBeginning', false); + Konva.Collection.mapMethods(Konva.Arrow); + +})(); diff --git a/support/client/lib/vwf/model/kinetic/konva.js b/support/client/lib/vwf/model/kinetic/konva.js new file mode 100644 index 000000000..f2c390875 --- /dev/null +++ b/support/client/lib/vwf/model/kinetic/konva.js @@ -0,0 +1,16283 @@ + +/* + * Konva JavaScript Framework v0.15.0 + * http://konvajs.github.io/ + * Licensed under the MIT or GPL Version 2 licenses. + * Date: Fri Jun 24 2016 + * + * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) + * Modified work Copyright (C) 2014 - 2015 by Anton Lavrenov (Konva) + * + * @license + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// runtime check for already included Konva +(function(global){ + 'use strict'; + /** + * @namespace Konva + */ + + var PI_OVER_180 = Math.PI / 180; + + var Konva = { + // public + version: '0.15.0', + + // private + stages: [], + idCounter: 0, + ids: {}, + names: {}, + shapes: {}, + listenClickTap: false, + inDblClickWindow: false, + + // configurations + enableTrace: false, + traceArrMax: 100, + dblClickWindow: 400, + /** + * Global pixel ratio configuration. KonvaJS automatically detect pixel ratio of current device. + * But you may override such property, if you want to use your value. + * @property pixelRatio + * @default undefined + * @memberof Konva + * @example + * Konva.pixelRatio = 1; + */ + pixelRatio: undefined, + /** + * Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point, + * only then start dragging. + * @property dragDistance + * @default 0 + * @memberof Konva + * @example + * Konva.dragDistance = 10; + */ + dragDistance: 0, + /** + * Use degree values for angle properties. You may set this property to false if you want to use radiant values. + * @property angleDeg + * @default true + * @memberof Konva + * @example + * node.rotation(45); // 45 degrees + * Konva.angleDeg = false; + * node.rotation(Math.PI / 2); // PI/2 radian + */ + angleDeg: true, + /** + * Show different warnings about errors or wrong API usage + * @property showWarnings + * @default true + * @memberof Konva + * @example + * Konva.showWarnings = false; + */ + showWarnings: true, + + + + /** + * @namespace Filters + * @memberof Konva + */ + Filters: {}, + + /** + * returns whether or not drag and drop is currently active + * @method + * @memberof Konva + */ + isDragging: function() { + var dd = Konva.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (dd) { + return dd.isDragging; + } + return false; + }, + /** + * returns whether or not a drag and drop operation is ready, but may + * not necessarily have started + * @method + * @memberof Konva + */ + isDragReady: function() { + var dd = Konva.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (dd) { + return !!dd.node; + } + return false; + }, + _addId: function(node, id) { + if(id !== undefined) { + this.ids[id] = node; + } + }, + _removeId: function(id) { + if(id !== undefined) { + delete this.ids[id]; + } + }, + _addName: function(node, name) { + if(name) { + if(!this.names[name]) { + this.names[name] = []; + } + this.names[name].push(node); + } + }, + _removeName: function(name, _id) { + if(!name) { + return; + } + var nodes = this.names[name]; + if(!nodes) { + return; + } + for(var n = 0; n < nodes.length; n++) { + var no = nodes[n]; + if(no._id === _id) { + nodes.splice(n, 1); + } + } + if(nodes.length === 0) { + delete this.names[name]; + } + }, + getAngle: function(angle) { + return this.angleDeg ? angle * PI_OVER_180 : angle; + }, + _detectIE: function(ua) { + var msie = ua.indexOf('msie '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + var edge = ua.indexOf('edge/'); + if (edge > 0) { + // Edge (IE 12+) => return version number + return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); + } + + // other browser + return false; + }, + _parseUA: function(userAgent) { + var ua = userAgent.toLowerCase(), + // jQuery UA regex + match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + [], + + // adding mobile flag as well + mobile = !!(userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)), + ieMobile = !!(userAgent.match(/IEMobile/i)); + + return { + browser: match[ 1 ] || '', + version: match[ 2 ] || '0', + isIE: Konva._detectIE(ua), + // adding mobile flab + mobile: mobile, + ieMobile: ieMobile // If this is true (i.e., WP8), then Konva touch events are executed instead of equivalent Konva mouse events + }; + }, + // user agent + UA: undefined + }; + + var glob = + typeof window !== 'undefined' ? window : + typeof global !== 'undefined' ? global : + typeof WorkerGlobalScope !== 'undefined' ? self : {}; + + + Konva.UA = Konva._parseUA((glob.navigator && glob.navigator.userAgent) || ''); + + + if (glob.Konva) { + console.error( + 'Konva instance is already exist in current eviroment. ' + + 'Please use only one instance.' + ); + } + glob.Konva = Konva; + Konva.global = glob; + + + if( typeof exports === 'object') { + // runtime-check for browserify and nw.js (node-webkit) + if(glob.window && glob.window.document) { + Konva.document = glob.window.document; + Konva.window = glob.window; + } else { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + var Canvas = require('canvas'); + var jsdom = require('jsdom').jsdom; + + Konva.window = jsdom('').defaultView; + Konva.document = Konva.window.document; + Konva.window.Image = Canvas.Image; + Konva._nodeCanvas = Canvas; + } + module.exports = Konva; + return; + } + else if( typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(function() { + return Konva; + }); + } + Konva.document = document; + Konva.window = window; +})(typeof window !== 'undefined' ? window : global); + +/*eslint-disable eqeqeq, no-cond-assign, no-empty*/ +(function() { + 'use strict'; + /** + * Collection constructor. Collection extends + * Array. This class is used in conjunction with {@link Konva.Container#get} + * @constructor + * @memberof Konva + */ + Konva.Collection = function() { + var args = [].slice.call(arguments), length = args.length, i = 0; + + this.length = length; + for(; i < length; i++) { + this[i] = args[i]; + } + return this; + }; + Konva.Collection.prototype = []; + /** + * iterate through node array and run a function for each node. + * The node and index is passed into the function + * @method + * @memberof Konva.Collection.prototype + * @param {Function} func + * @example + * // get all nodes with name foo inside layer, and set x to 10 for each + * layer.get('.foo').each(function(shape, n) { + * shape.setX(10); + * }); + */ + Konva.Collection.prototype.each = function(func) { + for(var n = 0; n < this.length; n++) { + func(this[n], n); + } + }; + /** + * convert collection into an array + * @method + * @memberof Konva.Collection.prototype + */ + Konva.Collection.prototype.toArray = function() { + var arr = [], + len = this.length, + n; + + for(n = 0; n < len; n++) { + arr.push(this[n]); + } + return arr; + }; + /** + * convert array into a collection + * @method + * @memberof Konva.Collection + * @param {Array} arr + */ + Konva.Collection.toCollection = function(arr) { + var collection = new Konva.Collection(), + len = arr.length, + n; + + for(n = 0; n < len; n++) { + collection.push(arr[n]); + } + return collection; + }; + + // map one method by it's name + Konva.Collection._mapMethod = function(methodName) { + Konva.Collection.prototype[methodName] = function() { + var len = this.length, + i; + + var args = [].slice.call(arguments); + for(i = 0; i < len; i++) { + this[i][methodName].apply(this[i], args); + } + + return this; + }; + }; + + Konva.Collection.mapMethods = function(constructor) { + var prot = constructor.prototype; + for(var methodName in prot) { + Konva.Collection._mapMethod(methodName); + } + }; + + /* + * Last updated November 2011 + * By Simon Sarris + * www.simonsarris.com + * sarris@acm.org + * + * Free to use and distribute at will + * So long as you are nice to people, etc + */ + + /* + * The usage of this class was inspired by some of the work done by a forked + * project, KineticJS-Ext by Wappworks, which is based on Simon's Transform + * class. Modified by Eric Rowell + */ + + /** + * Transform constructor + * @constructor + * @param {Array} [m] Optional six-element matrix + * @memberof Konva + */ + Konva.Transform = function(m) { + this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0]; + }; + + Konva.Transform.prototype = { + /** + * Copy Konva.Transform object + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + */ + copy: function() { + return new Konva.Transform(this.m); + }, + /** + * Transform point + * @method + * @memberof Konva.Transform.prototype + * @param {Object} point 2D point(x, y) + * @returns {Object} 2D point(x, y) + */ + point: function(point) { + var m = this.m; + return { + x: m[0] * point.x + m[2] * point.y + m[4], + y: m[1] * point.x + m[3] * point.y + m[5] + }; + }, + /** + * Apply translation + * @method + * @memberof Konva.Transform.prototype + * @param {Number} x + * @param {Number} y + * @returns {Konva.Transform} + */ + translate: function(x, y) { + this.m[4] += this.m[0] * x + this.m[2] * y; + this.m[5] += this.m[1] * x + this.m[3] * y; + return this; + }, + /** + * Apply scale + * @method + * @memberof Konva.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Konva.Transform} + */ + scale: function(sx, sy) { + this.m[0] *= sx; + this.m[1] *= sx; + this.m[2] *= sy; + this.m[3] *= sy; + return this; + }, + /** + * Apply rotation + * @method + * @memberof Konva.Transform.prototype + * @param {Number} rad Angle in radians + * @returns {Konva.Transform} + */ + rotate: function(rad) { + var c = Math.cos(rad); + var s = Math.sin(rad); + var m11 = this.m[0] * c + this.m[2] * s; + var m12 = this.m[1] * c + this.m[3] * s; + var m21 = this.m[0] * -s + this.m[2] * c; + var m22 = this.m[1] * -s + this.m[3] * c; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Returns the translation + * @method + * @memberof Konva.Transform.prototype + * @returns {Object} 2D point(x, y) + */ + getTranslation: function() { + return { + x: this.m[4], + y: this.m[5] + }; + }, + /** + * Apply skew + * @method + * @memberof Konva.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Konva.Transform} + */ + skew: function(sx, sy) { + var m11 = this.m[0] + this.m[2] * sy; + var m12 = this.m[1] + this.m[3] * sy; + var m21 = this.m[2] + this.m[0] * sx; + var m22 = this.m[3] + this.m[1] * sx; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Transform multiplication + * @method + * @memberof Konva.Transform.prototype + * @param {Konva.Transform} matrix + * @returns {Konva.Transform} + */ + multiply: function(matrix) { + var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1]; + var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1]; + + var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3]; + var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3]; + + var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4]; + var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5]; + + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + this.m[4] = dx; + this.m[5] = dy; + return this; + }, + /** + * Invert the matrix + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + */ + invert: function() { + var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]); + var m0 = this.m[3] * d; + var m1 = -this.m[1] * d; + var m2 = -this.m[2] * d; + var m3 = this.m[0] * d; + var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]); + var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]); + this.m[0] = m0; + this.m[1] = m1; + this.m[2] = m2; + this.m[3] = m3; + this.m[4] = m4; + this.m[5] = m5; + return this; + }, + /** + * return matrix + * @method + * @memberof Konva.Transform.prototype + */ + getMatrix: function() { + return this.m; + }, + /** + * set to absolute position via translation + * @method + * @memberof Konva.Transform.prototype + * @returns {Konva.Transform} + * @author ericdrowell + */ + setAbsolutePosition: function(x, y) { + var m0 = this.m[0], + m1 = this.m[1], + m2 = this.m[2], + m3 = this.m[3], + m4 = this.m[4], + m5 = this.m[5], + yt = ((m0 * (y - m5)) - (m1 * (x - m4))) / ((m0 * m3) - (m1 * m2)), + xt = (x - m4 - (m2 * yt)) / m0; + + return this.translate(xt, yt); + } + }; + + // CONSTANTS + var CONTEXT_2D = '2d', + OBJECT_ARRAY = '[object Array]', + OBJECT_NUMBER = '[object Number]', + OBJECT_STRING = '[object String]', + PI_OVER_DEG180 = Math.PI / 180, + DEG180_OVER_PI = 180 / Math.PI, + HASH = '#', + EMPTY_STRING = '', + ZERO = '0', + KONVA_WARNING = 'Konva warning: ', + KONVA_ERROR = 'Konva error: ', + RGB_PAREN = 'rgb(', + COLORS = { + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 132, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 255, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + grey: [128, 128, 128], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 203], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + rebeccapurple: [102, 51, 153], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [119, 128, 144], + slategrey: [119, 128, 144], + snow: [255, 255, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + transparent: [255, 255, 255, 0], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 5] + }, + + RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; + + /** + * @namespace Util + * @memberof Konva + */ + Konva.Util = { + /* + * cherry-picked utilities from underscore.js + */ + _isElement: function(obj) { + return !!(obj && obj.nodeType == 1); + }, + _isFunction: function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }, + _isObject: function(obj) { + return (!!obj && obj.constructor === Object); + }, + _isArray: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_ARRAY; + }, + _isNumber: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_NUMBER; + }, + _isString: function(obj) { + return Object.prototype.toString.call(obj) === OBJECT_STRING; + }, + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _throttle: function(func, wait, opts) { + var context, args, result; + var timeout = null; + var previous = 0; + var options = opts || {}; + var later = function() { + previous = options.leading === false ? 0 : new Date().getTime(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = new Date().getTime(); + if (!previous && options.leading === false) { + previous = now; + } + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + /* + * other utils + */ + _hasMethods: function(obj) { + var names = [], + key; + + for(key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + if(this._isFunction(obj[key])) { + names.push(key); + } + } + return names.length > 0; + }, + isValidSelector: function(selector) { + if (typeof selector !== 'string') { + return false; + } + var firstChar = selector[0]; + return firstChar === '#' || firstChar === '.' || firstChar === firstChar.toUpperCase(); + }, + createCanvasElement: function() { + var canvas = Konva.document.createElement('canvas'); + // on some environments canvas.style is readonly + try { + canvas.style = canvas.style || {}; + } catch (e) { + } + return canvas; + }, + isBrowser: function() { + return (typeof exports !== 'object'); + }, + _isInDocument: function(el) { + while(el = el.parentNode) { + if(el == Konva.document) { + return true; + } + } + return false; + }, + _simplifyArray: function(arr) { + var retArr = [], + len = arr.length, + util = Konva.Util, + n, val; + + for (n = 0; n < len; n++) { + val = arr[n]; + if (util._isNumber(val)) { + val = Math.round(val * 1000) / 1000; + } + else if (!util._isString(val)) { + val = val.toString(); + } + + retArr.push(val); + } + + return retArr; + }, + /* + * arg can be an image object or image data + */ + _getImage: function(arg, callback) { + var imageObj, canvas; + + // if arg is null or undefined + if(!arg) { + callback(null); + } + + // if arg is already an image object + else if(this._isElement(arg)) { + callback(arg); + } + + // if arg is a string, then it's a data url + else if(this._isString(arg)) { + imageObj = new Konva.window.Image(); + imageObj.onload = function() { + callback(imageObj); + }; + imageObj.src = arg; + } + + //if arg is an object that contains the data property, it's an image object + else if(arg.data) { + canvas = Konva.Util.createCanvasElement(); + canvas.width = arg.width; + canvas.height = arg.height; + var _context = canvas.getContext(CONTEXT_2D); + _context.putImageData(arg, 0, 0); + this._getImage(canvas.toDataURL(), callback); + } + else { + callback(null); + } + }, + _getRGBAString: function(obj) { + var red = obj.red || 0, + green = obj.green || 0, + blue = obj.blue || 0, + alpha = obj.alpha || 1; + + return [ + 'rgba(', + red, + ',', + green, + ',', + blue, + ',', + alpha, + ')' + ].join(EMPTY_STRING); + }, + _rgbToHex: function(r, g, b) { + return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); + }, + _hexToRgb: function(hex) { + hex = hex.replace(HASH, EMPTY_STRING); + var bigint = parseInt(hex, 16); + return { + r: (bigint >> 16) & 255, + g: (bigint >> 8) & 255, + b: bigint & 255 + }; + }, + /** + * return random hex color + * @method + * @memberof Konva.Util.prototype + */ + getRandomColor: function() { + var randColor = (Math.random() * 0xFFFFFF << 0).toString(16); + while (randColor.length < 6) { + randColor = ZERO + randColor; + } + return HASH + randColor; + }, + /** + * return value with default fallback + * @method + * @memberof Konva.Util.prototype + */ + get: function(val, def) { + if (val === undefined) { + return def; + } + else { + return val; + } + }, + /** + * get RGB components of a color + * @method + * @memberof Konva.Util.prototype + * @param {String} color + * @example + * // each of the following examples return {r:0, g:0, b:255} + * var rgb = Konva.Util.getRGB('blue'); + * var rgb = Konva.Util.getRGB('#0000ff'); + * var rgb = Konva.Util.getRGB('rgb(0,0,255)'); + */ + getRGB: function(color) { + var rgb; + // color string + if (color in COLORS) { + rgb = COLORS[color]; + return { + r: rgb[0], + g: rgb[1], + b: rgb[2] + }; + } + // hex + else if (color[0] === HASH) { + return this._hexToRgb(color.substring(1)); + } + // rgb string + else if (color.substr(0, 4) === RGB_PAREN) { + rgb = RGB_REGEX.exec(color.replace(/ /g, '')); + return { + r: parseInt(rgb[1], 10), + g: parseInt(rgb[2], 10), + b: parseInt(rgb[3], 10) + }; + } + // default + else { + return { + r: 0, + g: 0, + b: 0 + }; + } + }, + // convert any color string to RGBA object + // from https://github.com/component/color-parser + colorToRGBA: function(str) { + str = str || 'black'; + return Konva.Util._namedColorToRBA(str) + || Konva.Util._hex3ColorToRGBA(str) + || Konva.Util._hex6ColorToRGBA(str) + || Konva.Util._rgbColorToRGBA(str) + || Konva.Util._rgbaColorToRGBA(str); + }, + // Parse named css color. Like "green" + _namedColorToRBA: function(str) { + var c = COLORS[str.toLowerCase()]; + if (!c) { + return null; + } + return { + r: c[0], + g: c[1], + b: c[2], + a: 1 + }; + }, + // Parse rgb(n, n, n) + _rgbColorToRGBA: function(str) { + if (str.indexOf('rgb(') === 0) { + str = str.match(/rgb\(([^)]+)\)/)[1]; + var parts = str.split(/ *, */).map(Number); + return { + r: parts[0], + g: parts[1], + b: parts[2], + a: 1 + }; + } + }, + // Parse rgba(n, n, n, n) + _rgbaColorToRGBA: function(str) { + if (str.indexOf('rgba(') === 0) { + str = str.match(/rgba\(([^)]+)\)/)[1]; + var parts = str.split(/ *, */).map(Number); + return { + r: parts[0], + g: parts[1], + b: parts[2], + a: parts[3] + }; + } + + }, + // Parse #nnnnnn + _hex6ColorToRGBA: function(str) { + if ((str[0] === '#') && (str.length === 7)) { + return { + r: parseInt(str.slice(1, 3), 16), + g: parseInt(str.slice(3, 5), 16), + b: parseInt(str.slice(5, 7), 16), + a: 1 + }; + } + }, + // Parse #nnn + _hex3ColorToRGBA: function(str) { + if ((str[0] === '#') && (str.length === 4)) { + return { + r: parseInt(str[1] + str[1], 16), + g: parseInt(str[2] + str[2], 16), + b: parseInt(str[3] + str[3], 16), + a: 1 + }; + } + }, + // o1 takes precedence over o2 + _merge: function(o1, o2) { + var retObj = this._clone(o2); + for(var key in o1) { + if(this._isObject(o1[key])) { + retObj[key] = this._merge(o1[key], retObj[key]); + } + else { + retObj[key] = o1[key]; + } + } + return retObj; + }, + cloneObject: function(obj) { + var retObj = {}; + for(var key in obj) { + if(this._isObject(obj[key])) { + retObj[key] = this.cloneObject(obj[key]); + } + else if (this._isArray(obj[key])) { + retObj[key] = this.cloneArray(obj[key]); + } else { + retObj[key] = obj[key]; + } + } + return retObj; + }, + cloneArray: function(arr) { + return arr.slice(0); + }, + _degToRad: function(deg) { + return deg * PI_OVER_DEG180; + }, + _radToDeg: function(rad) { + return rad * DEG180_OVER_PI; + }, + _capitalize: function(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + }, + throw: function(str) { + throw new Error(KONVA_ERROR + str); + }, + error: function(str) { + console.error(KONVA_ERROR + str); + }, + warn: function(str) { + /* + * IE9 on Windows7 64bit will throw a JS error + * if we don't use window.console in the conditional + */ + if(Konva.global.console && console.warn && Konva.showWarnings) { + console.warn(KONVA_WARNING + str); + } + }, + extend: function(child, parent) { + function Ctor() { + this.constructor = child; + } + Ctor.prototype = parent.prototype; + var oldProto = child.prototype; + child.prototype = new Ctor(); + for (var key in oldProto) { + if (oldProto.hasOwnProperty(key)) { + child.prototype[key] = oldProto[key]; + } + } + child.__super__ = parent.prototype; + // create reference to parent + child.super = parent; + }, + /** + * adds methods to a constructor prototype + * @method + * @memberof Konva.Util.prototype + * @param {Function} constructor + * @param {Object} methods + */ + addMethods: function(constructor, methods) { + var key; + + for (key in methods) { + constructor.prototype[key] = methods[key]; + } + }, + _getControlPoints: function(x0, y0, x1, y1, x2, y2, t) { + var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2)), + d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), + fa = t * d01 / (d01 + d12), + fb = t * d12 / (d01 + d12), + p1x = x1 - fa * (x2 - x0), + p1y = y1 - fa * (y2 - y0), + p2x = x1 + fb * (x2 - x0), + p2y = y1 + fb * (y2 - y0); + + return [p1x, p1y, p2x, p2y]; + }, + _expandPoints: function(p, tension) { + var len = p.length, + allPoints = [], + n, cp; + + for (n = 2; n < len - 2; n += 2) { + cp = Konva.Util._getControlPoints(p[n - 2], p[n - 1], p[n], p[n + 1], p[n + 2], p[n + 3], tension); + allPoints.push(cp[0]); + allPoints.push(cp[1]); + allPoints.push(p[n]); + allPoints.push(p[n + 1]); + allPoints.push(cp[2]); + allPoints.push(cp[3]); + } + + return allPoints; + }, + _removeLastLetter: function(str) { + return str.substring(0, str.length - 1); + }, + each: function(obj, func) { + for (var key in obj) { + func(key, obj[key]); + } + }, + _getProjectionToSegment: function(x1, y1, x2, y2, x3, y3) { + var x, y, dist; + + var pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + if(pd2 == 0) { + x = x1; + y = y1; + dist = (x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2); + } else { + var u = ((x3 - x1) * (x2 - x1) + (y3 - y1) * (y2 - y1)) / pd2; + if(u < 0) { + x = x1; + y = y1; + dist = (x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3); + } else if (u > 1.0) { + x = x2; + y = y2; + dist = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3); + } else { + x = x1 + u * (x2 - x1); + y = y1 + u * (y2 - y1); + dist = (x - x3) * (x - x3) + (y - y3) * (y - y3); + } + } + return [x, y, dist]; + }, + // line as array of points. + // line might be closed + _getProjectionToLine: function(pt, line, isClosed) { + var pc = Konva.Util.cloneObject(pt); + var dist = Number.MAX_VALUE; + line.forEach(function(p1, i) { + if (!isClosed && i === line.length - 1) { + return; + } + var p2 = line[(i + 1) % line.length]; + var proj = Konva.Util._getProjectionToSegment(p1.x, p1.y, p2.x, p2.y, pt.x, pt.y); + var px = proj[0], py = proj[1], pdist = proj[2]; + if (pdist < dist) { + pc.x = px; + pc.y = py; + dist = pdist; + } + }); + return pc; + }, + _prepareArrayForTween: function(startArray, endArray, isClosed) { + var n, start = [], end = []; + if (startArray.length > endArray.length) { + var temp = endArray; + endArray = startArray; + startArray = temp; + } + for (n = 0; n < startArray.length; n += 2) { + start.push({ + x: startArray[n], + y: startArray[n + 1] + }); + } + for (n = 0; n < endArray.length; n += 2) { + end.push({ + x: endArray[n], + y: endArray[n + 1] + }); + } + + + var newStart = []; + end.forEach(function(point) { + var pr = Konva.Util._getProjectionToLine(point, start, isClosed); + newStart.push(pr.x); + newStart.push(pr.y); + }); + return newStart; + } + }; +})(); + +(function() { + 'use strict'; + // calculate pixel ratio + var canvas = Konva.Util.createCanvasElement(), + context = canvas.getContext('2d'), + _pixelRatio = (function(){ + var devicePixelRatio = Konva.window.devicePixelRatio || 1, + backingStoreRatio = context.webkitBackingStorePixelRatio + || context.mozBackingStorePixelRatio + || context.msBackingStorePixelRatio + || context.oBackingStorePixelRatio + || context.backingStorePixelRatio + || 1; + return devicePixelRatio / backingStoreRatio; + })(); + + /** + * Canvas Renderer constructor + * @constructor + * @abstract + * @memberof Konva + * @param {Object} config + * @param {Number} config.width + * @param {Number} config.height + * @param {Number} config.pixelRatio KonvaJS automatically handles pixel ratio adjustments in order to render crisp drawings + * on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios + * of 1. Some high end tablets and phones, like iPhones and iPads (not the mini) have a device pixel ratio + * of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel + * ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise + * specified, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel + * ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1. + */ + Konva.Canvas = function(config) { + this.init(config); + }; + + Konva.Canvas.prototype = { + init: function(config) { + var conf = config || {}; + + var pixelRatio = conf.pixelRatio || Konva.pixelRatio || _pixelRatio; + + this.pixelRatio = pixelRatio; + this._canvas = Konva.Util.createCanvasElement(); + + // set inline styles + this._canvas.style.padding = 0; + this._canvas.style.margin = 0; + this._canvas.style.border = 0; + this._canvas.style.background = 'transparent'; + this._canvas.style.position = 'absolute'; + this._canvas.style.top = 0; + this._canvas.style.left = 0; + }, + /** + * get canvas context + * @method + * @memberof Konva.Canvas.prototype + * @returns {CanvasContext} context + */ + getContext: function() { + return this.context; + }, + /** + * get pixel ratio + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} pixel ratio + */ + getPixelRatio: function() { + return this.pixelRatio; + }, + /** + * get pixel ratio + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} pixelRatio KonvaJS automatically handles pixel ratio adustments in order to render crisp drawings + * on all devices. Most desktops, low end tablets, and low end phones, have device pixel ratios + * of 1. Some high end tablets and phones, like iPhones and iPads have a device pixel ratio + * of 2. Some Macbook Pros, and iMacs also have a device pixel ratio of 2. Some high end Android devices have pixel + * ratios of 2 or 3. Some browsers like Firefox allow you to configure the pixel ratio of the viewport. Unless otherwise + * specificed, the pixel ratio will be defaulted to the actual device pixel ratio. You can override the device pixel + * ratio for special situations, or, if you don't want the pixel ratio to be taken into account, you can set it to 1. + */ + setPixelRatio: function(pixelRatio) { + var previousRatio = this.pixelRatio; + this.pixelRatio = pixelRatio; + this.setSize(this.getWidth() / previousRatio, this.getHeight() / previousRatio); + }, + /** + * set width + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} width + */ + setWidth: function(width) { + // take into account pixel ratio + this.width = this._canvas.width = width * this.pixelRatio; + this._canvas.style.width = width + 'px'; + + var pixelRatio = this.pixelRatio, + _context = this.getContext()._context; + _context.scale(pixelRatio, pixelRatio); + }, + /** + * set height + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} height + */ + setHeight: function(height) { + // take into account pixel ratio + this.height = this._canvas.height = height * this.pixelRatio; + this._canvas.style.height = height + 'px'; + var pixelRatio = this.pixelRatio, + _context = this.getContext()._context; + _context.scale(pixelRatio, pixelRatio); + }, + /** + * get width + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} width + */ + getWidth: function() { + return this.width; + }, + /** + * get height + * @method + * @memberof Konva.Canvas.prototype + * @returns {Number} height + */ + getHeight: function() { + return this.height; + }, + /** + * set size + * @method + * @memberof Konva.Canvas.prototype + * @param {Number} width + * @param {Number} height + */ + setSize: function(width, height) { + this.setWidth(width); + this.setHeight(height); + }, + /** + * to data url + * @method + * @memberof Konva.Canvas.prototype + * @param {String} mimeType + * @param {Number} quality between 0 and 1 for jpg mime types + * @returns {String} data url string + */ + toDataURL: function(mimeType, quality) { + try { + // If this call fails (due to browser bug, like in Firefox 3.6), + // then revert to previous no-parameter image/png behavior + return this._canvas.toDataURL(mimeType, quality); + } + catch(e) { + try { + return this._canvas.toDataURL(); + } + catch(err) { + Konva.Util.warn('Unable to get data URL. ' + err.message); + return ''; + } + } + } + }; + + Konva.SceneCanvas = function(config) { + var conf = config || {}; + var width = conf.width || 0, + height = conf.height || 0; + + Konva.Canvas.call(this, conf); + this.context = new Konva.SceneContext(this); + this.setSize(width, height); + }; + + Konva.Util.extend(Konva.SceneCanvas, Konva.Canvas); + + Konva.HitCanvas = function(config) { + var conf = config || {}; + var width = conf.width || 0, + height = conf.height || 0; + + Konva.Canvas.call(this, conf); + this.context = new Konva.HitContext(this); + this.setSize(width, height); + this.hitCanvas = true; + }; + Konva.Util.extend(Konva.HitCanvas, Konva.Canvas); + +})(); + +(function() { + 'use strict'; + var COMMA = ',', + OPEN_PAREN = '(', + CLOSE_PAREN = ')', + OPEN_PAREN_BRACKET = '([', + CLOSE_BRACKET_PAREN = '])', + SEMICOLON = ';', + DOUBLE_PAREN = '()', + // EMPTY_STRING = '', + EQUALS = '=', + // SET = 'set', + CONTEXT_METHODS = [ + 'arc', + 'arcTo', + 'beginPath', + 'bezierCurveTo', + 'clearRect', + 'clip', + 'closePath', + 'createLinearGradient', + 'createPattern', + 'createRadialGradient', + 'drawImage', + 'fill', + 'fillText', + 'getImageData', + 'createImageData', + 'lineTo', + 'moveTo', + 'putImageData', + 'quadraticCurveTo', + 'rect', + 'restore', + 'rotate', + 'save', + 'scale', + 'setLineDash', + 'setTransform', + 'stroke', + 'strokeText', + 'transform', + 'translate' + ]; + + var CONTEXT_PROPERTIES = ['fillStyle', 'strokeStyle', 'shadowColor', 'shadowBlur', 'shadowOffsetX', + 'shadowOffsetY', 'lineCap', 'lineJoin', 'lineWidth', 'miterLimit', 'font', 'textAlign', 'textBaseline', + 'globalAlpha', 'globalCompositeOperation']; + + /** + * Canvas Context constructor + * @constructor + * @abstract + * @memberof Konva + */ + Konva.Context = function(canvas) { + this.init(canvas); + }; + + Konva.Context.prototype = { + init: function(canvas) { + this.canvas = canvas; + this._context = canvas._canvas.getContext('2d'); + + if (Konva.enableTrace) { + this.traceArr = []; + this._enableTrace(); + } + }, + /** + * fill shape + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + fillShape: function(shape) { + if(shape.getFillEnabled()) { + this._fill(shape); + } + }, + /** + * stroke shape + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + strokeShape: function(shape) { + if(shape.getStrokeEnabled()) { + this._stroke(shape); + } + }, + /** + * fill then stroke + * @method + * @memberof Konva.Context.prototype + * @param {Konva.Shape} shape + */ + fillStrokeShape: function(shape) { + var fillEnabled = shape.getFillEnabled(); + if(fillEnabled) { + this._fill(shape); + } + if(shape.getStrokeEnabled()) { + this._stroke(shape); + } + }, + /** + * get context trace if trace is enabled + * @method + * @memberof Konva.Context.prototype + * @param {Boolean} relaxed if false, return strict context trace, which includes method names, method parameters + * properties, and property values. If true, return relaxed context trace, which only returns method names and + * properites. + * @returns {String} + */ + getTrace: function(relaxed) { + var traceArr = this.traceArr, + len = traceArr.length, + str = '', + n, trace, method, args; + + for (n = 0; n < len; n++) { + trace = traceArr[n]; + method = trace.method; + + // methods + if (method) { + args = trace.args; + str += method; + if (relaxed) { + str += DOUBLE_PAREN; + } + else { + if (Konva.Util._isArray(args[0])) { + str += OPEN_PAREN_BRACKET + args.join(COMMA) + CLOSE_BRACKET_PAREN; + } + else { + str += OPEN_PAREN + args.join(COMMA) + CLOSE_PAREN; + } + } + } + // properties + else { + str += trace.property; + if (!relaxed) { + str += EQUALS + trace.val; + } + } + + str += SEMICOLON; + } + + return str; + }, + /** + * clear trace if trace is enabled + * @method + * @memberof Konva.Context.prototype + */ + clearTrace: function() { + this.traceArr = []; + }, + _trace: function(str) { + var traceArr = this.traceArr, + len; + + traceArr.push(str); + len = traceArr.length; + + if (len >= Konva.traceArrMax) { + traceArr.shift(); + } + }, + /** + * reset canvas context transform + * @method + * @memberof Konva.Context.prototype + */ + reset: function() { + var pixelRatio = this.getCanvas().getPixelRatio(); + this.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0); + }, + /** + * get canvas + * @method + * @memberof Konva.Context.prototype + * @returns {Konva.Canvas} + */ + getCanvas: function() { + return this.canvas; + }, + /** + * clear canvas + * @method + * @memberof Konva.Context.prototype + * @param {Object} [bounds] + * @param {Number} [bounds.x] + * @param {Number} [bounds.y] + * @param {Number} [bounds.width] + * @param {Number} [bounds.height] + */ + clear: function(bounds) { + var canvas = this.getCanvas(); + + if (bounds) { + this.clearRect(bounds.x || 0, bounds.y || 0, bounds.width || 0, bounds.height || 0); + } + else { + this.clearRect(0, 0, canvas.getWidth() / canvas.pixelRatio, canvas.getHeight() / canvas.pixelRatio); + } + }, + _applyLineCap: function(shape) { + var lineCap = shape.getLineCap(); + if(lineCap) { + this.setAttr('lineCap', lineCap); + } + }, + _applyOpacity: function(shape) { + var absOpacity = shape.getAbsoluteOpacity(); + if(absOpacity !== 1) { + this.setAttr('globalAlpha', absOpacity); + } + }, + _applyLineJoin: function(shape) { + var lineJoin = shape.getLineJoin(); + if(lineJoin) { + this.setAttr('lineJoin', lineJoin); + } + }, + setAttr: function(attr, val) { + this._context[attr] = val; + }, + + // context pass through methods + arc: function() { + var a = arguments; + this._context.arc(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + beginPath: function() { + this._context.beginPath(); + }, + bezierCurveTo: function() { + var a = arguments; + this._context.bezierCurveTo(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + clearRect: function() { + var a = arguments; + this._context.clearRect(a[0], a[1], a[2], a[3]); + }, + clip: function() { + this._context.clip(); + }, + closePath: function() { + this._context.closePath(); + }, + createImageData: function() { + var a = arguments; + if(a.length === 2) { + return this._context.createImageData(a[0], a[1]); + } + else if(a.length === 1) { + return this._context.createImageData(a[0]); + } + }, + createLinearGradient: function() { + var a = arguments; + return this._context.createLinearGradient(a[0], a[1], a[2], a[3]); + }, + createPattern: function() { + var a = arguments; + return this._context.createPattern(a[0], a[1]); + }, + createRadialGradient: function() { + var a = arguments; + return this._context.createRadialGradient(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + drawImage: function() { + var a = arguments, + _context = this._context; + + if(a.length === 3) { + _context.drawImage(a[0], a[1], a[2]); + } + else if(a.length === 5) { + _context.drawImage(a[0], a[1], a[2], a[3], a[4]); + } + else if(a.length === 9) { + _context.drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + } + }, + isPointInPath: function(x, y) { + return this._context.isPointInPath(x, y); + }, + fill: function() { + this._context.fill(); + }, + fillRect: function(x, y, width, height) { + this._context.fillRect(x, y, width, height); + }, + strokeRect: function(x, y, width, height) { + this._context.strokeRect(x, y, width, height); + }, + fillText: function() { + var a = arguments; + this._context.fillText(a[0], a[1], a[2]); + }, + measureText: function(text) { + return this._context.measureText(text); + }, + getImageData: function() { + var a = arguments; + return this._context.getImageData(a[0], a[1], a[2], a[3]); + }, + lineTo: function() { + var a = arguments; + this._context.lineTo(a[0], a[1]); + }, + moveTo: function() { + var a = arguments; + this._context.moveTo(a[0], a[1]); + }, + rect: function() { + var a = arguments; + this._context.rect(a[0], a[1], a[2], a[3]); + }, + putImageData: function() { + var a = arguments; + this._context.putImageData(a[0], a[1], a[2]); + }, + quadraticCurveTo: function() { + var a = arguments; + this._context.quadraticCurveTo(a[0], a[1], a[2], a[3]); + }, + restore: function() { + this._context.restore(); + }, + rotate: function() { + var a = arguments; + this._context.rotate(a[0]); + }, + save: function() { + this._context.save(); + }, + scale: function() { + var a = arguments; + this._context.scale(a[0], a[1]); + }, + setLineDash: function() { + var a = arguments, + _context = this._context; + + // works for Chrome and IE11 + if(this._context.setLineDash) { + _context.setLineDash(a[0]); + } + // verified that this works in firefox + else if('mozDash' in _context) { + _context.mozDash = a[0]; + } + // does not currently work for Safari + else if('webkitLineDash' in _context) { + _context.webkitLineDash = a[0]; + } + + // no support for IE9 and IE10 + }, + getLineDash: function() { + return this._context.getLineDash(); + }, + setTransform: function() { + var a = arguments; + this._context.setTransform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + stroke: function() { + this._context.stroke(); + }, + strokeText: function() { + var a = arguments; + this._context.strokeText(a[0], a[1], a[2]); + }, + transform: function() { + var a = arguments; + this._context.transform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + translate: function() { + var a = arguments; + this._context.translate(a[0], a[1]); + }, + _enableTrace: function() { + var that = this, + len = CONTEXT_METHODS.length, + _simplifyArray = Konva.Util._simplifyArray, + origSetter = this.setAttr, + n, args; + + // to prevent creating scope function at each loop + var func = function(methodName) { + var origMethod = that[methodName], + ret; + + that[methodName] = function() { + args = _simplifyArray(Array.prototype.slice.call(arguments, 0)); + ret = origMethod.apply(that, arguments); + + that._trace({ + method: methodName, + args: args + }); + + return ret; + }; + }; + // methods + for (n = 0; n < len; n++) { + func(CONTEXT_METHODS[n]); + } + + // attrs + that.setAttr = function() { + origSetter.apply(that, arguments); + that._trace({ + property: arguments[0], + val: arguments[1] + }); + }; + } + }; + + CONTEXT_PROPERTIES.forEach(function(prop) { + Object.defineProperty(Konva.Context.prototype, prop, { + get: function () { + return this._context[prop]; + }, + set: function (val) { + this._context[prop] = val; + } + }); + }); + + Konva.SceneContext = function(canvas) { + Konva.Context.call(this, canvas); + }; + + Konva.SceneContext.prototype = { + _fillColor: function(shape) { + var fill = shape.fill(); + + this.setAttr('fillStyle', fill); + shape._fillFunc(this); + }, + _fillPattern: function(shape) { + var fillPatternX = shape.getFillPatternX(), + fillPatternY = shape.getFillPatternY(), + fillPatternScale = shape.getFillPatternScale(), + fillPatternRotation = Konva.getAngle(shape.getFillPatternRotation()), + fillPatternOffset = shape.getFillPatternOffset(); + + if(fillPatternX || fillPatternY) { + this.translate(fillPatternX || 0, fillPatternY || 0); + } + if(fillPatternRotation) { + this.rotate(fillPatternRotation); + } + if(fillPatternScale) { + this.scale(fillPatternScale.x, fillPatternScale.y); + } + if(fillPatternOffset) { + this.translate(-1 * fillPatternOffset.x, -1 * fillPatternOffset.y); + } + + this.setAttr('fillStyle', this.createPattern(shape.getFillPatternImage(), shape.getFillPatternRepeat() || 'repeat')); + this.fill(); + }, + _fillLinearGradient: function(shape) { + var start = shape.getFillLinearGradientStartPoint(), + end = shape.getFillLinearGradientEndPoint(), + colorStops = shape.getFillLinearGradientColorStops(), + grd = this.createLinearGradient(start.x, start.y, end.x, end.y); + + if (colorStops) { + // build color stops + for(var n = 0; n < colorStops.length; n += 2) { + grd.addColorStop(colorStops[n], colorStops[n + 1]); + } + this.setAttr('fillStyle', grd); + shape._fillFunc(this); + } + }, + _fillRadialGradient: function(shape) { + var start = shape.getFillRadialGradientStartPoint(), + end = shape.getFillRadialGradientEndPoint(), + startRadius = shape.getFillRadialGradientStartRadius(), + endRadius = shape.getFillRadialGradientEndRadius(), + colorStops = shape.getFillRadialGradientColorStops(), + grd = this.createRadialGradient(start.x, start.y, startRadius, end.x, end.y, endRadius); + + // build color stops + for(var n = 0; n < colorStops.length; n += 2) { + grd.addColorStop(colorStops[n], colorStops[n + 1]); + } + this.setAttr('fillStyle', grd); + this.fill(); + }, + _fill: function(shape) { + var hasColor = shape.fill(), + hasPattern = shape.getFillPatternImage(), + hasLinearGradient = shape.getFillLinearGradientColorStops(), + hasRadialGradient = shape.getFillRadialGradientColorStops(), + fillPriority = shape.getFillPriority(); + + // priority fills + if(hasColor && fillPriority === 'color') { + this._fillColor(shape); + } + else if(hasPattern && fillPriority === 'pattern') { + this._fillPattern(shape); + } + else if(hasLinearGradient && fillPriority === 'linear-gradient') { + this._fillLinearGradient(shape); + } + else if(hasRadialGradient && fillPriority === 'radial-gradient') { + this._fillRadialGradient(shape); + } + // now just try and fill with whatever is available + else if(hasColor) { + this._fillColor(shape); + } + else if(hasPattern) { + this._fillPattern(shape); + } + else if(hasLinearGradient) { + this._fillLinearGradient(shape); + } + else if(hasRadialGradient) { + this._fillRadialGradient(shape); + } + }, + _stroke: function(shape) { + var dash = shape.dash(), + // ignore strokeScaleEnabled for Text + strokeScaleEnabled = (shape.getStrokeScaleEnabled() || (shape instanceof Konva.Text)); + + if(shape.hasStroke()) { + if (!strokeScaleEnabled) { + this.save(); + this.setTransform(1, 0, 0, 1, 0, 0); + } + + this._applyLineCap(shape); + if(dash && shape.dashEnabled()) { + this.setLineDash(dash); + } + + this.setAttr('lineWidth', shape.strokeWidth()); + this.setAttr('strokeStyle', shape.stroke()); + + if (!shape.getShadowForStrokeEnabled()) { + this.setAttr('shadowColor', 'rgba(0,0,0,0)'); + } + shape._strokeFunc(this); + + if (!strokeScaleEnabled) { + this.restore(); + } + } + }, + _applyShadow: function(shape) { + var util = Konva.Util, + color = util.get(shape.getShadowRGBA(), 'black'), + blur = util.get(shape.getShadowBlur(), 5), + offset = util.get(shape.getShadowOffset(), { + x: 0, + y: 0 + }), + // TODO: get this info from transform?? + scale = shape.getAbsoluteScale(), + scaleX = scale.x, + scaleY = scale.y; + + this.setAttr('shadowColor', color); + this.setAttr('shadowBlur', blur); + this.setAttr('shadowOffsetX', offset.x * scaleX); + this.setAttr('shadowOffsetY', offset.y * scaleY); + } + }; + Konva.Util.extend(Konva.SceneContext, Konva.Context); + + Konva.HitContext = function(canvas) { + Konva.Context.call(this, canvas); + }; + + Konva.HitContext.prototype = { + _fill: function(shape) { + this.save(); + this.setAttr('fillStyle', shape.colorKey); + shape._fillFuncHit(this); + this.restore(); + }, + _stroke: function(shape) { + if(shape.hasStroke() && shape.strokeHitEnabled()) { + // ignore strokeScaleEnabled for Text + var strokeScaleEnabled = (shape.getStrokeScaleEnabled() || (shape instanceof Konva.Text)); + if (!strokeScaleEnabled) { + this.save(); + this.setTransform(1, 0, 0, 1, 0, 0); + } + this._applyLineCap(shape); + this.setAttr('lineWidth', shape.strokeWidth()); + this.setAttr('strokeStyle', shape.colorKey); + shape._strokeFuncHit(this); + if (!strokeScaleEnabled) { + this.restore(); + } + } + } + }; + Konva.Util.extend(Konva.HitContext, Konva.Context); +})(); + +(function() { + 'use strict'; + // CONSTANTS + var GET = 'get', + SET = 'set'; + + Konva.Factory = { + addGetterSetter: function(constructor, attr, def, validator, after) { + this.addGetter(constructor, attr, def); + this.addSetter(constructor, attr, validator, after); + this.addOverloadedGetterSetter(constructor, attr); + }, + addGetter: function(constructor, attr, def) { + var method = GET + Konva.Util._capitalize(attr); + + constructor.prototype[method] = function() { + var val = this.attrs[attr]; + return val === undefined ? def : val; + }; + }, + addSetter: function(constructor, attr, validator, after) { + var method = SET + Konva.Util._capitalize(attr); + + constructor.prototype[method] = function(val) { + if (validator) { + val = validator.call(this, val); + } + + this._setAttr(attr, val); + + if (after) { + after.call(this); + } + + return this; + }; + }, + addComponentsGetterSetter: function(constructor, attr, components, validator, after) { + var len = components.length, + capitalize = Konva.Util._capitalize, + getter = GET + capitalize(attr), + setter = SET + capitalize(attr), + n, component; + + // getter + constructor.prototype[getter] = function() { + var ret = {}; + + for (n = 0; n < len; n++) { + component = components[n]; + ret[component] = this.getAttr(attr + capitalize(component)); + } + + return ret; + }; + + // setter + constructor.prototype[setter] = function(val) { + var oldVal = this.attrs[attr], + key; + + if (validator) { + val = validator.call(this, val); + } + + for (key in val) { + if (!val.hasOwnProperty(key)) { + continue; + } + this._setAttr(attr + capitalize(key), val[key]); + } + + this._fireChangeEvent(attr, oldVal, val); + + if (after) { + after.call(this); + } + + return this; + }; + + this.addOverloadedGetterSetter(constructor, attr); + }, + addOverloadedGetterSetter: function(constructor, attr) { + var capitalizedAttr = Konva.Util._capitalize(attr), + setter = SET + capitalizedAttr, + getter = GET + capitalizedAttr; + + constructor.prototype[attr] = function() { + // setting + if (arguments.length) { + this[setter](arguments[0]); + return this; + } + // getting + return this[getter](); + }; + }, + addDeprecatedGetterSetter: function(constructor, attr, def, validator) { + var method = GET + Konva.Util._capitalize(attr); + var message = attr + ' property is deprecated and will be removed soon. Look at Konva change log for more information.'; + constructor.prototype[method] = function() { + Konva.Util.error(message); + var val = this.attrs[attr]; + return val === undefined ? def : val; + }; + this.addSetter(constructor, attr, validator, function() { + Konva.Util.error(message); + }); + this.addOverloadedGetterSetter(constructor, attr); + }, + backCompat: function(constructor, methods) { + Konva.Util.each(methods, function(oldMethodName, newMethodName) { + var method = constructor.prototype[newMethodName]; + constructor.prototype[oldMethodName] = function(){ + method.apply(this, arguments); + Konva.Util.error(oldMethodName + ' method is deprecated and will be removed soon. Use ' + newMethodName + ' instead'); + }; + }); + }, + afterSetFilter: function() { + this._filterUpToDate = false; + } + }; + + Konva.Validators = { + /** + * @return {number} + */ + RGBComponent: function(val) { + if (val > 255) { + return 255; + } else if (val < 0) { + return 0; + } + return Math.round(val); + }, + alphaComponent: function(val) { + if (val > 1) { + return 1; + } + // chrome does not honor alpha values of 0 + else if (val < 0.0001) { + return 0.0001; + } + + return val; + } + }; +})(); + +(function(Konva) { + 'use strict'; + // CONSTANTS + var ABSOLUTE_OPACITY = 'absoluteOpacity', + ABSOLUTE_TRANSFORM = 'absoluteTransform', + ABSOLUTE_SCALE = 'absoluteScale', + CHANGE = 'Change', + CHILDREN = 'children', + DOT = '.', + EMPTY_STRING = '', + GET = 'get', + ID = 'id', + KONVA = 'konva', + LISTENING = 'listening', + MOUSEENTER = 'mouseenter', + MOUSELEAVE = 'mouseleave', + NAME = 'name', + SET = 'set', + SHAPE = 'Shape', + SPACE = ' ', + STAGE = 'stage', + TRANSFORM = 'transform', + UPPER_STAGE = 'Stage', + VISIBLE = 'visible', + CLONE_BLACK_LIST = ['id'], + + TRANSFORM_CHANGE_STR = [ + 'xChange.konva', + 'yChange.konva', + 'scaleXChange.konva', + 'scaleYChange.konva', + 'skewXChange.konva', + 'skewYChange.konva', + 'rotationChange.konva', + 'offsetXChange.konva', + 'offsetYChange.konva', + 'transformsEnabledChange.konva' + ].join(SPACE), + + SCALE_CHANGE_STR = [ + 'scaleXChange.konva', + 'scaleYChange.konva' + ].join(SPACE); + + /** + * Node constructor. Nodes are entities that can be transformed, layered, + * and have bound events. The stage, layers, groups, and shapes all extend Node. + * @constructor + * @memberof Konva + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + */ + Konva.Node = function(config) { + this._init(config); + }; + + Konva.Util.addMethods(Konva.Node, { + _init: function(config) { + var that = this; + this._id = Konva.idCounter++; + this.eventListeners = {}; + this.attrs = {}; + this._cache = {}; + this._filterUpToDate = false; + this.setAttrs(config); + + // event bindings for cache handling + this.on(TRANSFORM_CHANGE_STR, function() { + this._clearCache(TRANSFORM); + that._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + }); + + this.on(SCALE_CHANGE_STR, function() { + that._clearSelfAndDescendantCache(ABSOLUTE_SCALE); + }); + + this.on('visibleChange.konva', function() { + that._clearSelfAndDescendantCache(VISIBLE); + }); + this.on('listeningChange.konva', function() { + that._clearSelfAndDescendantCache(LISTENING); + }); + this.on('opacityChange.konva', function() { + that._clearSelfAndDescendantCache(ABSOLUTE_OPACITY); + }); + }, + _clearCache: function(attr){ + if (attr) { + delete this._cache[attr]; + } + else { + this._cache = {}; + } + }, + _getCache: function(attr, privateGetter){ + var cache = this._cache[attr]; + + // if not cached, we need to set it using the private getter method. + if (cache === undefined) { + this._cache[attr] = privateGetter.call(this); + } + + return this._cache[attr]; + }, + /* + * when the logic for a cached result depends on ancestor propagation, use this + * method to clear self and children cache + */ + _clearSelfAndDescendantCache: function(attr) { + this._clearCache(attr); + + if (this.children) { + this.getChildren().each(function(node) { + node._clearSelfAndDescendantCache(attr); + }); + } + }, + /** + * clear cached canvas + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.clearCache(); + */ + clearCache: function() { + delete this._cache.canvas; + this._filterUpToDate = false; + return this; + }, + /** + * cache node to improve drawing performance, apply filters, or create more accurate + * hit regions. For all basic shapes size of cache canvas will be automatically detected. + * If you need to cache your custom `Konva.Shape` instance you have to pass shape's bounding box + * properties. Look at [link to demo page](link to demo page) for more information. + * @method + * @memberof Konva.Node.prototype + * @param {Object} [config] + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Number} [config.offset] increase canvas size by `offset` pixel in all directions. + * @param {Boolean} [config.drawBorder] when set to true, a red border will be drawn around the cached + * region for debugging purposes + * @returns {Konva.Node} + * @example + * // cache a shape with the x,y position of the bounding box at the center and + * // the width and height of the bounding box equal to the width and height of + * // the shape obtained from shape.width() and shape.height() + * image.cache(); + * + * // cache a node and define the bounding box position and size + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200 + * }); + * + * // cache a node and draw a red border around the bounding box + * // for debugging purposes + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200, + * offset : 10, + * drawBorder: true + * }); + */ + cache: function(config) { + var conf = config || {}, + rect = this.getClientRect(true), + width = conf.width || rect.width, + height = conf.height || rect.height, + x = conf.x || rect.x, + y = conf.y || rect.y, + offset = conf.offset || 0, + drawBorder = conf.drawBorder || false; + + if (!width || !height) { + throw new Error('Width or height of caching configuration equals 0.'); + } + + width += offset * 2; + height += offset * 2; + + x -= offset; + y -= offset; + + + var cachedSceneCanvas = new Konva.SceneCanvas({ + width: width, + height: height + }), + cachedFilterCanvas = new Konva.SceneCanvas({ + width: width, + height: height + }), + cachedHitCanvas = new Konva.HitCanvas({ + pixelRatio: 1, + width: width, + height: height + }), + sceneContext = cachedSceneCanvas.getContext(), + hitContext = cachedHitCanvas.getContext(); + + cachedHitCanvas.isCache = true; + + this.clearCache(); + + sceneContext.save(); + hitContext.save(); + + sceneContext.translate(-x, -y); + hitContext.translate(-x, -y); + + this.drawScene(cachedSceneCanvas, this, true); + this.drawHit(cachedHitCanvas, this, true); + + sceneContext.restore(); + hitContext.restore(); + + // this will draw a red border around the cached box for + // debugging purposes + if (drawBorder) { + sceneContext.save(); + sceneContext.beginPath(); + sceneContext.rect(0, 0, width, height); + sceneContext.closePath(); + sceneContext.setAttr('strokeStyle', 'red'); + sceneContext.setAttr('lineWidth', 5); + sceneContext.stroke(); + sceneContext.restore(); + } + + this._cache.canvas = { + scene: cachedSceneCanvas, + filter: cachedFilterCanvas, + hit: cachedHitCanvas, + x: x, + y: y + }; + + return this; + }, + /** + * Return client rectangle {x, y, width, height} of node. This rectangle also include all styling (strokes, shadows, etc). + * The rectangle position is relative to parent container. + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} [skipTransform] flag should we skip transformation to rectangle + * @returns {Object} rect with {x, y, width, height} properties + * @example + * var rect = new Konva.Rect({ + * width : 100, + * height : 100, + * x : 50, + * y : 50, + * strokeWidth : 4, + * stroke : 'black', + * offsetX : 50, + * scaleY : 2 + * }); + * + * // get client rect without think off transformations (position, rotation, scale, offset, etc) + * rect.getClientRect(true); + * // returns { + * // x : -2, // two pixels for stroke / 2 + * // y : -2, + * // width : 104, // increased by 4 for stroke + * // height : 104 + * //} + * + * // get client rect with transformation applied + * rect.getClientRect(); + * // returns Object {x: -2, y: 46, width: 104, height: 208} + */ + getClientRect: function() { + // abstract method + // redefine in Container and Shape + throw new Error('abstract "getClientRect" method call'); + }, + _transformedRect: function(rect) { + var points = [ + {x: rect.x, y: rect.y}, + {x: rect.x + rect.width, y: rect.y}, + {x: rect.x + rect.width, y: rect.y + rect.height}, + {x: rect.x, y: rect.y + rect.height} + ]; + var minX, minY, maxX, maxY; + var trans = this.getTransform(); + points.forEach(function(point) { + var transformed = trans.point(point); + if (minX === undefined) { + minX = maxX = transformed.x; + minY = maxY = transformed.y; + } + minX = Math.min(minX, transformed.x); + minY = Math.min(minY, transformed.y); + maxX = Math.max(maxX, transformed.x); + maxY = Math.max(maxY, transformed.y); + }); + return { + x: minX, + y: minY, + width: maxX - minX, + height: maxY - minY + }; + }, + _drawCachedSceneCanvas: function(context) { + context.save(); + context._applyOpacity(this); + context.translate( + this._cache.canvas.x, + this._cache.canvas.y + ); + + var cacheCanvas = this._getCachedSceneCanvas(); + var ratio = cacheCanvas.pixelRatio; + + context.drawImage(cacheCanvas._canvas, 0, 0, cacheCanvas.width / ratio, cacheCanvas.height / ratio); + context.restore(); + }, + _drawCachedHitCanvas: function(context) { + var cachedCanvas = this._cache.canvas, + hitCanvas = cachedCanvas.hit; + context.save(); + context.translate( + this._cache.canvas.x, + this._cache.canvas.y + ); + context.drawImage(hitCanvas._canvas, 0, 0); + context.restore(); + }, + _getCachedSceneCanvas: function() { + var filters = this.filters(), + cachedCanvas = this._cache.canvas, + sceneCanvas = cachedCanvas.scene, + filterCanvas = cachedCanvas.filter, + filterContext = filterCanvas.getContext(), + len, imageData, n, filter; + + if (filters) { + if (!this._filterUpToDate) { + var ratio = sceneCanvas.pixelRatio; + + try { + len = filters.length; + filterContext.clear(); + + // copy cached canvas onto filter context + filterContext.drawImage(sceneCanvas._canvas, 0, 0, sceneCanvas.getWidth() / ratio, sceneCanvas.getHeight() / ratio); + imageData = filterContext.getImageData(0, 0, filterCanvas.getWidth(), filterCanvas.getHeight()); + + // apply filters to filter context + for (n = 0; n < len; n++) { + filter = filters[n]; + filter.call(this, imageData); + filterContext.putImageData(imageData, 0, 0); + } + } + catch(e) { + Konva.Util.warn('Unable to apply filter. ' + e.message); + } + + this._filterUpToDate = true; + } + + return filterCanvas; + } + return sceneCanvas; + }, + /** + * bind events to the node. KonvaJS supports mouseover, mousemove, + * mouseout, mouseenter, mouseleave, mousedown, mouseup, wheel, click, dblclick, touchstart, touchmove, + * touchend, tap, dbltap, dragstart, dragmove, and dragend events. The Konva Stage supports + * contentMouseover, contentMousemove, contentMouseout, contentMousedown, contentMouseup, contentWheel + * contentClick, contentDblclick, contentTouchstart, contentTouchmove, contentTouchend, contentTap, + * and contentDblTap. Pass in a string of events delimmited by a space to bind multiple events at once + * such as 'mousedown mouseup mousemove'. Include a namespace to bind an + * event by name such as 'click.foobar'. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' + * @param {Function} handler The handler function is passed an event object + * @returns {Konva.Node} + * @example + * // add click listener + * node.on('click', function() { + * console.log('you clicked me!'); + * }); + * + * // get the target node + * node.on('click', function(evt) { + * console.log(evt.target); + * }); + * + * // stop event propagation + * node.on('click', function(evt) { + * evt.cancelBubble = true; + * }); + * + * // bind multiple listeners + * node.on('click touchstart', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // namespace listener + * node.on('click.foo', function() { + * console.log('you clicked/touched me!'); + * }); + * + * // get the event type + * node.on('click tap', function(evt) { + * var eventType = evt.type; + * }); + * + * // get native event object + * node.on('click tap', function(evt) { + * var nativeEvent = evt.evt; + * }); + * + * // for change events, get the old and new val + * node.on('xChange', function(evt) { + * var oldVal = evt.oldVal; + * var newVal = evt.newVal; + * }); + * + * // get event targets + * // with event delegations + * layer.on('click', 'Group', function(evt) { + * var shape = evt.target; + * var group = evtn.currentTarger; + * }); + */ + on: function(evtStr, handler) { + if (arguments.length === 3) { + return this._delegate.apply(this, arguments); + } + var events = evtStr.split(SPACE), + len = events.length, + n, event, parts, baseEvent, name; + + /* + * loop through types and attach event listeners to + * each one. eg. 'click mouseover.namespace mouseout' + * will create three event bindings + */ + for(n = 0; n < len; n++) { + event = events[n]; + parts = event.split(DOT); + baseEvent = parts[0]; + name = parts[1] || EMPTY_STRING; + + // create events array if it doesn't exist + if(!this.eventListeners[baseEvent]) { + this.eventListeners[baseEvent] = []; + } + + this.eventListeners[baseEvent].push({ + name: name, + handler: handler + }); + } + + return this; + }, + /** + * remove event bindings from the node. Pass in a string of + * event types delimmited by a space to remove multiple event + * bindings at once such as 'mousedown mouseup mousemove'. + * include a namespace to remove an event binding by name + * such as 'click.foobar'. If you only give a name like '.foobar', + * all events in that namespace will be removed. + * @method + * @memberof Konva.Node.prototype + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar' + * @returns {Konva.Node} + * @example + * // remove listener + * node.off('click'); + * + * // remove multiple listeners + * node.off('click touchstart'); + * + * // remove listener by name + * node.off('click.foo'); + */ + off: function(evtStr) { + var events = (evtStr || '').split(SPACE), + len = events.length, + n, t, event, parts, baseEvent, name; + + if (!evtStr) { + // remove all events + for(t in this.eventListeners) { + this._off(t); + } + } + for(n = 0; n < len; n++) { + event = events[n]; + parts = event.split(DOT); + baseEvent = parts[0]; + name = parts[1]; + + if(baseEvent) { + if(this.eventListeners[baseEvent]) { + this._off(baseEvent, name); + } + } + else { + for(t in this.eventListeners) { + this._off(t, name); + } + } + } + return this; + }, + // some event aliases for third party integration like HammerJS + dispatchEvent: function(evt) { + var e = { + target: this, + type: evt.type, + evt: evt + }; + this.fire(evt.type, e); + return this; + }, + addEventListener: function(type, handler) { + // we have to pass native event to handler + this.on(type, function(evt){ + handler.call(this, evt.evt); + }); + return this; + }, + removeEventListener: function(type) { + this.off(type); + return this; + }, + // like node.on + _delegate: function(event, selector, handler) { + var stopNode = this; + this.on(event, function(evt) { + var targets = evt.target.findAncestors(selector, true, stopNode); + for(var i = 0; i < targets.length; i++) { + evt = Konva.Util.cloneObject(evt); + evt.currentTarget = targets[i]; + handler.call(targets[i], evt); + } + }); + }, + /** + * remove self from parent, but don't destroy + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + * @example + * node.remove(); + */ + remove: function() { + var parent = this.getParent(); + + if(parent && parent.children) { + parent.children.splice(this.index, 1); + parent._setChildrenIndices(); + delete this.parent; + } + + // every cached attr that is calculated via node tree + // traversal must be cleared when removing a node + this._clearSelfAndDescendantCache(STAGE); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + this._clearSelfAndDescendantCache(VISIBLE); + this._clearSelfAndDescendantCache(LISTENING); + this._clearSelfAndDescendantCache(ABSOLUTE_OPACITY); + + return this; + }, + /** + * remove and destroy self + * @method + * @memberof Konva.Node.prototype + * @example + * node.destroy(); + */ + destroy: function() { + // remove from ids and names hashes + Konva._removeId(this.getId()); + Konva._removeName(this.getName(), this._id); + + this.remove(); + return this; + }, + /** + * get attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @returns {Integer|String|Object|Array} + * @example + * var x = node.getAttr('x'); + */ + getAttr: function(attr) { + var method = GET + Konva.Util._capitalize(attr); + if(Konva.Util._isFunction(this[method])) { + return this[method](); + } + // otherwise get directly + return this.attrs[attr]; + }, + /** + * get ancestors + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Collection} + * @example + * shape.getAncestors().each(function(node) { + * console.log(node.getId()); + * }) + */ + getAncestors: function() { + var parent = this.getParent(), + ancestors = new Konva.Collection(); + + while (parent) { + ancestors.push(parent); + parent = parent.getParent(); + } + + return ancestors; + }, + /** + * get attrs object literal + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ + getAttrs: function() { + return this.attrs || {}; + }, + /** + * set multiple attrs at once using an object literal + * @method + * @memberof Konva.Node.prototype + * @param {Object} config object containing key value pairs + * @returns {Konva.Node} + * @example + * node.setAttrs({ + * x: 5, + * fill: 'red' + * }); + */ + setAttrs: function(config) { + var key, method; + + if(!config) { + return this; + } + for(key in config) { + if (key === CHILDREN) { + continue; + } + method = SET + Konva.Util._capitalize(key); + // use setter if available + if(Konva.Util._isFunction(this[method])) { + this[method](config[key]); + } + // otherwise set directly + else { + this._setAttr(key, config[key]); + } + } + return this; + }, + /** + * determine if node is listening for events by taking into account ancestors. + * + * Parent | Self | isListening + * listening | listening | + * ----------+-----------+------------ + * T | T | T + * T | F | F + * F | T | T + * F | F | F + * ----------+-----------+------------ + * T | I | T + * F | I | F + * I | I | T + * + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + isListening: function() { + return this._getCache(LISTENING, this._isListening); + }, + _isListening: function() { + var listening = this.getListening(), + parent = this.getParent(); + + // the following conditions are a simplification of the truth table above. + // please modify carefully + if (listening === 'inherit') { + if (parent) { + return parent.isListening(); + } + else { + return true; + } + } + else { + return listening; + } + }, + /** + * determine if node is visible by taking into account ancestors. + * + * Parent | Self | isVisible + * visible | visible | + * ----------+-----------+------------ + * T | T | T + * T | F | F + * F | T | T + * F | F | F + * ----------+-----------+------------ + * T | I | T + * F | I | F + * I | I | T + + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + isVisible: function() { + return this._getCache(VISIBLE, this._isVisible); + }, + _isVisible: function() { + var visible = this.getVisible(), + parent = this.getParent(); + + // the following conditions are a simplification of the truth table above. + // please modify carefully + if (visible === 'inherit') { + if (parent) { + return parent.isVisible(); + } + else { + return true; + } + } + else { + return visible; + } + }, + /** + * determine if listening is enabled by taking into account descendants. If self or any children + * have _isListeningEnabled set to true, then self also has listening enabled. + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + shouldDrawHit: function(canvas) { + var layer = this.getLayer(); + return (canvas && canvas.isCache) || (layer && layer.hitGraphEnabled()) + && this.isListening() && this.isVisible(); + }, + /** + * show node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + show: function() { + this.setVisible(true); + return this; + }, + /** + * hide node. Hidden nodes are no longer detectable + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + hide: function() { + this.setVisible(false); + return this; + }, + /** + * get zIndex relative to the node's siblings who share the same parent + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getZIndex: function() { + return this.index || 0; + }, + /** + * get absolute z-index which takes into account sibling + * and ancestor indices + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getAbsoluteZIndex: function() { + var depth = this.getDepth(), + that = this, + index = 0, + nodes, len, n, child; + + function addChildren(children) { + nodes = []; + len = children.length; + for(n = 0; n < len; n++) { + child = children[n]; + index++; + + if(child.nodeType !== SHAPE) { + nodes = nodes.concat(child.getChildren().toArray()); + } + + if(child._id === that._id) { + n = len; + } + } + + if(nodes.length > 0 && nodes[0].getDepth() <= depth) { + addChildren(nodes); + } + } + if(that.nodeType !== UPPER_STAGE) { + addChildren(that.getStage().getChildren()); + } + + return index; + }, + /** + * get node depth in node tree. Returns an integer. + * e.g. Stage depth will always be 0. Layers will always be 1. Groups and Shapes will always + * be >= 2 + * @method + * @memberof Konva.Node.prototype + * @returns {Integer} + */ + getDepth: function() { + var depth = 0, + parent = this.parent; + + while(parent) { + depth++; + parent = parent.parent; + } + return depth; + }, + setPosition: function(pos) { + this.setX(pos.x); + this.setY(pos.y); + return this; + }, + getPosition: function() { + return { + x: this.getX(), + y: this.getY() + }; + }, + /** + * get absolute position relative to the top left corner of the stage container div + * or relative to passed node + * @method + * @param {Object} [top] optional parent node + * @memberof Konva.Node.prototype + * @returns {Object} + */ + getAbsolutePosition: function(top) { + var absoluteMatrix = this.getAbsoluteTransform(top).getMatrix(), + absoluteTransform = new Konva.Transform(), + offset = this.offset(); + + // clone the matrix array + absoluteTransform.m = absoluteMatrix.slice(); + absoluteTransform.translate(offset.x, offset.y); + + return absoluteTransform.getTranslation(); + }, + /** + * set absolute position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Konva.Node} + */ + setAbsolutePosition: function(pos) { + var origTrans = this._clearTransform(), + it; + + // don't clear translation + this.attrs.x = origTrans.x; + this.attrs.y = origTrans.y; + delete origTrans.x; + delete origTrans.y; + + // unravel transform + it = this.getAbsoluteTransform(); + + it.invert(); + it.translate(pos.x, pos.y); + pos = { + x: this.attrs.x + it.getTranslation().x, + y: this.attrs.y + it.getTranslation().y + }; + + this.setPosition({x: pos.x, y: pos.y}); + this._setTransform(origTrans); + + return this; + }, + _setTransform: function(trans) { + var key; + + for(key in trans) { + this.attrs[key] = trans[key]; + } + + this._clearCache(TRANSFORM); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + }, + _clearTransform: function() { + var trans = { + x: this.getX(), + y: this.getY(), + rotation: this.getRotation(), + scaleX: this.getScaleX(), + scaleY: this.getScaleY(), + offsetX: this.getOffsetX(), + offsetY: this.getOffsetY(), + skewX: this.getSkewX(), + skewY: this.getSkewY() + }; + + this.attrs.x = 0; + this.attrs.y = 0; + this.attrs.rotation = 0; + this.attrs.scaleX = 1; + this.attrs.scaleY = 1; + this.attrs.offsetX = 0; + this.attrs.offsetY = 0; + this.attrs.skewX = 0; + this.attrs.skewY = 0; + + this._clearCache(TRANSFORM); + this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + + // return original transform + return trans; + }, + /** + * move node by an amount relative to its current position + * @method + * @memberof Konva.Node.prototype + * @param {Object} change + * @param {Number} change.x + * @param {Number} change.y + * @returns {Konva.Node} + * @example + * // move node in x direction by 1px and y direction by 2px + * node.move({ + * x: 1, + * y: 2) + * }); + */ + move: function(change) { + var changeX = change.x, + changeY = change.y, + x = this.getX(), + y = this.getY(); + + if(changeX !== undefined) { + x += changeX; + } + + if(changeY !== undefined) { + y += changeY; + } + + this.setPosition({x: x, y: y}); + return this; + }, + _eachAncestorReverse: function(func, top) { + var family = [], + parent = this.getParent(), + len, n; + + // if top node is defined, and this node is top node, + // there's no need to build a family tree. just execute + // func with this because it will be the only node + if (top && top._id === this._id) { + func(this); + return true; + } + + family.unshift(this); + + while(parent && (!top || parent._id !== top._id)) { + family.unshift(parent); + parent = parent.parent; + } + + len = family.length; + for(n = 0; n < len; n++) { + func(family[n]); + } + }, + /** + * rotate node by an amount in degrees relative to its current rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} theta + * @returns {Konva.Node} + */ + rotate: function(theta) { + this.setRotation(this.getRotation() + theta); + return this; + }, + /** + * move node to the top of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveToTop: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveToTop function is ignored.'); + return false; + } + var index = this.index; + this.parent.children.splice(index, 1); + this.parent.children.push(this); + this.parent._setChildrenIndices(); + return true; + }, + /** + * move node up + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} flag is moved or not + */ + moveUp: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveUp function is ignored.'); + return false; + } + var index = this.index, + len = this.parent.getChildren().length; + if(index < len - 1) { + this.parent.children.splice(index, 1); + this.parent.children.splice(index + 1, 0, this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * move node down + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveDown: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveDown function is ignored.'); + return false; + } + var index = this.index; + if(index > 0) { + this.parent.children.splice(index, 1); + this.parent.children.splice(index - 1, 0, this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * move node to the bottom of its siblings + * @method + * @memberof Konva.Node.prototype + * @returns {Boolean} + */ + moveToBottom: function() { + if (!this.parent) { + Konva.Util.warn('Node has no parent. moveToBottom function is ignored.'); + return false; + } + var index = this.index; + if(index > 0) { + this.parent.children.splice(index, 1); + this.parent.children.unshift(this); + this.parent._setChildrenIndices(); + return true; + } + return false; + }, + /** + * set zIndex relative to siblings + * @method + * @memberof Konva.Node.prototype + * @param {Integer} zIndex + * @returns {Konva.Node} + */ + setZIndex: function(zIndex) { + if (!this.parent) { + Konva.Util.warn('Node has no parent. zIndex parameter is ignored.'); + return false; + } + var index = this.index; + this.parent.children.splice(index, 1); + this.parent.children.splice(zIndex, 0, this); + this.parent._setChildrenIndices(); + return this; + }, + /** + * get absolute opacity + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + */ + getAbsoluteOpacity: function() { + return this._getCache(ABSOLUTE_OPACITY, this._getAbsoluteOpacity); + }, + _getAbsoluteOpacity: function() { + var absOpacity = this.getOpacity(); + if(this.getParent()) { + absOpacity *= this.getParent().getAbsoluteOpacity(); + } + return absOpacity; + }, + /** + * move node to another container + * @method + * @memberof Konva.Node.prototype + * @param {Container} newContainer + * @returns {Konva.Node} + * @example + * // move node from current layer into layer2 + * node.moveTo(layer2); + */ + moveTo: function(newContainer) { + // do nothing if new container is already parent + if (this.getParent() !== newContainer) { + this.remove(); + newContainer.add(this); + } + return this; + }, + /** + * convert Node into an object for serialization. Returns an object. + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + */ + toObject: function() { + var obj = {}, + attrs = this.getAttrs(), + key, val, getter, defaultValue; + + obj.attrs = {}; + + for(key in attrs) { + val = attrs[key]; + // serialize only attributes that are not function, image, DOM, or objects with methods + if (Konva.Util._isFunction(val) || Konva.Util._isElement(val) || + (Konva.Util._isObject(val) || Konva.Util._hasMethods(val))) { + continue; + } + getter = this[key]; + // remove attr value so that we can extract the default value from the getter + delete attrs[key]; + defaultValue = getter ? getter.call(this) : null; + // restore attr value + attrs[key] = val; + if (defaultValue !== val) { + obj.attrs[key] = val; + } + } + + obj.className = this.getClassName(); + return obj; + }, + /** + * convert Node into a JSON string. Returns a JSON string. + * @method + * @memberof Konva.Node.prototype + * @returns {String}} + */ + toJSON: function() { + return JSON.stringify(this.toObject()); + }, + /** + * get parent container + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + getParent: function() { + return this.parent; + }, + /** + * get all ancestros (parent then parent of the parent, etc) of the node + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Array} [ancestors] + * @example + * // get one of the parent group + * var parentGroups = node.findAncestors('Group'); + */ + findAncestors: function(selector, includeSelf, stopNode) { + var res = []; + + if (includeSelf && this._isMatch(selector)) { + res.push(this); + } + var ancestor = this.parent; + while(ancestor) { + if (ancestor === stopNode) { + return res; + } + if (ancestor._isMatch(selector)) { + res.push(ancestor); + } + ancestor = ancestor.parent; + } + return res; + }, + /** + * get ancestor (parent or parent of the parent, etc) of the node that match passed selector + * @method + * @memberof Konva.Node.prototype + * @param {String} [selector] selector for search + * @param {Boolean} [includeSelf] show we think that node is ancestro itself? + * @param {Konva.Node} [stopNode] optional node where we need to stop searching (one of ancestors) + * @returns {Konva.Node} ancestor + * @example + * // get one of the parent group + * var group = node.findAncestors('.mygroup'); + */ + findAncestor: function(selector, includeSelf, stopNode) { + return this.findAncestors(selector, includeSelf, stopNode)[0]; + }, + // is current node match passed selector? + _isMatch: function(selector) { + if (!selector) { + return false; + } + var selectorArr = selector.replace(/ /g, '').split(','), + len = selectorArr.length, + n, sel; + + for (n = 0; n < len; n++) { + sel = selectorArr[n]; + if (!Konva.Util.isValidSelector(sel)) { + Konva.Util.warn('Selector "' + sel + '" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".'); + Konva.Util.warn('If you have a custom shape with such className, please change it to start with upper letter like "Triangle".'); + Konva.Util.warn('Konva is awesome, right?'); + } + // id selector + if(sel.charAt(0) === '#') { + if (this.id() === sel.slice(1)) { + return true; + } + } + // name selector + else if(sel.charAt(0) === '.') { + if (this.hasName(sel.slice(1))) { + return true; + } + } else if (this._get(sel).length !== 0) { + return true; + } + } + return false; + }, + /** + * get layer ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Layer} + */ + getLayer: function() { + var parent = this.getParent(); + return parent ? parent.getLayer() : null; + }, + /** + * get stage ancestor + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Stage} + */ + getStage: function() { + return this._getCache(STAGE, this._getStage); + }, + _getStage: function() { + var parent = this.getParent(); + if(parent) { + return parent.getStage(); + } + else { + return undefined; + } + }, + /** + * fire event + * @method + * @memberof Konva.Node.prototype + * @param {String} eventType event type. can be a regular event, like click, mouseover, or mouseout, or it can be a custom event, like myCustomEvent + * @param {Event} [evt] event object + * @param {Boolean} [bubble] setting the value to false, or leaving it undefined, will result in the event + * not bubbling. Setting the value to true will result in the event bubbling. + * @returns {Konva.Node} + * @example + * // manually fire click event + * node.fire('click'); + * + * // fire custom event + * node.fire('foo'); + * + * // fire custom event with custom event object + * node.fire('foo', { + * bar: 10 + * }); + * + * // fire click event that bubbles + * node.fire('click', null, true); + */ + fire: function(eventType, evt, bubble) { + evt = evt || {}; + evt.target = evt.target || this; + // bubble + if (bubble) { + this._fireAndBubble(eventType, evt); + } + // no bubble + else { + this._fire(eventType, evt); + } + return this; + }, + /** + * get absolute transform of the node which takes into + * account its ancestor transforms + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getAbsoluteTransform: function(top) { + // if using an argument, we can't cache the result. + if (top) { + return this._getAbsoluteTransform(top); + } + // if no argument, we can cache the result + else { + return this._getCache(ABSOLUTE_TRANSFORM, this._getAbsoluteTransform); + } + }, + _getAbsoluteTransform: function(top) { + var at = new Konva.Transform(), + transformsEnabled, trans; + + // start with stage and traverse downwards to self + this._eachAncestorReverse(function(node) { + transformsEnabled = node.transformsEnabled(); + trans = node.getTransform(); + + if (transformsEnabled === 'all') { + at.multiply(trans); + } + else if (transformsEnabled === 'position') { + at.translate(node.x(), node.y()); + } + }, top); + return at; + }, + /** + * get absolute scale of the node which takes into + * account its ancestor scales + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getAbsoluteScale: function(top) { + // if using an argument, we can't cache the result. + if (top) { + return this._getAbsoluteTransform(top); + } + // if no argument, we can cache the result + else { + return this._getCache(ABSOLUTE_SCALE, this._getAbsoluteScale); + } + }, + _getAbsoluteScale: function(top) { + var scaleX = 1, scaleY = 1; + + // start with stage and traverse downwards to self + this._eachAncestorReverse(function(node) { + scaleX *= node.scaleX(); + scaleY *= node.scaleY(); + }, top); + return { + x: scaleX, + y: scaleY + }; + }, + /** + * get transform of the node + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Transform} + */ + getTransform: function() { + return this._getCache(TRANSFORM, this._getTransform); + }, + _getTransform: function() { + var m = new Konva.Transform(), + x = this.getX(), + y = this.getY(), + rotation = Konva.getAngle(this.getRotation()), + scaleX = this.getScaleX(), + scaleY = this.getScaleY(), + skewX = this.getSkewX(), + skewY = this.getSkewY(), + offsetX = this.getOffsetX(), + offsetY = this.getOffsetY(); + + if(x !== 0 || y !== 0) { + m.translate(x, y); + } + if(rotation !== 0) { + m.rotate(rotation); + } + if(skewX !== 0 || skewY !== 0) { + m.skew(skewX, skewY); + } + if(scaleX !== 1 || scaleY !== 1) { + m.scale(scaleX, scaleY); + } + if(offsetX !== 0 || offsetY !== 0) { + m.translate(-1 * offsetX, -1 * offsetY); + } + + return m; + }, + /** + * clone node. Returns a new Node instance with identical attributes. You can also override + * the node properties with an object literal, enabling you to use an existing node as a template + * for another node + * @method + * @memberof Konva.Node.prototype + * @param {Object} obj override attrs + * @returns {Konva.Node} + * @example + * // simple clone + * var clone = node.clone(); + * + * // clone a node and override the x position + * var clone = rect.clone({ + * x: 5 + * }); + */ + clone: function(obj) { + // instantiate new node + var attrs = Konva.Util.cloneObject(this.attrs), + key, allListeners, len, n, listener; + // filter black attrs + for (var i in CLONE_BLACK_LIST) { + var blockAttr = CLONE_BLACK_LIST[i]; + delete attrs[blockAttr]; + } + // apply attr overrides + for (key in obj) { + attrs[key] = obj[key]; + } + + var node = new this.constructor(attrs); + // copy over listeners + for(key in this.eventListeners) { + allListeners = this.eventListeners[key]; + len = allListeners.length; + for(n = 0; n < len; n++) { + listener = allListeners[n]; + /* + * don't include konva namespaced listeners because + * these are generated by the constructors + */ + if(listener.name.indexOf(KONVA) < 0) { + // if listeners array doesn't exist, then create it + if(!node.eventListeners[key]) { + node.eventListeners[key] = []; + } + node.eventListeners[key].push(listener); + } + } + } + return node; + }, + /** + * Creates a composite data URL. If MIME type is not + * specified, then "image/png" will result. For "image/jpeg", specify a quality + * level as quality (range 0.0 - 1.0) + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image url. Default is 1 + * @returns {String} + */ + toDataURL: function(config) { + config = config || {}; + + var mimeType = config.mimeType || null, + quality = config.quality || null, + stage = this.getStage(), + x = config.x || 0, + y = config.y || 0, + pixelRatio = config.pixelRatio || 1, + canvas = new Konva.SceneCanvas({ + width: config.width || this.getWidth() || (stage ? stage.getWidth() : 0), + height: config.height || this.getHeight() || (stage ? stage.getHeight() : 0), + pixelRatio: pixelRatio + }), + context = canvas.getContext(); + + context.save(); + + if(x || y) { + context.translate(-1 * x, -1 * y); + } + + this.drawScene(canvas); + context.restore(); + + return canvas.toDataURL(mimeType, quality); + }, + /** + * converts node into an image. Since the toImage + * method is asynchronous, a callback is required. toImage is most commonly used + * to cache complex drawings as an image so that they don't have to constantly be redrawn + * @method + * @memberof Konva.Node.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + * @paremt {Number} [config.pixelRatio] pixelRatio of ouput image. Default is 1. + * @example + * var image = node.toImage({ + * callback: function(img) { + * // do stuff with img + * } + * }); + */ + toImage: function(config) { + if (!config || !config.callback) { + throw 'callback required for toImage method config argument'; + } + Konva.Util._getImage(this.toDataURL(config), function(img) { + config.callback(img); + }); + }, + setSize: function(size) { + this.setWidth(size.width); + this.setHeight(size.height); + return this; + }, + getSize: function() { + return { + width: this.getWidth(), + height: this.getHeight() + }; + }, + getWidth: function() { + return this.attrs.width || 0; + }, + getHeight: function() { + return this.attrs.height || 0; + }, + /** + * get class name, which may return Stage, Layer, Group, or shape class names like Rect, Circle, Text, etc. + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ + getClassName: function() { + return this.className || this.nodeType; + }, + /** + * get the node type, which may return Stage, Layer, Group, or Node + * @method + * @memberof Konva.Node.prototype + * @returns {String} + */ + getType: function() { + return this.nodeType; + }, + getDragDistance: function() { + // compare with undefined because we need to track 0 value + if (this.attrs.dragDistance !== undefined) { + return this.attrs.dragDistance; + } else if (this.parent) { + return this.parent.getDragDistance(); + } else { + return Konva.dragDistance; + } + }, + _get: function(selector) { + return this.className === selector || this.nodeType === selector ? [this] : []; + }, + _off: function(type, name) { + var evtListeners = this.eventListeners[type], + i, evtName; + + for(i = 0; i < evtListeners.length; i++) { + evtName = evtListeners[i].name; + // the following two conditions must be true in order to remove a handler: + // 1) the current event name cannot be konva unless the event name is konva + // this enables developers to force remove a konva specific listener for whatever reason + // 2) an event name is not specified, or if one is specified, it matches the current event name + if((evtName !== 'konva' || name === 'konva') && (!name || evtName === name)) { + evtListeners.splice(i, 1); + if(evtListeners.length === 0) { + delete this.eventListeners[type]; + break; + } + i--; + } + } + }, + _fireChangeEvent: function(attr, oldVal, newVal) { + this._fire(attr + CHANGE, { + oldVal: oldVal, + newVal: newVal + }); + }, + setId: function(id) { + var oldId = this.getId(); + + Konva._removeId(oldId); + Konva._addId(this, id); + this._setAttr(ID, id); + return this; + }, + setName: function(name) { + var oldNames = (this.getName() || '').split(/\s/g); + var newNames = (name || '').split(/\s/g); + var subname, i; + // remove all subnames + for(i = 0; i < oldNames.length; i++) { + subname = oldNames[i]; + if ((newNames.indexOf(subname)) === -1 && subname) { + Konva._removeName(subname, this._id); + } + } + + // add new names + for(i = 0; i < newNames.length; i++) { + subname = newNames[i]; + if ((oldNames.indexOf(subname) === -1) && subname) { + Konva._addName(this, subname); + } + } + + this._setAttr(NAME, name); + return this; + }, + // naming methods + /** + * add name to node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red'); + * node.addName('selected'); + * node.name(); // return 'red selected' + */ + addName: function(name) { + if (!this.hasName(name)) { + var oldName = this.name(); + var newName = oldName ? (oldName + ' ' + name) : name; + this.setName(newName); + } + return this; + }, + /** + * check is node has name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Boolean} + * @example + * node.name('red'); + * node.hasName('red'); // return true + * node.hasName('selected'); // return false + */ + hasName: function(name) { + var names = (this.name() || '').split(/\s/g); + return names.indexOf(name) !== -1; + }, + /** + * remove name from node + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {Konva.Node} + * @example + * node.name('red selected'); + * node.removeName('selected'); + * node.hasName('selected'); // return false + * node.name(); // return 'red' + */ + removeName: function(name) { + var names = (this.name() || '').split(/\s/g); + var index = names.indexOf(name); + if (index !== -1) { + names.splice(index, 1); + this.setName(names.join(' ')); + } + return this; + }, + /** + * set attr + * @method + * @memberof Konva.Node.prototype + * @param {String} attr + * @param {*} val + * @returns {Konva.Node} + * @example + * node.setAttr('x', 5); + */ + setAttr: function(attr, val) { + var method = SET + Konva.Util._capitalize(attr), + func = this[method]; + + if(Konva.Util._isFunction(func)) { + func.call(this, val); + } + // otherwise set directly + else { + this._setAttr(attr, val); + } + return this; + }, + _setAttr: function(key, val) { + var oldVal; + if(val !== undefined) { + oldVal = this.attrs[key]; + if (oldVal === val) { + return; + } + this.attrs[key] = val; + this._fireChangeEvent(key, oldVal, val); + } + }, + _setComponentAttr: function(key, component, val) { + var oldVal; + if(val !== undefined) { + oldVal = this.attrs[key]; + + if (!oldVal) { + // set value to default value using getAttr + this.attrs[key] = this.getAttr(key); + } + + this.attrs[key][component] = val; + this._fireChangeEvent(key, oldVal, val); + } + }, + _fireAndBubble: function(eventType, evt, compareShape) { + var okayToRun = true; + + if(evt && this.nodeType === SHAPE) { + evt.target = this; + } + + if(eventType === MOUSEENTER && compareShape && (this._id === compareShape._id || (this.isAncestorOf && this.isAncestorOf(compareShape)))) { + okayToRun = false; + } + else if(eventType === MOUSELEAVE && compareShape && (this._id === compareShape._id || (this.isAncestorOf && this.isAncestorOf(compareShape)))) { + okayToRun = false; + } + if(okayToRun) { + this._fire(eventType, evt); + + // simulate event bubbling + var stopBubble = + (eventType === MOUSEENTER || eventType === MOUSELEAVE) && + ((compareShape && compareShape.isAncestorOf && compareShape.isAncestorOf(this) && !compareShape.isAncestorOf(this.parent))); + if((evt && !evt.cancelBubble || !evt) && this.parent && this.parent.isListening() && (!stopBubble)) { + if (compareShape && compareShape.parent) { + this._fireAndBubble.call(this.parent, eventType, evt, compareShape.parent); + } + else { + this._fireAndBubble.call(this.parent, eventType, evt); + } + } + } + }, + _fire: function(eventType, evt) { + var events = this.eventListeners[eventType], + i; + + evt = evt || {}; + evt.currentTarget = this; + evt.type = eventType; + + if (events) { + for(i = 0; i < events.length; i++) { + events[i].handler.call(this, evt); + } + } + }, + /** + * draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redrawn + * @method + * @memberof Konva.Node.prototype + * @returns {Konva.Node} + */ + draw: function() { + this.drawScene(); + this.drawHit(); + return this; + } + }); + + /** + * create node with JSON string or an Object. De-serializtion does not generate custom + * shape drawing functions, images, or event handlers (this would make the + * serialized object huge). If your app uses custom shapes, images, and + * event handlers (it probably does), then you need to select the appropriate + * shapes after loading the stage and set these properties via on(), setDrawFunc(), + * and setImage() methods + * @method + * @memberof Konva.Node + * @param {String|Object} json string or object + * @param {Element} [container] optional container dom element used only if you're + * creating a stage node + */ + Konva.Node.create = function(data, container) { + if (Konva.Util._isString(data)) { + data = JSON.parse(data); + } + return this._createNode(data, container); + }; + Konva.Node._createNode = function(obj, container) { + var className = Konva.Node.prototype.getClassName.call(obj), + children = obj.children, + no, len, n; + + // if container was passed in, add it to attrs + if(container) { + obj.attrs.container = container; + } + + no = new Konva[className](obj.attrs); + if(children) { + len = children.length; + for(n = 0; n < len; n++) { + no.add(this._createNode(children[n])); + } + } + + return no; + }; + + + // =========================== add getters setters =========================== + + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'position'); + /** + * get/set node position relative to parent + * @name position + * @method + * @memberof Konva.Node.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Object} + * @example + * // get position + * var position = node.position(); + * + * // set position + * node.position({ + * x: 5 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'x', 0); + + /** + * get/set x position + * @name x + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Object} + * @example + * // get x + * var x = node.x(); + * + * // set x + * node.x(5); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'y', 0); + + /** + * get/set y position + * @name y + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Integer} + * @example + * // get y + * var y = node.y(); + * + * // set y + * node.y(5); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'opacity', 1); + + /** + * get/set opacity. Opacity values range from 0 to 1. + * A node with an opacity of 0 is fully transparent, and a node + * with an opacity of 1 is fully opaque + * @name opacity + * @method + * @memberof Konva.Node.prototype + * @param {Object} opacity + * @returns {Number} + * @example + * // get opacity + * var opacity = node.opacity(); + * + * // set opacity + * node.opacity(0.5); + */ + + Konva.Factory.addGetter(Konva.Node, 'name'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'name'); + + /** + * get/set name + * @name name + * @method + * @memberof Konva.Node.prototype + * @param {String} name + * @returns {String} + * @example + * // get name + * var name = node.name(); + * + * // set name + * node.name('foo'); + * + * // also node may have multiple names (as css classes) + * node.name('foo bar'); + */ + + Konva.Factory.addGetter(Konva.Node, 'id'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'id'); + + /** + * get/set id. Id is global for whole page. + * @name id + * @method + * @memberof Konva.Node.prototype + * @param {String} id + * @returns {String} + * @example + * // get id + * var name = node.id(); + * + * // set id + * node.id('foo'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'rotation', 0); + + /** + * get/set rotation in degrees + * @name rotation + * @method + * @memberof Konva.Node.prototype + * @param {Number} rotation + * @returns {Number} + * @example + * // get rotation in degrees + * var rotation = node.rotation(); + * + * // set rotation in degrees + * node.rotation(45); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'scale', ['x', 'y']); + + /** + * get/set scale + * @name scale + * @param {Object} scale + * @param {Number} scale.x + * @param {Number} scale.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get scale + * var scale = node.scale(); + * + * // set scale + * shape.scale({ + * x: 2 + * y: 3 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'scaleX', 1); + + /** + * get/set scale x + * @name scaleX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale x + * var scaleX = node.scaleX(); + * + * // set scale x + * node.scaleX(2); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'scaleY', 1); + + /** + * get/set scale y + * @name scaleY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get scale y + * var scaleY = node.scaleY(); + * + * // set scale y + * node.scaleY(2); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'skew', ['x', 'y']); + + /** + * get/set skew + * @name skew + * @param {Object} skew + * @param {Number} skew.x + * @param {Number} skew.y + * @method + * @memberof Konva.Node.prototype + * @returns {Object} + * @example + * // get skew + * var skew = node.skew(); + * + * // set skew + * node.skew({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'skewX', 0); + + /** + * get/set skew x + * @name skewX + * @param {Number} x + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew x + * var skewX = node.skewX(); + * + * // set skew x + * node.skewX(3); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'skewY', 0); + + /** + * get/set skew y + * @name skewY + * @param {Number} y + * @method + * @memberof Konva.Node.prototype + * @returns {Number} + * @example + * // get skew y + * var skewY = node.skewY(); + * + * // set skew y + * node.skewY(3); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Node, 'offset', ['x', 'y']); + + /** + * get/set offset. Offsets the default position and rotation point + * @method + * @memberof Konva.Node.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get offset + * var offset = node.offset(); + * + * // set offset + * node.offset({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'offsetX', 0); + + /** + * get/set offset x + * @name offsetX + * @method + * @memberof Konva.Node.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get offset x + * var offsetX = node.offsetX(); + * + * // set offset x + * node.offsetX(3); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'offsetY', 0); + + /** + * get/set offset y + * @name offsetY + * @method + * @memberof Konva.Node.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get offset y + * var offsetY = node.offsetY(); + * + * // set offset y + * node.offsetY(3); + */ + + Konva.Factory.addSetter(Konva.Node, 'dragDistance'); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'dragDistance'); + + /** + * get/set drag distance + * @name dragDistance + * @method + * @memberof Konva.Node.prototype + * @param {Number} distance + * @returns {Number} + * @example + * // get drag distance + * var dragDistance = node.dragDistance(); + * + * // set distance + * // node starts dragging only if pointer moved more then 3 pixels + * node.dragDistance(3); + * // or set globally + * Konva.dragDistance = 3; + */ + + + Konva.Factory.addSetter(Konva.Node, 'width', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'width'); + /** + * get/set width + * @name width + * @method + * @memberof Konva.Node.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get width + * var width = node.width(); + * + * // set width + * node.width(100); + */ + + Konva.Factory.addSetter(Konva.Node, 'height', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'height'); + /** + * get/set height + * @name height + * @method + * @memberof Konva.Node.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get height + * var height = node.height(); + * + * // set height + * node.height(100); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'listening', 'inherit'); + /** + * get/set listenig attr. If you need to determine if a node is listening or not + * by taking into account its parents, use the isListening() method + * @name listening + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} listening Can be "inherit", true, or false. The default is "inherit". + * @returns {Boolean|String} + * @example + * // get listening attr + * var listening = node.listening(); + * + * // stop listening for events + * node.listening(false); + * + * // listen for events + * node.listening(true); + * + * // listen to events according to the parent + * node.listening('inherit'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'filters', undefined, function(val) {this._filterUpToDate = false; return val; }); + /** + * get/set filters. Filters are applied to cached canvases + * @name filters + * @method + * @memberof Konva.Node.prototype + * @param {Array} filters array of filters + * @returns {Array} + * @example + * // get filters + * var filters = node.filters(); + * + * // set a single filter + * node.cache(); + * node.filters([Konva.Filters.Blur]); + * + * // set multiple filters + * node.cache(); + * node.filters([ + * Konva.Filters.Blur, + * Konva.Filters.Sepia, + * Konva.Filters.Invert + * ]); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'visible', 'inherit'); + /** + * get/set visible attr. Can be "inherit", true, or false. The default is "inherit". + * If you need to determine if a node is visible or not + * by taking into account its parents, use the isVisible() method + * @name visible + * @method + * @memberof Konva.Node.prototype + * @param {Boolean|String} visible + * @returns {Boolean|String} + * @example + * // get visible attr + * var visible = node.visible(); + * + * // make invisible + * node.visible(false); + * + * // make visible + * node.visible(true); + * + * // make visible according to the parent + * node.visible('inherit'); + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'transformsEnabled', 'all'); + + /** + * get/set transforms that are enabled. Can be "all", "none", or "position". The default + * is "all" + * @name transformsEnabled + * @method + * @memberof Konva.Node.prototype + * @param {String} enabled + * @returns {String} + * @example + * // enable position transform only to improve draw performance + * node.transformsEnabled('position'); + * + * // enable all transforms + * node.transformsEnabled('all'); + */ + + + + /** + * get/set node size + * @name size + * @method + * @memberof Konva.Node.prototype + * @param {Object} size + * @param {Number} size.width + * @param {Number} size.height + * @returns {Object} + * @example + * // get node size + * var size = node.size(); + * var x = size.x; + * var y = size.y; + * + * // set size + * node.size({ + * width: 100, + * height: 200 + * }); + */ + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'size'); + + Konva.Factory.backCompat(Konva.Node, { + rotateDeg: 'rotate', + setRotationDeg: 'setRotation', + getRotationDeg: 'getRotation' + }); + + Konva.Collection.mapMethods(Konva.Node); +})(Konva); + +(function() { + 'use strict'; + /** + * Grayscale Filter + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Grayscale]); + */ + Konva.Filters.Grayscale = function(imageData) { + var data = imageData.data, + len = data.length, + i, brightness; + + for(i = 0; i < len; i += 4) { + brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; + // red + data[i] = brightness; + // green + data[i + 1] = brightness; + // blue + data[i + 2] = brightness; + } + }; +})(); + +(function() { + 'use strict'; + /** + * Brighten Filter. + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Brighten]); + * node.brightness(0.8); + */ + Konva.Filters.Brighten = function(imageData) { + var brightness = this.brightness() * 255, + data = imageData.data, + len = data.length, + i; + + for(i = 0; i < len; i += 4) { + // red + data[i] += brightness; + // green + data[i + 1] += brightness; + // blue + data[i + 2] += brightness; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'brightness', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set filter brightness. The brightness is a number between -1 and 1.  Positive values + * brighten the pixels and negative values darken them. Use with {@link Konva.Filters.Brighten} filter. + * @name brightness + * @method + * @memberof Konva.Node.prototype + * @param {Number} brightness value between -1 and 1 + * @returns {Number} + */ + +})(); + +(function() { + 'use strict'; + /** + * Invert Filter + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Invert]); + */ + Konva.Filters.Invert = function(imageData) { + var data = imageData.data, + len = data.length, + i; + + for(i = 0; i < len; i += 4) { + // red + data[i] = 255 - data[i]; + // green + data[i + 1] = 255 - data[i + 1]; + // blue + data[i + 2] = 255 - data[i + 2]; + } + }; +})(); + +/* + the Gauss filter + master repo: https://github.com/pavelpower/kineticjsGaussFilter +*/ +(function() { + 'use strict'; + /* + + StackBlur - a fast almost Gaussian Blur For Canvas + + Version: 0.5 + Author: Mario Klingemann + Contact: mario@quasimondo.com + Website: http://www.quasimondo.com/StackBlurForCanvas + Twitter: @quasimondo + + In case you find this class useful - especially in commercial projects - + I am not totally unhappy for a small donation to my PayPal account + mario@quasimondo.de + + Or support me on flattr: + https://flattr.com/thing/72791/StackBlur-a-fast-almost-Gaussian-Blur-Effect-for-CanvasJavascript + + Copyright (c) 2010 Mario Klingemann + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + */ + + function BlurStack() { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 0; + this.next = null; + } + + var mul_table = [ + 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, + 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, + 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, + 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, + 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, + 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, + 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, + 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, + 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, + 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, + 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, + 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, + 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, + 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, + 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, + 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259 + ]; + + var shg_table = [ + 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + ]; + + function filterGaussBlurRGBA( imageData, radius) { + + var pixels = imageData.data, + width = imageData.width, + height = imageData.height; + + var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum, a_sum, + r_out_sum, g_out_sum, b_out_sum, a_out_sum, + r_in_sum, g_in_sum, b_in_sum, a_in_sum, + pr, pg, pb, pa, rbs; + + var div = radius + radius + 1, + widthMinus1 = width - 1, + heightMinus1 = height - 1, + radiusPlus1 = radius + 1, + sumFactor = radiusPlus1 * ( radiusPlus1 + 1 ) / 2, + stackStart = new BlurStack(), + stackEnd = null, + stack = stackStart, + stackIn = null, + stackOut = null, + mul_sum = mul_table[radius], + shg_sum = shg_table[radius]; + + for ( i = 1; i < div; i++ ) { + stack = stack.next = new BlurStack(); + if ( i === radiusPlus1 ){ + stackEnd = stack; + } + } + + stack.next = stackStart; + + yw = yi = 0; + + for ( y = 0; y < height; y++ ) + { + r_in_sum = g_in_sum = b_in_sum = a_in_sum = r_sum = g_sum = b_sum = a_sum = 0; + + r_out_sum = radiusPlus1 * ( pr = pixels[yi] ); + g_out_sum = radiusPlus1 * ( pg = pixels[yi + 1] ); + b_out_sum = radiusPlus1 * ( pb = pixels[yi + 2] ); + a_out_sum = radiusPlus1 * ( pa = pixels[yi + 3] ); + + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; + + stack = stackStart; + + for( i = 0; i < radiusPlus1; i++ ) + { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } + + for( i = 1; i < radiusPlus1; i++ ) + { + p = yi + (( widthMinus1 < i ? widthMinus1 : i ) << 2 ); + r_sum += ( stack.r = ( pr = pixels[p])) * ( rbs = radiusPlus1 - i ); + g_sum += ( stack.g = ( pg = pixels[p + 1])) * rbs; + b_sum += ( stack.b = ( pb = pixels[p + 2])) * rbs; + a_sum += ( stack.a = ( pa = pixels[p + 3])) * rbs; + + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; + + stack = stack.next; + } + + + stackIn = stackStart; + stackOut = stackEnd; + for ( x = 0; x < width; x++ ) + { + pixels[yi + 3] = pa = (a_sum * mul_sum) >> shg_sum; + if ( pa !== 0 ) + { + pa = 255 / pa; + pixels[yi] = ((r_sum * mul_sum) >> shg_sum) * pa; + pixels[yi + 1] = ((g_sum * mul_sum) >> shg_sum) * pa; + pixels[yi + 2] = ((b_sum * mul_sum) >> shg_sum) * pa; + } else { + pixels[yi] = pixels[yi + 1] = pixels[yi + 2] = 0; + } + + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; + + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; + + p = (yw + ( ( p = x + radius + 1 ) < widthMinus1 ? p : widthMinus1 ) ) << 2; + + r_in_sum += ( stackIn.r = pixels[p]); + g_in_sum += ( stackIn.g = pixels[p + 1]); + b_in_sum += ( stackIn.b = pixels[p + 2]); + a_in_sum += ( stackIn.a = pixels[p + 3]); + + r_sum += r_in_sum; + g_sum += g_in_sum; + b_sum += b_in_sum; + a_sum += a_in_sum; + + stackIn = stackIn.next; + + r_out_sum += ( pr = stackOut.r ); + g_out_sum += ( pg = stackOut.g ); + b_out_sum += ( pb = stackOut.b ); + a_out_sum += ( pa = stackOut.a ); + + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; + + stackOut = stackOut.next; + + yi += 4; + } + yw += width; + } + + + for ( x = 0; x < width; x++ ) + { + g_in_sum = b_in_sum = a_in_sum = r_in_sum = g_sum = b_sum = a_sum = r_sum = 0; + + yi = x << 2; + r_out_sum = radiusPlus1 * ( pr = pixels[yi]); + g_out_sum = radiusPlus1 * ( pg = pixels[yi + 1]); + b_out_sum = radiusPlus1 * ( pb = pixels[yi + 2]); + a_out_sum = radiusPlus1 * ( pa = pixels[yi + 3]); + + r_sum += sumFactor * pr; + g_sum += sumFactor * pg; + b_sum += sumFactor * pb; + a_sum += sumFactor * pa; + + stack = stackStart; + + for( i = 0; i < radiusPlus1; i++ ) + { + stack.r = pr; + stack.g = pg; + stack.b = pb; + stack.a = pa; + stack = stack.next; + } + + yp = width; + + for( i = 1; i <= radius; i++ ) + { + yi = ( yp + x ) << 2; + + r_sum += ( stack.r = ( pr = pixels[yi])) * ( rbs = radiusPlus1 - i ); + g_sum += ( stack.g = ( pg = pixels[yi + 1])) * rbs; + b_sum += ( stack.b = ( pb = pixels[yi + 2])) * rbs; + a_sum += ( stack.a = ( pa = pixels[yi + 3])) * rbs; + + r_in_sum += pr; + g_in_sum += pg; + b_in_sum += pb; + a_in_sum += pa; + + stack = stack.next; + + if( i < heightMinus1 ) + { + yp += width; + } + } + + yi = x; + stackIn = stackStart; + stackOut = stackEnd; + for ( y = 0; y < height; y++ ) + { + p = yi << 2; + pixels[p + 3] = pa = (a_sum * mul_sum) >> shg_sum; + if ( pa > 0 ) + { + pa = 255 / pa; + pixels[p] = ((r_sum * mul_sum) >> shg_sum ) * pa; + pixels[p + 1] = ((g_sum * mul_sum) >> shg_sum ) * pa; + pixels[p + 2] = ((b_sum * mul_sum) >> shg_sum ) * pa; + } else { + pixels[p] = pixels[p + 1] = pixels[p + 2] = 0; + } + + r_sum -= r_out_sum; + g_sum -= g_out_sum; + b_sum -= b_out_sum; + a_sum -= a_out_sum; + + r_out_sum -= stackIn.r; + g_out_sum -= stackIn.g; + b_out_sum -= stackIn.b; + a_out_sum -= stackIn.a; + + p = ( x + (( ( p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1 ) * width )) << 2; + + r_sum += ( r_in_sum += ( stackIn.r = pixels[p])); + g_sum += ( g_in_sum += ( stackIn.g = pixels[p + 1])); + b_sum += ( b_in_sum += ( stackIn.b = pixels[p + 2])); + a_sum += ( a_in_sum += ( stackIn.a = pixels[p + 3])); + + stackIn = stackIn.next; + + r_out_sum += ( pr = stackOut.r ); + g_out_sum += ( pg = stackOut.g ); + b_out_sum += ( pb = stackOut.b ); + a_out_sum += ( pa = stackOut.a ); + + r_in_sum -= pr; + g_in_sum -= pg; + b_in_sum -= pb; + a_in_sum -= pa; + + stackOut = stackOut.next; + + yi += width; + } + } + } + + /** + * Blur Filter + * @function + * @name Blur + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Blur]); + * node.blurRadius(10); + */ + Konva.Filters.Blur = function Blur(imageData) { + var radius = Math.round(this.blurRadius()); + + if (radius > 0) { + filterGaussBlurRGBA(imageData, radius); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'blurRadius', 0, null, Konva.Factory.afterSetFilter); + + /** + * get/set blur radius. Use with {@link Konva.Filters.Blur} filter + * @name blurRadius + * @method + * @memberof Konva.Node.prototype + * @param {Integer} radius + * @returns {Integer} + */ +})(); + +/*eslint-disable max-depth */ +(function() { + 'use strict'; + function pixelAt(idata, x, y) { + var idx = (y * idata.width + x) * 4; + var d = []; + d.push(idata.data[idx++], idata.data[idx++], idata.data[idx++], idata.data[idx++]); + return d; + } + + function rgbDistance(p1, p2) { + return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2)); + } + + function rgbMean(pTab) { + var m = [0, 0, 0]; + + for (var i = 0; i < pTab.length; i++) { + m[0] += pTab[i][0]; + m[1] += pTab[i][1]; + m[2] += pTab[i][2]; + } + + m[0] /= pTab.length; + m[1] /= pTab.length; + m[2] /= pTab.length; + + return m; + } + + function backgroundMask(idata, threshold) { + var rgbv_no = pixelAt(idata, 0, 0); + var rgbv_ne = pixelAt(idata, idata.width - 1, 0); + var rgbv_so = pixelAt(idata, 0, idata.height - 1); + var rgbv_se = pixelAt(idata, idata.width - 1, idata.height - 1); + + + var thres = threshold || 10; + if (rgbDistance(rgbv_no, rgbv_ne) < thres && rgbDistance(rgbv_ne, rgbv_se) < thres && rgbDistance(rgbv_se, rgbv_so) < thres && rgbDistance(rgbv_so, rgbv_no) < thres) { + + // Mean color + var mean = rgbMean([rgbv_ne, rgbv_no, rgbv_se, rgbv_so]); + + // Mask based on color distance + var mask = []; + for (var i = 0; i < idata.width * idata.height; i++) { + var d = rgbDistance(mean, [idata.data[i * 4], idata.data[i * 4 + 1], idata.data[i * 4 + 2]]); + mask[i] = (d < thres) ? 0 : 255; + } + + return mask; + } + } + + function applyMask(idata, mask) { + for (var i = 0; i < idata.width * idata.height; i++) { + idata.data[4 * i + 3] = mask[i]; + } + } + + function erodeMask(mask, sw, sh) { + + var weights = [1, 1, 1, 1, 0, 1, 1, 1, 1]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = (a === 255 * 8) ? 255 : 0; + } + } + + return maskResult; + } + + function dilateMask(mask, sw, sh) { + + var weights = [1, 1, 1, 1, 1, 1, 1, 1, 1]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = (a >= 255 * 4) ? 255 : 0; + } + } + + return maskResult; + } + + function smoothEdgeMask(mask, sw, sh) { + + var weights = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9]; + var side = Math.round(Math.sqrt(weights.length)); + var halfSide = Math.floor(side / 2); + + var maskResult = []; + for (var y = 0; y < sh; y++) { + for (var x = 0; x < sw; x++) { + + var so = y * sw + x; + var a = 0; + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + var scy = y + cy - halfSide; + var scx = x + cx - halfSide; + + if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + + var srcOff = scy * sw + scx; + var wt = weights[cy * side + cx]; + + a += mask[srcOff] * wt; + } + } + } + + maskResult[so] = a; + } + } + + return maskResult; + } + + /** + * Mask Filter + * @function + * @name Mask + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Mask]); + * node.threshold(200); + */ + Konva.Filters.Mask = function(imageData) { + // Detect pixels close to the background color + var threshold = this.threshold(), + mask = backgroundMask(imageData, threshold); + if (mask) { + // Erode + mask = erodeMask(mask, imageData.width, imageData.height); + + // Dilate + mask = dilateMask(mask, imageData.width, imageData.height); + + // Gradient + mask = smoothEdgeMask(mask, imageData.width, imageData.height); + + // Apply mask + applyMask(imageData, mask); + + // todo : Update hit region function according to mask + } + + return imageData; + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'threshold', 0, null, Konva.Factory.afterSetFilter); +})(); + +(function () { + 'use strict'; + /** + * RGB Filter + * @function + * @name RGB + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.RGB]); + * node.blue(120); + * node.green(200); + */ + Konva.Filters.RGB = function (imageData) { + var data = imageData.data, + nPixels = data.length, + red = this.red(), + green = this.green(), + blue = this.blue(), + i, brightness; + + for (i = 0; i < nPixels; i += 4) { + brightness = (0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]) / 255; + data[i] = brightness * red; // r + data[i + 1] = brightness * green; // g + data[i + 2] = brightness * blue; // b + data[i + 3] = data[i + 3]; // alpha + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'red', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter red value. Use with {@link Konva.Filters.RGB} filter. + * @name red + * @method + * @memberof Konva.Node.prototype + * @param {Integer} red value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'green', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter green value. Use with {@link Konva.Filters.RGB} filter. + * @name green + * @method + * @memberof Konva.Node.prototype + * @param {Integer} green value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'blue', 0, Konva.Validators.RGBComponent, Konva.Factory.afterSetFilter); + /** + * get/set filter blue value. Use with {@link Konva.Filters.RGB} filter. + * @name blue + * @method + * @memberof Konva.Node.prototype + * @param {Integer} blue value between 0 and 255 + * @returns {Integer} + */ +})(); + +(function () { + 'use strict'; + /** + * RGBA Filter + * @function + * @name RGBA + * @memberof Konva.Filters + * @param {Object} imageData + * @author codefo + * @example + * node.cache(); + * node.filters([Konva.Filters.RGBA]); + * node.blue(120); + * node.green(200); + * node.alpha(0.3); + */ + Konva.Filters.RGBA = function (imageData) { + var data = imageData.data, + nPixels = data.length, + red = this.red(), + green = this.green(), + blue = this.blue(), + alpha = this.alpha(), + i, ia; + + for (i = 0; i < nPixels; i += 4) { + ia = 1 - alpha; + + data[i] = red * alpha + data[i] * ia; // r + data[i + 1] = green * alpha + data[i + 1] * ia; // g + data[i + 2] = blue * alpha + data[i + 2] * ia; // b + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'red', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter red value. Use with {@link Konva.Filters.RGBA} filter. + * @name red + * @method + * @memberof Konva.Node.prototype + * @param {Integer} red value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'green', 0, function(val) { + this._filterUpToDate = false; + if (val > 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }); + /** + * get/set filter green value. Use with {@link Konva.Filters.RGBA} filter. + * @name green + * @method + * @memberof Konva.Node.prototype + * @param {Integer} green value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'blue', 0, Konva.Validators.RGBComponent, Konva.Factory.afterSetFilter); + /** + * get/set filter blue value. Use with {@link Konva.Filters.RGBA} filter. + * @name blue + * @method + * @memberof Konva.Node.prototype + * @param {Integer} blue value between 0 and 255 + * @returns {Integer} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'alpha', 1, function(val) { + this._filterUpToDate = false; + if (val > 1) { + return 1; + } + else if (val < 0) { + return 0; + } + else { + return val; + } + }); + /** + * get/set filter alpha value. Use with {@link Konva.Filters.RGBA} filter. + * @name alpha + * @method + * @memberof Konva.Node.prototype + * @param {Float} alpha value between 0 and 1 + * @returns {Float} + */ +})(); + +(function () { + 'use strict'; + /** + * HSV Filter. Adjusts the hue, saturation and value + * @function + * @name HSV + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * image.filters([Konva.Filters.HSV]); + * image.value(200); + */ + + Konva.Filters.HSV = function (imageData) { + var data = imageData.data, + nPixels = data.length, + v = Math.pow(2, this.value()), + s = Math.pow(2, this.saturation()), + h = Math.abs((this.hue()) + 360) % 360, + i; + + // Basis for the technique used: + // http://beesbuzz.biz/code/hsv_color_transforms.php + // V is the value multiplier (1 for none, 2 for double, 0.5 for half) + // S is the saturation multiplier (1 for none, 2 for double, 0.5 for half) + // H is the hue shift in degrees (0 to 360) + // vsu = V*S*cos(H*PI/180); + // vsw = V*S*sin(H*PI/180); + //[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R] + //[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G] + //[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B] + + // Precompute the values in the matrix: + var vsu = v * s * Math.cos(h * Math.PI / 180), + vsw = v * s * Math.sin(h * Math.PI / 180); + // (result spot)(source spot) + var rr = 0.299 * v + 0.701 * vsu + 0.167 * vsw, + rg = 0.587 * v - 0.587 * vsu + 0.330 * vsw, + rb = 0.114 * v - 0.114 * vsu - 0.497 * vsw; + var gr = 0.299 * v - 0.299 * vsu - 0.328 * vsw, + gg = 0.587 * v + 0.413 * vsu + 0.035 * vsw, + gb = 0.114 * v - 0.114 * vsu + 0.293 * vsw; + var br = 0.299 * v - 0.300 * vsu + 1.250 * vsw, + bg = 0.587 * v - 0.586 * vsu - 1.050 * vsw, + bb = 0.114 * v + 0.886 * vsu - 0.200 * vsw; + + var r, g, b, a; + + for (i = 0; i < nPixels; i += 4) { + r = data[i + 0]; + g = data[i + 1]; + b = data[i + 2]; + a = data[i + 3]; + + data[i + 0] = rr * r + rg * g + rb * b; + data[i + 1] = gr * r + gg * g + gb * b; + data[i + 2] = br * r + bg * g + bb * b; + data[i + 3] = a; // alpha + } + + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'hue', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv hue in degrees. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name hue + * @method + * @memberof Konva.Node.prototype + * @param {Number} hue value between 0 and 359 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'saturation', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv saturation. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name saturation + * @method + * @memberof Konva.Node.prototype + * @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc.. + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'value', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv value. Use with {@link Konva.Filters.HSV} filter. + * @name value + * @method + * @memberof Konva.Node.prototype + * @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc.. + * @returns {Number} + */ + +})(); + +(function () { + 'use strict'; + + Konva.Factory.addGetterSetter(Konva.Node, 'hue', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv hue in degrees. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name hue + * @method + * @memberof Konva.Node.prototype + * @param {Number} hue value between 0 and 359 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'saturation', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsv saturation. Use with {@link Konva.Filters.HSV} or {@link Konva.Filters.HSL} filter. + * @name saturation + * @method + * @memberof Konva.Node.prototype + * @param {Number} saturation 0 is no change, -1.0 halves the saturation, 1.0 doubles, etc.. + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'luminance', 0, null, Konva.Factory.afterSetFilter); + /** + * get/set hsl luminance. Use with {@link Konva.Filters.HSL} filter. + * @name value + * @method + * @memberof Konva.Node.prototype + * @param {Number} value 0 is no change, -1.0 halves the value, 1.0 doubles, etc.. + * @returns {Number} + */ + + /** + * HSL Filter. Adjusts the hue, saturation and luminance (or lightness) + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * image.filters([Konva.Filters.HSL]); + * image.luminance(200); + */ + + Konva.Filters.HSL = function (imageData) { + var data = imageData.data, + nPixels = data.length, + v = 1, + s = Math.pow(2, this.saturation()), + h = Math.abs((this.hue()) + 360) % 360, + l = this.luminance() * 127, + i; + + // Basis for the technique used: + // http://beesbuzz.biz/code/hsv_color_transforms.php + // V is the value multiplier (1 for none, 2 for double, 0.5 for half) + // S is the saturation multiplier (1 for none, 2 for double, 0.5 for half) + // H is the hue shift in degrees (0 to 360) + // vsu = V*S*cos(H*PI/180); + // vsw = V*S*sin(H*PI/180); + //[ .299V+.701vsu+.168vsw .587V-.587vsu+.330vsw .114V-.114vsu-.497vsw ] [R] + //[ .299V-.299vsu-.328vsw .587V+.413vsu+.035vsw .114V-.114vsu+.292vsw ]*[G] + //[ .299V-.300vsu+1.25vsw .587V-.588vsu-1.05vsw .114V+.886vsu-.203vsw ] [B] + + // Precompute the values in the matrix: + var vsu = v * s * Math.cos(h * Math.PI / 180), + vsw = v * s * Math.sin(h * Math.PI / 180); + // (result spot)(source spot) + var rr = 0.299 * v + 0.701 * vsu + 0.167 * vsw, + rg = 0.587 * v - 0.587 * vsu + 0.330 * vsw, + rb = 0.114 * v - 0.114 * vsu - 0.497 * vsw; + var gr = 0.299 * v - 0.299 * vsu - 0.328 * vsw, + gg = 0.587 * v + 0.413 * vsu + 0.035 * vsw, + gb = 0.114 * v - 0.114 * vsu + 0.293 * vsw; + var br = 0.299 * v - 0.300 * vsu + 1.250 * vsw, + bg = 0.587 * v - 0.586 * vsu - 1.050 * vsw, + bb = 0.114 * v + 0.886 * vsu - 0.200 * vsw; + + var r, g, b, a; + + for (i = 0; i < nPixels; i += 4) { + r = data[i + 0]; + g = data[i + 1]; + b = data[i + 2]; + a = data[i + 3]; + + data[i + 0] = rr * r + rg * g + rb * b + l; + data[i + 1] = gr * r + gg * g + gb * b + l; + data[i + 2] = br * r + bg * g + bb * b + l; + data[i + 3] = a; // alpha + } + }; +})(); + +(function () { + 'use strict'; + /** + * Emboss Filter. + * Pixastic Lib - Emboss filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * License: [http://www.pixastic.com/lib/license.txt] + * @function + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Emboss]); + * node.embossStrength(0.8); + * node.embossWhiteLevel(0.3); + * node.embossDirection('right'); + * node.embossBlend(true); + */ + Konva.Filters.Emboss = function (imageData) { + + // pixastic strength is between 0 and 10. I want it between 0 and 1 + // pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also, + // a max value of greyLevel yields a white emboss, and the min value yields a black + // emboss. Therefore, I changed greyLevel to whiteLevel + var strength = this.embossStrength() * 10, + greyLevel = this.embossWhiteLevel() * 255, + direction = this.embossDirection(), + blend = this.embossBlend(), + dirY = 0, + dirX = 0, + data = imageData.data, + w = imageData.width, + h = imageData.height, + w4 = w * 4, + y = h; + + switch (direction) { + case 'top-left': + dirY = -1; + dirX = -1; + break; + case 'top': + dirY = -1; + dirX = 0; + break; + case 'top-right': + dirY = -1; + dirX = 1; + break; + case 'right': + dirY = 0; + dirX = 1; + break; + case 'bottom-right': + dirY = 1; + dirX = 1; + break; + case 'bottom': + dirY = 1; + dirX = 0; + break; + case 'bottom-left': + dirY = 1; + dirX = -1; + break; + case 'left': + dirY = 0; + dirX = -1; + break; + } + + do { + var offsetY = (y - 1) * w4; + + var otherY = dirY; + if (y + otherY < 1){ + otherY = 0; + } + if (y + otherY > h) { + otherY = 0; + } + + var offsetYOther = (y - 1 + otherY) * w * 4; + + var x = w; + do { + var offset = offsetY + (x - 1) * 4; + + var otherX = dirX; + if (x + otherX < 1){ + otherX = 0; + } + if (x + otherX > w) { + otherX = 0; + } + + var offsetOther = offsetYOther + (x - 1 + otherX) * 4; + + var dR = data[offset] - data[offsetOther]; + var dG = data[offset + 1] - data[offsetOther + 1]; + var dB = data[offset + 2] - data[offsetOther + 2]; + + var dif = dR; + var absDif = dif > 0 ? dif : -dif; + + var absG = dG > 0 ? dG : -dG; + var absB = dB > 0 ? dB : -dB; + + if (absG > absDif) { + dif = dG; + } + if (absB > absDif) { + dif = dB; + } + + dif *= strength; + + if (blend) { + var r = data[offset] + dif; + var g = data[offset + 1] + dif; + var b = data[offset + 2] + dif; + + data[offset] = (r > 255) ? 255 : (r < 0 ? 0 : r); + data[offset + 1] = (g > 255) ? 255 : (g < 0 ? 0 : g); + data[offset + 2] = (b > 255) ? 255 : (b < 0 ? 0 : b); + } else { + var grey = greyLevel - dif; + if (grey < 0) { + grey = 0; + } else if (grey > 255) { + grey = 255; + } + + data[offset] = data[offset + 1] = data[offset + 2] = grey; + } + + } while (--x); + } while (--y); + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'embossStrength', 0.5, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss strength. Use with {@link Konva.Filters.Emboss} filter. + * @name embossStrength + * @method + * @memberof Konva.Node.prototype + * @param {Number} level between 0 and 1. Default is 0.5 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossWhiteLevel', 0.5, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss white level. Use with {@link Konva.Filters.Emboss} filter. + * @name embossWhiteLevel + * @method + * @memberof Konva.Node.prototype + * @param {Number} embossWhiteLevel between 0 and 1. Default is 0.5 + * @returns {Number} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossDirection', 'top-left', null, Konva.Factory.afterSetFilter); + /** + * get/set emboss direction. Use with {@link Konva.Filters.Emboss} filter. + * @name embossDirection + * @method + * @memberof Konva.Node.prototype + * @param {String} embossDirection can be top-left, top, top-right, right, bottom-right, bottom, bottom-left or left + * The default is top-left + * @returns {String} + */ + + Konva.Factory.addGetterSetter(Konva.Node, 'embossBlend', false, null, Konva.Factory.afterSetFilter); + /** + * get/set emboss blend. Use with {@link Konva.Filters.Emboss} filter. + * @name embossBlend + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} embossBlend + * @returns {Boolean} + */ +})(); + +(function () { + 'use strict'; + function remap(fromValue, fromMin, fromMax, toMin, toMax) { + // Compute the range of the data + var fromRange = fromMax - fromMin, + toRange = toMax - toMin, + toValue; + + // If either range is 0, then the value can only be mapped to 1 value + if (fromRange === 0) { + return toMin + toRange / 2; + } + if (toRange === 0) { + return toMin; + } + + // (1) untranslate, (2) unscale, (3) rescale, (4) retranslate + toValue = (fromValue - fromMin) / fromRange; + toValue = (toRange * toValue) + toMin; + + return toValue; + } + + + /** + * Enhance Filter. Adjusts the colors so that they span the widest + * possible range (ie 0-255). Performs w*h pixel reads and w*h pixel + * writes. + * @function + * @name Enhance + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Enhance]); + * node.enhance(0.4); + */ + Konva.Filters.Enhance = function (imageData) { + var data = imageData.data, + nSubPixels = data.length, + rMin = data[0], rMax = rMin, r, + gMin = data[1], gMax = gMin, g, + bMin = data[2], bMax = bMin, b, + i; + + // If we are not enhancing anything - don't do any computation + var enhanceAmount = this.enhance(); + if( enhanceAmount === 0 ){ return; } + + // 1st Pass - find the min and max for each channel: + for (i = 0; i < nSubPixels; i += 4) { + r = data[i + 0]; + if (r < rMin) { rMin = r; } + else if (r > rMax) { rMax = r; } + g = data[i + 1]; + if (g < gMin) { gMin = g; } else + if (g > gMax) { gMax = g; } + b = data[i + 2]; + if (b < bMin) { bMin = b; } else + if (b > bMax) { bMax = b; } + //a = data[i + 3]; + //if (a < aMin) { aMin = a; } else + //if (a > aMax) { aMax = a; } + } + + // If there is only 1 level - don't remap + if( rMax === rMin ){ rMax = 255; rMin = 0; } + if( gMax === gMin ){ gMax = 255; gMin = 0; } + if( bMax === bMin ){ bMax = 255; bMin = 0; } + + var rMid, rGoalMax, rGoalMin, + gMid, gGoalMax, gGoalMin, + bMid, bGoalMax, bGoalMin; + + // If the enhancement is positive - stretch the histogram + if ( enhanceAmount > 0 ){ + rGoalMax = rMax + enhanceAmount * (255 - rMax); + rGoalMin = rMin - enhanceAmount * (rMin - 0); + gGoalMax = gMax + enhanceAmount * (255 - gMax); + gGoalMin = gMin - enhanceAmount * (gMin - 0); + bGoalMax = bMax + enhanceAmount * (255 - bMax); + bGoalMin = bMin - enhanceAmount * (bMin - 0); + // If the enhancement is negative - compress the histogram + } else { + rMid = (rMax + rMin) * 0.5; + rGoalMax = rMax + enhanceAmount * (rMax - rMid); + rGoalMin = rMin + enhanceAmount * (rMin - rMid); + gMid = (gMax + gMin) * 0.5; + gGoalMax = gMax + enhanceAmount * (gMax - gMid); + gGoalMin = gMin + enhanceAmount * (gMin - gMid); + bMid = (bMax + bMin) * 0.5; + bGoalMax = bMax + enhanceAmount * (bMax - bMid); + bGoalMin = bMin + enhanceAmount * (bMin - bMid); + } + + // Pass 2 - remap everything, except the alpha + for (i = 0; i < nSubPixels; i += 4) { + data[i + 0] = remap(data[i + 0], rMin, rMax, rGoalMin, rGoalMax); + data[i + 1] = remap(data[i + 1], gMin, gMax, gGoalMin, gGoalMax); + data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax); + //data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'enhance', 0, null, Konva.Factory.afterSetFilter); + + /** + * get/set enhance. Use with {@link Konva.Filters.Enhance} filter. + * @name enhance + * @method + * @memberof Konva.Node.prototype + * @param {Float} amount + * @returns {Float} + */ +})(); + +(function () { + 'use strict'; + /** + * Posterize Filter. Adjusts the channels so that there are no more + * than n different values for that channel. This is also applied + * to the alpha channel. + * @function + * @name Posterize + * @author ippo615 + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Posterize]); + * node.levels(0.8); + */ + + Konva.Filters.Posterize = function (imageData) { + // level must be between 1 and 255 + var levels = Math.round(this.levels() * 254) + 1, + data = imageData.data, + len = data.length, + scale = (255 / levels), + i; + + for (i = 0; i < len; i += 1) { + data[i] = Math.floor(data[i] / scale) * scale; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'levels', 0.5, null, Konva.Factory.afterSetFilter); + + /** + * get/set levels. Must be a number between 0 and 1. Use with {@link Konva.Filters.Posterize} filter. + * @name levels + * @method + * @memberof Konva.Node.prototype + * @param {Number} level between 0 and 1 + * @returns {Number} + */ +})(); + +(function () { + 'use strict'; + + /** + * Noise Filter. Randomly adds or substracts to the color channels + * @function + * @name Noise + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Noise]); + * node.noise(0.8); + */ + Konva.Filters.Noise = function (imageData) { + var amount = this.noise() * 255, + data = imageData.data, + nPixels = data.length, + half = amount / 2, + i; + + for (i = 0; i < nPixels; i += 4) { + data[i + 0] += half - 2 * half * Math.random(); + data[i + 1] += half - 2 * half * Math.random(); + data[i + 2] += half - 2 * half * Math.random(); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'noise', 0.2, null, Konva.Factory.afterSetFilter); + + /** + * get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter. + * @name noise + * @method + * @memberof Konva.Node.prototype + * @param {Number} noise + * @returns {Number} + */ +})(); + +/*eslint-disable max-depth */ +(function () { + 'use strict'; + /** + * Pixelate Filter. Averages groups of pixels and redraws + * them as larger pixels + * @function + * @name Pixelate + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Pixelate]); + * node.pixelSize(10); + */ + + Konva.Filters.Pixelate = function (imageData) { + + var pixelSize = Math.ceil(this.pixelSize()), + width = imageData.width, + height = imageData.height, + x, y, i, + //pixelsPerBin = pixelSize * pixelSize, + red, green, blue, alpha, + nBinsX = Math.ceil(width / pixelSize), + nBinsY = Math.ceil(height / pixelSize), + xBinStart, xBinEnd, yBinStart, yBinEnd, + xBin, yBin, pixelsInBin; + imageData = imageData.data; + + for (xBin = 0; xBin < nBinsX; xBin += 1) { + for (yBin = 0; yBin < nBinsY; yBin += 1) { + + // Initialize the color accumlators to 0 + red = 0; + green = 0; + blue = 0; + alpha = 0; + + // Determine which pixels are included in this bin + xBinStart = xBin * pixelSize; + xBinEnd = xBinStart + pixelSize; + yBinStart = yBin * pixelSize; + yBinEnd = yBinStart + pixelSize; + + // Add all of the pixels to this bin! + pixelsInBin = 0; + for (x = xBinStart; x < xBinEnd; x += 1) { + if( x >= width ){ continue; } + for (y = yBinStart; y < yBinEnd; y += 1) { + if( y >= height ){ continue; } + i = (width * y + x) * 4; + red += imageData[i + 0]; + green += imageData[i + 1]; + blue += imageData[i + 2]; + alpha += imageData[i + 3]; + pixelsInBin += 1; + } + } + + // Make sure the channels are between 0-255 + red = red / pixelsInBin; + green = green / pixelsInBin; + blue = blue / pixelsInBin; + + // Draw this bin + for (x = xBinStart; x < xBinEnd; x += 1) { + if( x >= width ){ continue; } + for (y = yBinStart; y < yBinEnd; y += 1) { + if( y >= height ){ continue; } + i = (width * y + x) * 4; + imageData[i + 0] = red; + imageData[i + 1] = green; + imageData[i + 2] = blue; + imageData[i + 3] = alpha; + } + } + } + } + + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'pixelSize', 8, null, Konva.Factory.afterSetFilter); + + /** + * get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter. + * @name pixelSize + * @method + * @memberof Konva.Node.prototype + * @param {Integer} pixelSize + * @returns {Integer} + */ +})(); + +(function () { + 'use strict'; + /** + * Threshold Filter. Pushes any value above the mid point to + * the max and any value below the mid point to the min. + * This affects the alpha channel. + * @function + * @name Threshold + * @memberof Konva.Filters + * @param {Object} imageData + * @author ippo615 + * @example + * node.cache(); + * node.filters([Konva.Filters.Threshold]); + * node.threshold(0.1); + */ + + Konva.Filters.Threshold = function (imageData) { + var level = this.threshold() * 255, + data = imageData.data, + len = data.length, + i; + + for (i = 0; i < len; i += 1) { + data[i] = data[i] < level ? 0 : 255; + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'threshold', 0.5, null, Konva.Factory.afterSetFilter); + + /** + * get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter. + * @name threshold + * @method + * @memberof Konva.Node.prototype + * @param {Number} threshold + * @returns {Number} + */ +})(); + +(function() { + 'use strict'; + /** + * Sepia Filter + * Based on: Pixastic Lib - Sepia filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * @function + * @name Sepia + * @memberof Konva.Filters + * @param {Object} imageData + * @author Jacob Seidelin + * @license MPL v1.1 [http://www.pixastic.com/lib/license.txt] + * @example + * node.cache(); + * node.filters([Konva.Filters.Sepia]); + */ + Konva.Filters.Sepia = function (imageData) { + var data = imageData.data, + w = imageData.width, + y = imageData.height, + w4 = w * 4, + offsetY, x, offset, or, og, ob, r, g, b; + + do { + offsetY = (y - 1) * w4; + x = w; + do { + offset = offsetY + (x - 1) * 4; + + or = data[offset]; + og = data[offset + 1]; + ob = data[offset + 2]; + + r = or * 0.393 + og * 0.769 + ob * 0.189; + g = or * 0.349 + og * 0.686 + ob * 0.168; + b = or * 0.272 + og * 0.534 + ob * 0.131; + + data[offset] = r > 255 ? 255 : r; + data[offset + 1] = g > 255 ? 255 : g; + data[offset + 2] = b > 255 ? 255 : b; + data[offset + 3] = data[offset + 3]; + } while (--x); + } while (--y); + }; +})(); + +(function () { + 'use strict'; + /** + * Solarize Filter + * Pixastic Lib - Solarize filter - v0.1.0 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * License: [http://www.pixastic.com/lib/license.txt] + * @function + * @name Solarize + * @memberof Konva.Filters + * @param {Object} imageData + * @example + * node.cache(); + * node.filters([Konva.Filters.Solarize]); + */ + Konva.Filters.Solarize = function (imageData) { + var data = imageData.data, + w = imageData.width, + h = imageData.height, + w4 = w * 4, + y = h; + + do { + var offsetY = (y - 1) * w4; + var x = w; + do { + var offset = offsetY + (x - 1) * 4; + var r = data[offset]; + var g = data[offset + 1]; + var b = data[offset + 2]; + + if (r > 127) { + r = 255 - r; + } + if (g > 127) { + g = 255 - g; + } + if (b > 127) { + b = 255 - b; + } + + data[offset] = r; + data[offset + 1] = g; + data[offset + 2] = b; + } while (--x); + } while (--y); + }; +})(); + + + +(function () { + 'use strict'; + + /* + * ToPolar Filter. Converts image data to polar coordinates. Performs + * w*h*4 pixel reads and w*h pixel writes. The r axis is placed along + * what would be the y axis and the theta axis along the x axis. + * @function + * @author ippo615 + * @memberof Konva.Filters + * @param {ImageData} src, the source image data (what will be transformed) + * @param {ImageData} dst, the destination image data (where it will be saved) + * @param {Object} opt + * @param {Number} [opt.polarCenterX] horizontal location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarCenterY] vertical location for the center of the circle, + * default is in the middle + */ + + var ToPolar = function(src, dst, opt){ + + var srcPixels = src.data, + dstPixels = dst.data, + xSize = src.width, + ySize = src.height, + xMid = opt.polarCenterX || xSize / 2, + yMid = opt.polarCenterY || ySize / 2, + i, x, y, r = 0, g = 0, b = 0, a = 0; + + // Find the largest radius + var rad, rMax = Math.sqrt( xMid * xMid + yMid * yMid ); + x = xSize - xMid; + y = ySize - yMid; + rad = Math.sqrt( x * x + y * y ); + rMax = (rad > rMax) ? rad : rMax; + + // We'll be uisng y as the radius, and x as the angle (theta=t) + var rSize = ySize, + tSize = xSize, + radius, theta; + + // We want to cover all angles (0-360) and we need to convert to + // radians (*PI/180) + var conversion = 360 / tSize * Math.PI / 180, sin, cos; + + // var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale; + + for( theta = 0; theta < tSize; theta += 1 ){ + sin = Math.sin(theta * conversion); + cos = Math.cos(theta * conversion); + for( radius = 0; radius < rSize; radius += 1 ){ + x = Math.floor(xMid + rMax * radius / rSize * cos); + y = Math.floor(yMid + rMax * radius / rSize * sin); + i = (y * xSize + x) * 4; + r = srcPixels[i + 0]; + g = srcPixels[i + 1]; + b = srcPixels[i + 2]; + a = srcPixels[i + 3]; + + // Store it + //i = (theta * xSize + radius) * 4; + i = (theta + radius * xSize) * 4; + dstPixels[i + 0] = r; + dstPixels[i + 1] = g; + dstPixels[i + 2] = b; + dstPixels[i + 3] = a; + + } + } + }; + + /* + * FromPolar Filter. Converts image data from polar coordinates back to rectangular. + * Performs w*h*4 pixel reads and w*h pixel writes. + * @function + * @author ippo615 + * @memberof Konva.Filters + * @param {ImageData} src, the source image data (what will be transformed) + * @param {ImageData} dst, the destination image data (where it will be saved) + * @param {Object} opt + * @param {Number} [opt.polarCenterX] horizontal location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarCenterY] vertical location for the center of the circle, + * default is in the middle + * @param {Number} [opt.polarRotation] amount to rotate the image counterclockwis, + * 0 is no rotation, 360 degrees is a full rotation + */ + + var FromPolar = function(src, dst, opt){ + + var srcPixels = src.data, + dstPixels = dst.data, + xSize = src.width, + ySize = src.height, + xMid = opt.polarCenterX || xSize / 2, + yMid = opt.polarCenterY || ySize / 2, + i, x, y, dx, dy, r = 0, g = 0, b = 0, a = 0; + + + // Find the largest radius + var rad, rMax = Math.sqrt( xMid * xMid + yMid * yMid ); + x = xSize - xMid; + y = ySize - yMid; + rad = Math.sqrt( x * x + y * y ); + rMax = (rad > rMax) ? rad : rMax; + + // We'll be uisng x as the radius, and y as the angle (theta=t) + var rSize = ySize, + tSize = xSize, + radius, theta, + phaseShift = opt.polarRotation || 0; + + // We need to convert to degrees and we need to make sure + // it's between (0-360) + // var conversion = tSize/360*180/Math.PI; + //var conversion = tSize/360*180/Math.PI; + + var x1, y1; + + for( x = 0; x < xSize; x += 1 ){ + for( y = 0; y < ySize; y += 1 ){ + dx = x - xMid; + dy = y - yMid; + radius = Math.sqrt(dx * dx + dy * dy) * rSize / rMax; + theta = (Math.atan2(dy, dx) * 180 / Math.PI + 360 + phaseShift) % 360; + theta = theta * tSize / 360; + x1 = Math.floor(theta); + y1 = Math.floor(radius); + i = (y1 * xSize + x1) * 4; + r = srcPixels[i + 0]; + g = srcPixels[i + 1]; + b = srcPixels[i + 2]; + a = srcPixels[i + 3]; + + // Store it + i = (y * xSize + x) * 4; + dstPixels[i + 0] = r; + dstPixels[i + 1] = g; + dstPixels[i + 2] = b; + dstPixels[i + 3] = a; + } + } + + }; + + //Konva.Filters.ToPolar = Konva.Util._FilterWrapDoubleBuffer(ToPolar); + //Konva.Filters.FromPolar = Konva.Util._FilterWrapDoubleBuffer(FromPolar); + + // create a temporary canvas for working - shared between multiple calls + var tempCanvas = Konva.Util.createCanvasElement(); + + /* + * Kaleidoscope Filter. + * @function + * @name Kaleidoscope + * @author ippo615 + * @memberof Konva.Filters + * @example + * node.cache(); + * node.filters([Konva.Filters.Kaleidoscope]); + * node.kaleidoscopePower(3); + * node.kaleidoscopeAngle(45); + */ + Konva.Filters.Kaleidoscope = function(imageData){ + var xSize = imageData.width, + ySize = imageData.height; + + var x, y, xoff, i, r, g, b, a, srcPos, dstPos; + var power = Math.round( this.kaleidoscopePower() ); + var angle = Math.round( this.kaleidoscopeAngle() ); + var offset = Math.floor(xSize * (angle % 360) / 360); + + if( power < 1 ){return; } + + // Work with our shared buffer canvas + tempCanvas.width = xSize; + tempCanvas.height = ySize; + var scratchData = tempCanvas.getContext('2d').getImageData(0, 0, xSize, ySize); + + // Convert thhe original to polar coordinates + ToPolar( imageData, scratchData, { + polarCenterX: xSize / 2, + polarCenterY: ySize / 2 + }); + + // Determine how big each section will be, if it's too small + // make it bigger + var minSectionSize = xSize / Math.pow(2, power); + while( minSectionSize <= 8){ + minSectionSize = minSectionSize * 2; + power -= 1; + } + minSectionSize = Math.ceil(minSectionSize); + var sectionSize = minSectionSize; + + // Copy the offset region to 0 + // Depending on the size of filter and location of the offset we may need + // to copy the section backwards to prevent it from rewriting itself + var xStart = 0, + xEnd = sectionSize, + xDelta = 1; + if( offset + minSectionSize > xSize ){ + xStart = sectionSize; + xEnd = 0; + xDelta = -1; + } + for( y = 0; y < ySize; y += 1 ){ + for( x = xStart; x !== xEnd; x += xDelta ){ + xoff = Math.round(x + offset) % xSize; + srcPos = (xSize * y + xoff) * 4; + r = scratchData.data[srcPos + 0]; + g = scratchData.data[srcPos + 1]; + b = scratchData.data[srcPos + 2]; + a = scratchData.data[srcPos + 3]; + dstPos = (xSize * y + x) * 4; + scratchData.data[dstPos + 0] = r; + scratchData.data[dstPos + 1] = g; + scratchData.data[dstPos + 2] = b; + scratchData.data[dstPos + 3] = a; + } + } + + // Perform the actual effect + for( y = 0; y < ySize; y += 1 ){ + sectionSize = Math.floor( minSectionSize ); + for( i = 0; i < power; i += 1 ){ + for( x = 0; x < sectionSize + 1; x += 1 ){ + srcPos = (xSize * y + x) * 4; + r = scratchData.data[srcPos + 0]; + g = scratchData.data[srcPos + 1]; + b = scratchData.data[srcPos + 2]; + a = scratchData.data[srcPos + 3]; + dstPos = (xSize * y + sectionSize * 2 - x - 1) * 4; + scratchData.data[dstPos + 0] = r; + scratchData.data[dstPos + 1] = g; + scratchData.data[dstPos + 2] = b; + scratchData.data[dstPos + 3] = a; + } + sectionSize *= 2; + } + } + + // Convert back from polar coordinates + FromPolar(scratchData, imageData, {polarRotation: 0}); + }; + + /** + * get/set kaleidoscope power. Use with {@link Konva.Filters.Kaleidoscope} filter. + * @name kaleidoscopePower + * @method + * @memberof Konva.Node.prototype + * @param {Integer} power of kaleidoscope + * @returns {Integer} + */ + Konva.Factory.addGetterSetter(Konva.Node, 'kaleidoscopePower', 2, null, Konva.Factory.afterSetFilter); + + /** + * get/set kaleidoscope angle. Use with {@link Konva.Filters.Kaleidoscope} filter. + * @name kaleidoscopeAngle + * @method + * @memberof Konva.Node.prototype + * @param {Integer} degrees + * @returns {Integer} + */ + Konva.Factory.addGetterSetter(Konva.Node, 'kaleidoscopeAngle', 0, null, Konva.Factory.afterSetFilter); + +})(); + +(function() { + 'use strict'; + /** + * Container constructor.  Containers are used to contain nodes or other containers + * @constructor + * @memberof Konva + * @augments Konva.Node + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + */ + Konva.Container = function(config) { + this.__init(config); + }; + + Konva.Util.addMethods(Konva.Container, { + __init: function(config) { + this.children = new Konva.Collection(); + Konva.Node.call(this, config); + }, + /** + * returns a {@link Konva.Collection} of direct descendant nodes + * @method + * @memberof Konva.Container.prototype + * @param {Function} [filterFunc] filter function + * @returns {Konva.Collection} + * @example + * // get all children + * var children = layer.getChildren(); + * + * // get only circles + * var circles = layer.getChildren(function(node){ + * return node.getClassName() === 'Circle'; + * }); + */ + getChildren: function(filterFunc) { + if (!filterFunc) { + return this.children; + } + + var results = new Konva.Collection(); + this.children.each(function(child){ + if (filterFunc(child)) { + results.push(child); + } + }); + return results; + }, + /** + * determine if node has children + * @method + * @memberof Konva.Container.prototype + * @returns {Boolean} + */ + hasChildren: function() { + return this.getChildren().length > 0; + }, + /** + * remove all children + * @method + * @memberof Konva.Container.prototype + */ + removeChildren: function() { + var children = Konva.Collection.toCollection(this.children); + var child; + for (var i = 0; i < children.length; i++) { + child = children[i]; + // reset parent to prevent many _setChildrenIndices calls + delete child.parent; + child.index = 0; + child.remove(); + } + children = null; + this.children = new Konva.Collection(); + return this; + }, + /** + * destroy all children + * @method + * @memberof Konva.Container.prototype + */ + destroyChildren: function() { + var children = Konva.Collection.toCollection(this.children); + var child; + for (var i = 0; i < children.length; i++) { + child = children[i]; + // reset parent to prevent many _setChildrenIndices calls + delete child.parent; + child.index = 0; + child.destroy(); + } + children = null; + this.children = new Konva.Collection(); + return this; + }, + /** + * Add node or nodes to container. + * @method + * @memberof Konva.Container.prototype + * @param {...Konva.Node} child + * @returns {Container} + * @example + * layer.add(shape1, shape2, shape3); + */ + add: function(child) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.add(arguments[i]); + } + return this; + } + if (child.getParent()) { + child.moveTo(this); + return this; + } + var children = this.children; + this._validateAdd(child); + child.index = children.length; + child.parent = this; + children.push(child); + this._fire('add', { + child: child + }); + + // if node under drag we need to update drag animation + if (Konva.DD && child.isDragging()) { + Konva.DD.anim.setLayers(child.getLayer()); + } + + // chainable + return this; + }, + destroy: function() { + // destroy children + if (this.hasChildren()) { + this.destroyChildren(); + } + // then destroy self + Konva.Node.prototype.destroy.call(this); + return this; + }, + /** + * return a {@link Konva.Collection} of nodes that match the selector. Use '#' for id selections + * and '.' for name selections. You can also select by type or class name. Pass multiple selectors + * separated by a space. + * @method + * @memberof Konva.Container.prototype + * @param {String} selector + * @returns {Collection} + * @example + * // select node with id foo + * var node = stage.find('#foo'); + * + * // select nodes with name bar inside layer + * var nodes = layer.find('.bar'); + * + * // select all groups inside layer + * var nodes = layer.find('Group'); + * + * // select all rectangles inside layer + * var nodes = layer.find('Rect'); + * + * // select node with an id of foo or a name of bar inside layer + * var nodes = layer.find('#foo, .bar'); + */ + find: function(selector) { + var retArr = [], + selectorArr = selector.replace(/ /g, '').split(','), + len = selectorArr.length, + n, i, sel, arr, node, children, clen; + + for (n = 0; n < len; n++) { + sel = selectorArr[n]; + if (!Konva.Util.isValidSelector(sel)) { + Konva.Util.warn('Selector "' + sel + '" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".'); + Konva.Util.warn('If you have a custom shape with such className, please change it to start with upper letter like "Triangle".'); + Konva.Util.warn('Konva is awesome, right?'); + } + // id selector + if(sel.charAt(0) === '#') { + node = this._getNodeById(sel.slice(1)); + if(node) { + retArr.push(node); + } + } + // name selector + else if(sel.charAt(0) === '.') { + arr = this._getNodesByName(sel.slice(1)); + retArr = retArr.concat(arr); + } + // unrecognized selector, pass to children + else { + children = this.getChildren(); + clen = children.length; + for(i = 0; i < clen; i++) { + retArr = retArr.concat(children[i]._get(sel)); + } + } + } + + return Konva.Collection.toCollection(retArr); + }, + /** + * return a first node from `find` method + * @method + * @memberof Konva.Container.prototype + * @param {String} selector + * @returns {Konva.Node} + * @example + * // select node with id foo + * var node = stage.findOne('#foo'); + * + * // select node with name bar inside layer + * var nodes = layer.findOne('.bar'); + */ + findOne: function(selector) { + return this.find(selector)[0]; + }, + _getNodeById: function(key) { + var node = Konva.ids[key]; + + if(node !== undefined && this.isAncestorOf(node)) { + return node; + } + return null; + }, + _getNodesByName: function(key) { + var arr = Konva.names[key] || []; + return this._getDescendants(arr); + }, + _get: function(selector) { + var retArr = Konva.Node.prototype._get.call(this, selector); + var children = this.getChildren(); + var len = children.length; + for(var n = 0; n < len; n++) { + retArr = retArr.concat(children[n]._get(selector)); + } + return retArr; + }, + // extenders + toObject: function() { + var obj = Konva.Node.prototype.toObject.call(this); + + obj.children = []; + + var children = this.getChildren(); + var len = children.length; + for(var n = 0; n < len; n++) { + var child = children[n]; + obj.children.push(child.toObject()); + } + + return obj; + }, + _getDescendants: function(arr) { + var retArr = []; + var len = arr.length; + for(var n = 0; n < len; n++) { + var node = arr[n]; + if(this.isAncestorOf(node)) { + retArr.push(node); + } + } + + return retArr; + }, + /** + * determine if node is an ancestor + * of descendant + * @method + * @memberof Konva.Container.prototype + * @param {Konva.Node} node + */ + isAncestorOf: function(node) { + var parent = node.getParent(); + while(parent) { + if(parent._id === this._id) { + return true; + } + parent = parent.getParent(); + } + + return false; + }, + clone: function(obj) { + // call super method + var node = Konva.Node.prototype.clone.call(this, obj); + + this.getChildren().each(function(no) { + node.add(no.clone()); + }); + return node; + }, + /** + * get all shapes that intersect a point. Note: because this method must clear a temporary + * canvas and redraw every shape inside the container, it should only be used for special sitations + * because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible + * because it performs much better + * @method + * @memberof Konva.Container.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @returns {Array} array of shapes + */ + getAllIntersections: function(pos) { + var arr = []; + + this.find('Shape').each(function(shape) { + if(shape.isVisible() && shape.intersects(pos)) { + arr.push(shape); + } + }); + + return arr; + }, + _setChildrenIndices: function() { + this.children.each(function(child, n) { + child.index = n; + }); + }, + drawScene: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()), + context = canvas && canvas.getContext(), + cachedCanvas = this._cache.canvas, + cachedSceneCanvas = cachedCanvas && cachedCanvas.scene; + + if (this.isVisible()) { + if (!caching && cachedSceneCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedSceneCanvas(context); + context.restore(); + } + else { + this._drawChildren(canvas, 'drawScene', top, false, caching); + } + } + return this; + }, + drawHit: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || (layer && layer.hitCanvas), + context = canvas && canvas.getContext(), + cachedCanvas = this._cache.canvas, + cachedHitCanvas = cachedCanvas && cachedCanvas.hit; + + if (this.shouldDrawHit(canvas)) { + if (layer) { + layer.clearHitCache(); + } + if (!caching && cachedHitCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedHitCanvas(context); + context.restore(); + } + else { + this._drawChildren(canvas, 'drawHit', top); + } + } + return this; + }, + _drawChildren: function(canvas, drawMethod, top, caching, skipBuffer) { + var layer = this.getLayer(), + context = canvas && canvas.getContext(), + clipWidth = this.getClipWidth(), + clipHeight = this.getClipHeight(), + clipFunc = this.getClipFunc(), + hasClip = clipWidth && clipHeight || clipFunc, + clipX, clipY; + + if (hasClip && layer) { + context.save(); + layer._applyTransform(this, context); + context.beginPath(); + if (clipFunc) { + clipFunc.call(this, context, this); + } else { + clipX = this.getClipX(); + clipY = this.getClipY(); + context.rect(clipX, clipY, clipWidth, clipHeight); + } + context.clip(); + context.reset(); + } + + this.children.each(function(child) { + child[drawMethod](canvas, top, caching, skipBuffer); + }); + + if (hasClip) { + context.restore(); + } + }, + shouldDrawHit: function(canvas) { + var layer = this.getLayer(); + var dd = Konva.DD; + var layerUnderDrag = dd && Konva.isDragging() && (Konva.DD.anim.getLayers().indexOf(layer) !== -1); + return (canvas && canvas.isCache) || (layer && layer.hitGraphEnabled()) + && this.isVisible() && !layerUnderDrag; + }, + getClientRect: function(skipTransform) { + var minX, minY, maxX, maxY; + var selfRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + this.children.each(function(child) { + var rect = child.getClientRect(); + + // skip invisible children (like empty groups) + // or don't skip... hmmm... + // if (rect.width === 0 && rect.height === 0) { + // return; + // } + + if (minX === undefined) { // initial value for first child + minX = rect.x; + minY = rect.y; + maxX = rect.x + rect.width; + maxY = rect.y + rect.height; + } else { + minX = Math.min(minX, rect.x); + minY = Math.min(minY, rect.y); + maxX = Math.max(maxX, rect.x + rect.width); + maxY = Math.max(maxY, rect.y + rect.height); + } + + }); + + if (this.children.length !== 0) { + selfRect = { + x: minX, + y: minY, + width: maxX - minX, + height: maxY - minY + }; + } + + if (!skipTransform) { + return this._transformedRect(selfRect); + } + return selfRect; + } + }); + + Konva.Util.extend(Konva.Container, Konva.Node); + // deprecated methods + Konva.Container.prototype.get = Konva.Container.prototype.find; + + // add getters setters + Konva.Factory.addComponentsGetterSetter(Konva.Container, 'clip', ['x', 'y', 'width', 'height']); + /** + * get/set clip + * @method + * @name clip + * @memberof Konva.Container.prototype + * @param {Object} clip + * @param {Number} clip.x + * @param {Number} clip.y + * @param {Number} clip.width + * @param {Number} clip.height + * @returns {Object} + * @example + * // get clip + * var clip = container.clip(); + * + * // set clip + * container.setClip({ + * x: 20, + * y: 20, + * width: 20, + * height: 20 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipX'); + /** + * get/set clip x + * @name clipX + * @method + * @memberof Konva.Container.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get clip x + * var clipX = container.clipX(); + * + * // set clip x + * container.clipX(10); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipY'); + /** + * get/set clip y + * @name clipY + * @method + * @memberof Konva.Container.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get clip y + * var clipY = container.clipY(); + * + * // set clip y + * container.clipY(10); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipWidth'); + /** + * get/set clip width + * @name clipWidth + * @method + * @memberof Konva.Container.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get clip width + * var clipWidth = container.clipWidth(); + * + * // set clip width + * container.clipWidth(100); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipHeight'); + /** + * get/set clip height + * @name clipHeight + * @method + * @memberof Konva.Container.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get clip height + * var clipHeight = container.clipHeight(); + * + * // set clip height + * container.clipHeight(100); + */ + + Konva.Factory.addGetterSetter(Konva.Container, 'clipFunc'); + /** + * get/set clip function + * @name clipFunc + * @method + * @memberof Konva.Container.prototype + * @param {Function} function + * @returns {Function} + * @example + * // get clip function + * var clipFunction = container.clipFunc(); + * + * // set clip height + * container.clipFunc(function(ctx) { + * ctx.rect(0, 0, 100, 100); + * }); + */ + + Konva.Collection.mapMethods(Konva.Container); +})(); + +(function(Konva) { + 'use strict'; + var HAS_SHADOW = 'hasShadow'; + var SHADOW_RGBA = 'shadowRGBA'; + + function _fillFunc(context) { + context.fill(); + } + function _strokeFunc(context) { + context.stroke(); + } + function _fillFuncHit(context) { + context.fill(); + } + function _strokeFuncHit(context) { + context.stroke(); + } + + function _clearHasShadowCache() { + this._clearCache(HAS_SHADOW); + } + + function _clearGetShadowRGBACache() { + this._clearCache(SHADOW_RGBA); + } + + /** + * Shape constructor. Shapes are primitive objects such as rectangles, + * circles, text, lines, etc. + * @constructor + * @memberof Konva + * @augments Konva.Node + * @param {Object} config + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var customShape = new Konva.Shape({ + * x: 5, + * y: 10, + * fill: 'red', + * // a Konva.Canvas renderer is passed into the drawFunc function + * drawFunc: function(context) { + * context.beginPath(); + * context.moveTo(200, 50); + * context.lineTo(420, 80); + * context.quadraticCurveTo(300, 100, 260, 170); + * context.closePath(); + * context.fillStrokeShape(this); + * } + *}); + */ + Konva.Shape = function(config) { + this.__init(config); + }; + + Konva.Util.addMethods(Konva.Shape, { + __init: function(config) { + this.nodeType = 'Shape'; + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this._fillFuncHit = _fillFuncHit; + this._strokeFuncHit = _strokeFuncHit; + + // set colorKey + var shapes = Konva.shapes; + var key; + + while(true) { + key = Konva.Util.getRandomColor(); + if(key && !( key in shapes)) { + break; + } + } + + this.colorKey = key; + shapes[key] = this; + + // call super constructor + Konva.Node.call(this, config); + + this.on('shadowColorChange.konva shadowBlurChange.konva shadowOffsetChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearHasShadowCache); + + this.on('shadowColorChange.konva shadowOpacityChange.konva shadowEnabledChange.konva', _clearGetShadowRGBACache); + }, + hasChildren: function() { + return false; + }, + getChildren: function() { + return []; + }, + /** + * get canvas context tied to the layer + * @method + * @memberof Konva.Shape.prototype + * @returns {Konva.Context} + */ + getContext: function() { + return this.getLayer().getContext(); + }, + /** + * get canvas renderer tied to the layer. Note that this returns a canvas renderer, not a canvas element + * @method + * @memberof Konva.Shape.prototype + * @returns {Konva.Canvas} + */ + getCanvas: function() { + return this.getLayer().getCanvas(); + }, + /** + * returns whether or not a shadow will be rendered + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasShadow: function() { + return this._getCache(HAS_SHADOW, this._hasShadow); + }, + _hasShadow: function() { + return this.getShadowEnabled() && (this.getShadowOpacity() !== 0 && !!(this.getShadowColor() || this.getShadowBlur() || this.getShadowOffsetX() || this.getShadowOffsetY())); + }, + getShadowRGBA: function() { + return this._getCache(SHADOW_RGBA, this._getShadowRGBA); + }, + _getShadowRGBA: function() { + if (this.hasShadow()) { + var rgba = Konva.Util.colorToRGBA(this.shadowColor()); + return 'rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + (rgba.a * (this.getShadowOpacity() || 1)) + ')'; + } + }, + /** + * returns whether or not the shape will be filled + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasFill: function() { + return !!(this.getFill() || this.getFillPatternImage() || this.getFillLinearGradientColorStops() || this.getFillRadialGradientColorStops()); + }, + /** + * returns whether or not the shape will be stroked + * @method + * @memberof Konva.Shape.prototype + * @returns {Boolean} + */ + hasStroke: function() { + return !!(this.stroke()); + }, + /** + * determines if point is in the shape, regardless if other shapes are on top of it. Note: because + * this method clears a temporary canvas and then redraws the shape, it performs very poorly if executed many times + * consecutively. Please use the {@link Konva.Stage#getIntersection} method if at all possible + * because it performs much better + * @method + * @memberof Konva.Shape.prototype + * @param {Object} point + * @param {Number} point.x + * @param {Number} point.y + * @returns {Boolean} + */ + intersects: function(point) { + var stage = this.getStage(), + bufferHitCanvas = stage.bufferHitCanvas, + p; + + bufferHitCanvas.getContext().clear(); + this.drawScene(bufferHitCanvas); + p = bufferHitCanvas.context.getImageData(Math.round(point.x), Math.round(point.y), 1, 1).data; + return p[3] > 0; + }, + // extends Node.prototype.destroy + destroy: function() { + Konva.Node.prototype.destroy.call(this); + delete Konva.shapes[this.colorKey]; + return this; + }, + _useBufferCanvas: function(caching) { + return !caching && (this.perfectDrawEnabled() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()) || + (this.perfectDrawEnabled() && this.hasShadow() && (this.getAbsoluteOpacity() !== 1) && this.hasFill() && this.hasStroke() && this.getStage()); + }, + /** + * return self rectangle (x, y, width, height) of shape. + * This method are not taken into account transformation and styles. + * @method + * @memberof Konva.Node.prototype + * @returns {Object} rect with {x, y, width, height} properties + * @example + * + * rect.getSelfRect(); // return {x:0, y:0, width:rect.width(), height:rect.height()} + * circle.getSelfRect(); // return {x: - circle.width() / 2, y: - circle.height() / 2, width:circle.width(), height:circle.height()} + * + */ + getSelfRect: function() { + var size = this.getSize(); + return { + x: this._centroid ? Math.round(-size.width / 2) : 0, + y: this._centroid ? Math.round(-size.height / 2) : 0, + width: size.width, + height: size.height + }; + }, + getClientRect: function(skipTransform) { + var fillRect = this.getSelfRect(); + + var strokeWidth = (this.hasStroke() && this.strokeWidth()) || 0; + var fillAndStrokeWidth = fillRect.width + strokeWidth; + var fillAndStrokeHeight = fillRect.height + strokeWidth; + + var shadowOffsetX = this.shadowOffsetX(); + var shadowOffsetY = this.shadowOffsetY(); + + var preWidth = fillAndStrokeWidth + Math.abs(shadowOffsetX); + var preHeight = fillAndStrokeHeight + Math.abs(shadowOffsetY); + + var blurRadius = (this.hasShadow() && this.shadowBlur() || 0); + + var width = preWidth + blurRadius * 2; + var height = preHeight + blurRadius * 2; + + // if stroke, for example = 3 + // we need to set x to 1.5, but after Math.round it will be 2 + // as we have additional offset we need to increase width and height by 1 pixel + var roundingOffset = 0; + if (Math.round(strokeWidth / 2) !== strokeWidth / 2) { + roundingOffset = 1; + } + var rect = { + width: width + roundingOffset, + height: height + roundingOffset, + x: -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetX, 0) + fillRect.x, + y: -Math.round(strokeWidth / 2 + blurRadius) + Math.min(shadowOffsetY, 0) + fillRect.y + }; + if (!skipTransform) { + return this._transformedRect(rect); + } + return rect; + }, + drawScene: function(can, top, caching, skipBuffer) { + var layer = this.getLayer(), + canvas = can || layer.getCanvas(), + context = canvas.getContext(), + cachedCanvas = this._cache.canvas, + drawFunc = this.sceneFunc(), + hasShadow = this.hasShadow(), + hasStroke = this.hasStroke(), + stage, bufferCanvas, bufferContext; + + if(!this.isVisible()) { + return this; + } + if (cachedCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedSceneCanvas(context); + context.restore(); + return this; + } + if (!drawFunc) { + return this; + } + context.save(); + // if buffer canvas is needed + if (this._useBufferCanvas(caching) && !skipBuffer) { + stage = this.getStage(); + bufferCanvas = stage.bufferCanvas; + bufferContext = bufferCanvas.getContext(); + bufferContext.clear(); + bufferContext.save(); + bufferContext._applyLineJoin(this); + // layer might be undefined if we are using cache before adding to layer + if (!caching) { + if (layer) { + layer._applyTransform(this, bufferContext, top); + } else { + var m = this.getAbsoluteTransform(top).getMatrix(); + context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + } + + drawFunc.call(this, bufferContext); + bufferContext.restore(); + + var ratio = bufferCanvas.pixelRatio; + if (hasShadow && !canvas.hitCanvas) { + context.save(); + context._applyShadow(this); + context._applyOpacity(this); + context.drawImage(bufferCanvas._canvas, 0, 0, bufferCanvas.width / ratio, bufferCanvas.height / ratio); + context.restore(); + } else { + context._applyOpacity(this); + context.drawImage(bufferCanvas._canvas, 0, 0, bufferCanvas.width / ratio, bufferCanvas.height / ratio); + } + } + // if buffer canvas is not needed + else { + context._applyLineJoin(this); + // layer might be undefined if we are using cache before adding to layer + if (!caching) { + if (layer) { + layer._applyTransform(this, context, top); + } else { + var o = this.getAbsoluteTransform(top).getMatrix(); + context.transform(o[0], o[1], o[2], o[3], o[4], o[5]); + } + } + + if (hasShadow && hasStroke && !canvas.hitCanvas) { + context.save(); + // apply shadow + if (!caching) { + context._applyOpacity(this); + } + context._applyShadow(this); + drawFunc.call(this, context); + context.restore(); + // if shape has stroke we need to redraw shape + // otherwise we will see a shadow under stroke (and over fill) + // but I think this is unexpected behavior + if (this.hasFill() && this.getShadowForStrokeEnabled()) { + drawFunc.call(this, context); + } + } else if (hasShadow && !canvas.hitCanvas) { + context.save(); + if (!caching) { + context._applyOpacity(this); + } + context._applyShadow(this); + drawFunc.call(this, context); + context.restore(); + } else { + if (!caching) { + context._applyOpacity(this); + } + drawFunc.call(this, context); + } + } + context.restore(); + return this; + }, + drawHit: function(can, top, caching) { + var layer = this.getLayer(), + canvas = can || layer.hitCanvas, + context = canvas.getContext(), + drawFunc = this.hitFunc() || this.sceneFunc(), + cachedCanvas = this._cache.canvas, + cachedHitCanvas = cachedCanvas && cachedCanvas.hit; + + if(!this.shouldDrawHit(canvas)) { + return this; + } + if (layer) { + layer.clearHitCache(); + } + if (cachedHitCanvas) { + context.save(); + layer._applyTransform(this, context, top); + this._drawCachedHitCanvas(context); + context.restore(); + return this; + } + if (!drawFunc) { + return this; + } + context.save(); + context._applyLineJoin(this); + if (!caching) { + if (layer) { + layer._applyTransform(this, context, top); + } else { + var o = this.getAbsoluteTransform(top).getMatrix(); + context.transform(o[0], o[1], o[2], o[3], o[4], o[5]); + } + } + drawFunc.call(this, context); + context.restore(); + return this; + }, + /** + * draw hit graph using the cached scene canvas + * @method + * @memberof Konva.Shape.prototype + * @param {Integer} alphaThreshold alpha channel threshold that determines whether or not + * a pixel should be drawn onto the hit graph. Must be a value between 0 and 255. + * The default is 0 + * @returns {Konva.Shape} + * @example + * shape.cache(); + * shape.drawHitFromCache(); + */ + drawHitFromCache: function(alphaThreshold) { + var threshold = alphaThreshold || 0, + cachedCanvas = this._cache.canvas, + sceneCanvas = this._getCachedSceneCanvas(), + hitCanvas = cachedCanvas.hit, + hitContext = hitCanvas.getContext(), + hitWidth = hitCanvas.getWidth(), + hitHeight = hitCanvas.getHeight(), + hitImageData, hitData, len, rgbColorKey, i, alpha; + + hitContext.clear(); + hitContext.drawImage(sceneCanvas._canvas, 0, 0, hitWidth, hitHeight); + + try { + hitImageData = hitContext.getImageData(0, 0, hitWidth, hitHeight); + hitData = hitImageData.data; + len = hitData.length; + rgbColorKey = Konva.Util._hexToRgb(this.colorKey); + + // replace non transparent pixels with color key + for(i = 0; i < len; i += 4) { + alpha = hitData[i + 3]; + if (alpha > threshold) { + hitData[i] = rgbColorKey.r; + hitData[i + 1] = rgbColorKey.g; + hitData[i + 2] = rgbColorKey.b; + hitData[i + 3] = 255; + } + else { + hitData[i + 3] = 0; + } + } + hitContext.putImageData(hitImageData, 0, 0); + } + catch(e) { + Konva.Util.error('Unable to draw hit graph from cached scene canvas. ' + e.message); + } + + return this; + } + }); + Konva.Util.extend(Konva.Shape, Konva.Node); + + // add getters and setters + Konva.Factory.addGetterSetter(Konva.Shape, 'stroke'); + + /** + * get/set stroke color + * @name stroke + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get stroke color + * var stroke = shape.stroke(); + * + * // set stroke color with color string + * shape.stroke('green'); + * + * // set stroke color with hex + * shape.stroke('#00ff00'); + * + * // set stroke color with rgb + * shape.stroke('rgb(0,255,0)'); + * + * // set stroke color with rgba and make it 50% opaque + * shape.stroke('rgba(0,255,0,0.5'); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'strokeAlpha', 1, Konva.Validators.alphaComponent); + + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeWidth', 2); + + /** + * get/set stroke width + * @name strokeWidth + * @method + * @memberof Konva.Shape.prototype + * @param {Number} strokeWidth + * @returns {Number} + * @example + * // get stroke width + * var strokeWidth = shape.strokeWidth(); + * + * // set stroke width + * shape.strokeWidth(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeHitEnabled', true); + + /** + * get/set strokeHitEnabled property. Useful for performance optimization. + * You may set `shape.strokeHitEnabled(false)`. In this case stroke will be no draw on hit canvas, so hit area + * of shape will be decreased (by lineWidth / 2). Remember that non closed line with `strokeHitEnabled = false` + * will be not drawn on hit canvas, that is mean line will no trigger pointer events (like mouseover) + * Default value is true + * @name strokeHitEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} strokeHitEnabled + * @returns {Boolean} + * @example + * // get strokeHitEnabled + * var strokeHitEnabled = shape.strokeHitEnabled(); + * + * // set strokeHitEnabled + * shape.strokeHitEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'perfectDrawEnabled', true); + + /** + * get/set perfectDrawEnabled. If a shape has fill, stroke and opacity you may set `perfectDrawEnabled` to improve performance. + * See http://konvajs.github.io/docs/performance/Disable_Perfect_Draw.html for more information. + * Default value is true + * @name perfectDrawEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} perfectDrawEnabled + * @returns {Boolean} + * @example + * // get perfectDrawEnabled + * var perfectDrawEnabled = shape.perfectDrawEnabled(); + * + * // set perfectDrawEnabled + * shape.perfectDrawEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowForStrokeEnabled', true); + + /** + * get/set shadowForStrokeEnabled. Useful for performance optimization. + * You may set `shape.shadowForStrokeEnabled(false)`. In this case stroke will be no draw shadow for stroke. + * Remember if you set `shadowForStrokeEnabled = false` for non closed line - that line with have no shadow!. + * Default value is true + * @name shadowForStrokeEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} shadowForStrokeEnabled + * @returns {Boolean} + * @example + * // get shadowForStrokeEnabled + * var shadowForStrokeEnabled = shape.shadowForStrokeEnabled(); + * + * // set shadowForStrokeEnabled + * shape.shadowForStrokeEnabled(); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'lineJoin'); + + /** + * get/set line join. Can be miter, round, or bevel. The + * default is miter + * @name lineJoin + * @method + * @memberof Konva.Shape.prototype + * @param {String} lineJoin + * @returns {String} + * @example + * // get line join + * var lineJoin = shape.lineJoin(); + * + * // set line join + * shape.lineJoin('round'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'lineCap'); + + /** + * get/set line cap. Can be butt, round, or square + * @name lineCap + * @method + * @memberof Konva.Shape.prototype + * @param {String} lineCap + * @returns {String} + * @example + * // get line cap + * var lineCap = shape.lineCap(); + * + * // set line cap + * shape.lineCap('round'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'sceneFunc'); + + /** + * get/set scene draw function + * @name sceneFunc + * @method + * @memberof Konva.Shape.prototype + * @param {Function} drawFunc drawing function + * @returns {Function} + * @example + * // get scene draw function + * var sceneFunc = shape.sceneFunc(); + * + * // set scene draw function + * shape.sceneFunc(function(context) { + * context.beginPath(); + * context.rect(0, 0, this.width(), this.height()); + * context.closePath(); + * context.fillStrokeShape(this); + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'hitFunc'); + + /** + * get/set hit draw function + * @name hitFunc + * @method + * @memberof Konva.Shape.prototype + * @param {Function} drawFunc drawing function + * @returns {Function} + * @example + * // get hit draw function + * var hitFunc = shape.hitFunc(); + * + * // set hit draw function + * shape.hitFunc(function(context) { + * context.beginPath(); + * context.rect(0, 0, this.width(), this.height()); + * context.closePath(); + * context.fillStrokeShape(this); + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'dash'); + + /** + * get/set dash array for stroke. + * @name dash + * @method + * @memberof Konva.Shape.prototype + * @param {Array} dash + * @returns {Array} + * @example + * // apply dashed stroke that is 10px long and 5 pixels apart + * line.dash([10, 5]); + * // apply dashed stroke that is made up of alternating dashed + * // lines that are 10px long and 20px apart, and dots that have + * // a radius of 5px and are 20px apart + * line.dash([10, 20, 0.001, 20]); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowColor'); + + /** + * get/set shadow color + * @name shadowColor + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get shadow color + * var shadow = shape.shadowColor(); + * + * // set shadow color with color string + * shape.shadowColor('green'); + * + * // set shadow color with hex + * shape.shadowColor('#00ff00'); + * + * // set shadow color with rgb + * shape.shadowColor('rgb(0,255,0)'); + * + * // set shadow color with rgba and make it 50% opaque + * shape.shadowColor('rgba(0,255,0,0.5'); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'shadowAlpha', 1, Konva.Validators.alphaComponent); + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowBlur'); + + /** + * get/set shadow blur + * @name shadowBlur + * @method + * @memberof Konva.Shape.prototype + * @param {Number} blur + * @returns {Number} + * @example + * // get shadow blur + * var shadowBlur = shape.shadowBlur(); + * + * // set shadow blur + * shape.shadowBlur(10); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOpacity'); + + /** + * get/set shadow opacity. must be a value between 0 and 1 + * @name shadowOpacity + * @method + * @memberof Konva.Shape.prototype + * @param {Number} opacity + * @returns {Number} + * @example + * // get shadow opacity + * var shadowOpacity = shape.shadowOpacity(); + * + * // set shadow opacity + * shape.shadowOpacity(0.5); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'shadowOffset', ['x', 'y']); + + /** + * get/set shadow offset + * @name shadowOffset + * @method + * @memberof Konva.Shape.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get shadow offset + * var shadowOffset = shape.shadowOffset(); + * + * // set shadow offset + * shape.shadowOffset({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOffsetX', 0); + + /** + * get/set shadow offset x + * @name shadowOffsetX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get shadow offset x + * var shadowOffsetX = shape.shadowOffsetX(); + * + * // set shadow offset x + * shape.shadowOffsetX(5); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowOffsetY', 0); + + /** + * get/set shadow offset y + * @name shadowOffsetY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get shadow offset y + * var shadowOffsetY = shape.shadowOffsetY(); + * + * // set shadow offset y + * shape.shadowOffsetY(5); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternImage'); + + /** + * get/set fill pattern image + * @name fillPatternImage + * @method + * @memberof Konva.Shape.prototype + * @param {Image} image object + * @returns {Image} + * @example + * // get fill pattern image + * var fillPatternImage = shape.fillPatternImage(); + * + * // set fill pattern image + * var imageObj = new Image(); + * imageObj.onload = function() { + * shape.fillPatternImage(imageObj); + * }; + * imageObj.src = 'path/to/image/jpg'; + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fill'); + + /** + * get/set fill color + * @name fill + * @method + * @memberof Konva.Shape.prototype + * @param {String} color + * @returns {String} + * @example + * // get fill color + * var fill = shape.fill(); + * + * // set fill color with color string + * shape.fill('green'); + * + * // set fill color with hex + * shape.fill('#00ff00'); + * + * // set fill color with rgb + * shape.fill('rgb(0,255,0)'); + * + * // set fill color with rgba and make it 50% opaque + * shape.fill('rgba(0,255,0,0.5'); + * + * // shape without fill + * shape.fill(null); + */ + + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillRed', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillGreen', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillBlue', 0, Konva.Validators.RGBComponent); + Konva.Factory.addDeprecatedGetterSetter(Konva.Shape, 'fillAlpha', 1, Konva.Validators.alphaComponent); + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternX', 0); + + /** + * get/set fill pattern x + * @name fillPatternX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern x + * var fillPatternX = shape.fillPatternX(); + * // set fill pattern x + * shape.fillPatternX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternY', 0); + + /** + * get/set fill pattern y + * @name fillPatternY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern y + * var fillPatternY = shape.fillPatternY(); + * // set fill pattern y + * shape.fillPatternY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientColorStops'); + + /** + * get/set fill linear gradient color stops + * @name fillLinearGradientColorStops + * @method + * @memberof Konva.Shape.prototype + * @param {Array} colorStops + * @returns {Array} colorStops + * @example + * // get fill linear gradient color stops + * var colorStops = shape.fillLinearGradientColorStops(); + * + * // create a linear gradient that starts with red, changes to blue + * // halfway through, and then changes to green + * shape.fillLinearGradientColorStops(0, 'red', 0.5, 'blue', 1, 'green'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartRadius', 0); + + /** + * get/set fill radial gradient start radius + * @name fillRadialGradientStartRadius + * @method + * @memberof Konva.Shape.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radial gradient start radius + * var startRadius = shape.fillRadialGradientStartRadius(); + * + * // set radial gradient start radius + * shape.fillRadialGradientStartRadius(0); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndRadius', 0); + + /** + * get/set fill radial gradient end radius + * @name fillRadialGradientEndRadius + * @method + * @memberof Konva.Shape.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radial gradient end radius + * var endRadius = shape.fillRadialGradientEndRadius(); + * + * // set radial gradient end radius + * shape.fillRadialGradientEndRadius(100); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientColorStops'); + + /** + * get/set fill radial gradient color stops + * @name fillRadialGradientColorStops + * @method + * @memberof Konva.Shape.prototype + * @param {Number} colorStops + * @returns {Array} + * @example + * // get fill radial gradient color stops + * var colorStops = shape.fillRadialGradientColorStops(); + * + * // create a radial gradient that starts with red, changes to blue + * // halfway through, and then changes to green + * shape.fillRadialGradientColorStops(0, 'red', 0.5, 'blue', 1, 'green'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternRepeat', 'repeat'); + + /** + * get/set fill pattern repeat. Can be 'repeat', 'repeat-x', 'repeat-y', or 'no-repeat'. The default is 'repeat' + * @name fillPatternRepeat + * @method + * @memberof Konva.Shape.prototype + * @param {String} repeat + * @returns {String} + * @example + * // get fill pattern repeat + * var repeat = shape.fillPatternRepeat(); + * + * // repeat pattern in x direction only + * shape.fillPatternRepeat('repeat-x'); + * + * // do not repeat the pattern + * shape.fillPatternRepeat('no repeat'); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillEnabled', true); + + /** + * get/set fill enabled flag + * @name fillEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get fill enabled flag + * var fillEnabled = shape.fillEnabled(); + * + * // disable fill + * shape.fillEnabled(false); + * + * // enable fill + * shape.fillEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeEnabled', true); + + /** + * get/set stroke enabled flag + * @name strokeEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get stroke enabled flag + * var strokeEnabled = shape.strokeEnabled(); + * + * // disable stroke + * shape.strokeEnabled(false); + * + * // enable stroke + * shape.strokeEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'shadowEnabled', true); + + /** + * get/set shadow enabled flag + * @name shadowEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get shadow enabled flag + * var shadowEnabled = shape.shadowEnabled(); + * + * // disable shadow + * shape.shadowEnabled(false); + * + * // enable shadow + * shape.shadowEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'dashEnabled', true); + + /** + * get/set dash enabled flag + * @name dashEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get dash enabled flag + * var dashEnabled = shape.dashEnabled(); + * + * // disable dash + * shape.dashEnabled(false); + * + * // enable dash + * shape.dashEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'strokeScaleEnabled', true); + + /** + * get/set strokeScale enabled flag + * @name strokeScaleEnabled + * @method + * @memberof Konva.Shape.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get stroke scale enabled flag + * var strokeScaleEnabled = shape.strokeScaleEnabled(); + * + * // disable stroke scale + * shape.strokeScaleEnabled(false); + * + * // enable stroke scale + * shape.strokeScaleEnabled(true); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPriority', 'color'); + + /** + * get/set fill priority. can be color, pattern, linear-gradient, or radial-gradient. The default is color. + * This is handy if you want to toggle between different fill types. + * @name fillPriority + * @method + * @memberof Konva.Shape.prototype + * @param {String} priority + * @returns {String} + * @example + * // get fill priority + * var fillPriority = shape.fillPriority(); + * + * // set fill priority + * shape.fillPriority('linear-gradient'); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillPatternOffset', ['x', 'y']); + + /** + * get/set fill pattern offset + * @name fillPatternOffset + * @method + * @memberof Konva.Shape.prototype + * @param {Object} offset + * @param {Number} offset.x + * @param {Number} offset.y + * @returns {Object} + * @example + * // get fill pattern offset + * var patternOffset = shape.fillPatternOffset(); + * + * // set fill pattern offset + * shape.fillPatternOffset({ + * x: 20 + * y: 10 + * }); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternOffsetX', 0); + /** + * get/set fill pattern offset x + * @name fillPatternOffsetX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern offset x + * var patternOffsetX = shape.fillPatternOffsetX(); + * + * // set fill pattern offset x + * shape.fillPatternOffsetX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternOffsetY', 0); + /** + * get/set fill pattern offset y + * @name fillPatternOffsetY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern offset y + * var patternOffsetY = shape.fillPatternOffsetY(); + * + * // set fill pattern offset y + * shape.fillPatternOffsetY(10); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillPatternScale', ['x', 'y']); + + /** + * get/set fill pattern scale + * @name fillPatternScale + * @method + * @memberof Konva.Shape.prototype + * @param {Object} scale + * @param {Number} scale.x + * @param {Number} scale.y + * @returns {Object} + * @example + * // get fill pattern scale + * var patternScale = shape.fillPatternScale(); + * + * // set fill pattern scale + * shape.fillPatternScale({ + * x: 2 + * y: 2 + * }); + */ + + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternScaleX', 1); + /** + * get/set fill pattern scale x + * @name fillPatternScaleX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill pattern scale x + * var patternScaleX = shape.fillPatternScaleX(); + * + * // set fill pattern scale x + * shape.fillPatternScaleX(2); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternScaleY', 1); + /** + * get/set fill pattern scale y + * @name fillPatternScaleY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill pattern scale y + * var patternScaleY = shape.fillPatternScaleY(); + * + * // set fill pattern scale y + * shape.fillPatternScaleY(2); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillLinearGradientStartPoint', ['x', 'y']); + + /** + * get/set fill linear gradient start point + * @name fillLinearGradientStartPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} startPoint + * @param {Number} startPoint.x + * @param {Number} startPoint.y + * @returns {Object} + * @example + * // get fill linear gradient start point + * var startPoint = shape.fillLinearGradientStartPoint(); + * + * // set fill linear gradient start point + * shape.fillLinearGradientStartPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientStartPointX', 0); + /** + * get/set fill linear gradient start point x + * @name fillLinearGradientStartPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill linear gradient start point x + * var startPointX = shape.fillLinearGradientStartPointX(); + * + * // set fill linear gradient start point x + * shape.fillLinearGradientStartPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientStartPointY', 0); + /** + * get/set fill linear gradient start point y + * @name fillLinearGradientStartPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill linear gradient start point y + * var startPointY = shape.fillLinearGradientStartPointY(); + * + * // set fill linear gradient start point y + * shape.fillLinearGradientStartPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillLinearGradientEndPoint', ['x', 'y']); + + /** + * get/set fill linear gradient end point + * @name fillLinearGradientEndPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} endPoint + * @param {Number} endPoint.x + * @param {Number} endPoint.y + * @returns {Object} + * @example + * // get fill linear gradient end point + * var endPoint = shape.fillLinearGradientEndPoint(); + * + * // set fill linear gradient end point + * shape.fillLinearGradientEndPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientEndPointX', 0); + /** + * get/set fill linear gradient end point x + * @name fillLinearGradientEndPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill linear gradient end point x + * var endPointX = shape.fillLinearGradientEndPointX(); + * + * // set fill linear gradient end point x + * shape.fillLinearGradientEndPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillLinearGradientEndPointY', 0); + /** + * get/set fill linear gradient end point y + * @name fillLinearGradientEndPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill linear gradient end point y + * var endPointY = shape.fillLinearGradientEndPointY(); + * + * // set fill linear gradient end point y + * shape.fillLinearGradientEndPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillRadialGradientStartPoint', ['x', 'y']); + + /** + * get/set fill radial gradient start point + * @name fillRadialGradientStartPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} startPoint + * @param {Number} startPoint.x + * @param {Number} startPoint.y + * @returns {Object} + * @example + * // get fill radial gradient start point + * var startPoint = shape.fillRadialGradientStartPoint(); + * + * // set fill radial gradient start point + * shape.fillRadialGradientStartPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartPointX', 0); + /** + * get/set fill radial gradient start point x + * @name fillRadialGradientStartPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill radial gradient start point x + * var startPointX = shape.fillRadialGradientStartPointX(); + * + * // set fill radial gradient start point x + * shape.fillRadialGradientStartPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientStartPointY', 0); + /** + * get/set fill radial gradient start point y + * @name fillRadialGradientStartPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill radial gradient start point y + * var startPointY = shape.fillRadialGradientStartPointY(); + * + * // set fill radial gradient start point y + * shape.fillRadialGradientStartPointY(20); + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Shape, 'fillRadialGradientEndPoint', ['x', 'y']); + + /** + * get/set fill radial gradient end point + * @name fillRadialGradientEndPoint + * @method + * @memberof Konva.Shape.prototype + * @param {Object} endPoint + * @param {Number} endPoint.x + * @param {Number} endPoint.y + * @returns {Object} + * @example + * // get fill radial gradient end point + * var endPoint = shape.fillRadialGradientEndPoint(); + * + * // set fill radial gradient end point + * shape.fillRadialGradientEndPoint({ + * x: 20 + * y: 10 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndPointX', 0); + /** + * get/set fill radial gradient end point x + * @name fillRadialGradientEndPointX + * @method + * @memberof Konva.Shape.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get fill radial gradient end point x + * var endPointX = shape.fillRadialGradientEndPointX(); + * + * // set fill radial gradient end point x + * shape.fillRadialGradientEndPointX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillRadialGradientEndPointY', 0); + /** + * get/set fill radial gradient end point y + * @name fillRadialGradientEndPointY + * @method + * @memberof Konva.Shape.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get fill radial gradient end point y + * var endPointY = shape.fillRadialGradientEndPointY(); + * + * // set fill radial gradient end point y + * shape.fillRadialGradientEndPointY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Shape, 'fillPatternRotation', 0); + + /** + * get/set fill pattern rotation in degrees + * @name fillPatternRotation + * @method + * @memberof Konva.Shape.prototype + * @param {Number} rotation + * @returns {Konva.Shape} + * @example + * // get fill pattern rotation + * var patternRotation = shape.fillPatternRotation(); + * + * // set fill pattern rotation + * shape.fillPatternRotation(20); + */ + + + Konva.Factory.backCompat(Konva.Shape, { + dashArray: 'dash', + getDashArray: 'getDash', + setDashArray: 'getDash', + + drawFunc: 'sceneFunc', + getDrawFunc: 'getSceneFunc', + setDrawFunc: 'setSceneFunc', + + drawHitFunc: 'hitFunc', + getDrawHitFunc: 'getHitFunc', + setDrawHitFunc: 'setHitFunc' + }); + + Konva.Collection.mapMethods(Konva.Shape); +})(Konva); + +(function() { + 'use strict'; + // CONSTANTS + var STAGE = 'Stage', + STRING = 'string', + PX = 'px', + + MOUSEOUT = 'mouseout', + MOUSELEAVE = 'mouseleave', + MOUSEOVER = 'mouseover', + MOUSEENTER = 'mouseenter', + MOUSEMOVE = 'mousemove', + MOUSEDOWN = 'mousedown', + MOUSEUP = 'mouseup', + CLICK = 'click', + DBL_CLICK = 'dblclick', + TOUCHSTART = 'touchstart', + TOUCHEND = 'touchend', + TAP = 'tap', + DBL_TAP = 'dbltap', + TOUCHMOVE = 'touchmove', + DOMMOUSESCROLL = 'DOMMouseScroll', + MOUSEWHEEL = 'mousewheel', + WHEEL = 'wheel', + + CONTENT_MOUSEOUT = 'contentMouseout', + CONTENT_MOUSEOVER = 'contentMouseover', + CONTENT_MOUSEMOVE = 'contentMousemove', + CONTENT_MOUSEDOWN = 'contentMousedown', + CONTENT_MOUSEUP = 'contentMouseup', + CONTENT_CLICK = 'contentClick', + CONTENT_DBL_CLICK = 'contentDblclick', + CONTENT_TOUCHSTART = 'contentTouchstart', + CONTENT_TOUCHEND = 'contentTouchend', + CONTENT_DBL_TAP = 'contentDbltap', + CONTENT_TAP = 'contentTap', + CONTENT_TOUCHMOVE = 'contentTouchmove', + CONTENT_WHEEL = 'contentWheel', + + DIV = 'div', + RELATIVE = 'relative', + KONVA_CONTENT = 'konvajs-content', + SPACE = ' ', + UNDERSCORE = '_', + CONTAINER = 'container', + EMPTY_STRING = '', + EVENTS = [MOUSEDOWN, MOUSEMOVE, MOUSEUP, MOUSEOUT, TOUCHSTART, TOUCHMOVE, TOUCHEND, MOUSEOVER, DOMMOUSESCROLL, MOUSEWHEEL, WHEEL], + + // cached variables + eventsLength = EVENTS.length; + + function addEvent(ctx, eventName) { + ctx.content.addEventListener(eventName, function(evt) { + ctx[UNDERSCORE + eventName](evt); + }, false); + } + + /** + * Stage constructor. A stage is used to contain multiple layers + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {String|Element} config.container Container selector or DOM element + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var stage = new Konva.Stage({ + * width: 500, + * height: 800, + * container: 'containerId' // or "#containerId" or ".containerClass" + * }); + */ + Konva.Stage = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.Stage, { + ___init: function(config) { + this.nodeType = STAGE; + // call super constructor + Konva.Container.call(this, config); + this._id = Konva.idCounter++; + this._buildDOM(); + this._bindContentEvents(); + this._enableNestedTransforms = false; + Konva.stages.push(this); + }, + _validateAdd: function(child) { + if (child.getType() !== 'Layer') { + Konva.Util.throw('You may only add layers to the stage.'); + } + }, + /** + * set container dom element which contains the stage wrapper div element + * @method + * @memberof Konva.Stage.prototype + * @param {DomElement} container can pass in a dom element or id string + */ + setContainer: function (container) { + if (typeof container === STRING) { + if (container.charAt(0) === '.') { + var className = container.slice(1); + container = Konva.document.getElementsByClassName(className)[0]; + } else { + var id; + if (container.charAt(0) !== '#') { + id = container; + } else { + id = container.slice(1); + } + container = Konva.document.getElementById(id); + } + if (!container) { + throw 'Can not find container in document with id ' + id; + } + } + this._setAttr(CONTAINER, container); + return this; + }, + shouldDrawHit: function() { + return true; + }, + draw: function() { + Konva.Node.prototype.draw.call(this); + return this; + }, + /** + * draw layer scene graphs + * @name draw + * @method + * @memberof Konva.Stage.prototype + */ + + /** + * draw layer hit graphs + * @name drawHit + * @method + * @memberof Konva.Stage.prototype + */ + + /** + * set height + * @method + * @memberof Konva.Stage.prototype + * @param {Number} height + */ + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + this._resizeDOM(); + return this; + }, + /** + * set width + * @method + * @memberof Konva.Stage.prototype + * @param {Number} width + */ + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + this._resizeDOM(); + return this; + }, + /** + * clear all layers + * @method + * @memberof Konva.Stage.prototype + */ + clear: function() { + var layers = this.children, + len = layers.length, + n; + + for(n = 0; n < len; n++) { + layers[n].clear(); + } + return this; + }, + clone: function(obj) { + if (!obj) { + obj = {}; + } + obj.container = Konva.document.createElement(DIV); + return Konva.Container.prototype.clone.call(this, obj); + }, + /** + * destroy stage + * @method + * @memberof Konva.Stage.prototype + */ + destroy: function() { + var content = this.content; + Konva.Container.prototype.destroy.call(this); + + if(content && Konva.Util._isInDocument(content)) { + this.getContainer().removeChild(content); + } + var index = Konva.stages.indexOf(this); + if (index > -1) { + Konva.stages.splice(index, 1); + } + return this; + }, + /** + * get pointer position which can be a touch position or mouse position + * @method + * @memberof Konva.Stage.prototype + * @returns {Object} + */ + getPointerPosition: function() { + return this.pointerPos; + }, + getStage: function() { + return this; + }, + /** + * get stage content div element which has the + * the class name "konvajs-content" + * @method + * @memberof Konva.Stage.prototype + */ + getContent: function() { + return this.content; + }, + /** + * Creates a composite data URL + * @method + * @memberof Konva.Stage.prototype + * @param {Object} config + * @param {Function} [config.callback] function executed when the composite has completed. Deprecated as method is sync now. + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + */ + toDataURL: function(config) { + config = config || {}; + + var mimeType = config.mimeType || null, + quality = config.quality || null, + x = config.x || 0, + y = config.y || 0, + canvas = new Konva.SceneCanvas({ + width: config.width || this.getWidth(), + height: config.height || this.getHeight(), + pixelRatio: config.pixelRatio + }), + _context = canvas.getContext()._context, + layers = this.children; + + if(x || y) { + _context.translate(-1 * x, -1 * y); + } + + + layers.each(function(layer) { + var width = layer.getCanvas().getWidth(); + var height = layer.getCanvas().getHeight(); + var ratio = layer.getCanvas().getPixelRatio(); + _context.drawImage(layer.getCanvas()._canvas, 0, 0, width / ratio, height / ratio); + }); + var src = canvas.toDataURL(mimeType, quality); + + if (config.callback) { + config.callback(src); + } + + return src; + }, + /** + * converts stage into an image. + * @method + * @memberof Konva.Stage.prototype + * @param {Object} config + * @param {Function} config.callback function executed when the composite has completed + * @param {String} [config.mimeType] can be "image/png" or "image/jpeg". + * "image/png" is the default + * @param {Number} [config.x] x position of canvas section + * @param {Number} [config.y] y position of canvas section + * @param {Number} [config.width] width of canvas section + * @param {Number} [config.height] height of canvas section + * @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType, + * you can specify the quality from 0 to 1, where 0 is very poor quality and 1 + * is very high quality + */ + toImage: function(config) { + var cb = config.callback; + + config.callback = function(dataUrl) { + Konva.Util._getImage(dataUrl, function(img) { + cb(img); + }); + }; + this.toDataURL(config); + }, + /** + * get visible intersection shape. This is the preferred + * method for determining if a point intersects a shape or not + * @method + * @memberof Konva.Stage.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @param {String} [selector] + * @returns {Konva.Node} + * @example + * var shape = stage.getIntersection({x: 50, y: 50}); + * // or if you interested in shape parent: + * var group = stage.getIntersection({x: 50, y: 50}, 'Group'); + */ + getIntersection: function(pos, selector) { + var layers = this.getChildren(), + len = layers.length, + end = len - 1, + n, shape; + + for(n = end; n >= 0; n--) { + shape = layers[n].getIntersection(pos, selector); + if (shape) { + return shape; + } + } + + return null; + }, + _resizeDOM: function() { + if(this.content) { + var width = this.getWidth(), + height = this.getHeight(), + layers = this.getChildren(), + len = layers.length, + n, layer; + + // set content dimensions + this.content.style.width = width + PX; + this.content.style.height = height + PX; + + this.bufferCanvas.setSize(width, height); + this.bufferHitCanvas.setSize(width, height); + + // set layer dimensions + for(n = 0; n < len; n++) { + layer = layers[n]; + layer.setSize(width, height); + layer.draw(); + } + } + }, + /** + * add layer or layers to stage + * @method + * @memberof Konva.Stage.prototype + * @param {...Konva.Layer} layer + * @example + * stage.add(layer1, layer2, layer3); + */ + add: function(layer) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.add(arguments[i]); + } + return this; + } + Konva.Container.prototype.add.call(this, layer); + layer._setCanvasSize(this.width(), this.height()); + + // draw layer and append canvas to container + layer.draw(); + this.content.appendChild(layer.canvas._canvas); + + // chainable + return this; + }, + getParent: function() { + return null; + }, + getLayer: function() { + return null; + }, + /** + * returns a {@link Konva.Collection} of layers + * @method + * @memberof Konva.Stage.prototype + */ + getLayers: function() { + return this.getChildren(); + }, + _bindContentEvents: function() { + for (var n = 0; n < eventsLength; n++) { + addEvent(this, EVENTS[n]); + } + }, + _mouseover: function(evt) { + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + this._fire(CONTENT_MOUSEOVER, {evt: evt}); + } + }, + _mouseout: function(evt) { + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var targetShape = this.targetShape; + + if(targetShape && !Konva.isDragging()) { + targetShape._fireAndBubble(MOUSEOUT, {evt: evt}); + targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}); + this.targetShape = null; + } + this.pointerPos = undefined; + + this._fire(CONTENT_MOUSEOUT, {evt: evt}); + } + }, + _mousemove: function(evt) { + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchmove(evt); + } + // workaround fake mousemove event in chrome browser https://code.google.com/p/chromium/issues/detail?id=161464 + if ((typeof evt.movementX !== 'undefined' || typeof evt.movementY !== 'undefined') && evt.movementY === 0 && evt.movementX === 0) { + return null; + } + if (Konva.UA.mobile) { + return null; + } + this._setPointerPosition(evt); + var dd = Konva.DD, shape; + + if (!Konva.isDragging()) { + shape = this.getIntersection(this.getPointerPosition()); + if(shape && shape.isListening()) { + if(!Konva.isDragging() && (!this.targetShape || this.targetShape._id !== shape._id)) { + if(this.targetShape) { + this.targetShape._fireAndBubble(MOUSEOUT, {evt: evt}, shape); + this.targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}, shape); + } + shape._fireAndBubble(MOUSEOVER, {evt: evt}, this.targetShape); + shape._fireAndBubble(MOUSEENTER, {evt: evt}, this.targetShape); + this.targetShape = shape; + } + else { + shape._fireAndBubble(MOUSEMOVE, {evt: evt}); + } + } + /* + * if no shape was detected, clear target shape and try + * to run mouseout from previous target shape + */ + else { + if(this.targetShape && !Konva.isDragging()) { + this.targetShape._fireAndBubble(MOUSEOUT, {evt: evt}); + this.targetShape._fireAndBubble(MOUSELEAVE, {evt: evt}); + this.targetShape = null; + } + + } + + // content event + this._fire(CONTENT_MOUSEMOVE, {evt: evt}); + } + if(dd) { + dd._drag(evt); + } + + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _mousedown: function(evt) { + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchstart(evt); + } + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + Konva.listenClickTap = true; + + if (shape && shape.isListening()) { + this.clickStartShape = shape; + shape._fireAndBubble(MOUSEDOWN, {evt: evt}); + } + + // content event + this._fire(CONTENT_MOUSEDOWN, {evt: evt}); + } + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _mouseup: function(evt) { + + // workaround for mobile IE to force touch event when unhandled pointer event elevates into a mouse event + if (Konva.UA.ieMobile) { + return this._touchend(evt); + } + if (!Konva.UA.mobile) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()), + clickStartShape = this.clickStartShape, + fireDblClick = false, + dd = Konva.DD; + + if(Konva.inDblClickWindow) { + fireDblClick = true; + Konva.inDblClickWindow = false; + } + // don't set inDblClickWindow after dragging + else if (!dd || !dd.justDragged) { + Konva.inDblClickWindow = true; + } else if (dd) { + dd.justDragged = false; + } + + setTimeout(function() { + Konva.inDblClickWindow = false; + }, Konva.dblClickWindow); + + if (shape && shape.isListening()) { + shape._fireAndBubble(MOUSEUP, {evt: evt}); + + // detect if click or double click occurred + if(Konva.listenClickTap && clickStartShape && clickStartShape._id === shape._id) { + shape._fireAndBubble(CLICK, {evt: evt}); + + if(fireDblClick) { + shape._fireAndBubble(DBL_CLICK, {evt: evt}); + } + } + } + // content events + this._fire(CONTENT_MOUSEUP, {evt: evt}); + if (Konva.listenClickTap) { + this._fire(CONTENT_CLICK, {evt: evt}); + if(fireDblClick) { + this._fire(CONTENT_DBL_CLICK, {evt: evt}); + } + } + + Konva.listenClickTap = false; + } + + // always call preventDefault for desktop events because some browsers + // try to drag and drop the canvas element + if (evt.preventDefault) { + evt.preventDefault(); + } + }, + _touchstart: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + Konva.listenClickTap = true; + + if (shape && shape.isListening()) { + this.tapStartShape = shape; + shape._fireAndBubble(TOUCHSTART, {evt: evt}); + + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + // content event + this._fire(CONTENT_TOUCHSTART, {evt: evt}); + }, + _touchend: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()), + fireDblClick = false; + + if(Konva.inDblClickWindow) { + fireDblClick = true; + Konva.inDblClickWindow = false; + } + else { + Konva.inDblClickWindow = true; + } + + setTimeout(function() { + Konva.inDblClickWindow = false; + }, Konva.dblClickWindow); + + if (shape && shape.isListening()) { + shape._fireAndBubble(TOUCHEND, {evt: evt}); + + // detect if tap or double tap occurred + if(Konva.listenClickTap && shape._id === this.tapStartShape._id) { + shape._fireAndBubble(TAP, {evt: evt}); + + if(fireDblClick) { + shape._fireAndBubble(DBL_TAP, {evt: evt}); + } + } + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + // content events + this._fire(CONTENT_TOUCHEND, {evt: evt}); + if (Konva.listenClickTap) { + this._fire(CONTENT_TAP, {evt: evt}); + if(fireDblClick) { + this._fire(CONTENT_DBL_TAP, {evt: evt}); + } + } + + Konva.listenClickTap = false; + }, + _touchmove: function(evt) { + this._setPointerPosition(evt); + var dd = Konva.DD, + shape; + if (!Konva.isDragging()) { + shape = this.getIntersection(this.getPointerPosition()); + if (shape && shape.isListening()) { + shape._fireAndBubble(TOUCHMOVE, {evt: evt}); + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + this._fire(CONTENT_TOUCHMOVE, {evt: evt}); + } + if(dd) { + dd._drag(evt); + if (Konva.isDragging()) { + evt.preventDefault(); + } + } + }, + _DOMMouseScroll: function(evt) { + this._mousewheel(evt); + }, + _mousewheel: function(evt) { + this._setPointerPosition(evt); + var shape = this.getIntersection(this.getPointerPosition()); + + if (shape && shape.isListening()) { + shape._fireAndBubble(WHEEL, {evt: evt}); + } + this._fire(CONTENT_WHEEL, {evt: evt}); + }, + _wheel: function(evt) { + this._mousewheel(evt); + }, + _setPointerPosition: function(evt) { + var contentPosition = this._getContentPosition(), + x = null, + y = null; + evt = evt ? evt : window.event; + + // touch events + if(evt.touches !== undefined) { + // currently, only handle one finger + if (evt.touches.length > 0) { + + var touch = evt.touches[0]; + // get the information for finger #1 + x = touch.clientX - contentPosition.left; + y = touch.clientY - contentPosition.top; + } + } + // mouse events + else { + x = evt.clientX - contentPosition.left; + y = evt.clientY - contentPosition.top; + } + if (x !== null && y !== null) { + this.pointerPos = { + x: x, + y: y + }; + } + }, + _getContentPosition: function() { + var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top: 0, left: 0 }; + return { + top: rect.top, + left: rect.left + }; + }, + _buildDOM: function() { + var container = this.getContainer(); + if (!container) { + if (Konva.Util.isBrowser()) { + throw 'Stage has no container. A container is required.'; + } else { + // automatically create element for jsdom in nodejs env + container = Konva.document.createElement(DIV); + } + } + // clear content inside container + container.innerHTML = EMPTY_STRING; + + // content + this.content = Konva.document.createElement(DIV); + this.content.style.position = RELATIVE; + this.content.className = KONVA_CONTENT; + this.content.setAttribute('role', 'presentation'); + container.appendChild(this.content); + + // the buffer canvas pixel ratio must be 1 because it is used as an + // intermediate canvas before copying the result onto a scene canvas. + // not setting it to 1 will result in an over compensation + this.bufferCanvas = new Konva.SceneCanvas(); + this.bufferHitCanvas = new Konva.HitCanvas({pixelRatio: 1}); + + this._resizeDOM(); + }, + _onContent: function(typesStr, handler) { + var types = typesStr.split(SPACE), + len = types.length, + n, baseEvent; + + for(n = 0; n < len; n++) { + baseEvent = types[n]; + this.content.addEventListener(baseEvent, handler, false); + } + }, + // currently cache function is now working for stage, because stage has no its own canvas element + // TODO: may be it is better to cache all children layers? + cache: function() { + Konva.Util.warn('Cache function is not allowed for stage. You may use cache only for layers, groups and shapes.'); + }, + clearCache: function() { + } + }); + Konva.Util.extend(Konva.Stage, Konva.Container); + + // add getters and setters + Konva.Factory.addGetter(Konva.Stage, 'container'); + Konva.Factory.addOverloadedGetterSetter(Konva.Stage, 'container'); + + /** + * get container DOM element + * @name container + * @method + * @memberof Konva.Stage.prototype + * @returns {DomElement} container + * @example + * // get container + * var container = stage.container(); + * // set container + * var container = document.createElement('div'); + * body.appendChild(container); + * stage.container(container); + */ + +})(); + +(function() { + 'use strict'; + /** + * BaseLayer constructor. + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.Layer(); + */ + Konva.BaseLayer = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.BaseLayer, { + ___init: function(config) { + this.nodeType = 'Layer'; + Konva.Container.call(this, config); + }, + createPNGStream: function() { + return this.canvas._canvas.createPNGStream(); + }, + /** + * get layer canvas + * @method + * @memberof Konva.BaseLayer.prototype + */ + getCanvas: function() { + return this.canvas; + }, + /** + * get layer hit canvas + * @method + * @memberof Konva.BaseLayer.prototype + */ + getHitCanvas: function() { + return this.hitCanvas; + }, + /** + * get layer canvas context + * @method + * @memberof Konva.BaseLayer.prototype + */ + getContext: function() { + return this.getCanvas().getContext(); + }, + /** + * clear scene and hit canvas contexts tied to the layer + * @method + * @memberof Konva.BaseLayer.prototype + * @param {Object} [bounds] + * @param {Number} [bounds.x] + * @param {Number} [bounds.y] + * @param {Number} [bounds.width] + * @param {Number} [bounds.height] + * @example + * layer.clear(); + * layer.clear({ + * x : 0, + * y : 0, + * width : 100, + * height : 100 + * }); + */ + clear: function(bounds) { + this.getContext().clear(bounds); + return this; + }, + clearHitCache: function() { + this._hitImageData = undefined; + }, + // extend Node.prototype.setZIndex + setZIndex: function(index) { + Konva.Node.prototype.setZIndex.call(this, index); + var stage = this.getStage(); + if(stage) { + stage.content.removeChild(this.getCanvas()._canvas); + + if(index < stage.getChildren().length - 1) { + stage.content.insertBefore(this.getCanvas()._canvas, stage.getChildren()[index + 1].getCanvas()._canvas); + } + else { + stage.content.appendChild(this.getCanvas()._canvas); + } + } + return this; + }, + // extend Node.prototype.moveToTop + moveToTop: function() { + Konva.Node.prototype.moveToTop.call(this); + var stage = this.getStage(); + if(stage) { + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.appendChild(this.getCanvas()._canvas); + } + return this; + }, + // extend Node.prototype.moveUp + moveUp: function() { + var moved = Konva.Node.prototype.moveUp.call(this); + if (!moved){ + return this; + } + var stage = this.getStage(); + if(!stage) { + return this; + } + stage.content.removeChild(this.getCanvas()._canvas); + + if(this.index < stage.getChildren().length - 1) { + stage.content.insertBefore(this.getCanvas()._canvas, stage.getChildren()[this.index + 1].getCanvas()._canvas); + } else { + stage.content.appendChild(this.getCanvas()._canvas); + } + return this; + }, + // extend Node.prototype.moveDown + moveDown: function() { + if(Konva.Node.prototype.moveDown.call(this)) { + var stage = this.getStage(); + if(stage) { + var children = stage.getChildren(); + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.insertBefore(this.getCanvas()._canvas, children[this.index + 1].getCanvas()._canvas); + } + } + return this; + }, + // extend Node.prototype.moveToBottom + moveToBottom: function() { + if(Konva.Node.prototype.moveToBottom.call(this)) { + var stage = this.getStage(); + if(stage) { + var children = stage.getChildren(); + stage.content.removeChild(this.getCanvas()._canvas); + stage.content.insertBefore(this.getCanvas()._canvas, children[1].getCanvas()._canvas); + } + } + return this; + }, + getLayer: function() { + return this; + }, + remove: function() { + var _canvas = this.getCanvas()._canvas; + + Konva.Node.prototype.remove.call(this); + + if(_canvas && _canvas.parentNode && Konva.Util._isInDocument(_canvas)) { + _canvas.parentNode.removeChild(_canvas); + } + return this; + }, + getStage: function() { + return this.parent; + }, + setSize: function(width, height) { + this.canvas.setSize(width, height); + return this; + }, + /** + * get/set width of layer.getter return width of stage. setter doing nothing. + * if you want change width use `stage.width(value);` + * @name width + * @method + * @memberof Konva.BaseLayer.prototype + * @returns {Number} + * @example + * var width = layer.width(); + */ + getWidth: function() { + if (this.parent) { + return this.parent.getWidth(); + } + }, + setWidth: function() { + Konva.Util.warn('Can not change width of layer. Use "stage.width(value)" function instead.'); + }, + /** + * get/set height of layer.getter return height of stage. setter doing nothing. + * if you want change height use `stage.height(value);` + * @name height + * @method + * @memberof Konva.BaseLayer.prototype + * @returns {Number} + * @example + * var height = layer.height(); + */ + getHeight: function() { + if (this.parent) { + return this.parent.getHeight(); + } + }, + setHeight: function() { + Konva.Util.warn('Can not change height of layer. Use "stage.height(value)" function instead.'); + }, + // the apply transform method is handled by the Layer and FastLayer class + // because it is up to the layer to decide if an absolute or relative transform + // should be used + _applyTransform: function(shape, context, top) { + var m = shape.getAbsoluteTransform(top).getMatrix(); + context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + }); + Konva.Util.extend(Konva.BaseLayer, Konva.Container); + + // add getters and setters + Konva.Factory.addGetterSetter(Konva.BaseLayer, 'clearBeforeDraw', true); + /** + * get/set clearBeforeDraw flag which determines if the layer is cleared or not + * before drawing + * @name clearBeforeDraw + * @method + * @memberof Konva.BaseLayer.prototype + * @param {Boolean} clearBeforeDraw + * @returns {Boolean} + * @example + * // get clearBeforeDraw flag + * var clearBeforeDraw = layer.clearBeforeDraw(); + * + * // disable clear before draw + * layer.clearBeforeDraw(false); + * + * // enable clear before draw + * layer.clearBeforeDraw(true); + */ + + Konva.Collection.mapMethods(Konva.BaseLayer); +})(); + +(function() { + 'use strict'; + // constants + var HASH = '#', + BEFORE_DRAW = 'beforeDraw', + DRAW = 'draw', + + /* + * 2 - 3 - 4 + * | | + * 1 - 0 5 + * | + * 8 - 7 - 6 + */ + INTERSECTION_OFFSETS = [ + {x: 0, y: 0}, // 0 + {x: -1, y: 0}, // 1 + {x: -1, y: -1}, // 2 + {x: 0, y: -1}, // 3 + {x: 1, y: -1}, // 4 + {x: 1, y: 0}, // 5 + {x: 1, y: 1}, // 6 + {x: 0, y: 1}, // 7 + {x: -1, y: 1} // 8 + ], + INTERSECTION_OFFSETS_LEN = INTERSECTION_OFFSETS.length; + + /** + * Layer constructor. Layers are tied to their own canvas element and are used + * to contain groups or shapes. + * @constructor + * @memberof Konva + * @augments Konva.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.Layer(); + */ + Konva.Layer = function(config) { + this.____init(config); + }; + + Konva.Util.addMethods(Konva.Layer, { + ____init: function(config) { + this.nodeType = 'Layer'; + this.canvas = new Konva.SceneCanvas(); + this.hitCanvas = new Konva.HitCanvas({ + pixelRatio: 1 + }); + // call super constructor + Konva.BaseLayer.call(this, config); + }, + _setCanvasSize: function(width, height) { + this.canvas.setSize(width, height); + this.hitCanvas.setSize(width, height); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Group' && type !== 'Shape') { + Konva.Util.throw('You may only add groups and shapes to a layer.'); + } + }, + /** + * get visible intersection shape. This is the preferred + * method for determining if a point intersects a shape or not + * also you may pass optional selector parametr to return ancestor of intersected shape + * @method + * @memberof Konva.Layer.prototype + * @param {Object} pos + * @param {Number} pos.x + * @param {Number} pos.y + * @param {String} [selector] + * @returns {Konva.Node} + * @example + * var shape = layer.getIntersection({x: 50, y: 50}); + * // or if you interested in shape parent: + * var group = layer.getIntersection({x: 50, y: 50}, 'Group'); + */ + getIntersection: function(pos, selector) { + var obj, i, intersectionOffset, shape; + + if(!this.hitGraphEnabled() || !this.isVisible()) { + return null; + } + // in some cases antialiased area may be bigger than 1px + // it is possible if we will cache node, then scale it a lot + // TODO: check { 0; 0 } point before loop, and remove it from INTERSECTION_OFFSETS. + var spiralSearchDistance = 1; + var continueSearch = false; + while (true) { + for (i = 0; i < INTERSECTION_OFFSETS_LEN; i++) { + intersectionOffset = INTERSECTION_OFFSETS[i]; + obj = this._getIntersection({ + x: pos.x + intersectionOffset.x * spiralSearchDistance, + y: pos.y + intersectionOffset.y * spiralSearchDistance + }); + shape = obj.shape; + if (shape && selector) { + return shape.findAncestor(selector, true); + } else if (shape) { + return shape; + } + // we should continue search if we found antialiased pixel + // that means our node somewhere very close + continueSearch = !!obj.antialiased; + // stop search if found empty pixel + if (!obj.antialiased) { + break; + } + } + // if no shape, and no antialiased pixel, we should end searching + if (continueSearch) { + spiralSearchDistance += 1; + } else { + return null; + } + } + }, + _getImageData: function(x, y) { + var width = this.hitCanvas.width || 1, + height = this.hitCanvas.height || 1, + index = (Math.round(y) * width ) + Math.round(x); + + if (!this._hitImageData) { + this._hitImageData = this.hitCanvas.context.getImageData(0, 0, width, height); + } + + return [ + this._hitImageData.data[4 * index + 0], // Red + this._hitImageData.data[4 * index + 1], // Green + this._hitImageData.data[4 * index + 2], // Blue + this._hitImageData.data[4 * index + 3] // Alpha + ]; + }, + _getIntersection: function(pos) { + var ratio = this.hitCanvas.pixelRatio; + var p = this.hitCanvas.context.getImageData(Math.round(pos.x * ratio), Math.round(pos.y * ratio), 1, 1).data, + p3 = p[3], + colorKey, shape; + // fully opaque pixel + if(p3 === 255) { + colorKey = Konva.Util._rgbToHex(p[0], p[1], p[2]); + shape = Konva.shapes[HASH + colorKey]; + if (shape) { + return { + shape: shape + }; + } + return { + antialiased: true + }; + } + // antialiased pixel + else if(p3 > 0) { + return { + antialiased: true + }; + } + // empty pixel + return {}; + }, + drawScene: function(can, top) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()); + + this._fire(BEFORE_DRAW, { + node: this + }); + + if(this.getClearBeforeDraw()) { + canvas.getContext().clear(); + } + + Konva.Container.prototype.drawScene.call(this, canvas, top); + + this._fire(DRAW, { + node: this + }); + + return this; + }, + drawHit: function(can, top) { + var layer = this.getLayer(), + canvas = can || (layer && layer.hitCanvas); + + if(layer && layer.getClearBeforeDraw()) { + layer.getHitCanvas().getContext().clear(); + } + + Konva.Container.prototype.drawHit.call(this, canvas, top); + this.imageData = null; // Clear imageData cache + return this; + }, + clear: function(bounds) { + Konva.BaseLayer.prototype.clear.call(this, bounds); + this.getHitCanvas().getContext().clear(bounds); + this.imageData = null; // Clear getImageData cache + return this; + }, + // extend Node.prototype.setVisible + setVisible: function(visible) { + Konva.Node.prototype.setVisible.call(this, visible); + if(visible) { + this.getCanvas()._canvas.style.display = 'block'; + this.hitCanvas._canvas.style.display = 'block'; + } + else { + this.getCanvas()._canvas.style.display = 'none'; + this.hitCanvas._canvas.style.display = 'none'; + } + return this; + }, + /** + * enable hit graph + * @name enableHitGraph + * @method + * @memberof Konva.Layer.prototype + * @returns {Layer} + */ + enableHitGraph: function() { + this.setHitGraphEnabled(true); + return this; + }, + /** + * disable hit graph + * @name disableHitGraph + * @method + * @memberof Konva.Layer.prototype + * @returns {Layer} + */ + disableHitGraph: function() { + this.setHitGraphEnabled(false); + return this; + }, + setSize: function(width, height) { + Konva.BaseLayer.prototype.setSize.call(this, width, height); + this.hitCanvas.setSize(width, height); + return this; + } + }); + Konva.Util.extend(Konva.Layer, Konva.BaseLayer); + + Konva.Factory.addGetterSetter(Konva.Layer, 'hitGraphEnabled', true); + /** + * get/set hitGraphEnabled flag. Disabling the hit graph will greatly increase + * draw performance because the hit graph will not be redrawn each time the layer is + * drawn. This, however, also disables mouse/touch event detection + * @name hitGraphEnabled + * @method + * @memberof Konva.Layer.prototype + * @param {Boolean} enabled + * @returns {Boolean} + * @example + * // get hitGraphEnabled flag + * var hitGraphEnabled = layer.hitGraphEnabled(); + * + * // disable hit graph + * layer.hitGraphEnabled(false); + * + * // enable hit graph + * layer.hitGraphEnabled(true); + */ + Konva.Collection.mapMethods(Konva.Layer); +})(); + +(function() { + 'use strict'; + /** + * FastLayer constructor. Layers are tied to their own canvas element and are used + * to contain shapes only. If you don't need node nesting, mouse and touch interactions, + * or event pub/sub, you should use FastLayer instead of Layer to create your layers. + * It renders about 2x faster than normal layers. + * @constructor + * @memberof Konva + * @augments Konva.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Boolean} [config.visible] + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var layer = new Konva.FastLayer(); + */ + Konva.FastLayer = function(config) { + this.____init(config); + }; + + Konva.Util.addMethods(Konva.FastLayer, { + ____init: function(config) { + this.nodeType = 'Layer'; + this.canvas = new Konva.SceneCanvas(); + // call super constructor + Konva.BaseLayer.call(this, config); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Shape') { + Konva.Util.throw('You may only add shapes to a fast layer.'); + } + }, + _setCanvasSize: function(width, height) { + this.canvas.setSize(width, height); + }, + hitGraphEnabled: function() { + return false; + }, + getIntersection: function() { + return null; + }, + drawScene: function(can) { + var layer = this.getLayer(), + canvas = can || (layer && layer.getCanvas()); + + if(this.getClearBeforeDraw()) { + canvas.getContext().clear(); + } + + Konva.Container.prototype.drawScene.call(this, canvas); + + return this; + }, + draw: function() { + this.drawScene(); + return this; + }, + // extend Node.prototype.setVisible + setVisible: function(visible) { + Konva.Node.prototype.setVisible.call(this, visible); + if(visible) { + this.getCanvas()._canvas.style.display = 'block'; + } + else { + this.getCanvas()._canvas.style.display = 'none'; + } + return this; + } + }); + Konva.Util.extend(Konva.FastLayer, Konva.BaseLayer); + + Konva.Collection.mapMethods(Konva.FastLayer); +})(); + +(function() { + 'use strict'; + /** + * Group constructor. Groups are used to contain shapes or other groups. + * @constructor + * @memberof Konva + * @augments Konva.Container + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func + + * @example + * var group = new Konva.Group(); + */ + Konva.Group = function(config) { + this.___init(config); + }; + + Konva.Util.addMethods(Konva.Group, { + ___init: function(config) { + this.nodeType = 'Group'; + // call super constructor + Konva.Container.call(this, config); + }, + _validateAdd: function(child) { + var type = child.getType(); + if (type !== 'Group' && type !== 'Shape') { + Konva.Util.throw('You may only add groups and shapes to groups.'); + } + } + }); + Konva.Util.extend(Konva.Group, Konva.Container); + + Konva.Collection.mapMethods(Konva.Group); +})(); + +(function(Konva) { + 'use strict'; + + var now = (function() { + if (Konva.global.performance && Konva.global.performance.now) { + return function() { + return Konva.global.performance.now(); + }; + } + + return function() { + return new Date().getTime(); + }; + })(); + + function FRAF(callback) { + setTimeout(callback, 1000 / 60); + } + + var RAF = (function(){ + return Konva.global.requestAnimationFrame + || Konva.global.webkitRequestAnimationFrame + || Konva.global.mozRequestAnimationFrame + || Konva.global.oRequestAnimationFrame + || Konva.global.msRequestAnimationFrame + || FRAF; + })(); + + + + function requestAnimFrame() { + return RAF.apply(Konva.global, arguments); + } + + /** + * Animation constructor. A stage is used to contain multiple layers and handle + * @constructor + * @memberof Konva + * @param {Function} func function executed on each animation frame. The function is passed a frame object, which contains + * timeDiff, lastTime, time, and frameRate properties. The timeDiff property is the number of milliseconds that have passed + * since the last animation frame. The lastTime property is time in milliseconds that elapsed from the moment the animation started + * to the last animation frame. The time property is the time in milliseconds that ellapsed from the moment the animation started + * to the current animation frame. The frameRate property is the current frame rate in frames / second. Return false from function, + * if you don't need to redraw layer/layers on some frames. + * @param {Konva.Layer|Array} [layers] layer(s) to be redrawn on each animation frame. Can be a layer, an array of layers, or null. + * Not specifying a node will result in no redraw. + * @example + * // move a node to the right at 50 pixels / second + * var velocity = 50; + * + * var anim = new Konva.Animation(function(frame) { + * var dist = velocity * (frame.timeDiff / 1000); + * node.move(dist, 0); + * }, layer); + * + * anim.start(); + */ + Konva.Animation = function(func, layers) { + var Anim = Konva.Animation; + this.func = func; + this.setLayers(layers); + this.id = Anim.animIdCounter++; + this.frame = { + time: 0, + timeDiff: 0, + lastTime: now() + }; + }; + /* + * Animation methods + */ + Konva.Animation.prototype = { + /** + * set layers to be redrawn on each animation frame + * @method + * @memberof Konva.Animation.prototype + * @param {Konva.Layer|Array} [layers] layer(s) to be redrawn.  Can be a layer, an array of layers, or null. Not specifying a node will result in no redraw. + * @return {Konva.Animation} this + */ + setLayers: function(layers) { + var lays = []; + // if passing in no layers + if (!layers) { + lays = []; + } + // if passing in an array of Layers + // NOTE: layers could be an array or Konva.Collection. for simplicity, I'm just inspecting + // the length property to check for both cases + else if (layers.length > 0) { + lays = layers; + } + // if passing in a Layer + else { + lays = [layers]; + } + + this.layers = lays; + return this; + }, + /** + * get layers + * @method + * @memberof Konva.Animation.prototype + * @return {Array} Array of Konva.Layer + */ + getLayers: function() { + return this.layers; + }, + /** + * add layer. Returns true if the layer was added, and false if it was not + * @method + * @memberof Konva.Animation.prototype + * @param {Konva.Layer} layer to add + * @return {Bool} true if layer is added to animation, otherwise false + */ + addLayer: function(layer) { + var layers = this.layers, + len = layers.length, n; + + // don't add the layer if it already exists + for (n = 0; n < len; n++) { + if (layers[n]._id === layer._id){ + return false; + } + } + + this.layers.push(layer); + return true; + }, + /** + * determine if animation is running or not. returns true or false + * @method + * @memberof Konva.Animation.prototype + * @return {Bool} is animation running? + */ + isRunning: function() { + var a = Konva.Animation, + animations = a.animations, + len = animations.length, + n; + + for (n = 0; n < len; n++) { + if (animations[n].id === this.id) { + return true; + } + } + return false; + }, + /** + * start animation + * @method + * @memberof Konva.Animation.prototype + * @return {Konva.Animation} this + */ + start: function() { + var Anim = Konva.Animation; + this.stop(); + this.frame.timeDiff = 0; + this.frame.lastTime = now(); + Anim._addAnimation(this); + return this; + }, + /** + * stop animation + * @method + * @memberof Konva.Animation.prototype + * @return {Konva.Animation} this + */ + stop: function() { + Konva.Animation._removeAnimation(this); + return this; + }, + _updateFrameObject: function(time) { + this.frame.timeDiff = time - this.frame.lastTime; + this.frame.lastTime = time; + this.frame.time += this.frame.timeDiff; + this.frame.frameRate = 1000 / this.frame.timeDiff; + } + }; + Konva.Animation.animations = []; + Konva.Animation.animIdCounter = 0; + Konva.Animation.animRunning = false; + + Konva.Animation._addAnimation = function(anim) { + this.animations.push(anim); + this._handleAnimation(); + }; + Konva.Animation._removeAnimation = function(anim) { + var id = anim.id, + animations = this.animations, + len = animations.length, + n; + + for(n = 0; n < len; n++) { + if(animations[n].id === id) { + this.animations.splice(n, 1); + break; + } + } + }; + + Konva.Animation._runFrames = function() { + var layerHash = {}, + animations = this.animations, + anim, layers, func, n, i, layersLen, layer, key, needRedraw; + /* + * loop through all animations and execute animation + * function. if the animation object has specified node, + * we can add the node to the nodes hash to eliminate + * drawing the same node multiple times. The node property + * can be the stage itself or a layer + */ + /* + * WARNING: don't cache animations.length because it could change while + * the for loop is running, causing a JS error + */ + + for(n = 0; n < animations.length; n++) { + anim = animations[n]; + layers = anim.layers; + func = anim.func; + + + anim._updateFrameObject(now()); + layersLen = layers.length; + + // if animation object has a function, execute it + if (func) { + // allow anim bypassing drawing + needRedraw = (func.call(anim, anim.frame) !== false); + } else { + needRedraw = true; + } + if (!needRedraw) { + continue; + } + for (i = 0; i < layersLen; i++) { + layer = layers[i]; + + if (layer._id !== undefined) { + layerHash[layer._id] = layer; + } + } + } + + for (key in layerHash) { + if (!layerHash.hasOwnProperty(key)) { + continue; + } + layerHash[key].draw(); + } + }; + Konva.Animation._animationLoop = function() { + var Anim = Konva.Animation; + if(Anim.animations.length) { + Anim._runFrames(); + requestAnimFrame(Anim._animationLoop); + } + else { + Anim.animRunning = false; + } + }; + Konva.Animation._handleAnimation = function() { + if(!this.animRunning) { + this.animRunning = true; + requestAnimFrame(this._animationLoop); + } + }; + + /** + * batch draw. this function will not do immediate draw + * but it will schedule drawing to next tick (requestAnimFrame) + * @method + * @return {Konva.Layer} this + * @memberof Konva.Base.prototype + */ + Konva.BaseLayer.prototype.batchDraw = function() { + var that = this, + Anim = Konva.Animation; + + if (!this.batchAnim) { + this.batchAnim = new Anim(function() { + // stop animation after first tick + that.batchAnim.stop(); + }, this); + } + + this.lastBatchDrawTime = now(); + + if (!this.batchAnim.isRunning()) { + this.batchAnim.start(); + } + return this; + }; + + /** + * batch draw + * @method + * @return {Konva.Stage} this + * @memberof Konva.Stage.prototype + */ + Konva.Stage.prototype.batchDraw = function() { + this.getChildren().each(function(layer) { + layer.batchDraw(); + }); + return this; + }; +})(Konva); + +(function() { + 'use strict'; + var blacklist = { + node: 1, + duration: 1, + easing: 1, + onFinish: 1, + yoyo: 1 + }, + + PAUSED = 1, + PLAYING = 2, + REVERSING = 3, + + idCounter = 0, + colorAttrs = ['fill', 'stroke', 'shadowColor']; + + var Tween = function(prop, propFunc, func, begin, finish, duration, yoyo) { + this.prop = prop; + this.propFunc = propFunc; + this.begin = begin; + this._pos = begin; + this.duration = duration; + this._change = 0; + this.prevPos = 0; + this.yoyo = yoyo; + this._time = 0; + this._position = 0; + this._startTime = 0; + this._finish = 0; + this.func = func; + this._change = finish - this.begin; + this.pause(); + }; + /* + * Tween methods + */ + Tween.prototype = { + fire: function(str) { + var handler = this[str]; + if (handler) { + handler(); + } + }, + setTime: function(t) { + if(t > this.duration) { + if(this.yoyo) { + this._time = this.duration; + this.reverse(); + } + else { + this.finish(); + } + } + else if(t < 0) { + if(this.yoyo) { + this._time = 0; + this.play(); + } + else { + this.reset(); + } + } + else { + this._time = t; + this.update(); + } + }, + getTime: function() { + return this._time; + }, + setPosition: function(p) { + this.prevPos = this._pos; + this.propFunc(p); + this._pos = p; + }, + getPosition: function(t) { + if(t === undefined) { + t = this._time; + } + return this.func(t, this.begin, this._change, this.duration); + }, + play: function() { + this.state = PLAYING; + this._startTime = this.getTimer() - this._time; + this.onEnterFrame(); + this.fire('onPlay'); + }, + reverse: function() { + this.state = REVERSING; + this._time = this.duration - this._time; + this._startTime = this.getTimer() - this._time; + this.onEnterFrame(); + this.fire('onReverse'); + }, + seek: function(t) { + this.pause(); + this._time = t; + this.update(); + this.fire('onSeek'); + }, + reset: function() { + this.pause(); + this._time = 0; + this.update(); + this.fire('onReset'); + }, + finish: function() { + this.pause(); + this._time = this.duration; + this.update(); + this.fire('onFinish'); + }, + update: function() { + this.setPosition(this.getPosition(this._time)); + }, + onEnterFrame: function() { + var t = this.getTimer() - this._startTime; + if(this.state === PLAYING) { + this.setTime(t); + } + else if (this.state === REVERSING) { + this.setTime(this.duration - t); + } + }, + pause: function() { + this.state = PAUSED; + this.fire('onPause'); + }, + getTimer: function() { + return new Date().getTime(); + } + }; + + /** + * Tween constructor. Tweens enable you to animate a node between the current state and a new state. + * You can play, pause, reverse, seek, reset, and finish tweens. By default, tweens are animated using + * a linear easing. For more tweening options, check out {@link Konva.Easings} + * @constructor + * @memberof Konva + * @example + * // instantiate new tween which fully rotates a node in 1 second + * var tween = new Konva.Tween({ + * node: node, + * rotationDeg: 360, + * duration: 1, + * easing: Konva.Easings.EaseInOut + * }); + * + * // play tween + * tween.play(); + * + * // pause tween + * tween.pause(); + */ + Konva.Tween = function(config) { + var that = this, + node = config.node, + nodeId = node._id, + duration, + easing = config.easing || Konva.Easings.Linear, + yoyo = !!config.yoyo, + key; + + if (typeof config.duration === 'undefined') { + duration = 1; + } else if (config.duration === 0) { // zero is bad value for duration + duration = 0.001; + } else { + duration = config.duration; + } + this.node = node; + this._id = idCounter++; + + var layers = node.getLayer() || ((node instanceof Konva.Stage) ? node.getLayers() : null); + if (!layers) { + Konva.Util.error( + 'Tween constructor have `node` that is not in a layer. Please add node into layer first.' + ); + } + this.anim = new Konva.Animation(function() { + that.tween.onEnterFrame(); + }, layers); + + this.tween = new Tween(key, function(i) { + that._tweenFunc(i); + }, easing, 0, 1, duration * 1000, yoyo); + + this._addListeners(); + + // init attrs map + if (!Konva.Tween.attrs[nodeId]) { + Konva.Tween.attrs[nodeId] = {}; + } + if (!Konva.Tween.attrs[nodeId][this._id]) { + Konva.Tween.attrs[nodeId][this._id] = {}; + } + // init tweens map + if (!Konva.Tween.tweens[nodeId]) { + Konva.Tween.tweens[nodeId] = {}; + } + + for (key in config) { + if (blacklist[key] === undefined) { + this._addAttr(key, config[key]); + } + } + + this.reset(); + + // callbacks + this.onFinish = config.onFinish; + this.onReset = config.onReset; + }; + + // start/diff object = attrs.nodeId.tweenId.attr + Konva.Tween.attrs = {}; + // tweenId = tweens.nodeId.attr + Konva.Tween.tweens = {}; + + Konva.Tween.prototype = { + _addAttr: function(key, end) { + var node = this.node, + nodeId = node._id, + start, diff, tweenId, n, len, trueEnd, trueStart; + + // remove conflict from tween map if it exists + tweenId = Konva.Tween.tweens[nodeId][key]; + + if (tweenId) { + delete Konva.Tween.attrs[nodeId][tweenId][key]; + } + + // add to tween map + start = node.getAttr(key); + + if (Konva.Util._isArray(end)) { + diff = []; + len = Math.max(end.length, start.length); + + if (key === 'points' && end.length !== start.length) { + // before tweening points we need to make sure that start.length === end.length + // Konva.Util._prepareArrayForTween thinking that end.length > start.length + + if (end.length > start.length) { + // so in this case we will increase number of starting points + trueStart = start; + start = Konva.Util._prepareArrayForTween(start, end, node.closed()); + } else { + // in this case we will increase number of eding points + trueEnd = end; + end = Konva.Util._prepareArrayForTween(end, start, node.closed()); + } + } + + for (n = 0; n < len; n++) { + diff.push((end[n]) - (start[n])); + } + + } else if (colorAttrs.indexOf(key) !== -1) { + start = Konva.Util.colorToRGBA(start); + var endRGBA = Konva.Util.colorToRGBA(end); + diff = { + r: endRGBA.r - start.r, + g: endRGBA.g - start.g, + b: endRGBA.b - start.b, + a: endRGBA.a - start.a + }; + } else { + diff = end - start; + } + + Konva.Tween.attrs[nodeId][this._id][key] = { + start: start, + diff: diff, + end: end, + trueEnd: trueEnd, + trueStart: trueStart + }; + Konva.Tween.tweens[nodeId][key] = this._id; + }, + _tweenFunc: function(i) { + var node = this.node, + attrs = Konva.Tween.attrs[node._id][this._id], + key, attr, start, diff, newVal, n, len, end; + + for (key in attrs) { + attr = attrs[key]; + start = attr.start; + diff = attr.diff; + end = attr.end; + + if (Konva.Util._isArray(start)) { + newVal = []; + len = Math.max(start.length, end.length); + for (n = 0; n < len; n++) { + newVal.push((start[n] || 0) + (diff[n] * i)); + } + } else if (colorAttrs.indexOf(key) !== -1) { + newVal = 'rgba(' + + Math.round(start.r + diff.r * i) + ',' + + Math.round(start.g + diff.g * i) + ',' + + Math.round(start.b + diff.b * i) + ',' + + (start.a + diff.a * i) + ')'; + } else { + newVal = start + (diff * i); + } + + node.setAttr(key, newVal); + } + }, + _addListeners: function() { + var that = this; + + // start listeners + this.tween.onPlay = function() { + that.anim.start(); + }; + this.tween.onReverse = function() { + that.anim.start(); + }; + + // stop listeners + this.tween.onPause = function() { + that.anim.stop(); + }; + this.tween.onFinish = function() { + var node = that.node; + + // after tweening points of line we need to set original end + var attrs = Konva.Tween.attrs[node._id][that._id]; + if (attrs.points && attrs.points.trueEnd) { + node.points(attrs.points.trueEnd); + } + + if (that.onFinish) { + that.onFinish.call(that); + } + }; + this.tween.onReset = function() { + var node = that.node; + // after tweening points of line we need to set original start + var attrs = Konva.Tween.attrs[node._id][that._id]; + if (attrs.points && attrs.points.trueStart) { + node.points(attrs.points.trueStart); + } + + if (that.onReset) { + that.onReset(); + } + }; + }, + /** + * play + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + play: function() { + this.tween.play(); + return this; + }, + /** + * reverse + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + reverse: function() { + this.tween.reverse(); + return this; + }, + /** + * reset + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + reset: function() { + this.tween.reset(); + return this; + }, + /** + * seek + * @method + * @memberof Konva.Tween.prototype + * @param {Integer} t time in seconds between 0 and the duration + * @returns {Tween} + */ + seek: function(t) { + this.tween.seek(t * 1000); + return this; + }, + /** + * pause + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + pause: function() { + this.tween.pause(); + return this; + }, + /** + * finish + * @method + * @memberof Konva.Tween.prototype + * @returns {Tween} + */ + finish: function() { + this.tween.finish(); + return this; + }, + /** + * destroy + * @method + * @memberof Konva.Tween.prototype + */ + destroy: function() { + var nodeId = this.node._id, + thisId = this._id, + attrs = Konva.Tween.tweens[nodeId], + key; + + this.pause(); + + for (key in attrs) { + delete Konva.Tween.tweens[nodeId][key]; + } + + delete Konva.Tween.attrs[nodeId][thisId]; + } + }; + + /** + * Tween node properties. Shorter usage of {@link Konva.Tween} object. + * + * @method Konva.Node#to + * @memberof Konva.Node + * @param {Object} [params] tween params + * @example + * + * circle.to({ + * x : 50, + * duration : 0.5 + * }); + */ + Konva.Node.prototype.to = function(params) { + var onFinish = params.onFinish; + params.node = this; + params.onFinish = function() { + this.destroy(); + if (onFinish) { + onFinish(); + } + }; + var tween = new Konva.Tween(params); + tween.play(); + }; + + /* + * These eases were ported from an Adobe Flash tweening library to JavaScript + * by Xaric + */ + + /** + * @namespace Easings + * @memberof Konva + */ + Konva.Easings = { + /** + * back ease in + * @function + * @memberof Konva.Easings + */ + 'BackEaseIn': function(t, b, c, d) { + var s = 1.70158; + return c * (t /= d) * t * ((s + 1) * t - s) + b; + }, + /** + * back ease out + * @function + * @memberof Konva.Easings + */ + 'BackEaseOut': function(t, b, c, d) { + var s = 1.70158; + return c * (( t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + }, + /** + * back ease in out + * @function + * @memberof Konva.Easings + */ + 'BackEaseInOut': function(t, b, c, d) { + var s = 1.70158; + if((t /= d / 2) < 1) { + return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; + } + return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + }, + /** + * elastic ease in + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseIn': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d) === 1) { + return b + c; + } + if(!p) { + p = d * 0.3; + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; + }, + /** + * elastic ease out + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseOut': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d) === 1) { + return b + c; + } + if(!p) { + p = d * 0.3; + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b); + }, + /** + * elastic ease in out + * @function + * @memberof Konva.Easings + */ + 'ElasticEaseInOut': function(t, b, c, d, a, p) { + // added s = 0 + var s = 0; + if(t === 0) { + return b; + } + if((t /= d / 2) === 2) { + return b + c; + } + if(!p) { + p = d * (0.3 * 1.5); + } + if(!a || a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + if(t < 1) { + return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; + } + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b; + }, + /** + * bounce ease out + * @function + * @memberof Konva.Easings + */ + 'BounceEaseOut': function(t, b, c, d) { + if((t /= d) < (1 / 2.75)) { + return c * (7.5625 * t * t) + b; + } + else if(t < (2 / 2.75)) { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; + } + else if(t < (2.5 / 2.75)) { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; + } + else { + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; + } + }, + /** + * bounce ease in + * @function + * @memberof Konva.Easings + */ + 'BounceEaseIn': function(t, b, c, d) { + return c - Konva.Easings.BounceEaseOut(d - t, 0, c, d) + b; + }, + /** + * bounce ease in out + * @function + * @memberof Konva.Easings + */ + 'BounceEaseInOut': function(t, b, c, d) { + if(t < d / 2) { + return Konva.Easings.BounceEaseIn(t * 2, 0, c, d) * 0.5 + b; + } + else { + return Konva.Easings.BounceEaseOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; + } + }, + /** + * ease in + * @function + * @memberof Konva.Easings + */ + 'EaseIn': function(t, b, c, d) { + return c * (t /= d) * t + b; + }, + /** + * ease out + * @function + * @memberof Konva.Easings + */ + 'EaseOut': function(t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + }, + /** + * ease in out + * @function + * @memberof Konva.Easings + */ + 'EaseInOut': function(t, b, c, d) { + if((t /= d / 2) < 1) { + return c / 2 * t * t + b; + } + return -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + /** + * strong ease in + * @function + * @memberof Konva.Easings + */ + 'StrongEaseIn': function(t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + }, + /** + * strong ease out + * @function + * @memberof Konva.Easings + */ + 'StrongEaseOut': function(t, b, c, d) { + return c * (( t = t / d - 1) * t * t * t * t + 1) + b; + }, + /** + * strong ease in out + * @function + * @memberof Konva.Easings + */ + 'StrongEaseInOut': function(t, b, c, d) { + if((t /= d / 2) < 1) { + return c / 2 * t * t * t * t * t + b; + } + return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + }, + /** + * linear + * @function + * @memberof Konva.Easings + */ + 'Linear': function(t, b, c, d) { + return c * t / d + b; + } + }; +})(); + +(function() { + 'use strict'; + Konva.DD = { + // properties + anim: new Konva.Animation(function() { + var b = this.dirty; + this.dirty = false; + return b; + }), + isDragging: false, + justDragged: false, + offset: { + x: 0, + y: 0 + }, + node: null, + + // methods + _drag: function(evt) { + var dd = Konva.DD, + node = dd.node; + + if(node) { + if(!dd.isDragging) { + var pos = node.getStage().getPointerPosition(); + var dragDistance = node.dragDistance(); + var distance = Math.max( + Math.abs(pos.x - dd.startPointerPos.x), + Math.abs(pos.y - dd.startPointerPos.y) + ); + if (distance < dragDistance) { + return; + } + } + + + node.getStage()._setPointerPosition(evt); + node._setDragPosition(evt); + if(!dd.isDragging) { + dd.isDragging = true; + node.fire('dragstart', { + type: 'dragstart', + target: node, + evt: evt + }, true); + } + + // execute ondragmove if defined + node.fire('dragmove', { + type: 'dragmove', + target: node, + evt: evt + }, true); + } + }, + _endDragBefore: function(evt) { + var dd = Konva.DD, + node = dd.node, + layer; + + if(node) { + layer = node.getLayer(); + dd.anim.stop(); + + // only fire dragend event if the drag and drop + // operation actually started. + if(dd.isDragging) { + dd.isDragging = false; + dd.justDragged = true; + Konva.listenClickTap = false; + + if (evt) { + evt.dragEndNode = node; + } + } + + delete dd.node; + + (layer || node).draw(); + } + }, + _endDragAfter: function(evt) { + evt = evt || {}; + var dragEndNode = evt.dragEndNode; + + if (evt && dragEndNode) { + dragEndNode.fire('dragend', { + type: 'dragend', + target: dragEndNode, + evt: evt + }, true); + } + } + }; + + // Node extenders + + /** + * initiate drag and drop + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.startDrag = function() { + var dd = Konva.DD, + stage = this.getStage(), + layer = this.getLayer(), + pos = stage.getPointerPosition(), + ap = this.getAbsolutePosition(); + + if(pos) { + if (dd.node) { + dd.node.stopDrag(); + } + + dd.node = this; + dd.startPointerPos = pos; + dd.offset.x = pos.x - ap.x; + dd.offset.y = pos.y - ap.y; + dd.anim.setLayers(layer || this.getLayers()); + dd.anim.start(); + + this._setDragPosition(); + } + }; + + Konva.Node.prototype._setDragPosition = function(evt) { + var dd = Konva.DD, + pos = this.getStage().getPointerPosition(), + dbf = this.getDragBoundFunc(); + if (!pos) { + return; + } + var newNodePos = { + x: pos.x - dd.offset.x, + y: pos.y - dd.offset.y + }; + + if(dbf !== undefined) { + newNodePos = dbf.call(this, newNodePos, evt); + } + this.setAbsolutePosition(newNodePos); + + if (!this._lastPos || this._lastPos.x !== newNodePos.x || + this._lastPos.y !== newNodePos.y) { + dd.anim.dirty = true; + } + + this._lastPos = newNodePos; + }; + + /** + * stop drag and drop + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.stopDrag = function() { + var dd = Konva.DD, + evt = {}; + dd._endDragBefore(evt); + dd._endDragAfter(evt); + }; + + Konva.Node.prototype.setDraggable = function(draggable) { + this._setAttr('draggable', draggable); + this._dragChange(); + }; + + var origDestroy = Konva.Node.prototype.destroy; + + Konva.Node.prototype.destroy = function() { + var dd = Konva.DD; + + // stop DD + if(dd.node && dd.node._id === this._id) { + + this.stopDrag(); + } + + origDestroy.call(this); + }; + + /** + * determine if node is currently in drag and drop mode + * @method + * @memberof Konva.Node.prototype + */ + Konva.Node.prototype.isDragging = function() { + var dd = Konva.DD; + return !!(dd.node && dd.node._id === this._id && dd.isDragging); + }; + + Konva.Node.prototype._listenDrag = function() { + var that = this; + + this._dragCleanup(); + + if (this.getClassName() === 'Stage') { + this.on('contentMousedown.konva contentTouchstart.konva', function(evt) { + if(!Konva.DD.node) { + that.startDrag(evt); + } + }); + } + else { + this.on('mousedown.konva touchstart.konva', function(evt) { + // ignore right and middle buttons + if (evt.evt.button === 1 || evt.evt.button === 2) { + return; + } + if(!Konva.DD.node) { + that.startDrag(evt); + } + }); + } + + // listening is required for drag and drop + /* + this._listeningEnabled = true; + this._clearSelfAndAncestorCache('listeningEnabled'); + */ + }; + + Konva.Node.prototype._dragChange = function() { + if(this.attrs.draggable) { + this._listenDrag(); + } + else { + // remove event listeners + this._dragCleanup(); + + /* + * force drag and drop to end + * if this node is currently in + * drag and drop mode + */ + var stage = this.getStage(); + var dd = Konva.DD; + if(stage && dd.node && dd.node._id === this._id) { + dd.node.stopDrag(); + } + } + }; + + Konva.Node.prototype._dragCleanup = function() { + if (this.getClassName() === 'Stage') { + this.off('contentMousedown.konva'); + this.off('contentTouchstart.konva'); + } else { + this.off('mousedown.konva'); + this.off('touchstart.konva'); + } + }; + + Konva.Factory.addGetterSetter(Konva.Node, 'dragBoundFunc'); + + /** + * get/set drag bound function. This is used to override the default + * drag and drop position + * @name dragBoundFunc + * @method + * @memberof Konva.Node.prototype + * @param {Function} dragBoundFunc + * @returns {Function} + * @example + * // get drag bound function + * var dragBoundFunc = node.dragBoundFunc(); + * + * // create vertical drag and drop + * node.dragBoundFunc(function(pos){ + * return { + * x: this.getAbsolutePosition().x, + * y: pos.y + * }; + * }); + */ + + Konva.Factory.addGetter(Konva.Node, 'draggable', false); + Konva.Factory.addOverloadedGetterSetter(Konva.Node, 'draggable'); + + /** + * get/set draggable flag + * @name draggable + * @method + * @memberof Konva.Node.prototype + * @param {Boolean} draggable + * @returns {Boolean} + * @example + * // get draggable flag + * var draggable = node.draggable(); + * + * // enable drag and drop + * node.draggable(true); + * + * // disable drag and drop + * node.draggable(false); + */ + + var html = Konva.document.documentElement; + html.addEventListener('mouseup', Konva.DD._endDragBefore, true); + html.addEventListener('touchend', Konva.DD._endDragBefore, true); + + // html.addEventListener('mousemove', Konva.DD._drag); + // html.addEventListener('touchmove', Konva.DD._drag); + + html.addEventListener('mouseup', Konva.DD._endDragAfter, false); + html.addEventListener('touchend', Konva.DD._endDragAfter, false); + +})(); + +(function() { + 'use strict'; + /** + * Rect constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} [config.cornerRadius] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var rect = new Konva.Rect({ + * width: 100, + * height: 50, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 5 + * }); + */ + Konva.Rect = function(config) { + this.___init(config); + }; + + Konva.Rect.prototype = { + ___init: function(config) { + Konva.Shape.call(this, config); + this.className = 'Rect'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var cornerRadius = this.getCornerRadius(), + width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + + if(!cornerRadius) { + // simple rect - don't bother doing all that complicated maths stuff. + context.rect(0, 0, width, height); + } else { + // arcTo would be nicer, but browser support is patchy (Opera) + cornerRadius = Math.min(cornerRadius, width / 2, height / 2); + context.moveTo(cornerRadius, 0); + context.lineTo(width - cornerRadius, 0); + context.arc(width - cornerRadius, cornerRadius, cornerRadius, Math.PI * 3 / 2, 0, false); + context.lineTo(width, height - cornerRadius); + context.arc(width - cornerRadius, height - cornerRadius, cornerRadius, 0, Math.PI / 2, false); + context.lineTo(cornerRadius, height); + context.arc(cornerRadius, height - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false); + context.lineTo(0, cornerRadius); + context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false); + } + context.closePath(); + context.fillStrokeShape(this); + } + }; + + Konva.Util.extend(Konva.Rect, Konva.Shape); + + Konva.Factory.addGetterSetter(Konva.Rect, 'cornerRadius', 0); + /** + * get/set corner radius + * @name cornerRadius + * @method + * @memberof Konva.Rect.prototype + * @param {Number} cornerRadius + * @returns {Number} + * @example + * // get corner radius + * var cornerRadius = rect.cornerRadius(); + * + * // set corner radius + * rect.cornerRadius(10); + */ + + Konva.Collection.mapMethods(Konva.Rect); +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001, + CIRCLE = 'Circle'; + + /** + * Circle constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // create circle + * var circle = new Konva.Circle({ + * radius: 40, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5 + * }); + */ + Konva.Circle = function(config) { + this.___init(config); + }; + + Konva.Circle.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = CIRCLE; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getRadius(), 0, PIx2, false); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Circle, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Circle, 'radius', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Circle, 'radius'); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Circle.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radius + * var radius = circle.radius(); + * + * // set radius + * circle.radius(10); + */ + + Konva.Collection.mapMethods(Konva.Circle); +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001, + ELLIPSE = 'Ellipse'; + + /** + * Ellipse constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Object} config.radius defines x and y radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var ellipse = new Konva.Ellipse({ + * radius : { + * x : 50, + * y : 50 + * }, + * fill: 'red' + * }); + */ + Konva.Ellipse = function(config) { + this.___init(config); + }; + + Konva.Ellipse.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = ELLIPSE; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var rx = this.getRadiusX(), + ry = this.getRadiusY(); + + context.beginPath(); + context.save(); + if(rx !== ry) { + context.scale(1, ry / rx); + } + context.arc(0, 0, rx, 0, PIx2, false); + context.restore(); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadiusX() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadiusY() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + this.setRadius({ + x: width / 2 + }); + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + this.setRadius({ + y: height / 2 + }); + } + }; + Konva.Util.extend(Konva.Ellipse, Konva.Shape); + + // add getters setters + Konva.Factory.addComponentsGetterSetter(Konva.Ellipse, 'radius', ['x', 'y']); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Ellipse.prototype + * @param {Object} radius + * @param {Number} radius.x + * @param {Number} radius.y + * @returns {Object} + * @example + * // get radius + * var radius = ellipse.radius(); + * + * // set radius + * ellipse.radius({ + * x: 200, + * y: 100 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Ellipse, 'radiusX', 0); + /** + * get/set radius x + * @name radiusX + * @method + * @memberof Konva.Ellipse.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get radius x + * var radiusX = ellipse.radiusX(); + * + * // set radius x + * ellipse.radiusX(200); + */ + + Konva.Factory.addGetterSetter(Konva.Ellipse, 'radiusY', 0); + /** + * get/set radius y + * @name radiusY + * @method + * @memberof Konva.Ellipse.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get radius y + * var radiusY = ellipse.radiusY(); + * + * // set radius y + * ellipse.radiusY(200); + */ + + Konva.Collection.mapMethods(Konva.Ellipse); + +})(); + +(function() { + 'use strict'; + // the 0.0001 offset fixes a bug in Chrome 27 + var PIx2 = (Math.PI * 2) - 0.0001; + /** + * Ring constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var ring = new Konva.Ring({ + * innerRadius: 40, + * outerRadius: 80, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 5 + * }); + */ + Konva.Ring = function(config) { + this.___init(config); + }; + + Konva.Ring.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Ring'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getInnerRadius(), 0, PIx2, false); + context.moveTo(this.getOuterRadius(), 0); + context.arc(0, 0, this.getOuterRadius(), PIx2, 0, true); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.outerRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.outerRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + }, + setOuterRadius: function(val) { + this._setAttr('outerRadius', val); + this.setWidth(val * 2); + this.setHeight(val * 2); + } + }; + Konva.Util.extend(Konva.Ring, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Ring, 'innerRadius', 0); + + /** + * get/set innerRadius + * @name innerRadius + * @method + * @memberof Konva.Ring.prototype + * @param {Number} innerRadius + * @returns {Number} + * @example + * // get inner radius + * var innerRadius = ring.innerRadius(); + * + * // set inner radius + * ring.innerRadius(20); + */ + Konva.Factory.addGetter(Konva.Ring, 'outerRadius', 0); + Konva.Factory.addOverloadedGetterSetter(Konva.Ring, 'outerRadius'); + + /** + * get/set outerRadius + * @name outerRadius + * @method + * @memberof Konva.Ring.prototype + * @param {Number} outerRadius + * @returns {Number} + * @example + * // get outer radius + * var outerRadius = ring.outerRadius(); + * + * // set outer radius + * ring.outerRadius(20); + */ + + Konva.Collection.mapMethods(Konva.Ring); +})(); + +(function() { + 'use strict'; + /** + * Wedge constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.angle in degrees + * @param {Number} config.radius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // draw a wedge that's pointing downwards + * var wedge = new Konva.Wedge({ + * radius: 40, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5, + * angleDeg: 60, + * rotationDeg: -120 + * }); + */ + Konva.Wedge = function(config) { + this.___init(config); + }; + + Konva.Wedge.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Wedge'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.beginPath(); + context.arc(0, 0, this.getRadius(), 0, Konva.getAngle(this.getAngle()), this.getClockwise()); + context.lineTo(0, 0); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Wedge, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Wedge, 'radius', 0); + + /** + * get/set radius + * @name radius + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} radius + * @returns {Number} + * @example + * // get radius + * var radius = wedge.radius(); + * + * // set radius + * wedge.radius(10); + */ + + Konva.Factory.addGetterSetter(Konva.Wedge, 'angle', 0); + + /** + * get/set angle in degrees + * @name angle + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} angle + * @returns {Number} + * @example + * // get angle + * var angle = wedge.angle(); + * + * // set angle + * wedge.angle(20); + */ + + Konva.Factory.addGetterSetter(Konva.Wedge, 'clockwise', false); + + /** + * get/set clockwise flag + * @name clockwise + * @method + * @memberof Konva.Wedge.prototype + * @param {Number} clockwise + * @returns {Number} + * @example + * // get clockwise flag + * var clockwise = wedge.clockwise(); + * + * // draw wedge counter-clockwise + * wedge.clockwise(false); + * + * // draw wedge clockwise + * wedge.clockwise(true); + */ + + Konva.Factory.backCompat(Konva.Wedge, { + angleDeg: 'angle', + getAngleDeg: 'getAngle', + setAngleDeg: 'setAngle' + }); + + Konva.Collection.mapMethods(Konva.Wedge); +})(); + +(function() { + 'use strict'; + /** + * Arc constructor + * @constructor + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.angle in degrees + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {Boolean} [config.clockwise] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // draw a Arc that's pointing downwards + * var arc = new Konva.Arc({ + * innerRadius: 40, + * outerRadius: 80, + * fill: 'red', + * stroke: 'black' + * strokeWidth: 5, + * angle: 60, + * rotationDeg: -120 + * }); + */ + Konva.Arc = function(config) { + this.___init(config); + }; + + Konva.Arc.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Arc'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var angle = Konva.getAngle(this.angle()), + clockwise = this.clockwise(); + + context.beginPath(); + context.arc(0, 0, this.getOuterRadius(), 0, angle, clockwise); + context.arc(0, 0, this.getInnerRadius(), angle, 0, !clockwise); + context.closePath(); + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.getOuterRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.getOuterRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Arc, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Arc, 'innerRadius', 0); + + /** + * get/set innerRadius + * @name innerRadius + * @method + * @memberof Konva.Arc.prototype + * @param {Number} innerRadius + * @returns {Number} + * @example + * // get inner radius + * var innerRadius = arc.innerRadius(); + * + * // set inner radius + * arc.innerRadius(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'outerRadius', 0); + + /** + * get/set outerRadius + * @name outerRadius + * @method + * @memberof Konva.Arc.prototype + * @param {Number} outerRadius + * @returns {Number} + * @example + * // get outer radius + * var outerRadius = arc.outerRadius(); + * + * // set outer radius + * arc.outerRadius(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'angle', 0); + + /** + * get/set angle in degrees + * @name angle + * @method + * @memberof Konva.Arc.prototype + * @param {Number} angle + * @returns {Number} + * @example + * // get angle + * var angle = arc.angle(); + * + * // set angle + * arc.angle(20); + */ + + Konva.Factory.addGetterSetter(Konva.Arc, 'clockwise', false); + + /** + * get/set clockwise flag + * @name clockwise + * @method + * @memberof Konva.Arc.prototype + * @param {Boolean} clockwise + * @returns {Boolean} + * @example + * // get clockwise flag + * var clockwise = arc.clockwise(); + * + * // draw arc counter-clockwise + * arc.clockwise(false); + * + * // draw arc clockwise + * arc.clockwise(true); + */ + + Konva.Collection.mapMethods(Konva.Arc); +})(); + +(function() { + 'use strict'; + // CONSTANTS + var IMAGE = 'Image'; + + /** + * Image constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Image} config.image + * @param {Object} [config.crop] + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var imageObj = new Image(); + * imageObj.onload = function() { + * var image = new Konva.Image({ + * x: 200, + * y: 50, + * image: imageObj, + * width: 100, + * height: 100 + * }); + * }; + * imageObj.src = '/path/to/image.jpg' + */ + Konva.Image = function(config) { + this.___init(config); + }; + + Konva.Image.prototype = { + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = IMAGE; + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _useBufferCanvas: function() { + return (this.hasShadow() || this.getAbsoluteOpacity() !== 1) && this.hasStroke() && this.getStage(); + }, + _sceneFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(), + image = this.getImage(), + cropWidth, cropHeight, params; + + if (image) { + cropWidth = this.getCropWidth(); + cropHeight = this.getCropHeight(); + if (cropWidth && cropHeight) { + params = [image, this.getCropX(), this.getCropY(), cropWidth, cropHeight, 0, 0, width, height]; + } else { + params = [image, 0, 0, width, height]; + } + } + + if (this.hasFill() || this.hasStroke()) { + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + } + + if (image) { + context.drawImage.apply(context, params); + } + }, + _hitFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + }, + getWidth: function() { + var image = this.getImage(); + return this.attrs.width || (image ? image.width : 0); + }, + getHeight: function() { + var image = this.getImage(); + return this.attrs.height || (image ? image.height : 0); + } + }; + Konva.Util.extend(Konva.Image, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Image, 'image'); + + /** + * set image + * @name setImage + * @method + * @memberof Konva.Image.prototype + * @param {Image} image + */ + + /** + * get image + * @name getImage + * @method + * @memberof Konva.Image.prototype + * @returns {Image} + */ + + Konva.Factory.addComponentsGetterSetter(Konva.Image, 'crop', ['x', 'y', 'width', 'height']); + /** + * get/set crop + * @method + * @name crop + * @memberof Konva.Image.prototype + * @param {Object} crop + * @param {Number} crop.x + * @param {Number} crop.y + * @param {Number} crop.width + * @param {Number} crop.height + * @returns {Object} + * @example + * // get crop + * var crop = image.crop(); + * + * // set crop + * image.crop({ + * x: 20, + * y: 20, + * width: 20, + * height: 20 + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropX', 0); + /** + * get/set crop x + * @method + * @name cropX + * @memberof Konva.Image.prototype + * @param {Number} x + * @returns {Number} + * @example + * // get crop x + * var cropX = image.cropX(); + * + * // set crop x + * image.cropX(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropY', 0); + /** + * get/set crop y + * @name cropY + * @method + * @memberof Konva.Image.prototype + * @param {Number} y + * @returns {Number} + * @example + * // get crop y + * var cropY = image.cropY(); + * + * // set crop y + * image.cropY(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropWidth', 0); + /** + * get/set crop width + * @name cropWidth + * @method + * @memberof Konva.Image.prototype + * @param {Number} width + * @returns {Number} + * @example + * // get crop width + * var cropWidth = image.cropWidth(); + * + * // set crop width + * image.cropWidth(20); + */ + + Konva.Factory.addGetterSetter(Konva.Image, 'cropHeight', 0); + /** + * get/set crop height + * @name cropHeight + * @method + * @memberof Konva.Image.prototype + * @param {Number} height + * @returns {Number} + * @example + * // get crop height + * var cropHeight = image.cropHeight(); + * + * // set crop height + * image.cropHeight(20); + */ + + Konva.Collection.mapMethods(Konva.Image); + + /** + * load image from given url and create `Konva.Image` instance + * @method + * @memberof Konva.Image + * @param {String} url image source + * @param {Function} callback with Konva.Image instance as first argument + * @example + * Konva.Image.fromURL(imageURL, function(image){ + * // image is Konva.Image instance + * layer.add(image); + * layer.draw(); + * }); + */ + Konva.Image.fromURL = function(url, callback) { + var img = new Image(); + img.onload = function() { + var image = new Konva.Image({ + image: img + }); + callback(image); + }; + img.src = url; + }; +})(); + +/*eslint-disable max-depth */ +(function() { + 'use strict'; + // constants + var AUTO = 'auto', + //CANVAS = 'canvas', + CENTER = 'center', + CHANGE_KONVA = 'Change.konva', + CONTEXT_2D = '2d', + DASH = '-', + EMPTY_STRING = '', + LEFT = 'left', + TEXT = 'text', + TEXT_UPPER = 'Text', + MIDDLE = 'middle', + NORMAL = 'normal', + PX_SPACE = 'px ', + SPACE = ' ', + RIGHT = 'right', + WORD = 'word', + CHAR = 'char', + NONE = 'none', + ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'fontVariant', 'padding', 'align', 'lineHeight', 'text', 'width', 'height', 'wrap'], + + // cached variables + attrChangeListLen = ATTR_CHANGE_LIST.length, + dummyContext = Konva.Util.createCanvasElement().getContext(CONTEXT_2D); + + /** + * Text constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} [config.fontFamily] default is Arial + * @param {Number} [config.fontSize] in pixels. Default is 12 + * @param {String} [config.fontStyle] can be normal, bold, or italic. Default is normal + * @param {String} [config.fontVariant] can be normal or small-caps. Default is normal + * @param {String} config.text + * @param {String} [config.align] can be left, center, or right + * @param {Number} [config.padding] + * @param {Number} [config.width] default is auto + * @param {Number} [config.height] default is auto + * @param {Number} [config.lineHeight] default is 1 + * @param {String} [config.wrap] can be word, char, or none. Default is word + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var text = new Konva.Text({ + * x: 10, + * y: 15, + * text: 'Simple Text', + * fontSize: 30, + * fontFamily: 'Calibri', + * fill: 'green' + * }); + */ + Konva.Text = function(config) { + this.___init(config); + }; + function _fillFunc(context) { + context.fillText(this.partialText, 0, 0); + } + function _strokeFunc(context) { + context.strokeText(this.partialText, 0, 0); + } + + Konva.Text.prototype = { + ___init: function(config) { + config = config || {}; + + // set default color to black + if (!config.fillLinearGradientColorStops && !config.fillRadialGradientColorStops) { + config.fill = config.fill || 'black'; + } + + if (config.width === undefined) { + config.width = AUTO; + } + if (config.height === undefined) { + config.height = AUTO; + } + + // call super constructor + Konva.Shape.call(this, config); + + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this.className = TEXT_UPPER; + + // update text data for certain attr changes + for(var n = 0; n < attrChangeListLen; n++) { + this.on(ATTR_CHANGE_LIST[n] + CHANGE_KONVA, this._setTextData); + } + + this._setTextData(); + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _sceneFunc: function(context) { + var p = this.getPadding(), + textHeight = this.getTextHeight(), + lineHeightPx = this.getLineHeight() * textHeight, + textArr = this.textArr, + textArrLen = textArr.length, + totalWidth = this.getWidth(), + n; + + context.setAttr('font', this._getContextFont()); + + context.setAttr('textBaseline', MIDDLE); + context.setAttr('textAlign', LEFT); + context.save(); + if (p) { + context.translate(p, 0); + context.translate(0, p + textHeight / 2); + } else { + context.translate(0, textHeight / 2); + } + + + // draw text lines + for(n = 0; n < textArrLen; n++) { + var obj = textArr[n], + text = obj.text, + width = obj.width; + + // horizontal alignment + context.save(); + if(this.getAlign() === RIGHT) { + context.translate(totalWidth - width - p * 2, 0); + } + else if(this.getAlign() === CENTER) { + context.translate((totalWidth - width - p * 2) / 2, 0); + } + + this.partialText = text; + + context.fillStrokeShape(this); + context.restore(); + context.translate(0, lineHeightPx); + } + context.restore(); + }, + _hitFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(); + + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + }, + setText: function(text) { + var str = Konva.Util._isString(text) ? text : text.toString(); + this._setAttr(TEXT, str); + return this; + }, + /** + * get width of text area, which includes padding + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getWidth: function() { + return this.attrs.width === AUTO ? this.getTextWidth() + this.getPadding() * 2 : this.attrs.width; + }, + /** + * get the height of the text area, which takes into account multi-line text, line heights, and padding + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getHeight: function() { + return this.attrs.height === AUTO ? (this.getTextHeight() * this.textArr.length * this.getLineHeight()) + this.getPadding() * 2 : this.attrs.height; + }, + /** + * get text width + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getTextWidth: function() { + return this.textWidth; + }, + /** + * get text height + * @method + * @memberof Konva.Text.prototype + * @returns {Number} + */ + getTextHeight: function() { + return this.textHeight; + }, + _getTextSize: function(text) { + var _context = dummyContext, + fontSize = this.getFontSize(), + metrics; + + _context.save(); + _context.font = this._getContextFont(); + + metrics = _context.measureText(text); + _context.restore(); + return { + width: metrics.width, + height: parseInt(fontSize, 10) + }; + }, + _getContextFont: function() { + // IE don't want to work with usual font style + // bold was not working + // removing font variant will solve + // fix for: https://github.com/konvajs/konva/issues/94 + if (Konva.UA.isIE) { + return this.getFontStyle() + SPACE + this.getFontSize() + PX_SPACE + this.getFontFamily(); + } + return this.getFontStyle() + SPACE + + this.getFontVariant() + SPACE + + this.getFontSize() + PX_SPACE + + this.getFontFamily(); + }, + _addTextLine: function (line, width) { + return this.textArr.push({text: line, width: width}); + }, + _getTextWidth: function (text) { + return dummyContext.measureText(text).width; + }, + _setTextData: function () { + var lines = this.getText().split('\n'), + fontSize = +this.getFontSize(), + textWidth = 0, + lineHeightPx = this.getLineHeight() * fontSize, + width = this.attrs.width, + height = this.attrs.height, + fixedWidth = width !== AUTO, + fixedHeight = height !== AUTO, + padding = this.getPadding(), + maxWidth = width - padding * 2, + maxHeightPx = height - padding * 2, + currentHeightPx = 0, + wrap = this.getWrap(), + shouldWrap = wrap !== NONE, + wrapAtWord = wrap !== CHAR && shouldWrap; + + this.textArr = []; + dummyContext.save(); + dummyContext.font = this._getContextFont(); + for (var i = 0, max = lines.length; i < max; ++i) { + var line = lines[i], + lineWidth = this._getTextWidth(line); + if (fixedWidth && lineWidth > maxWidth) { + /* + * if width is fixed and line does not fit entirely + * break the line into multiple fitting lines + */ + while (line.length > 0) { + /* + * use binary search to find the longest substring that + * that would fit in the specified width + */ + var low = 0, high = line.length, + match = '', matchWidth = 0; + while (low < high) { + var mid = (low + high) >>> 1, + substr = line.slice(0, mid + 1), + substrWidth = this._getTextWidth(substr); + if (substrWidth <= maxWidth) { + low = mid + 1; + match = substr; + matchWidth = substrWidth; + } else { + high = mid; + } + } + /* + * 'low' is now the index of the substring end + * 'match' is the substring + * 'matchWidth' is the substring width in px + */ + if (match) { + // a fitting substring was found + if (wrapAtWord) { + // try to find a space or dash where wrapping could be done + var wrapIndex = Math.max(match.lastIndexOf(SPACE), + match.lastIndexOf(DASH)) + 1; + if (wrapIndex > 0) { + // re-cut the substring found at the space/dash position + low = wrapIndex; + match = match.slice(0, low); + matchWidth = this._getTextWidth(match); + } + } + this._addTextLine(match, matchWidth); + textWidth = Math.max(textWidth, matchWidth); + currentHeightPx += lineHeightPx; + if (!shouldWrap || + (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)) { + /* + * stop wrapping if wrapping is disabled or if adding + * one more line would overflow the fixed height + */ + break; + } + line = line.slice(low); + if (line.length > 0) { + // Check if the remaining text would fit on one line + lineWidth = this._getTextWidth(line); + if (lineWidth <= maxWidth) { + // if it does, add the line and break out of the loop + this._addTextLine(line, lineWidth); + currentHeightPx += lineHeightPx; + textWidth = Math.max(textWidth, lineWidth); + break; + } + } + } else { + // not even one character could fit in the element, abort + break; + } + } + } else { + // element width is automatically adjusted to max line width + this._addTextLine(line, lineWidth); + currentHeightPx += lineHeightPx; + textWidth = Math.max(textWidth, lineWidth); + } + // if element height is fixed, abort if adding one more line would overflow + if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) { + break; + } + } + dummyContext.restore(); + this.textHeight = fontSize; + this.textWidth = textWidth; + } + }; + Konva.Util.extend(Konva.Text, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Text, 'fontFamily', 'Arial'); + + /** + * get/set font family + * @name fontFamily + * @method + * @memberof Konva.Text.prototype + * @param {String} fontFamily + * @returns {String} + * @example + * // get font family + * var fontFamily = text.fontFamily(); + * + * // set font family + * text.fontFamily('Arial'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontSize', 12); + + /** + * get/set font size in pixels + * @name fontSize + * @method + * @memberof Konva.Text.prototype + * @param {Number} fontSize + * @returns {Number} + * @example + * // get font size + * var fontSize = text.fontSize(); + * + * // set font size to 22px + * text.fontSize(22); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontStyle', NORMAL); + + /** + * set font style. Can be 'normal', 'italic', or 'bold'. 'normal' is the default. + * @name fontStyle + * @method + * @memberof Konva.Text.prototype + * @param {String} fontStyle + * @returns {String} + * @example + * // get font style + * var fontStyle = text.fontStyle(); + * + * // set font style + * text.fontStyle('bold'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'fontVariant', NORMAL); + + /** + * set font variant. Can be 'normal' or 'small-caps'. 'normal' is the default. + * @name fontVariant + * @method + * @memberof Konva.Text.prototype + * @param {String} fontVariant + * @returns {String} + * @example + * // get font variant + * var fontVariant = text.fontVariant(); + * + * // set font variant + * text.fontVariant('small-caps'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'padding', 0); + + /** + * set padding + * @name padding + * @method + * @memberof Konva.Text.prototype + * @param {Number} padding + * @returns {Number} + * @example + * // get padding + * var padding = text.padding(); + * + * // set padding to 10 pixels + * text.padding(10); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'align', LEFT); + + /** + * get/set horizontal align of text. Can be 'left', 'center', or 'right' + * @name align + * @method + * @memberof Konva.Text.prototype + * @param {String} align + * @returns {String} + * @example + * // get text align + * var align = text.align(); + * + * // center text + * text.align('center'); + * + * // align text to right + * text.align('right'); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'lineHeight', 1); + + /** + * get/set line height. The default is 1. + * @name lineHeight + * @method + * @memberof Konva.Text.prototype + * @param {Number} lineHeight + * @returns {Number} + * @example + * // get line height + * var lineHeight = text.lineHeight(); + * + * // set the line height + * text.lineHeight(2); + */ + + Konva.Factory.addGetterSetter(Konva.Text, 'wrap', WORD); + + /** + * get/set wrap. Can be word, char, or none. Default is word. + * @name wrap + * @method + * @memberof Konva.Text.prototype + * @param {String} wrap + * @returns {String} + * @example + * // get wrap + * var wrap = text.wrap(); + * + * // set wrap + * text.wrap('word'); + */ + + Konva.Factory.addGetter(Konva.Text, 'text', EMPTY_STRING); + Konva.Factory.addOverloadedGetterSetter(Konva.Text, 'text'); + + /** + * get/set text + * @name getText + * @method + * @memberof Konva.Text.prototype + * @param {String} text + * @returns {String} + * @example + * // get text + * var text = text.text(); + * + * // set text + * text.text('Hello world!'); + */ + + Konva.Collection.mapMethods(Konva.Text); +})(); + +(function () { + 'use strict'; + /** + * Line constructor.  Lines are defined by an array of points and + * a tension + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Array} config.points + * @param {Number} [config.tension] Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @param {Boolean} [config.closed] defines whether or not the line shape is closed, creating a polygon or blob + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var line = new Konva.Line({ + * x: 100, + * y: 50, + * points: [73, 70, 340, 23, 450, 60, 500, 20], + * stroke: 'red', + * tension: 1 + * }); + */ + Konva.Line = function (config) { + this.___init(config); + }; + + Konva.Line.prototype = { + ___init: function (config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Line'; + + this.on('pointsChange.konva tensionChange.konva closedChange.konva', function () { + this._clearCache('tensionPoints'); + }); + + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function (context) { + var points = this.getPoints(), + length = points.length, + tension = this.getTension(), + closed = this.getClosed(), + tp, len, n; + + if (!length) { + return; + } + + context.beginPath(); + context.moveTo(points[0], points[1]); + + // tension + if (tension !== 0 && length > 4) { + tp = this.getTensionPoints(); + len = tp.length; + n = closed ? 0 : 4; + + if (!closed) { + context.quadraticCurveTo(tp[0], tp[1], tp[2], tp[3]); + } + + while (n < len - 2) { + context.bezierCurveTo(tp[n++], tp[n++], tp[n++], tp[n++], tp[n++], tp[n++]); + } + + if (!closed) { + context.quadraticCurveTo(tp[len - 2], tp[len - 1], points[length - 2], points[length - 1]); + } + } + // no tension + else { + for (n = 2; n < length; n += 2) { + context.lineTo(points[n], points[n + 1]); + } + } + + // closed e.g. polygons and blobs + if (closed) { + context.closePath(); + context.fillStrokeShape(this); + } + // open e.g. lines and splines + else { + context.strokeShape(this); + } + }, + getTensionPoints: function () { + return this._getCache('tensionPoints', this._getTensionPoints); + }, + _getTensionPoints: function () { + if (this.getClosed()) { + return this._getTensionPointsClosed(); + } else { + return Konva.Util._expandPoints(this.getPoints(), this.getTension()); + } + }, + _getTensionPointsClosed: function () { + var p = this.getPoints(), + len = p.length, + tension = this.getTension(), + util = Konva.Util, + firstControlPoints = util._getControlPoints( + p[len - 2], + p[len - 1], + p[0], + p[1], + p[2], + p[3], + tension + ), + lastControlPoints = util._getControlPoints( + p[len - 4], + p[len - 3], + p[len - 2], + p[len - 1], + p[0], + p[1], + tension + ), + middle = Konva.Util._expandPoints(p, tension), + tp = [ + firstControlPoints[2], + firstControlPoints[3] + ] + .concat(middle) + .concat([ + lastControlPoints[0], + lastControlPoints[1], + p[len - 2], + p[len - 1], + lastControlPoints[2], + lastControlPoints[3], + firstControlPoints[0], + firstControlPoints[1], + p[0], + p[1] + ]); + + return tp; + }, + getWidth: function () { + return this.getSelfRect().width; + }, + getHeight: function () { + return this.getSelfRect().height; + }, + // overload size detection + getSelfRect: function () { + var points; + if (this.getTension() !== 0) { + points = this._getTensionPoints(); + } else { + points = this.getPoints(); + } + var minX = points[0]; + var maxX = points[0]; + var minY = points[1]; + var maxY = points[1]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; + y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX), + y: Math.round(minY), + width: Math.round(maxX - minX), + height: Math.round(maxY - minY) + }; + } + }; + Konva.Util.extend(Konva.Line, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Line, 'closed', false); + + /** + * get/set closed flag. The default is false + * @name closed + * @method + * @memberof Konva.Line.prototype + * @param {Boolean} closed + * @returns {Boolean} + * @example + * // get closed flag + * var closed = line.closed(); + * + * // close the shape + * line.closed(true); + * + * // open the shape + * line.closed(false); + */ + + Konva.Factory.addGetterSetter(Konva.Line, 'tension', 0); + + /** + * get/set tension + * @name tension + * @method + * @memberof Konva.Line.prototype + * @param {Number} Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @returns {Number} + * @example + * // get tension + * var tension = line.tension(); + * + * // set tension + * line.tension(3); + */ + + Konva.Factory.addGetterSetter(Konva.Line, 'points', []); + /** + * get/set points array + * @name points + * @method + * @memberof Konva.Line.prototype + * @param {Array} points + * @returns {Array} + * @example + * // get points + * var points = line.points(); + * + * // set points + * line.points([10, 20, 30, 40, 50, 60]); + * + * // push a new point + * line.points(line.points().concat([70, 80])); + */ + + Konva.Collection.mapMethods(Konva.Line); +})(); + +(function() { + 'use strict'; + /** + * Sprite constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} config.animation animation key + * @param {Object} config.animations animation map + * @param {Integer} [config.frameIndex] animation frame index + * @param {Image} config.image image object + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var imageObj = new Image(); + * imageObj.onload = function() { + * var sprite = new Konva.Sprite({ + * x: 200, + * y: 100, + * image: imageObj, + * animation: 'standing', + * animations: { + * standing: [ + * // x, y, width, height (6 frames) + * 0, 0, 49, 109, + * 52, 0, 49, 109, + * 105, 0, 49, 109, + * 158, 0, 49, 109, + * 210, 0, 49, 109, + * 262, 0, 49, 109 + * ], + * kicking: [ + * // x, y, width, height (6 frames) + * 0, 109, 45, 98, + * 45, 109, 45, 98, + * 95, 109, 63, 98, + * 156, 109, 70, 98, + * 229, 109, 60, 98, + * 287, 109, 41, 98 + * ] + * }, + * frameRate: 7, + * frameIndex: 0 + * }); + * }; + * imageObj.src = '/path/to/image.jpg' + */ + Konva.Sprite = function(config) { + this.___init(config); + }; + + Konva.Sprite.prototype = { + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Sprite'; + + this._updated = true; + var that = this; + this.anim = new Konva.Animation(function() { + // if we don't need to redraw layer we should return false + var updated = that._updated; + that._updated = false; + return updated; + }); + this.on('animationChange.konva', function() { + // reset index when animation changes + this.frameIndex(0); + }); + this.on('frameIndexChange.konva', function() { + this._updated = true; + }); + // smooth change for frameRate + this.on('frameRateChange.konva', function() { + if (!this.anim.isRunning()) { + return; + } + clearInterval(this.interval); + this._setInterval(); + }); + + this.sceneFunc(this._sceneFunc); + this.hitFunc(this._hitFunc); + }, + _sceneFunc: function(context) { + var anim = this.getAnimation(), + index = this.frameIndex(), + ix4 = index * 4, + set = this.getAnimations()[anim], + offsets = this.frameOffsets(), + x = set[ix4 + 0], + y = set[ix4 + 1], + width = set[ix4 + 2], + height = set[ix4 + 3], + image = this.getImage(); + + if (this.hasFill() || this.hasStroke()) { + context.beginPath(); + context.rect(0, 0, width, height); + context.closePath(); + context.fillStrokeShape(this); + } + + if(image) { + if (offsets) { + var offset = offsets[anim], + ix2 = index * 2; + context.drawImage(image, x, y, width, height, offset[ix2 + 0], offset[ix2 + 1], width, height); + } else { + context.drawImage(image, x, y, width, height, 0, 0, width, height); + } + } + }, + _hitFunc: function(context) { + var anim = this.getAnimation(), + index = this.frameIndex(), + ix4 = index * 4, + set = this.getAnimations()[anim], + offsets = this.frameOffsets(), + width = set[ix4 + 2], + height = set[ix4 + 3]; + + context.beginPath(); + if (offsets) { + var offset = offsets[anim]; + var ix2 = index * 2; + context.rect(offset[ix2 + 0], offset[ix2 + 1], width, height); + } else { + context.rect(0, 0, width, height); + } + context.closePath(); + context.fillShape(this); + }, + _useBufferCanvas: function() { + return (this.hasShadow() || this.getAbsoluteOpacity() !== 1) && this.hasStroke(); + }, + _setInterval: function() { + var that = this; + this.interval = setInterval(function() { + that._updateIndex(); + }, 1000 / this.getFrameRate()); + }, + /** + * start sprite animation + * @method + * @memberof Konva.Sprite.prototype + */ + start: function() { + var layer = this.getLayer(); + + /* + * animation object has no executable function because + * the updates are done with a fixed FPS with the setInterval + * below. The anim object only needs the layer reference for + * redraw + */ + this.anim.setLayers(layer); + this._setInterval(); + this.anim.start(); + }, + /** + * stop sprite animation + * @method + * @memberof Konva.Sprite.prototype + */ + stop: function() { + this.anim.stop(); + clearInterval(this.interval); + }, + /** + * determine if animation of sprite is running or not. returns true or false + * @method + * @memberof Konva.Animation.prototype + * @returns {Boolean} + */ + isRunning: function() { + return this.anim.isRunning(); + }, + _updateIndex: function() { + var index = this.frameIndex(), + animation = this.getAnimation(), + animations = this.getAnimations(), + anim = animations[animation], + len = anim.length / 4; + + if(index < len - 1) { + this.frameIndex(index + 1); + } + else { + this.frameIndex(0); + } + } + }; + Konva.Util.extend(Konva.Sprite, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Sprite, 'animation'); + + /** + * get/set animation key + * @name animation + * @method + * @memberof Konva.Sprite.prototype + * @param {String} anim animation key + * @returns {String} + * @example + * // get animation key + * var animation = sprite.animation(); + * + * // set animation key + * sprite.animation('kicking'); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'animations'); + + /** + * get/set animations map + * @name animations + * @method + * @memberof Konva.Sprite.prototype + * @param {Object} animations + * @returns {Object} + * @example + * // get animations map + * var animations = sprite.animations(); + * + * // set animations map + * sprite.animations({ + * standing: [ + * // x, y, width, height (6 frames) + * 0, 0, 49, 109, + * 52, 0, 49, 109, + * 105, 0, 49, 109, + * 158, 0, 49, 109, + * 210, 0, 49, 109, + * 262, 0, 49, 109 + * ], + * kicking: [ + * // x, y, width, height (6 frames) + * 0, 109, 45, 98, + * 45, 109, 45, 98, + * 95, 109, 63, 98, + * 156, 109, 70, 98, + * 229, 109, 60, 98, + * 287, 109, 41, 98 + * ] + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameOffsets'); + + /** + * get/set offsets map + * @name offsets + * @method + * @memberof Konva.Sprite.prototype + * @param {Object} offsets + * @returns {Object} + * @example + * // get offsets map + * var offsets = sprite.offsets(); + * + * // set offsets map + * sprite.offsets({ + * standing: [ + * // x, y (6 frames) + * 0, 0, + * 0, 0, + * 5, 0, + * 0, 0, + * 0, 3, + * 2, 0 + * ], + * kicking: [ + * // x, y (6 frames) + * 0, 5, + * 5, 0, + * 10, 0, + * 0, 0, + * 2, 1, + * 0, 0 + * ] + * }); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'image'); + + /** + * get/set image + * @name image + * @method + * @memberof Konva.Sprite.prototype + * @param {Image} image + * @returns {Image} + * @example + * // get image + * var image = sprite.image(); + * + * // set image + * sprite.image(imageObj); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameIndex', 0); + + /** + * set/set animation frame index + * @name frameIndex + * @method + * @memberof Konva.Sprite.prototype + * @param {Integer} frameIndex + * @returns {Integer} + * @example + * // get animation frame index + * var frameIndex = sprite.frameIndex(); + * + * // set animation frame index + * sprite.frameIndex(3); + */ + + Konva.Factory.addGetterSetter(Konva.Sprite, 'frameRate', 17); + + /** + * get/set frame rate in frames per second. Increase this number to make the sprite + * animation run faster, and decrease the number to make the sprite animation run slower + * The default is 17 frames per second + * @name frameRate + * @method + * @memberof Konva.Sprite.prototype + * @param {Integer} frameRate + * @returns {Integer} + * @example + * // get frame rate + * var frameRate = sprite.frameRate(); + * + * // set frame rate to 2 frames per second + * sprite.frameRate(2); + */ + + Konva.Factory.backCompat(Konva.Sprite, { + index: 'frameIndex', + getIndex: 'getFrameIndex', + setIndex: 'setFrameIndex' + }); + + Konva.Collection.mapMethods(Konva.Sprite); +})(); + +/*eslint-disable no-shadow, max-len, max-depth */ +(function () { + 'use strict'; + /** + * Path constructor. + * @author Jason Follas + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} config.data SVG data string + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var path = new Konva.Path({ + * x: 240, + * y: 40, + * data: 'M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z', + * fill: 'green', + * scale: 2 + * }); + */ + Konva.Path = function (config) { + this.___init(config); + }; + + Konva.Path.prototype = { + ___init: function (config) { + this.dataArray = []; + var that = this; + + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Path'; + + this.dataArray = Konva.Path.parsePathData(this.getData()); + this.on('dataChange.konva', function () { + that.dataArray = Konva.Path.parsePathData(this.getData()); + }); + + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var ca = this.dataArray; + + // context position + context.beginPath(); + for (var n = 0; n < ca.length; n++) { + var c = ca[n].command; + var p = ca[n].points; + switch (c) { + case 'L': + context.lineTo(p[0], p[1]); + break; + case 'M': + context.moveTo(p[0], p[1]); + break; + case 'C': + context.bezierCurveTo(p[0], p[1], p[2], p[3], p[4], p[5]); + break; + case 'Q': + context.quadraticCurveTo(p[0], p[1], p[2], p[3]); + break; + case 'A': + var cx = p[0], cy = p[1], rx = p[2], ry = p[3], theta = p[4], dTheta = p[5], psi = p[6], fs = p[7]; + + var r = (rx > ry) ? rx : ry; + var scaleX = (rx > ry) ? 1 : rx / ry; + var scaleY = (rx > ry) ? ry / rx : 1; + + context.translate(cx, cy); + context.rotate(psi); + context.scale(scaleX, scaleY); + context.arc(0, 0, r, theta, theta + dTheta, 1 - fs); + context.scale(1 / scaleX, 1 / scaleY); + context.rotate(-psi); + context.translate(-cx, -cy); + + break; + case 'z': + context.closePath(); + break; + } + } + + context.fillStrokeShape(this); + }, + getSelfRect: function() { + var points = []; + this.dataArray.forEach(function(data) { + points = points.concat(data.points); + }); + var minX = points[0]; + var maxX = points[0]; + var minY = points[1]; + var maxY = points[1]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX), + y: Math.round(minY), + width: Math.round(maxX - minX), + height: Math.round(maxY - minY) + }; + } + }; + Konva.Util.extend(Konva.Path, Konva.Shape); + + Konva.Path.getLineLength = function(x1, y1, x2, y2) { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + }; + Konva.Path.getPointOnLine = function(dist, P1x, P1y, P2x, P2y, fromX, fromY) { + if(fromX === undefined) { + fromX = P1x; + } + if(fromY === undefined) { + fromY = P1y; + } + + var m = (P2y - P1y) / ((P2x - P1x) + 0.00000001); + var run = Math.sqrt(dist * dist / (1 + m * m)); + if(P2x < P1x) { + run *= -1; + } + var rise = m * run; + var pt; + + if (P2x === P1x) { // vertical line + pt = { + x: fromX, + y: fromY + rise + }; + } else if((fromY - P1y) / ((fromX - P1x) + 0.00000001) === m) { + pt = { + x: fromX + run, + y: fromY + rise + }; + } + else { + var ix, iy; + + var len = this.getLineLength(P1x, P1y, P2x, P2y); + if(len < 0.00000001) { + return undefined; + } + var u = (((fromX - P1x) * (P2x - P1x)) + ((fromY - P1y) * (P2y - P1y))); + u = u / (len * len); + ix = P1x + u * (P2x - P1x); + iy = P1y + u * (P2y - P1y); + + var pRise = this.getLineLength(fromX, fromY, ix, iy); + var pRun = Math.sqrt(dist * dist - pRise * pRise); + run = Math.sqrt(pRun * pRun / (1 + m * m)); + if(P2x < P1x) { + run *= -1; + } + rise = m * run; + pt = { + x: ix + run, + y: iy + rise + }; + } + + return pt; + }; + + Konva.Path.getPointOnCubicBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y, P4x, P4y) { + function CB1(t) { + return t * t * t; + } + function CB2(t) { + return 3 * t * t * (1 - t); + } + function CB3(t) { + return 3 * t * (1 - t) * (1 - t); + } + function CB4(t) { + return (1 - t) * (1 - t) * (1 - t); + } + var x = P4x * CB1(pct) + P3x * CB2(pct) + P2x * CB3(pct) + P1x * CB4(pct); + var y = P4y * CB1(pct) + P3y * CB2(pct) + P2y * CB3(pct) + P1y * CB4(pct); + + return { + x: x, + y: y + }; + }; + Konva.Path.getPointOnQuadraticBezier = function(pct, P1x, P1y, P2x, P2y, P3x, P3y) { + function QB1(t) { + return t * t; + } + function QB2(t) { + return 2 * t * (1 - t); + } + function QB3(t) { + return (1 - t) * (1 - t); + } + var x = P3x * QB1(pct) + P2x * QB2(pct) + P1x * QB3(pct); + var y = P3y * QB1(pct) + P2y * QB2(pct) + P1y * QB3(pct); + + return { + x: x, + y: y + }; + }; + Konva.Path.getPointOnEllipticalArc = function(cx, cy, rx, ry, theta, psi) { + var cosPsi = Math.cos(psi), sinPsi = Math.sin(psi); + var pt = { + x: rx * Math.cos(theta), + y: ry * Math.sin(theta) + }; + return { + x: cx + (pt.x * cosPsi - pt.y * sinPsi), + y: cy + (pt.x * sinPsi + pt.y * cosPsi) + }; + }; + /* + * get parsed data array from the data + * string. V, v, H, h, and l data are converted to + * L data for the purpose of high performance Path + * rendering + */ + Konva.Path.parsePathData = function(data) { + // Path Data Segment must begin with a moveTo + //m (x y)+ Relative moveTo (subsequent points are treated as lineTo) + //M (x y)+ Absolute moveTo (subsequent points are treated as lineTo) + //l (x y)+ Relative lineTo + //L (x y)+ Absolute LineTo + //h (x)+ Relative horizontal lineTo + //H (x)+ Absolute horizontal lineTo + //v (y)+ Relative vertical lineTo + //V (y)+ Absolute vertical lineTo + //z (closepath) + //Z (closepath) + //c (x1 y1 x2 y2 x y)+ Relative Bezier curve + //C (x1 y1 x2 y2 x y)+ Absolute Bezier curve + //q (x1 y1 x y)+ Relative Quadratic Bezier + //Q (x1 y1 x y)+ Absolute Quadratic Bezier + //t (x y)+ Shorthand/Smooth Relative Quadratic Bezier + //T (x y)+ Shorthand/Smooth Absolute Quadratic Bezier + //s (x2 y2 x y)+ Shorthand/Smooth Relative Bezier curve + //S (x2 y2 x y)+ Shorthand/Smooth Absolute Bezier curve + //a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ Relative Elliptical Arc + //A (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ Absolute Elliptical Arc + + // return early if data is not defined + if(!data) { + return []; + } + + // command string + var cs = data; + + // command chars + var cc = ['m', 'M', 'l', 'L', 'v', 'V', 'h', 'H', 'z', 'Z', 'c', 'C', 'q', 'Q', 't', 'T', 's', 'S', 'a', 'A']; + // convert white spaces to commas + cs = cs.replace(new RegExp(' ', 'g'), ','); + // create pipes so that we can split the data + for(var n = 0; n < cc.length; n++) { + cs = cs.replace(new RegExp(cc[n], 'g'), '|' + cc[n]); + } + // create array + var arr = cs.split('|'); + var ca = []; + // init context point + var cpx = 0; + var cpy = 0; + for( n = 1; n < arr.length; n++) { + var str = arr[n]; + var c = str.charAt(0); + str = str.slice(1); + // remove ,- for consistency + str = str.replace(new RegExp(',-', 'g'), '-'); + // add commas so that it's easy to split + str = str.replace(new RegExp('-', 'g'), ',-'); + str = str.replace(new RegExp('e,-', 'g'), 'e-'); + var p = str.split(','); + if(p.length > 0 && p[0] === '') { + p.shift(); + } + // convert strings to floats + for(var i = 0; i < p.length; i++) { + p[i] = parseFloat(p[i]); + } + while(p.length > 0) { + if(isNaN(p[0])) {// case for a trailing comma before next command + break; + } + + var cmd = null; + var points = []; + var startX = cpx, startY = cpy; + // Move var from within the switch to up here (jshint) + var prevCmd, ctlPtx, ctlPty; // Ss, Tt + var rx, ry, psi, fa, fs, x1, y1; // Aa + + + // convert l, H, h, V, and v to L + switch (c) { + + // Note: Keep the lineTo's above the moveTo's in this switch + case 'l': + cpx += p.shift(); + cpy += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'L': + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + + // Note: lineTo handlers need to be above this point + case 'm': + var dx = p.shift(); + var dy = p.shift(); + cpx += dx; + cpy += dy; + cmd = 'M'; + // After closing the path move the current position + // to the the first point of the path (if any). + if(ca.length > 2 && ca[ca.length - 1].command === 'z'){ + for(var idx = ca.length - 2; idx >= 0; idx--){ + if(ca[idx].command === 'M'){ + cpx = ca[idx].points[0] + dx; + cpy = ca[idx].points[1] + dy; + break; + } + } + } + points.push(cpx, cpy); + c = 'l'; + // subsequent points are treated as relative lineTo + break; + case 'M': + cpx = p.shift(); + cpy = p.shift(); + cmd = 'M'; + points.push(cpx, cpy); + c = 'L'; + // subsequent points are treated as absolute lineTo + break; + + case 'h': + cpx += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'H': + cpx = p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'v': + cpy += p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'V': + cpy = p.shift(); + cmd = 'L'; + points.push(cpx, cpy); + break; + case 'C': + points.push(p.shift(), p.shift(), p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + case 'c': + points.push(cpx + p.shift(), cpy + p.shift(), cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 'S': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'C') { + ctlPtx = cpx + (cpx - prevCmd.points[2]); + ctlPty = cpy + (cpy - prevCmd.points[3]); + } + points.push(ctlPtx, ctlPty, p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 's': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'C') { + ctlPtx = cpx + (cpx - prevCmd.points[2]); + ctlPty = cpy + (cpy - prevCmd.points[3]); + } + points.push(ctlPtx, ctlPty, cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'C'; + points.push(cpx, cpy); + break; + case 'Q': + points.push(p.shift(), p.shift()); + cpx = p.shift(); + cpy = p.shift(); + points.push(cpx, cpy); + break; + case 'q': + points.push(cpx + p.shift(), cpy + p.shift()); + cpx += p.shift(); + cpy += p.shift(); + cmd = 'Q'; + points.push(cpx, cpy); + break; + case 'T': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'Q') { + ctlPtx = cpx + (cpx - prevCmd.points[0]); + ctlPty = cpy + (cpy - prevCmd.points[1]); + } + cpx = p.shift(); + cpy = p.shift(); + cmd = 'Q'; + points.push(ctlPtx, ctlPty, cpx, cpy); + break; + case 't': + ctlPtx = cpx; + ctlPty = cpy; + prevCmd = ca[ca.length - 1]; + if(prevCmd.command === 'Q') { + ctlPtx = cpx + (cpx - prevCmd.points[0]); + ctlPty = cpy + (cpy - prevCmd.points[1]); + } + cpx += p.shift(); + cpy += p.shift(); + cmd = 'Q'; + points.push(ctlPtx, ctlPty, cpx, cpy); + break; + case 'A': + rx = p.shift(); + ry = p.shift(); + psi = p.shift(); + fa = p.shift(); + fs = p.shift(); + x1 = cpx; + y1 = cpy; + cpx = p.shift(); + cpy = p.shift(); + cmd = 'A'; + points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); + break; + case 'a': + rx = p.shift(); + ry = p.shift(); + psi = p.shift(); + fa = p.shift(); + fs = p.shift(); + x1 = cpx; + y1 = cpy; cpx += p.shift(); + cpy += p.shift(); + cmd = 'A'; + points = this.convertEndpointToCenterParameterization(x1, y1, cpx, cpy, fa, fs, rx, ry, psi); + break; + } + + ca.push({ + command: cmd || c, + points: points, + start: { + x: startX, + y: startY + }, + pathLength: this.calcLength(startX, startY, cmd || c, points) + }); + } + + if(c === 'z' || c === 'Z') { + ca.push({ + command: 'z', + points: [], + start: undefined, + pathLength: 0 + }); + } + } + + return ca; + }; + Konva.Path.calcLength = function(x, y, cmd, points) { + var len, p1, p2, t; + var path = Konva.Path; + + switch (cmd) { + case 'L': + return path.getLineLength(x, y, points[0], points[1]); + case 'C': + // Approximates by breaking curve into 100 line segments + len = 0.0; + p1 = path.getPointOnCubicBezier(0, x, y, points[0], points[1], points[2], points[3], points[4], points[5]); + for( t = 0.01; t <= 1; t += 0.01) { + p2 = path.getPointOnCubicBezier(t, x, y, points[0], points[1], points[2], points[3], points[4], points[5]); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + return len; + case 'Q': + // Approximates by breaking curve into 100 line segments + len = 0.0; + p1 = path.getPointOnQuadraticBezier(0, x, y, points[0], points[1], points[2], points[3]); + for( t = 0.01; t <= 1; t += 0.01) { + p2 = path.getPointOnQuadraticBezier(t, x, y, points[0], points[1], points[2], points[3]); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + return len; + case 'A': + // Approximates by breaking curve into line segments + len = 0.0; + var start = points[4]; + // 4 = theta + var dTheta = points[5]; + // 5 = dTheta + var end = points[4] + dTheta; + var inc = Math.PI / 180.0; + // 1 degree resolution + if(Math.abs(start - end) < inc) { + inc = Math.abs(start - end); + } + // Note: for purpose of calculating arc length, not going to worry about rotating X-axis by angle psi + p1 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], start, 0); + if(dTheta < 0) {// clockwise + for( t = start - inc; t > end; t -= inc) { + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + } + else {// counter-clockwise + for( t = start + inc; t < end; t += inc) { + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + p1 = p2; + } + } + p2 = path.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], end, 0); + len += path.getLineLength(p1.x, p1.y, p2.x, p2.y); + + return len; + } + + return 0; + }; + Konva.Path.convertEndpointToCenterParameterization = function(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg) { + // Derived from: http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes + var psi = psiDeg * (Math.PI / 180.0); + var xp = Math.cos(psi) * (x1 - x2) / 2.0 + Math.sin(psi) * (y1 - y2) / 2.0; + var yp = -1 * Math.sin(psi) * (x1 - x2) / 2.0 + Math.cos(psi) * (y1 - y2) / 2.0; + + var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); + + if(lambda > 1) { + rx *= Math.sqrt(lambda); + ry *= Math.sqrt(lambda); + } + + var f = Math.sqrt((((rx * rx) * (ry * ry)) - ((rx * rx) * (yp * yp)) - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp) + (ry * ry) * (xp * xp))); + + if(fa === fs) { + f *= -1; + } + if(isNaN(f)) { + f = 0; + } + + var cxp = f * rx * yp / ry; + var cyp = f * -ry * xp / rx; + + var cx = (x1 + x2) / 2.0 + Math.cos(psi) * cxp - Math.sin(psi) * cyp; + var cy = (y1 + y2) / 2.0 + Math.sin(psi) * cxp + Math.cos(psi) * cyp; + + var vMag = function(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1]); + }; + var vRatio = function(u, v) { + return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)); + }; + var vAngle = function(u, v) { + return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v)); + }; + var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]); + var u = [(xp - cxp) / rx, (yp - cyp) / ry]; + var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; + var dTheta = vAngle(u, v); + + if(vRatio(u, v) <= -1) { + dTheta = Math.PI; + } + if(vRatio(u, v) >= 1) { + dTheta = 0; + } + if(fs === 0 && dTheta > 0) { + dTheta = dTheta - 2 * Math.PI; + } + if(fs === 1 && dTheta < 0) { + dTheta = dTheta + 2 * Math.PI; + } + return [cx, cy, rx, ry, theta, dTheta, psi, fs]; + }; + // add getters setters + Konva.Factory.addGetterSetter(Konva.Path, 'data'); + + /** + * set SVG path data string. This method + * also automatically parses the data string + * into a data array. Currently supported SVG data: + * M, m, L, l, H, h, V, v, Q, q, T, t, C, c, S, s, A, a, Z, z + * @name setData + * @method + * @memberof Konva.Path.prototype + * @param {String} SVG path command string + */ + + /** + * get SVG path data string + * @name getData + * @method + * @memberof Konva.Path.prototype + */ + + Konva.Collection.mapMethods(Konva.Path); +})(); + +(function() { + 'use strict'; + var EMPTY_STRING = '', + //CALIBRI = 'Calibri', + NORMAL = 'normal'; + + /** + * Path constructor. + * @author Jason Follas + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {String} [config.fontFamily] default is Calibri + * @param {Number} [config.fontSize] default is 12 + * @param {String} [config.fontStyle] can be normal, bold, or italic. Default is normal + * @param {String} [config.fontVariant] can be normal or small-caps. Default is normal + * @param {String} config.text + * @param {String} config.data SVG data string + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var textpath = new Konva.TextPath({ + * x: 100, + * y: 50, + * fill: '#333', + * fontSize: '24', + * fontFamily: 'Arial', + * text: 'All the world\'s a stage, and all the men and women merely players.', + * data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50' + * }); + */ + Konva.TextPath = function(config) { + this.___init(config); + }; + + function _fillFunc(context) { + context.fillText(this.partialText, 0, 0); + } + function _strokeFunc(context) { + context.strokeText(this.partialText, 0, 0); + } + + Konva.TextPath.prototype = { + ___init: function(config) { + var that = this; + this.dummyCanvas = Konva.Util.createCanvasElement(); + this.dataArray = []; + + // call super constructor + Konva.Shape.call(this, config); + + // overrides + // TODO: shouldn't this be on the prototype? + this._fillFunc = _fillFunc; + this._strokeFunc = _strokeFunc; + this._fillFuncHit = _fillFunc; + this._strokeFuncHit = _strokeFunc; + + this.className = 'TextPath'; + + this.dataArray = Konva.Path.parsePathData(this.attrs.data); + this.on('dataChange.konva', function() { + that.dataArray = Konva.Path.parsePathData(this.attrs.data); + }); + + // update text data for certain attr changes + this.on('textChange.konva textStroke.konva textStrokeWidth.konva', that._setTextData); + that._setTextData(); + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + context.setAttr('font', this._getContextFont()); + context.setAttr('textBaseline', 'middle'); + context.setAttr('textAlign', 'left'); + context.save(); + + var glyphInfo = this.glyphInfo; + for(var i = 0; i < glyphInfo.length; i++) { + context.save(); + + var p0 = glyphInfo[i].p0; + + context.translate(p0.x, p0.y); + context.rotate(glyphInfo[i].rotation); + this.partialText = glyphInfo[i].text; + + context.fillStrokeShape(this); + context.restore(); + + //// To assist with debugging visually, uncomment following + // context.beginPath(); + // if (i % 2) + // context.strokeStyle = 'cyan'; + // else + // context.strokeStyle = 'green'; + // var p1 = glyphInfo[i].p1; + // context.moveTo(p0.x, p0.y); + // context.lineTo(p1.x, p1.y); + // context.stroke(); + } + context.restore(); + }, + /** + * get text width in pixels + * @method + * @memberof Konva.TextPath.prototype + */ + getTextWidth: function() { + return this.textWidth; + }, + /** + * get text height in pixels + * @method + * @memberof Konva.TextPath.prototype + */ + getTextHeight: function() { + return this.textHeight; + }, + /** + * set text + * @method + * @memberof Konva.TextPath.prototype + * @param {String} text + */ + setText: function(text) { + Konva.Text.prototype.setText.call(this, text); + }, + _getTextSize: function(text) { + var dummyCanvas = this.dummyCanvas; + var _context = dummyCanvas.getContext('2d'); + + _context.save(); + + _context.font = this._getContextFont(); + var metrics = _context.measureText(text); + + _context.restore(); + + return { + width: metrics.width, + height: parseInt(this.attrs.fontSize, 10) + }; + }, + _setTextData: function() { + + var that = this; + var size = this._getTextSize(this.attrs.text); + this.textWidth = size.width; + this.textHeight = size.height; + + this.glyphInfo = []; + + var charArr = this.attrs.text.split(''); + + var p0, p1, pathCmd; + + var pIndex = -1; + var currentT = 0; + + var getNextPathSegment = function() { + currentT = 0; + var pathData = that.dataArray; + + for(var j = pIndex + 1; j < pathData.length; j++) { + if(pathData[j].pathLength > 0) { + pIndex = j; + + return pathData[j]; + } + else if(pathData[j].command === 'M') { + p0 = { + x: pathData[j].points[0], + y: pathData[j].points[1] + }; + } + } + + return {}; + }; + var findSegmentToFitCharacter = function(c) { + + var glyphWidth = that._getTextSize(c).width; + + var currLen = 0; + var attempts = 0; + + p1 = undefined; + while(Math.abs(glyphWidth - currLen) / glyphWidth > 0.01 && attempts < 25) { + attempts++; + var cumulativePathLength = currLen; + while(pathCmd === undefined) { + pathCmd = getNextPathSegment(); + + if(pathCmd && cumulativePathLength + pathCmd.pathLength < glyphWidth) { + cumulativePathLength += pathCmd.pathLength; + pathCmd = undefined; + } + } + + if(pathCmd === {} || p0 === undefined) { + return undefined; + } + + var needNewSegment = false; + + switch (pathCmd.command) { + case 'L': + if(Konva.Path.getLineLength(p0.x, p0.y, pathCmd.points[0], pathCmd.points[1]) > glyphWidth) { + p1 = Konva.Path.getPointOnLine(glyphWidth, p0.x, p0.y, pathCmd.points[0], pathCmd.points[1], p0.x, p0.y); + } + else { + pathCmd = undefined; + } + break; + case 'A': + + var start = pathCmd.points[4]; + // 4 = theta + var dTheta = pathCmd.points[5]; + // 5 = dTheta + var end = pathCmd.points[4] + dTheta; + + if(currentT === 0){ + currentT = start + 0.00000001; + } + // Just in case start is 0 + else if(glyphWidth > currLen) { + currentT += (Math.PI / 180.0) * dTheta / Math.abs(dTheta); + } + else { + currentT -= Math.PI / 360.0 * dTheta / Math.abs(dTheta); + } + + // Credit for bug fix: @therth https://github.com/ericdrowell/KonvaJS/issues/249 + // Old code failed to render text along arc of this path: "M 50 50 a 150 50 0 0 1 250 50 l 50 0" + if(dTheta < 0 && currentT < end || dTheta >= 0 && currentT > end) { + currentT = end; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnEllipticalArc(pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], currentT, pathCmd.points[6]); + break; + case 'C': + if(currentT === 0) { + if(glyphWidth > pathCmd.pathLength) { + currentT = 0.00000001; + } + else { + currentT = glyphWidth / pathCmd.pathLength; + } + } + else if(glyphWidth > currLen) { + currentT += (glyphWidth - currLen) / pathCmd.pathLength; + } + else { + currentT -= (currLen - glyphWidth) / pathCmd.pathLength; + } + + if(currentT > 1.0) { + currentT = 1.0; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnCubicBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3], pathCmd.points[4], pathCmd.points[5]); + break; + case 'Q': + if(currentT === 0) { + currentT = glyphWidth / pathCmd.pathLength; + } + else if(glyphWidth > currLen) { + currentT += (glyphWidth - currLen) / pathCmd.pathLength; + } + else { + currentT -= (currLen - glyphWidth) / pathCmd.pathLength; + } + + if(currentT > 1.0) { + currentT = 1.0; + needNewSegment = true; + } + p1 = Konva.Path.getPointOnQuadraticBezier(currentT, pathCmd.start.x, pathCmd.start.y, pathCmd.points[0], pathCmd.points[1], pathCmd.points[2], pathCmd.points[3]); + break; + + } + + if(p1 !== undefined) { + currLen = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y); + } + + if(needNewSegment) { + needNewSegment = false; + pathCmd = undefined; + } + } + }; + for(var i = 0; i < charArr.length; i++) { + + // Find p1 such that line segment between p0 and p1 is approx. width of glyph + findSegmentToFitCharacter(charArr[i]); + + if(p0 === undefined || p1 === undefined) { + break; + } + + var width = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y); + + // Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used. + // Can foresee having a rough pair table built in that the developer can override as needed. + + var kern = 0; + // placeholder for future implementation + + var midpoint = Konva.Path.getPointOnLine(kern + width / 2.0, p0.x, p0.y, p1.x, p1.y); + + var rotation = Math.atan2((p1.y - p0.y), (p1.x - p0.x)); + this.glyphInfo.push({ + transposeX: midpoint.x, + transposeY: midpoint.y, + text: charArr[i], + rotation: rotation, + p0: p0, + p1: p1 + }); + p0 = p1; + } + }, + getSelfRect: function() { + var points = []; + var fontSize = this.fontSize(); + + this.glyphInfo.forEach(function(info) { + points.push(info.p0.x); + points.push(info.p0.y); + points.push(info.p1.x); + points.push(info.p1.y); + }); + var minX = points[0]; + var maxX = points[0]; + var minY = points[0]; + var maxY = points[0]; + var x, y; + for (var i = 0; i < points.length / 2; i++) { + x = points[i * 2]; y = points[i * 2 + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + return { + x: Math.round(minX) - fontSize, + y: Math.round(minY) - fontSize, + width: Math.round(maxX - minX) + fontSize * 2, + height: Math.round(maxY - minY) + fontSize * 2 + }; + } + }; + + // map TextPath methods to Text + Konva.TextPath.prototype._getContextFont = Konva.Text.prototype._getContextFont; + + Konva.Util.extend(Konva.TextPath, Konva.Shape); + + // add setters and getters + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontFamily', 'Arial'); + + /** + * set font family + * @name setFontFamily + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontFamily + */ + + /** + * get font family + * @name getFontFamily + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontSize', 12); + + /** + * set font size + * @name setFontSize + * @method + * @memberof Konva.TextPath.prototype + * @param {int} fontSize + */ + + /** + * get font size + * @name getFontSize + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontStyle', NORMAL); + + /** + * set font style. Can be 'normal', 'italic', or 'bold'. 'normal' is the default. + * @name setFontStyle + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontStyle + */ + + /** + * get font style + * @name getFontStyle + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetterSetter(Konva.TextPath, 'fontVariant', NORMAL); + + /** + * set font variant. Can be 'normal' or 'small-caps'. 'normal' is the default. + * @name setFontVariant + * @method + * @memberof Konva.TextPath.prototype + * @param {String} fontVariant + */ + + /** + * @get font variant + * @name getFontVariant + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Factory.addGetter(Konva.TextPath, 'text', EMPTY_STRING); + + /** + * get text + * @name getText + * @method + * @memberof Konva.TextPath.prototype + */ + + Konva.Collection.mapMethods(Konva.TextPath); +})(); + +(function() { + 'use strict'; + /** + * RegularPolygon constructor.  Examples include triangles, squares, pentagons, hexagons, etc. + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Number} config.sides + * @param {Number} config.radius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var hexagon = new Konva.RegularPolygon({ + * x: 100, + * y: 200, + * sides: 6, + * radius: 70, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 4 + * }); + */ + Konva.RegularPolygon = function(config) { + this.___init(config); + }; + + Konva.RegularPolygon.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'RegularPolygon'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var sides = this.attrs.sides, + radius = this.attrs.radius, + n, x, y; + + context.beginPath(); + context.moveTo(0, 0 - radius); + + for(n = 1; n < sides; n++) { + x = radius * Math.sin(n * 2 * Math.PI / sides); + y = -1 * radius * Math.cos(n * 2 * Math.PI / sides); + context.lineTo(x, y); + } + context.closePath(); + context.fillStrokeShape(this); + }, + getWidth: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.radius() !== width / 2) { + this.setRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.radius() !== height / 2) { + this.setRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.RegularPolygon, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.RegularPolygon, 'radius', 0); + + /** + * set radius + * @name setRadius + * @method + * @memberof Konva.RegularPolygon.prototype + * @param {Number} radius + */ + + /** + * get radius + * @name getRadius + * @method + * @memberof Konva.RegularPolygon.prototype + */ + + Konva.Factory.addGetterSetter(Konva.RegularPolygon, 'sides', 0); + + /** + * set number of sides + * @name setSides + * @method + * @memberof Konva.RegularPolygon.prototype + * @param {int} sides + */ + + /** + * get number of sides + * @name getSides + * @method + * @memberof Konva.RegularPolygon.prototype + */ + + Konva.Collection.mapMethods(Konva.RegularPolygon); +})(); + +(function() { + 'use strict'; + /** + * Star constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Integer} config.numPoints + * @param {Number} config.innerRadius + * @param {Number} config.outerRadius + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var star = new Konva.Star({ + * x: 100, + * y: 200, + * numPoints: 5, + * innerRadius: 70, + * outerRadius: 70, + * fill: 'red', + * stroke: 'black', + * strokeWidth: 4 + * }); + */ + Konva.Star = function(config) { + this.___init(config); + }; + + Konva.Star.prototype = { + _centroid: true, + ___init: function(config) { + // call super constructor + Konva.Shape.call(this, config); + this.className = 'Star'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var innerRadius = this.innerRadius(), + outerRadius = this.outerRadius(), + numPoints = this.numPoints(); + + context.beginPath(); + context.moveTo(0, 0 - outerRadius); + + for(var n = 1; n < numPoints * 2; n++) { + var radius = n % 2 === 0 ? outerRadius : innerRadius; + var x = radius * Math.sin(n * Math.PI / numPoints); + var y = -1 * radius * Math.cos(n * Math.PI / numPoints); + context.lineTo(x, y); + } + context.closePath(); + + context.fillStrokeShape(this); + }, + // implements Shape.prototype.getWidth() + getWidth: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.getHeight() + getHeight: function() { + return this.getOuterRadius() * 2; + }, + // implements Shape.prototype.setWidth() + setWidth: function(width) { + Konva.Node.prototype.setWidth.call(this, width); + if (this.outerRadius() !== width / 2) { + this.setOuterRadius(width / 2); + } + }, + // implements Shape.prototype.setHeight() + setHeight: function(height) { + Konva.Node.prototype.setHeight.call(this, height); + if (this.outerRadius() !== height / 2) { + this.setOuterRadius(height / 2); + } + } + }; + Konva.Util.extend(Konva.Star, Konva.Shape); + + // add getters setters + Konva.Factory.addGetterSetter(Konva.Star, 'numPoints', 5); + + /** + * set number of points + * @name setNumPoints + * @method + * @memberof Konva.Star.prototype + * @param {Integer} points + */ + + /** + * get number of points + * @name getNumPoints + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Star, 'innerRadius', 0); + + /** + * set inner radius + * @name setInnerRadius + * @method + * @memberof Konva.Star.prototype + * @param {Number} radius + */ + + /** + * get inner radius + * @name getInnerRadius + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Star, 'outerRadius', 0); + + /** + * set outer radius + * @name setOuterRadius + * @method + * @memberof Konva.Star.prototype + * @param {Number} radius + */ + + /** + * get outer radius + * @name getOuterRadius + * @method + * @memberof Konva.Star.prototype + */ + + Konva.Collection.mapMethods(Konva.Star); +})(); + +(function() { + 'use strict'; + // constants + var ATTR_CHANGE_LIST = ['fontFamily', 'fontSize', 'fontStyle', 'padding', 'lineHeight', 'text'], + CHANGE_KONVA = 'Change.konva', + NONE = 'none', + UP = 'up', + RIGHT = 'right', + DOWN = 'down', + LEFT = 'left', + LABEL = 'Label', + + // cached variables + attrChangeListLen = ATTR_CHANGE_LIST.length; + + /** + * Label constructor.  Labels are groups that contain a Text and Tag shape + * @constructor + * @memberof Konva + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * // create label + * var label = new Konva.Label({ + * x: 100, + * y: 100, + * draggable: true + * }); + * + * // add a tag to the label + * label.add(new Konva.Tag({ + * fill: '#bbb', + * stroke: '#333', + * shadowColor: 'black', + * shadowBlur: 10, + * shadowOffset: [10, 10], + * shadowOpacity: 0.2, + * lineJoin: 'round', + * pointerDirection: 'up', + * pointerWidth: 20, + * pointerHeight: 20, + * cornerRadius: 5 + * })); + * + * // add text to the label + * label.add(new Konva.Text({ + * text: 'Hello World!', + * fontSize: 50, + * lineHeight: 1.2, + * padding: 10, + * fill: 'green' + * })); + */ + Konva.Label = function(config) { + this.____init(config); + }; + + Konva.Label.prototype = { + ____init: function(config) { + var that = this; + + Konva.Group.call(this, config); + this.className = LABEL; + + this.on('add.konva', function(evt) { + that._addListeners(evt.child); + that._sync(); + }); + }, + /** + * get Text shape for the label. You need to access the Text shape in order to update + * the text properties + * @name getText + * @method + * @memberof Konva.Label.prototype + */ + getText: function() { + return this.find('Text')[0]; + }, + /** + * get Tag shape for the label. You need to access the Tag shape in order to update + * the pointer properties and the corner radius + * @name getTag + * @method + * @memberof Konva.Label.prototype + */ + getTag: function() { + return this.find('Tag')[0]; + }, + _addListeners: function(text) { + var that = this, + n; + var func = function(){ + that._sync(); + }; + + // update text data for certain attr changes + for(n = 0; n < attrChangeListLen; n++) { + text.on(ATTR_CHANGE_LIST[n] + CHANGE_KONVA, func); + } + }, + getWidth: function() { + return this.getText().getWidth(); + }, + getHeight: function() { + return this.getText().getHeight(); + }, + _sync: function() { + var text = this.getText(), + tag = this.getTag(), + width, height, pointerDirection, pointerWidth, x, y, pointerHeight; + + if (text && tag) { + width = text.getWidth(); + height = text.getHeight(); + pointerDirection = tag.getPointerDirection(); + pointerWidth = tag.getPointerWidth(); + pointerHeight = tag.getPointerHeight(); + x = 0; + y = 0; + + switch(pointerDirection) { + case UP: + x = width / 2; + y = -1 * pointerHeight; + break; + case RIGHT: + x = width + pointerWidth; + y = height / 2; + break; + case DOWN: + x = width / 2; + y = height + pointerHeight; + break; + case LEFT: + x = -1 * pointerWidth; + y = height / 2; + break; + } + + tag.setAttrs({ + x: -1 * x, + y: -1 * y, + width: width, + height: height + }); + + text.setAttrs({ + x: -1 * x, + y: -1 * y + }); + } + } + }; + + Konva.Util.extend(Konva.Label, Konva.Group); + + Konva.Collection.mapMethods(Konva.Label); + + /** + * Tag constructor.  A Tag can be configured + * to have a pointer element that points up, right, down, or left + * @constructor + * @memberof Konva + * @param {Object} config + * @param {String} [config.pointerDirection] can be up, right, down, left, or none; the default + * is none. When a pointer is present, the positioning of the label is relative to the tip of the pointer. + * @param {Number} [config.pointerWidth] + * @param {Number} [config.pointerHeight] + * @param {Number} [config.cornerRadius] + */ + Konva.Tag = function(config) { + this.___init(config); + }; + + Konva.Tag.prototype = { + ___init: function(config) { + Konva.Shape.call(this, config); + this.className = 'Tag'; + this.sceneFunc(this._sceneFunc); + }, + _sceneFunc: function(context) { + var width = this.getWidth(), + height = this.getHeight(), + pointerDirection = this.getPointerDirection(), + pointerWidth = this.getPointerWidth(), + pointerHeight = this.getPointerHeight(), + cornerRadius = Math.min(this.getCornerRadius(), width / 2, height / 2); + + context.beginPath(); + if (!cornerRadius) { + context.moveTo(0, 0); + } else { + context.moveTo(cornerRadius, 0); + } + + if (pointerDirection === UP) { + context.lineTo((width - pointerWidth) / 2, 0); + context.lineTo(width / 2, -1 * pointerHeight); + context.lineTo((width + pointerWidth) / 2, 0); + } + + if(!cornerRadius) { + context.lineTo(width, 0); + } else { + context.lineTo(width - cornerRadius, 0); + context.arc(width - cornerRadius, cornerRadius, cornerRadius, Math.PI * 3 / 2, 0, false); + } + + if (pointerDirection === RIGHT) { + context.lineTo(width, (height - pointerHeight) / 2); + context.lineTo(width + pointerWidth, height / 2); + context.lineTo(width, (height + pointerHeight) / 2); + } + + if(!cornerRadius) { + context.lineTo(width, height); + } else { + context.lineTo(width, height - cornerRadius); + context.arc(width - cornerRadius, height - cornerRadius, cornerRadius, 0, Math.PI / 2, false); + } + + if (pointerDirection === DOWN) { + context.lineTo((width + pointerWidth) / 2, height); + context.lineTo(width / 2, height + pointerHeight); + context.lineTo((width - pointerWidth) / 2, height); + } + + if(!cornerRadius) { + context.lineTo(0, height); + } else { + context.lineTo(cornerRadius, height); + context.arc(cornerRadius, height - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false); + } + + if (pointerDirection === LEFT) { + context.lineTo(0, (height + pointerHeight) / 2); + context.lineTo(-1 * pointerWidth, height / 2); + context.lineTo(0, (height - pointerHeight) / 2); + } + + if(cornerRadius) { + context.lineTo(0, cornerRadius); + context.arc(cornerRadius, cornerRadius, cornerRadius, Math.PI, Math.PI * 3 / 2, false); + } + + context.closePath(); + context.fillStrokeShape(this); + }, + getSelfRect: function() { + var x = 0, + y = 0, + pointerWidth = this.getPointerWidth(), + pointerHeight = this.getPointerHeight(), + direction = this.pointerDirection(), + width = this.getWidth(), + height = this.getHeight(); + + if (direction === UP) { + y -= pointerHeight; + height += pointerHeight; + } else if (direction === DOWN) { + height += pointerHeight; + } else if (direction === LEFT) { + // ARGH!!! I have no idea why should I used magic 1.5!!!!!!!!! + x -= pointerWidth * 1.5; + width += pointerWidth; + } else if (direction === RIGHT) { + width += pointerWidth * 1.5; + } + return { + x: x, + y: y, + width: width, + height: height + }; + } + }; + + Konva.Util.extend(Konva.Tag, Konva.Shape); + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerDirection', NONE); + + /** + * set pointer Direction + * @name setPointerDirection + * @method + * @memberof Konva.Tag.prototype + * @param {String} pointerDirection can be up, right, down, left, or none. The + * default is none + */ + + /** + * get pointer Direction + * @name getPointerDirection + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerWidth', 0); + + /** + * set pointer width + * @name setPointerWidth + * @method + * @memberof Konva.Tag.prototype + * @param {Number} pointerWidth + */ + + /** + * get pointer width + * @name getPointerWidth + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'pointerHeight', 0); + + /** + * set pointer height + * @name setPointerHeight + * @method + * @memberof Konva.Tag.prototype + * @param {Number} pointerHeight + */ + + /** + * get pointer height + * @name getPointerHeight + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Factory.addGetterSetter(Konva.Tag, 'cornerRadius', 0); + + /** + * set corner radius + * @name setCornerRadius + * @method + * @memberof Konva.Tag.prototype + * @param {Number} corner radius + */ + + /** + * get corner radius + * @name getCornerRadius + * @method + * @memberof Konva.Tag.prototype + */ + + Konva.Collection.mapMethods(Konva.Tag); +})(); + +(function() { + 'use strict'; + /** + * Arrow constructor + * @constructor + * @memberof Konva + * @augments Konva.Shape + * @param {Object} config + * @param {Array} config.points + * @param {Number} [config.tension] Higher values will result in a more curvy line. A value of 0 will result in no interpolation. + * The default is 0 + * @param {Number} config.pointerLength + * @param {Number} config.pointerWidth + * @param {String} [config.fill] fill color + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeHitEnabled] flag which enables or disables stroke hit region. The default is true + * @param {Boolean} [config.perfectDrawEnabled] flag which enables or disables using buffer canvas. The default is true + * @param {Boolean} [config.shadowForStrokeEnabled] flag which enables or disables shasow for stroke. The default is true + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var line = new Konva.Line({ + * points: [73, 70, 340, 23, 450, 60, 500, 20], + * stroke: 'red', + * tension: 1, + * pointerLength : 10, + * pointerWidth : 12 + * }); + */ + Konva.Arrow = function(config) { + this.____init(config); + }; + + Konva.Arrow.prototype = { + ____init: function(config) { + // call super constructor + Konva.Line.call(this, config); + this.className = 'Arrow'; + }, + _sceneFunc: function(ctx) { + Konva.Line.prototype._sceneFunc.apply(this, arguments); + var PI2 = Math.PI * 2; + var points = this.points(); + var n = points.length; + var dx = points[n - 2] - points[n - 4]; + var dy = points[n - 1] - points[n - 3]; + var radians = (Math.atan2(dy, dx) + PI2) % PI2; + var length = this.pointerLength(); + var width = this.pointerWidth(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(points[n - 2], points[n - 1]); + ctx.rotate(radians); + ctx.moveTo(0, 0); + ctx.lineTo(-length, width / 2); + ctx.lineTo(-length, -width / 2); + ctx.closePath(); + ctx.restore(); + + if (this.pointerAtBeginning()) { + ctx.save(); + ctx.translate(points[0], points[1]); + dx = points[2] - points[0]; + dy = points[3] - points[1]; + ctx.rotate((Math.atan2(-dy, -dx) + PI2) % PI2); + ctx.moveTo(0, 0); + ctx.lineTo(-length, width / 2); + ctx.lineTo(-length, -width / 2); + ctx.closePath(); + ctx.restore(); + } + ctx.fillStrokeShape(this); + } + }; + + Konva.Util.extend(Konva.Arrow, Konva.Line); + /** + * get/set pointerLength + * @name pointerLength + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Length of pointer of arrow. + * The default is 10. + * @returns {Number} + * @example + * // get tension + * var pointerLength = line.pointerLength(); + * + * // set tension + * line.pointerLength(15); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerLength', 10); + /** + * get/set pointerWidth + * @name pointerWidth + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Width of pointer of arrow. + * The default is 10. + * @returns {Number} + * @example + * // get tension + * var pointerWidth = line.pointerWidth(); + * + * // set tension + * line.pointerWidth(15); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerWidth', 10); + /** + * get/set pointerAtBeginning + * @name pointerAtBeginning + * @method + * @memberof Konva.Arrow.prototype + * @param {Number} Should pointer displayed at beginning of arrow. + * The default is false. + * @returns {Boolean} + * @example + * // get tension + * var pointerAtBeginning = line.pointerAtBeginning(); + * + * // set tension + * line.pointerAtBeginning(true); + */ + + Konva.Factory.addGetterSetter(Konva.Arrow, 'pointerAtBeginning', false); + Konva.Collection.mapMethods(Konva.Arrow); + +})(); diff --git a/support/client/lib/vwf/model/kinetic/konva.min.actual.js b/support/client/lib/vwf/model/kinetic/konva.min.actual.js new file mode 100644 index 000000000..502d249b0 --- /dev/null +++ b/support/client/lib/vwf/model/kinetic/konva.min.actual.js @@ -0,0 +1,46 @@ +/* + * Konva JavaScript Framework v0.15.0 + * http://konvajs.github.io/ + * Licensed under the MIT or GPL Version 2 licenses. + * Date: Fri Jun 24 2016 + * + * Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS) + * Modified work Copyright (C) 2014 - 2015 by Anton Lavrenov (Konva) + * + * @license + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +!function(t){"use strict";var e=Math.PI/180,n={version:"0.15.0",stages:[],idCounter:0,ids:{},names:{},shapes:{},listenClickTap:!1,inDblClickWindow:!1,enableTrace:!1,traceArrMax:100,dblClickWindow:400,pixelRatio:void 0,dragDistance:0,angleDeg:!0,showWarnings:!0,Filters:{},isDragging:function(){var t=n.DD;return!!t&&t.isDragging},isDragReady:function(){var t=n.DD;return!!t&&!!t.node},_addId:function(t,e){void 0!==e&&(this.ids[e]=t)},_removeId:function(t){void 0!==t&&delete this.ids[t]},_addName:function(t,e){e&&(this.names[e]||(this.names[e]=[]),this.names[e].push(t))},_removeName:function(t,e){if(t){var n=this.names[t];if(n){for(var i=0;i0)return parseInt(t.substring(e+5,t.indexOf(".",e)),10);var n=t.indexOf("trident/");if(n>0){var i=t.indexOf("rv:");return parseInt(t.substring(i+3,t.indexOf(".",i)),10)}var a=t.indexOf("edge/");return a>0&&parseInt(t.substring(a+5,t.indexOf(".",a)),10)},_parseUA:function(t){var e=t.toLowerCase(),i=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[],a=!!t.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i),r=!!t.match(/IEMobile/i);return{browser:i[1]||"",version:i[2]||"0",isIE:n._detectIE(e),mobile:a,ieMobile:r}},UA:void 0},i="undefined"!=typeof window?window:"undefined"!=typeof t?t:"undefined"!=typeof WorkerGlobalScope?self:{};if(n.UA=n._parseUA(i.navigator&&i.navigator.userAgent||""),i.Konva&&console.error("Konva instance is already exist in current eviroment. Please use only one instance."),i.Konva=n,n.global=i,"object"==typeof exports){if(i.window&&i.window.document)n.document=i.window.document,n.window=i.window;else{var a=require("canvas"),r=require("jsdom").jsdom;n.window=r("").defaultView,n.document=n.window.document,n.window.Image=a.Image,n._nodeCanvas=a}return void(module.exports=n)}"function"==typeof define&&define.amd&&define(function(){return n}),n.document=document,n.window=window}("undefined"!=typeof window?window:global),function(){"use strict";Konva.Collection=function(){var t=[].slice.call(arguments),e=t.length,n=0;for(this.length=e;n0},isValidSelector:function(t){if("string"!=typeof t)return!1;var e=t[0];return"#"===e||"."===e||e===e.toUpperCase()},createCanvasElement:function(){var t=Konva.document.createElement("canvas");try{t.style=t.style||{}}catch(e){}return t},isBrowser:function(){return"object"!=typeof exports},_isInDocument:function(t){for(;t=t.parentNode;)if(t==Konva.document)return!0;return!1},_simplifyArray:function(t){var e,n,i=[],a=t.length,r=Konva.Util;for(e=0;e>16&255,g:e>>8&255,b:255&e}},getRandomColor:function(){for(var t=(16777215*Math.random()<<0).toString(16);t.length<6;)t=h+t;return o+t},get:function(t,e){return void 0===t?e:t},getRGB:function(t){var e;return t in u?(e=u[t],{r:e[0],g:e[1],b:e[2]}):t[0]===o?this._hexToRgb(t.substring(1)):t.substr(0,4)===d?(e=f.exec(t.replace(/ /g,"")),{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}):{r:0,g:0,b:0}},colorToRGBA:function(t){return t=t||"black",Konva.Util._namedColorToRBA(t)||Konva.Util._hex3ColorToRGBA(t)||Konva.Util._hex6ColorToRGBA(t)||Konva.Util._rgbColorToRGBA(t)||Konva.Util._rgbaColorToRGBA(t)},_namedColorToRBA:function(t){var e=u[t.toLowerCase()];return e?{r:e[0],g:e[1],b:e[2],a:1}:null},_rgbColorToRGBA:function(t){if(0===t.indexOf("rgb(")){t=t.match(/rgb\(([^)]+)\)/)[1];var e=t.split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:1}}},_rgbaColorToRGBA:function(t){if(0===t.indexOf("rgba(")){t=t.match(/rgba\(([^)]+)\)/)[1];var e=t.split(/ *, */).map(Number);return{r:e[0],g:e[1],b:e[2],a:e[3]}}},_hex6ColorToRGBA:function(t){if("#"===t[0]&&7===t.length)return{r:parseInt(t.slice(1,3),16),g:parseInt(t.slice(3,5),16),b:parseInt(t.slice(5,7),16),a:1}},_hex3ColorToRGBA:function(t){if("#"===t[0]&&4===t.length)return{r:parseInt(t[1]+t[1],16),g:parseInt(t[2]+t[2],16),b:parseInt(t[3]+t[3],16),a:1}},_merge:function(t,e){var n=this._clone(e);for(var i in t)this._isObject(t[i])?n[i]=this._merge(t[i],n[i]):n[i]=t[i];return n},cloneObject:function(t){var e={};for(var n in t)this._isObject(t[n])?e[n]=this.cloneObject(t[n]):this._isArray(t[n])?e[n]=this.cloneArray(t[n]):e[n]=t[n];return e},cloneArray:function(t){return t.slice(0)},_degToRad:function(t){return t*a},_radToDeg:function(t){return t*r},_capitalize:function(t){return t.charAt(0).toUpperCase()+t.slice(1)},"throw":function(t){throw new Error(l+t)},error:function(t){console.error(l+t)},warn:function(t){Konva.global.console&&console.warn&&Konva.showWarnings&&console.warn(c+t)},extend:function(t,e){function n(){this.constructor=t}n.prototype=e.prototype;var i=t.prototype;t.prototype=new n;for(var a in i)i.hasOwnProperty(a)&&(t.prototype[a]=i[a]);t.__super__=e.prototype,t["super"]=e},addMethods:function(t,e){var n;for(n in e)t.prototype[n]=e[n]},_getControlPoints:function(t,e,n,i,a,r,o){var s=Math.sqrt(Math.pow(n-t,2)+Math.pow(i-e,2)),h=Math.sqrt(Math.pow(a-n,2)+Math.pow(r-i,2)),c=o*s/(s+h),l=o*h/(s+h),d=n-c*(a-t),u=i-c*(r-e),f=n+l*(a-t),v=i+l*(r-e);return[d,u,f,v]},_expandPoints:function(t,e){var n,i,a=t.length,r=[];for(n=2;n1?(o=n,s=i,h=(n-a)*(n-a)+(i-r)*(i-r)):(o=t+l*(n-t),s=e+l*(i-e),h=(o-a)*(o-a)+(s-r)*(s-r))}return[o,s,h]},_getProjectionToLine:function(t,e,n){var i=Konva.Util.cloneObject(t),a=Number.MAX_VALUE;return e.forEach(function(r,o){if(n||o!==e.length-1){var s=e[(o+1)%e.length],h=Konva.Util._getProjectionToSegment(r.x,r.y,s.x,s.y,t.x,t.y),c=h[0],l=h[1],d=h[2];de.length){var o=e;e=t,t=o}for(i=0;i=Konva.traceArrMax&&n.shift()},reset:function(){var t=this.getCanvas().getPixelRatio();this.setTransform(1*t,0,0,1*t,0,0)},getCanvas:function(){return this.canvas},clear:function(t){var e=this.getCanvas();t?this.clearRect(t.x||0,t.y||0,t.width||0,t.height||0):this.clearRect(0,0,e.getWidth()/e.pixelRatio,e.getHeight()/e.pixelRatio)},_applyLineCap:function(t){var e=t.getLineCap();e&&this.setAttr("lineCap",e)},_applyOpacity:function(t){var e=t.getAbsoluteOpacity();1!==e&&this.setAttr("globalAlpha",e)},_applyLineJoin:function(t){var e=t.getLineJoin();e&&this.setAttr("lineJoin",e)},setAttr:function(t,e){this._context[t]=e},arc:function(){var t=arguments;this._context.arc(t[0],t[1],t[2],t[3],t[4],t[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var t=arguments;this._context.bezierCurveTo(t[0],t[1],t[2],t[3],t[4],t[5])},clearRect:function(){var t=arguments;this._context.clearRect(t[0],t[1],t[2],t[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createImageData:function(){var t=arguments;return 2===t.length?this._context.createImageData(t[0],t[1]):1===t.length?this._context.createImageData(t[0]):void 0},createLinearGradient:function(){var t=arguments;return this._context.createLinearGradient(t[0],t[1],t[2],t[3])},createPattern:function(){var t=arguments;return this._context.createPattern(t[0],t[1])},createRadialGradient:function(){var t=arguments;return this._context.createRadialGradient(t[0],t[1],t[2],t[3],t[4],t[5])},drawImage:function(){var t=arguments,e=this._context;3===t.length?e.drawImage(t[0],t[1],t[2]):5===t.length?e.drawImage(t[0],t[1],t[2],t[3],t[4]):9===t.length&&e.drawImage(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},isPointInPath:function(t,e){return this._context.isPointInPath(t,e)},fill:function(){this._context.fill()},fillRect:function(t,e,n,i){this._context.fillRect(t,e,n,i)},strokeRect:function(t,e,n,i){this._context.strokeRect(t,e,n,i)},fillText:function(){var t=arguments;this._context.fillText(t[0],t[1],t[2])},measureText:function(t){return this._context.measureText(t)},getImageData:function(){var t=arguments;return this._context.getImageData(t[0],t[1],t[2],t[3])},lineTo:function(){var t=arguments;this._context.lineTo(t[0],t[1])},moveTo:function(){var t=arguments;this._context.moveTo(t[0],t[1])},rect:function(){var t=arguments;this._context.rect(t[0],t[1],t[2],t[3])},putImageData:function(){var t=arguments;this._context.putImageData(t[0],t[1],t[2])},quadraticCurveTo:function(){var t=arguments;this._context.quadraticCurveTo(t[0],t[1],t[2],t[3])},restore:function(){this._context.restore()},rotate:function(){var t=arguments;this._context.rotate(t[0])},save:function(){this._context.save()},scale:function(){var t=arguments;this._context.scale(t[0],t[1])},setLineDash:function(){var t=arguments,e=this._context;this._context.setLineDash?e.setLineDash(t[0]):"mozDash"in e?e.mozDash=t[0]:"webkitLineDash"in e&&(e.webkitLineDash=t[0])},getLineDash:function(){return this._context.getLineDash()},setTransform:function(){var t=arguments;this._context.setTransform(t[0],t[1],t[2],t[3],t[4],t[5])},stroke:function(){this._context.stroke()},strokeText:function(){var t=arguments;this._context.strokeText(t[0],t[1],t[2])},transform:function(){var t=arguments;this._context.transform(t[0],t[1],t[2],t[3],t[4],t[5])},translate:function(){var t=arguments;this._context.translate(t[0],t[1])},_enableTrace:function(){var t,e,n=this,i=h.length,a=Konva.Util._simplifyArray,r=this.setAttr,o=function(t){var i,r=n[t];n[t]=function(){return e=a(Array.prototype.slice.call(arguments,0)),i=r.apply(n,arguments),n._trace({method:t,args:e}),i}};for(t=0;t255?255:t<0?0:Math.round(t)},alphaComponent:function(t){return t>1?1:t<1e-4?1e-4:t}}}(),function(t){"use strict";var e="absoluteOpacity",n="absoluteTransform",i="absoluteScale",a="Change",r="children",o=".",s="",h="get",c="id",l="konva",d="listening",u="mouseenter",f="mouseleave",v="name",g="set",p="Shape",m=" ",_="stage",y="transform",K="Stage",S="visible",C=["id"],x=["xChange.konva","yChange.konva","scaleXChange.konva","scaleYChange.konva","skewXChange.konva","skewYChange.konva","rotationChange.konva","offsetXChange.konva","offsetYChange.konva","transformsEnabledChange.konva"].join(m),w=["scaleXChange.konva","scaleYChange.konva"].join(m);t.Node=function(t){this._init(t)},t.Util.addMethods(t.Node,{_init:function(a){var r=this;this._id=t.idCounter++,this.eventListeners={},this.attrs={},this._cache={},this._filterUpToDate=!1,this.setAttrs(a),this.on(x,function(){this._clearCache(y),r._clearSelfAndDescendantCache(n)}),this.on(w,function(){r._clearSelfAndDescendantCache(i)}),this.on("visibleChange.konva",function(){r._clearSelfAndDescendantCache(S)}),this.on("listeningChange.konva",function(){r._clearSelfAndDescendantCache(d)}),this.on("opacityChange.konva",function(){r._clearSelfAndDescendantCache(e)})},_clearCache:function(t){t?delete this._cache[t]:this._cache={}},_getCache:function(t,e){var n=this._cache[t];return void 0===n&&(this._cache[t]=e.call(this)),this._cache[t]},_clearSelfAndDescendantCache:function(t){this._clearCache(t),this.children&&this.getChildren().each(function(e){e._clearSelfAndDescendantCache(t)})},clearCache:function(){return delete this._cache.canvas,this._filterUpToDate=!1,this},cache:function(e){var n=e||{},i=this.getClientRect(!0),a=n.width||i.width,r=n.height||i.height,o=n.x||i.x,s=n.y||i.y,h=n.offset||0,c=n.drawBorder||!1;if(!a||!r)throw new Error("Width or height of caching configuration equals 0.");a+=2*h,r+=2*h,o-=h,s-=h;var l=new t.SceneCanvas({width:a,height:r}),d=new t.SceneCanvas({width:a,height:r}),u=new t.HitCanvas({pixelRatio:1,width:a,height:r}),f=l.getContext(),v=u.getContext();return u.isCache=!0,this.clearCache(),f.save(),v.save(),f.translate(-o,-s),v.translate(-o,-s),this.drawScene(l,this,!0),this.drawHit(u,this,!0),f.restore(),v.restore(),c&&(f.save(),f.beginPath(),f.rect(0,0,a,r),f.closePath(),f.setAttr("strokeStyle","red"),f.setAttr("lineWidth",5),f.stroke(),f.restore()),this._cache.canvas={scene:l,filter:d,hit:u,x:o,y:s},this},getClientRect:function(){throw new Error('abstract "getClientRect" method call')},_transformedRect:function(t){var e,n,i,a,r=[{x:t.x,y:t.y},{x:t.x+t.width,y:t.y},{x:t.x+t.width,y:t.y+t.height},{x:t.x,y:t.y+t.height}],o=this.getTransform();return r.forEach(function(t){var r=o.point(t);void 0===e&&(e=i=r.x,n=a=r.y),e=Math.min(e,r.x),n=Math.min(n,r.y),i=Math.max(i,r.x),a=Math.max(a,r.y)}),{x:e,y:n,width:i-e,height:a-n}},_drawCachedSceneCanvas:function(t){t.save(),t._applyOpacity(this),t.translate(this._cache.canvas.x,this._cache.canvas.y);var e=this._getCachedSceneCanvas(),n=e.pixelRatio;t.drawImage(e._canvas,0,0,e.width/n,e.height/n),t.restore()},_drawCachedHitCanvas:function(t){var e=this._cache.canvas,n=e.hit;t.save(),t.translate(this._cache.canvas.x,this._cache.canvas.y),t.drawImage(n._canvas,0,0),t.restore()},_getCachedSceneCanvas:function(){var e,n,i,a,r=this.filters(),o=this._cache.canvas,s=o.scene,h=o.filter,c=h.getContext();if(r){if(!this._filterUpToDate){var l=s.pixelRatio;try{for(e=r.length,c.clear(),c.drawImage(s._canvas,0,0,s.getWidth()/l,s.getHeight()/l),n=c.getImageData(0,0,h.getWidth(),h.getHeight()),i=0;i0&&e[0].getDepth()<=r&&t(e)}var e,n,i,a,r=this.getDepth(),o=this,s=0;return o.nodeType!==K&&t(o.getStage().getChildren()),s},getDepth:function(){for(var t=0,e=this.parent;e;)t++,e=e.parent;return t},setPosition:function(t){return this.setX(t.x),this.setY(t.y),this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(e){var n=this.getAbsoluteTransform(e).getMatrix(),i=new t.Transform,a=this.offset();return i.m=n.slice(),i.translate(a.x,a.y),i.getTranslation()},setAbsolutePosition:function(t){var e,n=this._clearTransform();return this.attrs.x=n.x,this.attrs.y=n.y,delete n.x,delete n.y,e=this.getAbsoluteTransform(),e.invert(),e.translate(t.x,t.y),t={x:this.attrs.x+e.getTranslation().x,y:this.attrs.y+e.getTranslation().y},this.setPosition({x:t.x,y:t.y}),this._setTransform(n),this},_setTransform:function(t){var e;for(e in t)this.attrs[e]=t[e];this._clearCache(y),this._clearSelfAndDescendantCache(n)},_clearTransform:function(){var t={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};return this.attrs.x=0,this.attrs.y=0,this.attrs.rotation=0,this.attrs.scaleX=1,this.attrs.scaleY=1,this.attrs.offsetX=0,this.attrs.offsetY=0,this.attrs.skewX=0,this.attrs.skewY=0,this._clearCache(y),this._clearSelfAndDescendantCache(n),t},move:function(t){var e=t.x,n=t.y,i=this.getX(),a=this.getY();return void 0!==e&&(i+=e),void 0!==n&&(a+=n),this.setPosition({x:i,y:a}),this},_eachAncestorReverse:function(t,e){var n,i,a=[],r=this.getParent();if(e&&e._id===this._id)return t(this),!0;for(a.unshift(this);r&&(!e||r._id!==e._id);)a.unshift(r),r=r.parent;for(n=a.length,i=0;i0&&(this.parent.children.splice(e,1),this.parent.children.splice(e-1,0,this),this.parent._setChildrenIndices(),!0)},moveToBottom:function(){if(!this.parent)return t.Util.warn("Node has no parent. moveToBottom function is ignored."),!1;var e=this.index;return e>0&&(this.parent.children.splice(e,1),this.parent.children.unshift(this),this.parent._setChildrenIndices(),!0)},setZIndex:function(e){if(!this.parent)return t.Util.warn("Node has no parent. zIndex parameter is ignored."),!1;var n=this.index;return this.parent.children.splice(n,1),this.parent.children.splice(e,0,this),this.parent._setChildrenIndices(),this},getAbsoluteOpacity:function(){return this._getCache(e,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var t=this.getOpacity();return this.getParent()&&(t*=this.getParent().getAbsoluteOpacity()),t},moveTo:function(t){return this.getParent()!==t&&(this.remove(),t.add(this)),this},toObject:function(){var e,n,i,a,r={},o=this.getAttrs();r.attrs={};for(e in o)n=o[e],t.Util._isFunction(n)||t.Util._isElement(n)||t.Util._isObject(n)||t.Util._hasMethods(n)||(i=this[e],delete o[e],a=i?i.call(this):null,o[e]=n,a!==n&&(r.attrs[e]=n));return r.className=this.getClassName(),r},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},findAncestors:function(t,e,n){var i=[];e&&this._isMatch(t)&&i.push(this);for(var a=this.parent;a;){if(a===n)return i;a._isMatch(t)&&i.push(a),a=a.parent}return i},findAncestor:function(t,e,n){return this.findAncestors(t,e,n)[0]},_isMatch:function(e){if(!e)return!1;var n,i,a=e.replace(/ /g,"").split(","),r=a.length;for(n=0;n>W,0!==T?(T=255/T,A[l]=(u*H>>W)*T,A[l+1]=(f*H>>W)*T,A[l+2]=(v*H>>W)*T):A[l]=A[l+1]=A[l+2]=0,u-=p,f-=m,v-=_,g-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=d+((h=r+a+1)>W,T>0?(T=255/T,A[h]=(u*H>>W)*T,A[h+1]=(f*H>>W)*T,A[h+2]=(v*H>>W)*T):A[h]=A[h+1]=A[h+2]=0,u-=p,f-=m,v-=_,g-=y,p-=E.r,m-=E.g,_-=E.b,y-=E.a,h=r+((h=o+L)0&&e(t,n)},Konva.Factory.addGetterSetter(Konva.Node,"blurRadius",0,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";function t(t,e,n){var i=4*(n*t.width+e),a=[];return a.push(t.data[i++],t.data[i++],t.data[i++],t.data[i++]),a}function e(t,e){return Math.sqrt(Math.pow(t[0]-e[0],2)+Math.pow(t[1]-e[1],2)+Math.pow(t[2]-e[2],2))}function n(t){for(var e=[0,0,0],n=0;n=0&&f=0&&v=0&&f=0&&v=1020?255:0}return o}function s(t,e,n){for(var i=[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9],a=Math.round(Math.sqrt(i.length)),r=Math.floor(a/2),o=[],s=0;s=0&&f=0&&v255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.RGBA=function(t){var e,n,i=t.data,a=i.length,r=this.red(),o=this.green(),s=this.blue(),h=this.alpha();for(e=0;e255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(t){return this._filterUpToDate=!1,t>255?255:t<0?0:Math.round(t)}),Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"alpha",1,function(t){return this._filterUpToDate=!1,t>1?1:t<0?0:t})}(),function(){"use strict";Konva.Filters.HSV=function(t){var e,n,i,a,r,o=t.data,s=o.length,h=Math.pow(2,this.value()),c=Math.pow(2,this.saturation()),l=Math.abs(this.hue()+360)%360,d=h*c*Math.cos(l*Math.PI/180),u=h*c*Math.sin(l*Math.PI/180),f=.299*h+.701*d+.167*u,v=.587*h-.587*d+.33*u,g=.114*h-.114*d-.497*u,p=.299*h-.299*d-.328*u,m=.587*h+.413*d+.035*u,_=.114*h-.114*d+.293*u,y=.299*h-.3*d+1.25*u,K=.587*h-.586*d-1.05*u,S=.114*h+.886*d-.2*u;for(e=0;ec&&(f=0);var v=(d-1+f)*h*4,g=h;do{var p=u+4*(g-1),m=o;g+m<1&&(m=0),g+m>h&&(m=0);var _=v+4*(g-1+m),y=s[p]-s[_],K=s[p+1]-s[_+1],S=s[p+2]-s[_+2],C=y,x=C>0?C:-C,w=K>0?K:-K,b=S>0?S:-S;if(w>x&&(C=K),b>x&&(C=S),C*=e,a){var F=s[p]+C,T=s[p+1]+C,P=s[p+2]+C;s[p]=F>255?255:F<0?0:F,s[p+1]=T>255?255:T<0?0:T,s[p+2]=P>255?255:P<0?0:P}else{var A=n-C;A<0?A=0:A>255&&(A=255),s[p]=s[p+1]=s[p+2]=A}}while(--g)}while(--d)},Konva.Factory.addGetterSetter(Konva.Node,"embossStrength",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossWhiteLevel",.5,null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossDirection","top-left",null,Konva.Factory.afterSetFilter),Konva.Factory.addGetterSetter(Konva.Node,"embossBlend",!1,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";function t(t,e,n,i,a){var r,o=n-e,s=a-i;return 0===o?i+s/2:0===s?i:(r=(t-e)/o,r=s*r+i)}Konva.Filters.Enhance=function(e){var n,i,a,r,o=e.data,s=o.length,h=o[0],c=h,l=o[1],d=l,u=o[2],f=u,v=this.enhance();if(0!==v){for(r=0;rc&&(c=n),i=o[r+1],id&&(d=i),a=o[r+2],af&&(f=a);c===h&&(c=255,h=0),d===l&&(d=255,l=0),f===u&&(f=255,u=0);var g,p,m,_,y,K,S,C,x;for(v>0?(p=c+v*(255-c),m=h-v*(h-0),y=d+v*(255-d),K=l-v*(l-0),C=f+v*(255-f),x=u-v*(u-0)):(g=.5*(c+h),p=c+v*(c-g),m=h+v*(h-g),_=.5*(d+l),y=d+v*(d-_),K=l+v*(l-_),S=.5*(f+u),C=f+v*(f-S),x=u+v*(u-S)),r=0;r=p))for(n=l;n=m||(i=4*(p*n+e),a+=t[i+0],r+=t[i+1],o+=t[i+2],s+=t[i+3],v+=1);for(a/=v,r/=v,o/=v,e=h;e=p))for(n=l;n=m||(i=4*(p*n+e),t[i+0]=a,t[i+1]=r,t[i+2]=o,t[i+3]=s)}},Konva.Factory.addGetterSetter(Konva.Node,"pixelSize",8,null,Konva.Factory.afterSetFilter)}(),function(){"use strict";Konva.Filters.Threshold=function(t){var e,n=255*this.threshold(),i=t.data,a=i.length;for(e=0;e + * @license MPL v1.1 [http://www.pixastic.com/lib/license.txt] + * @example + * node.cache(); + * node.filters([Konva.Filters.Sepia]); + */ +Konva.Filters.Sepia=function(t){var e,n,i,a,r,o,s,h,c,l=t.data,d=t.width,u=t.height,f=4*d;do{e=(u-1)*f,n=d;do i=e+4*(n-1),a=l[i],r=l[i+1],o=l[i+2],s=.393*a+.769*r+.189*o,h=.349*a+.686*r+.168*o,c=.272*a+.534*r+.131*o,l[i]=s>255?255:s,l[i+1]=h>255?255:h,l[i+2]=c>255?255:c,l[i+3]=l[i+3];while(--n)}while(--u)}}(),function(){"use strict";Konva.Filters.Solarize=function(t){var e=t.data,n=t.width,i=t.height,a=4*n,r=i;do{var o=(r-1)*a,s=n;do{var h=o+4*(s-1),c=e[h],l=e[h+1],d=e[h+2];c>127&&(c=255-c),l>127&&(l=255-l),d>127&&(d=255-d),e[h]=c,e[h+1]=l,e[h+2]=d}while(--s)}while(--r)}}(),function(){"use strict";var t=function(t,e,n){var i,a,r,o,s=t.data,h=e.data,c=t.width,l=t.height,d=n.polarCenterX||c/2,u=n.polarCenterY||l/2,f=0,v=0,g=0,p=0,m=Math.sqrt(d*d+u*u);a=c-d,r=l-u,o=Math.sqrt(a*a+r*r),m=o>m?o:m;var _,y,K,S,C=l,x=c,w=360/x*Math.PI/180;for(y=0;yy?h:y;var K,S,C,x,w=u,b=d,F=n.polarRotation||0;for(a=0;av&&(C=S,x=0,w=-1),r=0;r0},removeChildren:function(){for(var t,e=Konva.Collection.toCollection(this.children),n=0;n1){for(var e=0;e0},destroy:function(){return t.Node.prototype.destroy.call(this),delete t.shapes[this.colorKey],this},_useBufferCanvas:function(t){return!t&&this.perfectDrawEnabled()&&1!==this.getAbsoluteOpacity()&&this.hasFill()&&this.hasStroke()&&this.getStage()||this.perfectDrawEnabled()&&this.hasShadow()&&1!==this.getAbsoluteOpacity()&&this.hasFill()&&this.hasStroke()&&this.getStage()},getSelfRect:function(){var t=this.getSize();return{x:this._centroid?Math.round(-t.width/2):0,y:this._centroid?Math.round(-t.height/2):0,width:t.width,height:t.height}},getClientRect:function(t){var e=this.getSelfRect(),n=this.hasStroke()&&this.strokeWidth()||0,i=e.width+n,a=e.height+n,r=this.shadowOffsetX(),o=this.shadowOffsetY(),s=i+Math.abs(r),h=a+Math.abs(o),c=this.hasShadow()&&this.shadowBlur()||0,l=s+2*c,d=h+2*c,u=0;Math.round(n/2)!==n/2&&(u=1);var f={width:l+u,height:d+u,x:-Math.round(n/2+c)+Math.min(r,0)+e.x,y:-Math.round(n/2+c)+Math.min(o,0)+e.y};return t?f:this._transformedRect(f)},drawScene:function(t,e,n,i){var a,r,o,s=this.getLayer(),h=t||s.getCanvas(),c=h.getContext(),l=this._cache.canvas,d=this.sceneFunc(),u=this.hasShadow(),f=this.hasStroke();if(!this.isVisible())return this;if(l)return c.save(),s._applyTransform(this,c,e),this._drawCachedSceneCanvas(c),c.restore(),this;if(!d)return this;if(c.save(),this._useBufferCanvas(n)&&!i){if(a=this.getStage(),r=a.bufferCanvas,o=r.getContext(),o.clear(),o.save(),o._applyLineJoin(this),!n)if(s)s._applyTransform(this,o,e);else{var v=this.getAbsoluteTransform(e).getMatrix();c.transform(v[0],v[1],v[2],v[3],v[4],v[5])}d.call(this,o),o.restore();var g=r.pixelRatio;u&&!h.hitCanvas?(c.save(),c._applyShadow(this),c._applyOpacity(this),c.drawImage(r._canvas,0,0,r.width/g,r.height/g),c.restore()):(c._applyOpacity(this),c.drawImage(r._canvas,0,0,r.width/g,r.height/g))}else{if(c._applyLineJoin(this),!n)if(s)s._applyTransform(this,c,e);else{var p=this.getAbsoluteTransform(e).getMatrix();c.transform(p[0],p[1],p[2],p[3],p[4],p[5])}u&&f&&!h.hitCanvas?(c.save(),n||c._applyOpacity(this),c._applyShadow(this),d.call(this,c),c.restore(),this.hasFill()&&this.getShadowForStrokeEnabled()&&d.call(this,c)):u&&!h.hitCanvas?(c.save(),n||c._applyOpacity(this),c._applyShadow(this),d.call(this,c),c.restore()):(n||c._applyOpacity(this),d.call(this,c))}return c.restore(),this},drawHit:function(t,e,n){var i=this.getLayer(),a=t||i.hitCanvas,r=a.getContext(),o=this.hitFunc()||this.sceneFunc(),s=this._cache.canvas,h=s&&s.hit;if(!this.shouldDrawHit(a))return this;if(i&&i.clearHitCache(),h)return r.save(),i._applyTransform(this,r,e),this._drawCachedHitCanvas(r),r.restore(),this;if(!o)return this;if(r.save(),r._applyLineJoin(this),!n)if(i)i._applyTransform(this,r,e);else{var c=this.getAbsoluteTransform(e).getMatrix();r.transform(c[0],c[1],c[2],c[3],c[4],c[5])}return o.call(this,r),r.restore(),this},drawHitFromCache:function(e){var n,i,a,r,o,s,h=e||0,c=this._cache.canvas,l=this._getCachedSceneCanvas(),d=c.hit,u=d.getContext(),f=d.getWidth(),v=d.getHeight();u.clear(),u.drawImage(l._canvas,0,0,f,v);try{for(n=u.getImageData(0,0,f,v),i=n.data,a=i.length,r=t.Util._hexToRgb(this.colorKey),o=0;oh?(i[o]=r.r,i[o+1]=r.g,i[o+2]=r.b,i[o+3]=255):i[o+3]=0;u.putImageData(n,0,0)}catch(g){t.Util.error("Unable to draw hit graph from cached scene canvas. "+g.message)}return this}}),t.Util.extend(t.Shape,t.Node),t.Factory.addGetterSetter(t.Shape,"stroke"),t.Factory.addDeprecatedGetterSetter(t.Shape,"strokeRed",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"strokeGreen",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"strokeBlue",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"strokeAlpha",1,t.Validators.alphaComponent),t.Factory.addGetterSetter(t.Shape,"strokeWidth",2),t.Factory.addGetterSetter(t.Shape,"strokeHitEnabled",!0),t.Factory.addGetterSetter(t.Shape,"perfectDrawEnabled",!0),t.Factory.addGetterSetter(t.Shape,"shadowForStrokeEnabled",!0),t.Factory.addGetterSetter(t.Shape,"lineJoin"),t.Factory.addGetterSetter(t.Shape,"lineCap"),t.Factory.addGetterSetter(t.Shape,"sceneFunc"),t.Factory.addGetterSetter(t.Shape,"hitFunc"),t.Factory.addGetterSetter(t.Shape,"dash"),t.Factory.addGetterSetter(t.Shape,"shadowColor"),t.Factory.addDeprecatedGetterSetter(t.Shape,"shadowRed",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"shadowGreen",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"shadowBlue",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"shadowAlpha",1,t.Validators.alphaComponent),t.Factory.addGetterSetter(t.Shape,"shadowBlur"),t.Factory.addGetterSetter(t.Shape,"shadowOpacity"),t.Factory.addComponentsGetterSetter(t.Shape,"shadowOffset",["x","y"]),t.Factory.addGetterSetter(t.Shape,"shadowOffsetX",0),t.Factory.addGetterSetter(t.Shape,"shadowOffsetY",0),t.Factory.addGetterSetter(t.Shape,"fillPatternImage"),t.Factory.addGetterSetter(t.Shape,"fill"),t.Factory.addDeprecatedGetterSetter(t.Shape,"fillRed",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"fillGreen",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"fillBlue",0,t.Validators.RGBComponent),t.Factory.addDeprecatedGetterSetter(t.Shape,"fillAlpha",1,t.Validators.alphaComponent),t.Factory.addGetterSetter(t.Shape,"fillPatternX",0),t.Factory.addGetterSetter(t.Shape,"fillPatternY",0),t.Factory.addGetterSetter(t.Shape,"fillLinearGradientColorStops"),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientStartRadius",0),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientEndRadius",0),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientColorStops"),t.Factory.addGetterSetter(t.Shape,"fillPatternRepeat","repeat"),t.Factory.addGetterSetter(t.Shape,"fillEnabled",!0),t.Factory.addGetterSetter(t.Shape,"strokeEnabled",!0),t.Factory.addGetterSetter(t.Shape,"shadowEnabled",!0),t.Factory.addGetterSetter(t.Shape,"dashEnabled",!0),t.Factory.addGetterSetter(t.Shape,"strokeScaleEnabled",!0),t.Factory.addGetterSetter(t.Shape,"fillPriority","color"),t.Factory.addComponentsGetterSetter(t.Shape,"fillPatternOffset",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillPatternOffsetX",0),t.Factory.addGetterSetter(t.Shape,"fillPatternOffsetY",0),t.Factory.addComponentsGetterSetter(t.Shape,"fillPatternScale",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillPatternScaleX",1),t.Factory.addGetterSetter(t.Shape,"fillPatternScaleY",1),t.Factory.addComponentsGetterSetter(t.Shape,"fillLinearGradientStartPoint",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillLinearGradientStartPointX",0),t.Factory.addGetterSetter(t.Shape,"fillLinearGradientStartPointY",0),t.Factory.addComponentsGetterSetter(t.Shape,"fillLinearGradientEndPoint",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillLinearGradientEndPointX",0),t.Factory.addGetterSetter(t.Shape,"fillLinearGradientEndPointY",0),t.Factory.addComponentsGetterSetter(t.Shape,"fillRadialGradientStartPoint",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientStartPointX",0),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientStartPointY",0),t.Factory.addComponentsGetterSetter(t.Shape,"fillRadialGradientEndPoint",["x","y"]),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientEndPointX",0),t.Factory.addGetterSetter(t.Shape,"fillRadialGradientEndPointY",0),t.Factory.addGetterSetter(t.Shape,"fillPatternRotation",0),t.Factory.backCompat(t.Shape,{dashArray:"dash",getDashArray:"getDash",setDashArray:"getDash",drawFunc:"sceneFunc",getDrawFunc:"getSceneFunc",setDrawFunc:"setSceneFunc",drawHitFunc:"hitFunc",getDrawHitFunc:"getHitFunc",setDrawHitFunc:"setHitFunc"}),t.Collection.mapMethods(t.Shape)}(Konva),function(){"use strict";function t(t,e){t.content.addEventListener(e,function(n){t[O+e](n)},!1)}var e="Stage",n="string",i="px",a="mouseout",r="mouseleave",o="mouseover",s="mouseenter",h="mousemove",c="mousedown",l="mouseup",d="click",u="dblclick",f="touchstart",v="touchend",g="tap",p="dbltap",m="touchmove",_="DOMMouseScroll",y="mousewheel",K="wheel",S="contentMouseout",C="contentMouseover",x="contentMousemove",w="contentMousedown",b="contentMouseup",F="contentClick",T="contentDblclick",P="contentTouchstart",A="contentTouchend",k="contentDbltap",G="contentTap",D="contentTouchmove",M="contentWheel",R="div",L="relative",I="konvajs-content",N=" ",O="_",U="container",E="",B=[c,h,l,a,f,m,v,o,_,y,K],H=B.length;Konva.Stage=function(t){this.___init(t)},Konva.Util.addMethods(Konva.Stage,{___init:function(t){this.nodeType=e,Konva.Container.call(this,t),this._id=Konva.idCounter++,this._buildDOM(),this._bindContentEvents(),this._enableNestedTransforms=!1,Konva.stages.push(this)},_validateAdd:function(t){"Layer"!==t.getType()&&Konva.Util["throw"]("You may only add layers to the stage.")},setContainer:function(t){if(typeof t===n){if("."===t.charAt(0)){var e=t.slice(1);t=Konva.document.getElementsByClassName(e)[0]}else{var i;i="#"!==t.charAt(0)?t:t.slice(1),t=Konva.document.getElementById(i)}if(!t)throw"Can not find container in document with id "+i}return this._setAttr(U,t),this},shouldDrawHit:function(){return!0},draw:function(){return Konva.Node.prototype.draw.call(this),this},setHeight:function(t){return Konva.Node.prototype.setHeight.call(this,t),this._resizeDOM(),this},setWidth:function(t){return Konva.Node.prototype.setWidth.call(this,t),this._resizeDOM(),this},clear:function(){var t,e=this.children,n=e.length;for(t=0;t-1&&Konva.stages.splice(e,1),this},getPointerPosition:function(){return this.pointerPos},getStage:function(){return this},getContent:function(){return this.content},toDataURL:function(t){t=t||{};var e=t.mimeType||null,n=t.quality||null,i=t.x||0,a=t.y||0,r=new Konva.SceneCanvas({width:t.width||this.getWidth(),height:t.height||this.getHeight(),pixelRatio:t.pixelRatio}),o=r.getContext()._context,s=this.children;(i||a)&&o.translate(-1*i,-1*a),s.each(function(t){var e=t.getCanvas().getWidth(),n=t.getCanvas().getHeight(),i=t.getCanvas().getPixelRatio();o.drawImage(t.getCanvas()._canvas,0,0,e/i,n/i)});var h=r.toDataURL(e,n);return t.callback&&t.callback(h),h},toImage:function(t){var e=t.callback;t.callback=function(t){Konva.Util._getImage(t,function(t){e(t)})},this.toDataURL(t)},getIntersection:function(t,e){var n,i,a=this.getChildren(),r=a.length,o=r-1;for(n=o;n>=0;n--)if(i=a[n].getIntersection(t,e))return i;return null},_resizeDOM:function(){if(this.content){var t,e,n=this.getWidth(),a=this.getHeight(),r=this.getChildren(),o=r.length;for(this.content.style.width=n+i,this.content.style.height=a+i,this.bufferCanvas.setSize(n,a),this.bufferHitCanvas.setSize(n,a),t=0;t1){for(var e=0;e0){var a=t.touches[0];n=a.clientX-e.left,i=a.clientY-e.top}}else n=t.clientX-e.left,i=t.clientY-e.top;null!==n&&null!==i&&(this.pointerPos={x:n,y:i})},_getContentPosition:function(){var t=this.content.getBoundingClientRect?this.content.getBoundingClientRect():{top:0,left:0};return{top:t.top,left:t.left}},_buildDOM:function(){var t=this.getContainer();if(!t){if(Konva.Util.isBrowser())throw"Stage has no container. A container is required.";t=Konva.document.createElement(R)}t.innerHTML=E,this.content=Konva.document.createElement(R),this.content.style.position=L,this.content.className=I,this.content.setAttribute("role","presentation"),t.appendChild(this.content),this.bufferCanvas=new Konva.SceneCanvas,this.bufferHitCanvas=new Konva.HitCanvas({pixelRatio:1}),this._resizeDOM()},_onContent:function(t,e){var n,i,a=t.split(N),r=a.length;for(n=0;n0?{antialiased:!0}:{}},drawScene:function(t,i){var a=this.getLayer(),r=t||a&&a.getCanvas();return this._fire(e,{node:this}),this.getClearBeforeDraw()&&r.getContext().clear(),Konva.Container.prototype.drawScene.call(this,r,i),this._fire(n,{node:this}),this},drawHit:function(t,e){var n=this.getLayer(),i=t||n&&n.hitCanvas;return n&&n.getClearBeforeDraw()&&n.getHitCanvas().getContext().clear(),Konva.Container.prototype.drawHit.call(this,i,e),this.imageData=null,this},clear:function(t){return Konva.BaseLayer.prototype.clear.call(this,t),this.getHitCanvas().getContext().clear(t),this.imageData=null,this},setVisible:function(t){return Konva.Node.prototype.setVisible.call(this,t),t?(this.getCanvas()._canvas.style.display="block",this.hitCanvas._canvas.style.display="block"):(this.getCanvas()._canvas.style.display="none",this.hitCanvas._canvas.style.display="none"),this},enableHitGraph:function(){return this.setHitGraphEnabled(!0),this},disableHitGraph:function(){return this.setHitGraphEnabled(!1),this},setSize:function(t,e){return Konva.BaseLayer.prototype.setSize.call(this,t,e),this.hitCanvas.setSize(t,e),this}}),Konva.Util.extend(Konva.Layer,Konva.BaseLayer),Konva.Factory.addGetterSetter(Konva.Layer,"hitGraphEnabled",!0),Konva.Collection.mapMethods(Konva.Layer)}(),function(){"use strict";Konva.FastLayer=function(t){this.____init(t)},Konva.Util.addMethods(Konva.FastLayer,{____init:function(t){this.nodeType="Layer",this.canvas=new Konva.SceneCanvas,Konva.BaseLayer.call(this,t)},_validateAdd:function(t){var e=t.getType();"Shape"!==e&&Konva.Util["throw"]("You may only add shapes to a fast layer."); +},_setCanvasSize:function(t,e){this.canvas.setSize(t,e)},hitGraphEnabled:function(){return!1},getIntersection:function(){return null},drawScene:function(t){var e=this.getLayer(),n=t||e&&e.getCanvas();return this.getClearBeforeDraw()&&n.getContext().clear(),Konva.Container.prototype.drawScene.call(this,n),this},draw:function(){return this.drawScene(),this},setVisible:function(t){return Konva.Node.prototype.setVisible.call(this,t),t?this.getCanvas()._canvas.style.display="block":this.getCanvas()._canvas.style.display="none",this}}),Konva.Util.extend(Konva.FastLayer,Konva.BaseLayer),Konva.Collection.mapMethods(Konva.FastLayer)}(),function(){"use strict";Konva.Group=function(t){this.___init(t)},Konva.Util.addMethods(Konva.Group,{___init:function(t){this.nodeType="Group",Konva.Container.call(this,t)},_validateAdd:function(t){var e=t.getType();"Group"!==e&&"Shape"!==e&&Konva.Util["throw"]("You may only add groups and shapes to groups.")}}),Konva.Util.extend(Konva.Group,Konva.Container),Konva.Collection.mapMethods(Konva.Group)}(),function(t){"use strict";function e(t){setTimeout(t,1e3/60)}function n(){return a.apply(t.global,arguments)}var i=function(){return t.global.performance&&t.global.performance.now?function(){return t.global.performance.now()}:function(){return(new Date).getTime()}}(),a=function(){return t.global.requestAnimationFrame||t.global.webkitRequestAnimationFrame||t.global.mozRequestAnimationFrame||t.global.oRequestAnimationFrame||t.global.msRequestAnimationFrame||e}();t.Animation=function(e,n){var a=t.Animation;this.func=e,this.setLayers(n),this.id=a.animIdCounter++,this.frame={time:0,timeDiff:0,lastTime:i()}},t.Animation.prototype={setLayers:function(t){var e=[];return e=t?t.length>0?t:[t]:[],this.layers=e,this},getLayers:function(){return this.layers},addLayer:function(t){var e,n=this.layers,i=n.length;for(e=0;ethis.duration?this.yoyo?(this._time=this.duration,this.reverse()):this.finish():t<0?this.yoyo?(this._time=0,this.play()):this.reset():(this._time=t,this.update())},getTime:function(){return this._time},setPosition:function(t){this.prevPos=this._pos,this.propFunc(t),this._pos=t},getPosition:function(t){return void 0===t&&(t=this._time),this.func(t,this.begin,this._change,this.duration)},play:function(){this.state=n,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onPlay")},reverse:function(){this.state=i,this._time=this.duration-this._time,this._startTime=this.getTimer()-this._time,this.onEnterFrame(),this.fire("onReverse")},seek:function(t){this.pause(),this._time=t,this.update(),this.fire("onSeek")},reset:function(){this.pause(),this._time=0,this.update(),this.fire("onReset")},finish:function(){this.pause(),this._time=this.duration,this.update(),this.fire("onFinish")},update:function(){this.setPosition(this.getPosition(this._time))},onEnterFrame:function(){var t=this.getTimer()-this._startTime;this.state===n?this.setTime(t):this.state===i&&this.setTime(this.duration-t)},pause:function(){this.state=e,this.fire("onPause")},getTimer:function(){return(new Date).getTime()}},Konva.Tween=function(e){var n,i,r=this,s=e.node,h=s._id,c=e.easing||Konva.Easings.Linear,l=!!e.yoyo;n="undefined"==typeof e.duration?1:0===e.duration?.001:e.duration,this.node=s,this._id=a++;var d=s.getLayer()||(s instanceof Konva.Stage?s.getLayers():null);d||Konva.Util.error("Tween constructor have `node` that is not in a layer. Please add node into layer first."),this.anim=new Konva.Animation(function(){r.tween.onEnterFrame()},d),this.tween=new o(i,function(t){r._tweenFunc(t)},c,0,1,1e3*n,l),this._addListeners(),Konva.Tween.attrs[h]||(Konva.Tween.attrs[h]={}),Konva.Tween.attrs[h][this._id]||(Konva.Tween.attrs[h][this._id]={}),Konva.Tween.tweens[h]||(Konva.Tween.tweens[h]={});for(i in e)void 0===t[i]&&this._addAttr(i,e[i]);this.reset(),this.onFinish=e.onFinish,this.onReset=e.onReset},Konva.Tween.attrs={},Konva.Tween.tweens={},Konva.Tween.prototype={_addAttr:function(t,e){var n,i,a,o,s,h,c,l=this.node,d=l._id;if(a=Konva.Tween.tweens[d][t],a&&delete Konva.Tween.attrs[d][a][t],n=l.getAttr(t),Konva.Util._isArray(e))for(i=[],s=Math.max(e.length,n.length),"points"===t&&e.length!==n.length&&(e.length>n.length?(c=n,n=Konva.Util._prepareArrayForTween(n,e,l.closed())):(h=e,e=Konva.Util._prepareArrayForTween(e,n,l.closed()))),o=0;od)for(;x.length>0;){for(var b=0,F=x.length,T="",P=0;b>>1,k=x.slice(0,A+1),G=this._getTextWidth(k);G<=d?(b=A+1,T=k,P=G):F=A}if(!T)break;if(y){var D=Math.max(T.lastIndexOf(v),T.lastIndexOf(o))+1;D>0&&(b=D,T=T.slice(0,b),P=this._getTextWidth(T))}if(this._addTextLine(T,P),i=Math.max(i,P),f+=a,!p||c&&f+a>u)break;if(x=x.slice(b),x.length>0&&(w=this._getTextWidth(x),w<=d)){this._addTextLine(x,w),f+=a,i=Math.max(i,w);break}}else this._addTextLine(x,w),f+=a,i=Math.max(i,w);if(c&&f+a>u)break}S.restore(),this.textHeight=e,this.textWidth=i}},Konva.Util.extend(Konva.Text,Konva.Shape),Konva.Factory.addGetterSetter(Konva.Text,"fontFamily","Arial"),Konva.Factory.addGetterSetter(Konva.Text,"fontSize",12),Konva.Factory.addGetterSetter(Konva.Text,"fontStyle",u),Konva.Factory.addGetterSetter(Konva.Text,"fontVariant",u),Konva.Factory.addGetterSetter(Konva.Text,"padding",0),Konva.Factory.addGetterSetter(Konva.Text,"align",h),Konva.Factory.addGetterSetter(Konva.Text,"lineHeight",1),Konva.Factory.addGetterSetter(Konva.Text,"wrap",p),Konva.Factory.addGetter(Konva.Text,"text",s),Konva.Factory.addOverloadedGetterSetter(Konva.Text,"text"),Konva.Collection.mapMethods(Konva.Text)}(),function(){"use strict";Konva.Line=function(t){this.___init(t)},Konva.Line.prototype={___init:function(t){Konva.Shape.call(this,t),this.className="Line",this.on("pointsChange.konva tensionChange.konva closedChange.konva",function(){this._clearCache("tensionPoints")}),this.sceneFunc(this._sceneFunc)},_sceneFunc:function(t){var e,n,i,a=this.getPoints(),r=a.length,o=this.getTension(),s=this.getClosed();if(r){if(t.beginPath(),t.moveTo(a[0],a[1]),0!==o&&r>4){for(e=this.getTensionPoints(),n=e.length,i=s?0:4,s||t.quadraticCurveTo(e[0],e[1],e[2],e[3]);ih?s:h,v=s>h?1:s/h,g=s>h?h/s:1;t.translate(r,o),t.rotate(d),t.scale(v,g),t.arc(0,0,f,c,c+l,1-u),t.scale(1/v,1/g),t.rotate(-d),t.translate(-r,-o);break;case"z":t.closePath()}}t.fillStrokeShape(this)},getSelfRect:function(){var t=[];this.dataArray.forEach(function(e){t=t.concat(e.points)});for(var e,n,i=t[0],a=t[0],r=t[1],o=t[1],s=0;s0&&""===l[0]&&l.shift();for(var d=0;d0&&!isNaN(l[0]);){var u,f,v,g,p,m,_,y,K,S,C=null,x=[],w=o,b=s;switch(c){case"l":o+=l.shift(),s+=l.shift(),C="L",x.push(o,s);break;case"L":o=l.shift(),s=l.shift(),x.push(o,s);break;case"m":var F=l.shift(),T=l.shift();if(o+=F,s+=T,C="M",r.length>2&&"z"===r[r.length-1].command)for(var P=r.length-2;P>=0;P--)if("M"===r[P].command){o=r[P].points[0]+F,s=r[P].points[1]+T;break}x.push(o,s),c="l";break;case"M":o=l.shift(),s=l.shift(),C="M",x.push(o,s),c="L";break;case"h":o+=l.shift(),C="L",x.push(o,s);break;case"H":o=l.shift(),C="L",x.push(o,s);break;case"v":s+=l.shift(),C="L",x.push(o,s);break;case"V":s=l.shift(),C="L",x.push(o,s);break;case"C":x.push(l.shift(),l.shift(),l.shift(),l.shift()),o=l.shift(),s=l.shift(),x.push(o,s);break;case"c":x.push(o+l.shift(),s+l.shift(),o+l.shift(),s+l.shift()),o+=l.shift(),s+=l.shift(),C="C",x.push(o,s);break;case"S":f=o,v=s,u=r[r.length-1],"C"===u.command&&(f=o+(o-u.points[2]),v=s+(s-u.points[3])),x.push(f,v,l.shift(),l.shift()),o=l.shift(),s=l.shift(),C="C",x.push(o,s);break;case"s":f=o,v=s,u=r[r.length-1],"C"===u.command&&(f=o+(o-u.points[2]),v=s+(s-u.points[3])),x.push(f,v,o+l.shift(),s+l.shift()),o+=l.shift(),s+=l.shift(),C="C",x.push(o,s);break;case"Q":x.push(l.shift(),l.shift()),o=l.shift(),s=l.shift(),x.push(o,s);break;case"q":x.push(o+l.shift(),s+l.shift()),o+=l.shift(),s+=l.shift(),C="Q",x.push(o,s);break;case"T":f=o,v=s,u=r[r.length-1],"Q"===u.command&&(f=o+(o-u.points[0]),v=s+(s-u.points[1])),o=l.shift(),s=l.shift(),C="Q",x.push(f,v,o,s);break;case"t":f=o,v=s,u=r[r.length-1],"Q"===u.command&&(f=o+(o-u.points[0]),v=s+(s-u.points[1])),o+=l.shift(),s+=l.shift(),C="Q",x.push(f,v,o,s);break;case"A":g=l.shift(),p=l.shift(),m=l.shift(),_=l.shift(),y=l.shift(),K=o,S=s,o=l.shift(),s=l.shift(),C="A",x=this.convertEndpointToCenterParameterization(K,S,o,s,_,y,g,p,m);break;case"a":g=l.shift(),p=l.shift(),m=l.shift(),_=l.shift(),y=l.shift(),K=o,S=s,o+=l.shift(),s+=l.shift(),C="A",x=this.convertEndpointToCenterParameterization(K,S,o,s,_,y,g,p,m)}r.push({command:C||c,points:x,start:{x:w,y:b},pathLength:this.calcLength(w,b,C||c,x)})}"z"!==c&&"Z"!==c||r.push({command:"z",points:[],start:void 0,pathLength:0})}return r},Konva.Path.calcLength=function(t,e,n,i){var a,r,o,s,h=Konva.Path;switch(n){case"L":return h.getLineLength(t,e,i[0],i[1]);case"C":for(a=0,r=h.getPointOnCubicBezier(0,t,e,i[0],i[1],i[2],i[3],i[4],i[5]),s=.01;s<=1;s+=.01)o=h.getPointOnCubicBezier(s,t,e,i[0],i[1],i[2],i[3],i[4],i[5]),a+=h.getLineLength(r.x,r.y,o.x,o.y),r=o;return a;case"Q":for(a=0,r=h.getPointOnQuadraticBezier(0,t,e,i[0],i[1],i[2],i[3]),s=.01;s<=1;s+=.01)o=h.getPointOnQuadraticBezier(s,t,e,i[0],i[1],i[2],i[3]),a+=h.getLineLength(r.x,r.y,o.x,o.y),r=o;return a;case"A":a=0;var c=i[4],l=i[5],d=i[4]+l,u=Math.PI/180;if(Math.abs(c-d)d;s-=u)o=h.getPointOnEllipticalArc(i[0],i[1],i[2],i[3],s,0),a+=h.getLineLength(r.x,r.y,o.x,o.y),r=o;else for(s=c+u;s1&&(o*=Math.sqrt(u),s*=Math.sqrt(u));var f=Math.sqrt((o*o*(s*s)-o*o*(d*d)-s*s*(l*l))/(o*o*(d*d)+s*s*(l*l)));a===r&&(f*=-1),isNaN(f)&&(f=0);var v=f*o*d/s,g=f*-s*l/o,p=(t+n)/2+Math.cos(c)*v-Math.sin(c)*g,m=(e+i)/2+Math.sin(c)*v+Math.cos(c)*g,_=function(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])},y=function(t,e){return(t[0]*e[0]+t[1]*e[1])/(_(t)*_(e))},K=function(t,e){return(t[0]*e[1]=1&&(w=0),0===r&&w>0&&(w-=2*Math.PI),1===r&&w<0&&(w+=2*Math.PI),[p,m,o,s,S,w,c,r]},Konva.Factory.addGetterSetter(Konva.Path,"data"),Konva.Collection.mapMethods(Konva.Path)}(),function(){"use strict";function t(t){t.fillText(this.partialText,0,0)}function e(t){t.strokeText(this.partialText,0,0)}var n="",i="normal";Konva.TextPath=function(t){this.___init(t)},Konva.TextPath.prototype={___init:function(n){var i=this;this.dummyCanvas=Konva.Util.createCanvasElement(),this.dataArray=[],Konva.Shape.call(this,n),this._fillFunc=t,this._strokeFunc=e,this._fillFuncHit=t,this._strokeFuncHit=e,this.className="TextPath",this.dataArray=Konva.Path.parsePathData(this.attrs.data),this.on("dataChange.konva",function(){i.dataArray=Konva.Path.parsePathData(this.attrs.data)}),this.on("textChange.konva textStroke.konva textStrokeWidth.konva",i._setTextData),i._setTextData(),this.sceneFunc(this._sceneFunc)},_sceneFunc:function(t){t.setAttr("font",this._getContextFont()),t.setAttr("textBaseline","middle"),t.setAttr("textAlign","left"),t.save();for(var e=this.glyphInfo,n=0;n0)return o=i,e[i];"M"===e[i].command&&(n={x:e[i].points[0],y:e[i].points[1]})}return{}},c=function(e){var r=t._getTextSize(e).width,o=0,c=0;for(i=void 0;Math.abs(r-o)/r>.01&&c<25;){c++;for(var l=o;void 0===a;)a=h(),a&&l+a.pathLengthr?i=Konva.Path.getPointOnLine(r,n.x,n.y,a.points[0],a.points[1],n.x,n.y):a=void 0;break;case"A":var u=a.points[4],f=a.points[5],v=a.points[4]+f;0===s?s=u+1e-8:r>o?s+=Math.PI/180*f/Math.abs(f):s-=Math.PI/360*f/Math.abs(f),(f<0&&s=0&&s>v)&&(s=v,d=!0),i=Konva.Path.getPointOnEllipticalArc(a.points[0],a.points[1],a.points[2],a.points[3],s,a.points[6]);break;case"C":0===s?s=r>a.pathLength?1e-8:r/a.pathLength:r>o?s+=(r-o)/a.pathLength:s-=(o-r)/a.pathLength,s>1&&(s=1,d=!0),i=Konva.Path.getPointOnCubicBezier(s,a.start.x,a.start.y,a.points[0],a.points[1],a.points[2],a.points[3],a.points[4],a.points[5]);break;case"Q":0===s?s=r/a.pathLength:r>o?s+=(r-o)/a.pathLength:s-=(o-r)/a.pathLength,s>1&&(s=1,d=!0),i=Konva.Path.getPointOnQuadraticBezier(s,a.start.x,a.start.y,a.points[0],a.points[1],a.points[2],a.points[3])}void 0!==i&&(o=Konva.Path.getLineLength(n.x,n.y,i.x,i.y)),d&&(d=!1,a=void 0)}},l=0;l0){return parseInt(ua.substring(msie+5,ua.indexOf(".",msie)),10)}var trident=ua.indexOf("trident/");if(trident>0){var rv=ua.indexOf("rv:");return parseInt(ua.substring(rv+3,ua.indexOf(".",rv)),10)}var edge=ua.indexOf("edge/");if(edge>0){return parseInt(ua.substring(edge+5,ua.indexOf(".",edge)),10)}return false},_parseUA:function(userAgent){var ua=userAgent.toLowerCase(),match=/(chrome)[ \/]([\w.]+)/.exec(ua)||/(webkit)[ \/]([\w.]+)/.exec(ua)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua)||/(msie) ([\w.]+)/.exec(ua)||ua.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)||[],mobile=!!userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i),ieMobile=!!userAgent.match(/IEMobile/i);return{browser:match[1]||"",version:match[2]||"0",isIE:Konva._detectIE(ua),mobile:mobile,ieMobile:ieMobile}},UA:undefined};var glob=typeof window!=="undefined"?window:typeof global!=="undefined"?global:typeof WorkerGlobalScope!=="undefined"?self:{};Konva.UA=Konva._parseUA(glob.navigator&&glob.navigator.userAgent||"");if(glob.Konva){console.error("Konva instance is already exist in current eviroment. "+"Please use only one instance.")}glob.Konva=Konva;Konva.global=glob;if(typeof exports==="object"){if(glob.window&&glob.window.document){Konva.document=glob.window.document;Konva.window=glob.window}else{var Canvas=require("canvas");var jsdom=require("jsdom").jsdom;Konva.window=jsdom("").defaultView;Konva.document=Konva.window.document;Konva.window.Image=Canvas.Image;Konva._nodeCanvas=Canvas}module.exports=Konva;return}else if(typeof define==="function"&&define.amd){define(function(){return Konva})}Konva.document=document;Konva.window=window})(typeof window!=="undefined"?window:global);(function(){"use strict";Konva.Collection=function(){var args=[].slice.call(arguments),length=args.length,i=0;this.length=length;for(;i0},isValidSelector:function(selector){if(typeof selector!=="string"){return false}var firstChar=selector[0];return firstChar==="#"||firstChar==="."||firstChar===firstChar.toUpperCase()},createCanvasElement:function(){var canvas=Konva.document.createElement("canvas");try{canvas.style=canvas.style||{}}catch(e){}return canvas},isBrowser:function(){return typeof exports!=="object"},_isInDocument:function(el){while(el=el.parentNode){if(el==Konva.document){return true}}return false},_simplifyArray:function(arr){var retArr=[],len=arr.length,util=Konva.Util,n,val;for(n=0;n>16&255,g:bigint>>8&255,b:bigint&255}},getRandomColor:function(){var randColor=(Math.random()*16777215<<0).toString(16);while(randColor.length<6){randColor=ZERO+randColor}return HASH+randColor},get:function(val,def){if(val===undefined){return def}else{return val}},getRGB:function(color){var rgb;if(color in COLORS){rgb=COLORS[color];return{r:rgb[0],g:rgb[1],b:rgb[2]}}else if(color[0]===HASH){return this._hexToRgb(color.substring(1))}else if(color.substr(0,4)===RGB_PAREN){rgb=RGB_REGEX.exec(color.replace(/ /g,""));return{r:parseInt(rgb[1],10),g:parseInt(rgb[2],10),b:parseInt(rgb[3],10)}}else{return{r:0,g:0,b:0}}},colorToRGBA:function(str){str=str||"black";return Konva.Util._namedColorToRBA(str)||Konva.Util._hex3ColorToRGBA(str)||Konva.Util._hex6ColorToRGBA(str)||Konva.Util._rgbColorToRGBA(str)||Konva.Util._rgbaColorToRGBA(str)},_namedColorToRBA:function(str){var c=COLORS[str.toLowerCase()];if(!c){return null}return{r:c[0],g:c[1],b:c[2],a:1}},_rgbColorToRGBA:function(str){if(str.indexOf("rgb(")===0){str=str.match(/rgb\(([^)]+)\)/)[1];var parts=str.split(/ *, */).map(Number);return{r:parts[0],g:parts[1],b:parts[2],a:1}}},_rgbaColorToRGBA:function(str){if(str.indexOf("rgba(")===0){str=str.match(/rgba\(([^)]+)\)/)[1];var parts=str.split(/ *, */).map(Number);return{r:parts[0],g:parts[1],b:parts[2],a:parts[3]}}},_hex6ColorToRGBA:function(str){if(str[0]==="#"&&str.length===7){return{r:parseInt(str.slice(1,3),16),g:parseInt(str.slice(3,5),16),b:parseInt(str.slice(5,7),16),a:1}}},_hex3ColorToRGBA:function(str){if(str[0]==="#"&&str.length===4){return{r:parseInt(str[1]+str[1],16),g:parseInt(str[2]+str[2],16),b:parseInt(str[3]+str[3],16),a:1}}},_merge:function(o1,o2){var retObj=this._clone(o2);for(var key in o1){if(this._isObject(o1[key])){retObj[key]=this._merge(o1[key],retObj[key])}else{retObj[key]=o1[key]}}return retObj},cloneObject:function(obj){var retObj={};for(var key in obj){if(this._isObject(obj[key])){retObj[key]=this.cloneObject(obj[key])}else if(this._isArray(obj[key])){retObj[key]=this.cloneArray(obj[key])}else{retObj[key]=obj[key]}}return retObj},cloneArray:function(arr){return arr.slice(0)},_degToRad:function(deg){return deg*PI_OVER_DEG180},_radToDeg:function(rad){return rad*DEG180_OVER_PI},_capitalize:function(str){return str.charAt(0).toUpperCase()+str.slice(1)},throw:function(str){throw new Error(KONVA_ERROR+str)},error:function(str){console.error(KONVA_ERROR+str)},warn:function(str){if(Konva.global.console&&console.warn&&Konva.showWarnings){console.warn(KONVA_WARNING+str)}},extend:function(child,parent){function Ctor(){this.constructor=child}Ctor.prototype=parent.prototype;var oldProto=child.prototype;child.prototype=new Ctor;for(var key in oldProto){if(oldProto.hasOwnProperty(key)){child.prototype[key]=oldProto[key]}}child.__super__=parent.prototype;child.super=parent},addMethods:function(constructor,methods){var key;for(key in methods){constructor.prototype[key]=methods[key]}},_getControlPoints:function(x0,y0,x1,y1,x2,y2,t){var d01=Math.sqrt(Math.pow(x1-x0,2)+Math.pow(y1-y0,2)),d12=Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)),fa=t*d01/(d01+d12),fb=t*d12/(d01+d12),p1x=x1-fa*(x2-x0),p1y=y1-fa*(y2-y0),p2x=x1+fb*(x2-x0),p2y=y1+fb*(y2-y0);return[p1x,p1y,p2x,p2y]},_expandPoints:function(p,tension){var len=p.length,allPoints=[],n,cp;for(n=2;n1){x=x2;y=y2;dist=(x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)}else{x=x1+u*(x2-x1);y=y1+u*(y2-y1);dist=(x-x3)*(x-x3)+(y-y3)*(y-y3)}}return[x,y,dist]},_getProjectionToLine:function(pt,line,isClosed){var pc=Konva.Util.cloneObject(pt);var dist=Number.MAX_VALUE;line.forEach(function(p1,i){if(!isClosed&&i===line.length-1){return}var p2=line[(i+1)%line.length];var proj=Konva.Util._getProjectionToSegment(p1.x,p1.y,p2.x,p2.y,pt.x,pt.y);var px=proj[0],py=proj[1],pdist=proj[2];if(pdistendArray.length){var temp=endArray;endArray=startArray;startArray=temp}for(n=0;n=Konva.traceArrMax){traceArr.shift()}},reset:function(){var pixelRatio=this.getCanvas().getPixelRatio();this.setTransform(1*pixelRatio,0,0,1*pixelRatio,0,0)},getCanvas:function(){return this.canvas},clear:function(bounds){var canvas=this.getCanvas();if(bounds){this.clearRect(bounds.x||0,bounds.y||0,bounds.width||0,bounds.height||0)}else{this.clearRect(0,0,canvas.getWidth()/canvas.pixelRatio,canvas.getHeight()/canvas.pixelRatio)}},_applyLineCap:function(shape){var lineCap=shape.getLineCap();if(lineCap){this.setAttr("lineCap",lineCap)}},_applyOpacity:function(shape){var absOpacity=shape.getAbsoluteOpacity();if(absOpacity!==1){this.setAttr("globalAlpha",absOpacity)}},_applyLineJoin:function(shape){var lineJoin=shape.getLineJoin();if(lineJoin){this.setAttr("lineJoin",lineJoin)}},setAttr:function(attr,val){this._context[attr]=val},arc:function(){var a=arguments;this._context.arc(a[0],a[1],a[2],a[3],a[4],a[5])},beginPath:function(){this._context.beginPath()},bezierCurveTo:function(){var a=arguments;this._context.bezierCurveTo(a[0],a[1],a[2],a[3],a[4],a[5])},clearRect:function(){var a=arguments;this._context.clearRect(a[0],a[1],a[2],a[3])},clip:function(){this._context.clip()},closePath:function(){this._context.closePath()},createImageData:function(){var a=arguments;if(a.length===2){return this._context.createImageData(a[0],a[1])}else if(a.length===1){return this._context.createImageData(a[0])}},createLinearGradient:function(){var a=arguments;return this._context.createLinearGradient(a[0],a[1],a[2],a[3])},createPattern:function(){var a=arguments;return this._context.createPattern(a[0],a[1])},createRadialGradient:function(){var a=arguments;return this._context.createRadialGradient(a[0],a[1],a[2],a[3],a[4],a[5])},drawImage:function(){var a=arguments,_context=this._context;if(a.length===3){_context.drawImage(a[0],a[1],a[2])}else if(a.length===5){try{_context.drawImage(a[0],a[1],a[2],a[3],a[4])}catch(e){Konva.Util.warn("Unable to drawImage due to: "+e.message)}}else if(a.length===9){_context.drawImage(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])}},isPointInPath:function(x,y){return this._context.isPointInPath(x,y)},fill:function(){this._context.fill()},fillRect:function(x,y,width,height){this._context.fillRect(x,y,width,height)},strokeRect:function(x,y,width,height){this._context.strokeRect(x,y,width,height)},fillText:function(){var a=arguments;this._context.fillText(a[0],a[1],a[2])},measureText:function(text){return this._context.measureText(text)},getImageData:function(){var a=arguments;return this._context.getImageData(a[0],a[1],a[2],a[3])},lineTo:function(){var a=arguments;this._context.lineTo(a[0],a[1])},moveTo:function(){var a=arguments;this._context.moveTo(a[0],a[1])},rect:function(){var a=arguments;this._context.rect(a[0],a[1],a[2],a[3])},putImageData:function(){var a=arguments;this._context.putImageData(a[0],a[1],a[2])},quadraticCurveTo:function(){var a=arguments;this._context.quadraticCurveTo(a[0],a[1],a[2],a[3])},restore:function(){this._context.restore()},rotate:function(){var a=arguments;this._context.rotate(a[0])},save:function(){this._context.save()},scale:function(){var a=arguments;this._context.scale(a[0],a[1])},setLineDash:function(){var a=arguments,_context=this._context;if(this._context.setLineDash){_context.setLineDash(a[0])}else if("mozDash"in _context){_context.mozDash=a[0]}else if("webkitLineDash"in _context){_context.webkitLineDash=a[0]}},getLineDash:function(){return this._context.getLineDash()},setTransform:function(){var a=arguments;this._context.setTransform(a[0],a[1],a[2],a[3],a[4],a[5])},stroke:function(){this._context.stroke()},strokeText:function(){var a=arguments;this._context.strokeText(a[0],a[1],a[2])},transform:function(){var a=arguments;this._context.transform(a[0],a[1],a[2],a[3],a[4],a[5])},translate:function(){var a=arguments;this._context.translate(a[0],a[1])},_enableTrace:function(){var that=this,len=CONTEXT_METHODS.length,_simplifyArray=Konva.Util._simplifyArray,origSetter=this.setAttr,n,args;var func=function(methodName){var origMethod=that[methodName],ret;that[methodName]=function(){args=_simplifyArray(Array.prototype.slice.call(arguments,0));ret=origMethod.apply(that,arguments);that._trace({method:methodName,args:args});return ret}};for(n=0;n255){return 255}else if(val<0){return 0}return Math.round(val)},alphaComponent:function(val){if(val>1){return 1}else if(val<1e-4){return 1e-4}return val}}})();(function(Konva){"use strict";var ABSOLUTE_OPACITY="absoluteOpacity",ABSOLUTE_TRANSFORM="absoluteTransform",ABSOLUTE_SCALE="absoluteScale",CHANGE="Change",CHILDREN="children",DOT=".",EMPTY_STRING="",GET="get",ID="id",KONVA="konva",LISTENING="listening",MOUSEENTER="mouseenter",MOUSELEAVE="mouseleave",NAME="name",SET="set",SHAPE="Shape",SPACE=" ",STAGE="stage",TRANSFORM="transform",UPPER_STAGE="Stage",VISIBLE="visible",CLONE_BLACK_LIST=["id"],TRANSFORM_CHANGE_STR=["xChange.konva","yChange.konva","scaleXChange.konva","scaleYChange.konva","skewXChange.konva","skewYChange.konva","rotationChange.konva","offsetXChange.konva","offsetYChange.konva","transformsEnabledChange.konva"].join(SPACE),SCALE_CHANGE_STR=["scaleXChange.konva","scaleYChange.konva"].join(SPACE);Konva.Node=function(config){this._init(config)};Konva.Util.addMethods(Konva.Node,{_init:function(config){var that=this;this._id=Konva.idCounter++;this.eventListeners={};this.attrs={};this._cache={};this._filterUpToDate=false;this.setAttrs(config);this.on(TRANSFORM_CHANGE_STR,function(){this._clearCache(TRANSFORM);that._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM)});this.on(SCALE_CHANGE_STR,function(){that._clearSelfAndDescendantCache(ABSOLUTE_SCALE)});this.on("visibleChange.konva",function(){that._clearSelfAndDescendantCache(VISIBLE)});this.on("listeningChange.konva",function(){that._clearSelfAndDescendantCache(LISTENING)});this.on("opacityChange.konva",function(){that._clearSelfAndDescendantCache(ABSOLUTE_OPACITY)})},_clearCache:function(attr){if(attr){delete this._cache[attr]}else{this._cache={}}},_getCache:function(attr,privateGetter){var cache=this._cache[attr];if(cache===undefined){this._cache[attr]=privateGetter.call(this)}return this._cache[attr]},_clearSelfAndDescendantCache:function(attr){this._clearCache(attr);if(this.children){this.getChildren().each(function(node){node._clearSelfAndDescendantCache(attr)})}},clearCache:function(){delete this._cache.canvas;this._filterUpToDate=false;return this},cache:function(config){var conf=config||{},rect=this.getClientRect(true),width=conf.width||rect.width,height=conf.height||rect.height,x=conf.x||rect.x,y=conf.y||rect.y,offset=conf.offset||0,drawBorder=conf.drawBorder||false;if(!width||!height){throw new Error("Width or height of caching configuration equals 0.")}width+=offset*2;height+=offset*2;x-=offset;y-=offset;var cachedSceneCanvas=new Konva.SceneCanvas({width:width,height:height}),cachedFilterCanvas=new Konva.SceneCanvas({width:width,height:height}),cachedHitCanvas=new Konva.HitCanvas({pixelRatio:1,width:width,height:height}),sceneContext=cachedSceneCanvas.getContext(),hitContext=cachedHitCanvas.getContext();cachedHitCanvas.isCache=true;this.clearCache();sceneContext.save();hitContext.save();sceneContext.translate(-x,-y);hitContext.translate(-x,-y);this.drawScene(cachedSceneCanvas,this,true);this.drawHit(cachedHitCanvas,this,true);sceneContext.restore();hitContext.restore();if(drawBorder){sceneContext.save();sceneContext.beginPath();sceneContext.rect(0,0,width,height);sceneContext.closePath();sceneContext.setAttr("strokeStyle","red");sceneContext.setAttr("lineWidth",5);sceneContext.stroke();sceneContext.restore()}this._cache.canvas={scene:cachedSceneCanvas,filter:cachedFilterCanvas,hit:cachedHitCanvas,x:x,y:y};return this},getClientRect:function(){throw new Error('abstract "getClientRect" method call')},_transformedRect:function(rect){var points=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];var minX,minY,maxX,maxY;var trans=this.getTransform();points.forEach(function(point){var transformed=trans.point(point);if(minX===undefined){minX=maxX=transformed.x;minY=maxY=transformed.y}minX=Math.min(minX,transformed.x);minY=Math.min(minY,transformed.y);maxX=Math.max(maxX,transformed.x);maxY=Math.max(maxY,transformed.y)});return{x:minX,y:minY,width:maxX-minX,height:maxY-minY}},_drawCachedSceneCanvas:function(context){context.save();context._applyOpacity(this);context.translate(this._cache.canvas.x,this._cache.canvas.y);var cacheCanvas=this._getCachedSceneCanvas();var ratio=cacheCanvas.pixelRatio;context.drawImage(cacheCanvas._canvas,0,0,cacheCanvas.width/ratio,cacheCanvas.height/ratio);context.restore()},_drawCachedHitCanvas:function(context){var cachedCanvas=this._cache.canvas,hitCanvas=cachedCanvas.hit;context.save();context.translate(this._cache.canvas.x,this._cache.canvas.y);context.drawImage(hitCanvas._canvas,0,0);context.restore()},_getCachedSceneCanvas:function(){var filters=this.filters(),cachedCanvas=this._cache.canvas,sceneCanvas=cachedCanvas.scene,filterCanvas=cachedCanvas.filter,filterContext=filterCanvas.getContext(),len,imageData,n,filter;if(filters){if(!this._filterUpToDate){var ratio=sceneCanvas.pixelRatio;try{len=filters.length;filterContext.clear();filterContext.drawImage(sceneCanvas._canvas,0,0,sceneCanvas.getWidth()/ratio,sceneCanvas.getHeight()/ratio);imageData=filterContext.getImageData(0,0,filterCanvas.getWidth(),filterCanvas.getHeight());for(n=0;n0&&nodes[0].getDepth()<=depth){addChildren(nodes)}}if(that.nodeType!==UPPER_STAGE){addChildren(that.getStage().getChildren())}return index},getDepth:function(){var depth=0,parent=this.parent;while(parent){depth++;parent=parent.parent}return depth},setPosition:function(pos){this.setX(pos.x);this.setY(pos.y);return this},getPosition:function(){return{x:this.getX(),y:this.getY()}},getAbsolutePosition:function(top){var absoluteMatrix=this.getAbsoluteTransform(top).getMatrix(),absoluteTransform=new Konva.Transform,offset=this.offset();absoluteTransform.m=absoluteMatrix.slice();absoluteTransform.translate(offset.x,offset.y);return absoluteTransform.getTranslation()},setAbsolutePosition:function(pos){var origTrans=this._clearTransform(),it;this.attrs.x=origTrans.x;this.attrs.y=origTrans.y;delete origTrans.x;delete origTrans.y;it=this.getAbsoluteTransform();it.invert();it.translate(pos.x,pos.y);pos={x:this.attrs.x+it.getTranslation().x,y:this.attrs.y+it.getTranslation().y};this.setPosition({x:pos.x,y:pos.y});this._setTransform(origTrans);return this},_setTransform:function(trans){var key;for(key in trans){this.attrs[key]=trans[key]}this._clearCache(TRANSFORM);this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM)},_clearTransform:function(){var trans={x:this.getX(),y:this.getY(),rotation:this.getRotation(),scaleX:this.getScaleX(),scaleY:this.getScaleY(),offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),skewX:this.getSkewX(),skewY:this.getSkewY()};this.attrs.x=0;this.attrs.y=0;this.attrs.rotation=0;this.attrs.scaleX=1;this.attrs.scaleY=1;this.attrs.offsetX=0;this.attrs.offsetY=0;this.attrs.skewX=0;this.attrs.skewY=0;this._clearCache(TRANSFORM);this._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM);return trans},move:function(change){var changeX=change.x,changeY=change.y,x=this.getX(),y=this.getY();if(changeX!==undefined){x+=changeX}if(changeY!==undefined){y+=changeY}this.setPosition({x:x,y:y});return this},_eachAncestorReverse:function(func,top){var family=[],parent=this.getParent(),len,n;if(top&&top._id===this._id){func(this);return true}family.unshift(this);while(parent&&(!top||parent._id!==top._id)){family.unshift(parent);parent=parent.parent}len=family.length;for(n=0;n0){this.parent.children.splice(index,1);this.parent.children.splice(index-1,0,this);this.parent._setChildrenIndices();return true}return false},moveToBottom:function(){if(!this.parent){Konva.Util.warn("Node has no parent. moveToBottom function is ignored.");return false}var index=this.index;if(index>0){this.parent.children.splice(index,1);this.parent.children.unshift(this);this.parent._setChildrenIndices();return true}return false},setZIndex:function(zIndex){if(!this.parent){Konva.Util.warn("Node has no parent. zIndex parameter is ignored.");return false}var index=this.index;this.parent.children.splice(index,1);this.parent.children.splice(zIndex,0,this);this.parent._setChildrenIndices();return this},getAbsoluteOpacity:function(){return this._getCache(ABSOLUTE_OPACITY,this._getAbsoluteOpacity)},_getAbsoluteOpacity:function(){var absOpacity=this.getOpacity();if(this.getParent()){absOpacity*=this.getParent().getAbsoluteOpacity()}return absOpacity},moveTo:function(newContainer){if(this.getParent()!==newContainer){this.remove();newContainer.add(this)}return this},toObject:function(){var obj={},attrs=this.getAttrs(),key,val,getter,defaultValue;obj.attrs={};for(key in attrs){val=attrs[key];if(Konva.Util._isFunction(val)||Konva.Util._isElement(val)||(Konva.Util._isObject(val)||Konva.Util._hasMethods(val))){continue}getter=this[key];delete attrs[key];defaultValue=getter?getter.call(this):null;attrs[key]=val;if(defaultValue!==val){obj.attrs[key]=val}}obj.className=this.getClassName();return obj},toJSON:function(){return JSON.stringify(this.toObject())},getParent:function(){return this.parent},findAncestors:function(selector,includeSelf,stopNode){var res=[];if(includeSelf&&this._isMatch(selector)){res.push(this)}var ancestor=this.parent;while(ancestor){if(ancestor===stopNode){return res}if(ancestor._isMatch(selector)){res.push(ancestor)}ancestor=ancestor.parent}return res},findAncestor:function(selector,includeSelf,stopNode){return this.findAncestors(selector,includeSelf,stopNode)[0]},_isMatch:function(selector){if(!selector){return false}var selectorArr=selector.replace(/ /g,"").split(","),len=selectorArr.length,n,sel;for(n=0;n>shg_sum;if(pa!==0){pa=255/pa;pixels[yi]=(r_sum*mul_sum>>shg_sum)*pa;pixels[yi+1]=(g_sum*mul_sum>>shg_sum)*pa;pixels[yi+2]=(b_sum*mul_sum>>shg_sum)*pa}else{pixels[yi]=pixels[yi+1]=pixels[yi+2]=0}r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;a_sum-=a_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;a_out_sum-=stackIn.a;p=yw+((p=x+radius+1)>shg_sum;if(pa>0){pa=255/pa;pixels[p]=(r_sum*mul_sum>>shg_sum)*pa;pixels[p+1]=(g_sum*mul_sum>>shg_sum)*pa;pixels[p+2]=(b_sum*mul_sum>>shg_sum)*pa}else{pixels[p]=pixels[p+1]=pixels[p+2]=0}r_sum-=r_out_sum;g_sum-=g_out_sum;b_sum-=b_out_sum;a_sum-=a_out_sum;r_out_sum-=stackIn.r;g_out_sum-=stackIn.g;b_out_sum-=stackIn.b;a_out_sum-=stackIn.a;p=x+((p=y+radiusPlus1)0){filterGaussBlurRGBA(imageData,radius)}};Konva.Factory.addGetterSetter(Konva.Node,"blurRadius",0,null,Konva.Factory.afterSetFilter)})();(function(){"use strict";function pixelAt(idata,x,y){var idx=(y*idata.width+x)*4; +var d=[];d.push(idata.data[idx++],idata.data[idx++],idata.data[idx++],idata.data[idx++]);return d}function rgbDistance(p1,p2){return Math.sqrt(Math.pow(p1[0]-p2[0],2)+Math.pow(p1[1]-p2[1],2)+Math.pow(p1[2]-p2[2],2))}function rgbMean(pTab){var m=[0,0,0];for(var i=0;i=0&&scy=0&&scx=0&&scy=0&&scx=255*4?255:0}}return maskResult}function smoothEdgeMask(mask,sw,sh){var weights=[1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9,1/9];var side=Math.round(Math.sqrt(weights.length));var halfSide=Math.floor(side/2);var maskResult=[];for(var y=0;y=0&&scy=0&&scx255){return 255}else if(val<0){return 0}else{return Math.round(val)}});Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(val){this._filterUpToDate=false;if(val>255){return 255}else if(val<0){return 0}else{return Math.round(val)}});Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter)})();(function(){"use strict";Konva.Filters.RGBA=function(imageData){var data=imageData.data,nPixels=data.length,red=this.red(),green=this.green(),blue=this.blue(),alpha=this.alpha(),i,ia;for(i=0;i255){return 255}else if(val<0){return 0}else{return Math.round(val)}});Konva.Factory.addGetterSetter(Konva.Node,"green",0,function(val){this._filterUpToDate=false;if(val>255){return 255}else if(val<0){return 0}else{return Math.round(val)}});Konva.Factory.addGetterSetter(Konva.Node,"blue",0,Konva.Validators.RGBComponent,Konva.Factory.afterSetFilter);Konva.Factory.addGetterSetter(Konva.Node,"alpha",1,function(val){this._filterUpToDate=false;if(val>1){return 1}else if(val<0){return 0}else{return val}})})();(function(){"use strict";Konva.Filters.HSV=function(imageData){var data=imageData.data,nPixels=data.length,v=Math.pow(2,this.value()),s=Math.pow(2,this.saturation()),h=Math.abs(this.hue()+360)%360,i;var vsu=v*s*Math.cos(h*Math.PI/180),vsw=v*s*Math.sin(h*Math.PI/180);var rr=.299*v+.701*vsu+.167*vsw,rg=.587*v-.587*vsu+.33*vsw,rb=.114*v-.114*vsu-.497*vsw;var gr=.299*v-.299*vsu-.328*vsw,gg=.587*v+.413*vsu+.035*vsw,gb=.114*v-.114*vsu+.293*vsw;var br=.299*v-.3*vsu+1.25*vsw,bg=.587*v-.586*vsu-1.05*vsw,bb=.114*v+.886*vsu-.2*vsw;var r,g,b,a;for(i=0;ih){otherY=0}var offsetYOther=(y-1+otherY)*w*4;var x=w;do{var offset=offsetY+(x-1)*4;var otherX=dirX;if(x+otherX<1){otherX=0}if(x+otherX>w){otherX=0}var offsetOther=offsetYOther+(x-1+otherX)*4;var dR=data[offset]-data[offsetOther];var dG=data[offset+1]-data[offsetOther+1];var dB=data[offset+2]-data[offsetOther+2];var dif=dR;var absDif=dif>0?dif:-dif;var absG=dG>0?dG:-dG;var absB=dB>0?dB:-dB;if(absG>absDif){dif=dG}if(absB>absDif){dif=dB}dif*=strength;if(blend){var r=data[offset]+dif;var g=data[offset+1]+dif;var b=data[offset+2]+dif;data[offset]=r>255?255:r<0?0:r;data[offset+1]=g>255?255:g<0?0:g;data[offset+2]=b>255?255:b<0?0:b}else{var grey=greyLevel-dif;if(grey<0){grey=0}else if(grey>255){grey=255}data[offset]=data[offset+1]=data[offset+2]=grey}}while(--x)}while(--y)};Konva.Factory.addGetterSetter(Konva.Node,"embossStrength",.5,null,Konva.Factory.afterSetFilter);Konva.Factory.addGetterSetter(Konva.Node,"embossWhiteLevel",.5,null,Konva.Factory.afterSetFilter);Konva.Factory.addGetterSetter(Konva.Node,"embossDirection","top-left",null,Konva.Factory.afterSetFilter);Konva.Factory.addGetterSetter(Konva.Node,"embossBlend",false,null,Konva.Factory.afterSetFilter)})();(function(){"use strict";function remap(fromValue,fromMin,fromMax,toMin,toMax){var fromRange=fromMax-fromMin,toRange=toMax-toMin,toValue;if(fromRange===0){return toMin+toRange/2}if(toRange===0){return toMin}toValue=(fromValue-fromMin)/fromRange;toValue=toRange*toValue+toMin;return toValue}Konva.Filters.Enhance=function(imageData){var data=imageData.data,nSubPixels=data.length,rMin=data[0],rMax=rMin,r,gMin=data[1],gMax=gMin,g,bMin=data[2],bMax=bMin,b,i;var enhanceAmount=this.enhance();if(enhanceAmount===0){return}for(i=0;irMax){rMax=r}g=data[i+1];if(ggMax){gMax=g}b=data[i+2];if(bbMax){bMax=b}}if(rMax===rMin){rMax=255;rMin=0}if(gMax===gMin){gMax=255;gMin=0}if(bMax===bMin){bMax=255;bMin=0}var rMid,rGoalMax,rGoalMin,gMid,gGoalMax,gGoalMin,bMid,bGoalMax,bGoalMin;if(enhanceAmount>0){rGoalMax=rMax+enhanceAmount*(255-rMax);rGoalMin=rMin-enhanceAmount*(rMin-0);gGoalMax=gMax+enhanceAmount*(255-gMax);gGoalMin=gMin-enhanceAmount*(gMin-0);bGoalMax=bMax+enhanceAmount*(255-bMax);bGoalMin=bMin-enhanceAmount*(bMin-0)}else{rMid=(rMax+rMin)*.5;rGoalMax=rMax+enhanceAmount*(rMax-rMid);rGoalMin=rMin+enhanceAmount*(rMin-rMid);gMid=(gMax+gMin)*.5;gGoalMax=gMax+enhanceAmount*(gMax-gMid);gGoalMin=gMin+enhanceAmount*(gMin-gMid);bMid=(bMax+bMin)*.5;bGoalMax=bMax+enhanceAmount*(bMax-bMid);bGoalMin=bMin+enhanceAmount*(bMin-bMid)}for(i=0;i=width){continue}for(y=yBinStart;y=height){continue}i=(width*y+x)*4;red+=imageData[i+0];green+=imageData[i+1];blue+=imageData[i+2];alpha+=imageData[i+3];pixelsInBin+=1}}red=red/pixelsInBin;green=green/pixelsInBin;blue=blue/pixelsInBin;for(x=xBinStart;x=width){continue}for(y=yBinStart;y=height){continue}i=(width*y+x)*4;imageData[i+0]=red;imageData[i+1]=green;imageData[i+2]=blue;imageData[i+3]=alpha}}}}};Konva.Factory.addGetterSetter(Konva.Node,"pixelSize",8,null,Konva.Factory.afterSetFilter)})();(function(){"use strict";Konva.Filters.Threshold=function(imageData){var level=this.threshold()*255,data=imageData.data,len=data.length,i;for(i=0;i255?255:r;data[offset+1]=g>255?255:g;data[offset+2]=b>255?255:b;data[offset+3]=data[offset+3]}while(--x)}while(--y)}})();(function(){"use strict";Konva.Filters.Solarize=function(imageData){var data=imageData.data,w=imageData.width,h=imageData.height,w4=w*4,y=h;do{var offsetY=(y-1)*w4;var x=w;do{var offset=offsetY+(x-1)*4;var r=data[offset];var g=data[offset+1];var b=data[offset+2];if(r>127){r=255-r}if(g>127){g=255-g}if(b>127){b=255-b}data[offset]=r;data[offset+1]=g;data[offset+2]=b}while(--x)}while(--y)}})();(function(){"use strict";var ToPolar=function(src,dst,opt){var srcPixels=src.data,dstPixels=dst.data,xSize=src.width,ySize=src.height,xMid=opt.polarCenterX||xSize/2,yMid=opt.polarCenterY||ySize/2,i,x,y,r=0,g=0,b=0,a=0;var rad,rMax=Math.sqrt(xMid*xMid+yMid*yMid);x=xSize-xMid;y=ySize-yMid;rad=Math.sqrt(x*x+y*y);rMax=rad>rMax?rad:rMax;var rSize=ySize,tSize=xSize,radius,theta;var conversion=360/tSize*Math.PI/180,sin,cos;for(theta=0;thetarMax?rad:rMax;var rSize=ySize,tSize=xSize,radius,theta,phaseShift=opt.polarRotation||0;var x1,y1;for(x=0;xxSize){xStart=sectionSize;xEnd=0;xDelta=-1}for(y=0;y0},removeChildren:function(){var children=Konva.Collection.toCollection(this.children);var child;for(var i=0;i1){for(var i=0;i0},destroy:function(){Konva.Node.prototype.destroy.call(this);delete Konva.shapes[this.colorKey];return this},_useBufferCanvas:function(caching){return!caching&&(this.perfectDrawEnabled()&&this.getAbsoluteOpacity()!==1&&this.hasFill()&&this.hasStroke()&&this.getStage())||this.perfectDrawEnabled()&&this.hasShadow()&&this.getAbsoluteOpacity()!==1&&this.hasFill()&&this.hasStroke()&&this.getStage()},getSelfRect:function(){var size=this.getSize();return{x:this._centroid?Math.round(-size.width/2):0,y:this._centroid?Math.round(-size.height/2):0,width:size.width,height:size.height}},getClientRect:function(skipTransform){var fillRect=this.getSelfRect();var strokeWidth=this.hasStroke()&&this.strokeWidth()||0;var fillAndStrokeWidth=fillRect.width+strokeWidth;var fillAndStrokeHeight=fillRect.height+strokeWidth;var shadowOffsetX=this.shadowOffsetX();var shadowOffsetY=this.shadowOffsetY();var preWidth=fillAndStrokeWidth+Math.abs(shadowOffsetX);var preHeight=fillAndStrokeHeight+Math.abs(shadowOffsetY);var blurRadius=this.hasShadow()&&this.shadowBlur()||0;var width=preWidth+blurRadius*2;var height=preHeight+blurRadius*2;var roundingOffset=0;if(Math.round(strokeWidth/2)!==strokeWidth/2){roundingOffset=1}var rect={width:width+roundingOffset,height:height+roundingOffset,x:-Math.round(strokeWidth/2+blurRadius)+Math.min(shadowOffsetX,0)+fillRect.x,y:-Math.round(strokeWidth/2+blurRadius)+Math.min(shadowOffsetY,0)+fillRect.y};if(!skipTransform){return this._transformedRect(rect)}return rect},drawScene:function(can,top,caching,skipBuffer){var layer=this.getLayer(),canvas=can||layer.getCanvas(),context=canvas.getContext(),cachedCanvas=this._cache.canvas,drawFunc=this.sceneFunc(),hasShadow=this.hasShadow(),hasStroke=this.hasStroke(),stage,bufferCanvas,bufferContext;if(!this.isVisible()){return this}if(cachedCanvas){context.save();layer._applyTransform(this,context,top);this._drawCachedSceneCanvas(context);context.restore();return this}if(!drawFunc){return this}context.save();if(this._useBufferCanvas(caching)&&!skipBuffer){stage=this.getStage();bufferCanvas=stage.bufferCanvas;bufferContext=bufferCanvas.getContext();bufferContext.clear();bufferContext.save();bufferContext._applyLineJoin(this);if(!caching){if(layer){layer._applyTransform(this,bufferContext,top)}else{var m=this.getAbsoluteTransform(top).getMatrix();context.transform(m[0],m[1],m[2],m[3],m[4],m[5])}}drawFunc.call(this,bufferContext);bufferContext.restore();var ratio=bufferCanvas.pixelRatio;if(hasShadow&&!canvas.hitCanvas){context.save();context._applyShadow(this);context._applyOpacity(this);context.drawImage(bufferCanvas._canvas,0,0,bufferCanvas.width/ratio,bufferCanvas.height/ratio);context.restore()}else{context._applyOpacity(this);context.drawImage(bufferCanvas._canvas,0,0,bufferCanvas.width/ratio,bufferCanvas.height/ratio)}}else{context._applyLineJoin(this);if(!caching){if(layer){layer._applyTransform(this,context,top)}else{var o=this.getAbsoluteTransform(top).getMatrix();context.transform(o[0],o[1],o[2],o[3],o[4],o[5])}}if(hasShadow&&hasStroke&&!canvas.hitCanvas){context.save();if(!caching){context._applyOpacity(this)}context._applyShadow(this);drawFunc.call(this,context);context.restore();if(this.hasFill()&&this.getShadowForStrokeEnabled()){drawFunc.call(this,context)}}else if(hasShadow&&!canvas.hitCanvas){context.save();if(!caching){context._applyOpacity(this)}context._applyShadow(this);drawFunc.call(this,context);context.restore()}else{if(!caching){context._applyOpacity(this)}drawFunc.call(this,context)}}context.restore();return this},drawHit:function(can,top,caching){var layer=this.getLayer(),canvas=can||layer.hitCanvas,context=canvas.getContext(),drawFunc=this.hitFunc()||this.sceneFunc(),cachedCanvas=this._cache.canvas,cachedHitCanvas=cachedCanvas&&cachedCanvas.hit;if(!this.shouldDrawHit(canvas)){return this}if(layer){layer.clearHitCache()}if(cachedHitCanvas){context.save();layer._applyTransform(this,context,top);this._drawCachedHitCanvas(context);context.restore();return this}if(!drawFunc){return this}context.save();context._applyLineJoin(this);if(!caching){if(layer){layer._applyTransform(this,context,top)}else{var o=this.getAbsoluteTransform(top).getMatrix();context.transform(o[0],o[1],o[2],o[3],o[4],o[5])}}drawFunc.call(this,context);context.restore();return this},drawHitFromCache:function(alphaThreshold){var threshold=alphaThreshold||0,cachedCanvas=this._cache.canvas,sceneCanvas=this._getCachedSceneCanvas(),hitCanvas=cachedCanvas.hit,hitContext=hitCanvas.getContext(),hitWidth=hitCanvas.getWidth(),hitHeight=hitCanvas.getHeight(),hitImageData,hitData,len,rgbColorKey,i,alpha;hitContext.clear();hitContext.drawImage(sceneCanvas._canvas,0,0,hitWidth,hitHeight);try{hitImageData=hitContext.getImageData(0,0,hitWidth,hitHeight);hitData=hitImageData.data;len=hitData.length;rgbColorKey=Konva.Util._hexToRgb(this.colorKey);for(i=0;ithreshold){hitData[i]=rgbColorKey.r;hitData[i+1]=rgbColorKey.g;hitData[i+2]=rgbColorKey.b;hitData[i+3]=255}else{hitData[i+3]=0}}hitContext.putImageData(hitImageData,0,0)}catch(e){Konva.Util.error("Unable to draw hit graph from cached scene canvas. "+e.message)}return this}});Konva.Util.extend(Konva.Shape,Konva.Node);Konva.Factory.addGetterSetter(Konva.Shape,"stroke");Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"strokeRed",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"strokeGreen",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"strokeBlue",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"strokeAlpha",1,Konva.Validators.alphaComponent);Konva.Factory.addGetterSetter(Konva.Shape,"strokeWidth",2);Konva.Factory.addGetterSetter(Konva.Shape,"strokeHitEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"perfectDrawEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"shadowForStrokeEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"lineJoin");Konva.Factory.addGetterSetter(Konva.Shape,"lineCap");Konva.Factory.addGetterSetter(Konva.Shape,"sceneFunc");Konva.Factory.addGetterSetter(Konva.Shape,"hitFunc");Konva.Factory.addGetterSetter(Konva.Shape,"dash");Konva.Factory.addGetterSetter(Konva.Shape,"shadowColor");Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"shadowRed",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"shadowGreen",0,Konva.Validators.RGBComponent); +Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"shadowBlue",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"shadowAlpha",1,Konva.Validators.alphaComponent);Konva.Factory.addGetterSetter(Konva.Shape,"shadowBlur");Konva.Factory.addGetterSetter(Konva.Shape,"shadowOpacity");Konva.Factory.addComponentsGetterSetter(Konva.Shape,"shadowOffset",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"shadowOffsetX",0);Konva.Factory.addGetterSetter(Konva.Shape,"shadowOffsetY",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternImage");Konva.Factory.addGetterSetter(Konva.Shape,"fill");Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"fillRed",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"fillGreen",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"fillBlue",0,Konva.Validators.RGBComponent);Konva.Factory.addDeprecatedGetterSetter(Konva.Shape,"fillAlpha",1,Konva.Validators.alphaComponent);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternY",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillLinearGradientColorStops");Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientStartRadius",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientEndRadius",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientColorStops");Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternRepeat","repeat");Konva.Factory.addGetterSetter(Konva.Shape,"fillEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"strokeEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"shadowEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"dashEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"strokeScaleEnabled",true);Konva.Factory.addGetterSetter(Konva.Shape,"fillPriority","color");Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillPatternOffset",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternOffsetX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternOffsetY",0);Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillPatternScale",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternScaleX",1);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternScaleY",1);Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillLinearGradientStartPoint",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillLinearGradientStartPointX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillLinearGradientStartPointY",0);Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillLinearGradientEndPoint",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillLinearGradientEndPointX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillLinearGradientEndPointY",0);Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillRadialGradientStartPoint",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientStartPointX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientStartPointY",0);Konva.Factory.addComponentsGetterSetter(Konva.Shape,"fillRadialGradientEndPoint",["x","y"]);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientEndPointX",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillRadialGradientEndPointY",0);Konva.Factory.addGetterSetter(Konva.Shape,"fillPatternRotation",0);Konva.Factory.backCompat(Konva.Shape,{dashArray:"dash",getDashArray:"getDash",setDashArray:"getDash",drawFunc:"sceneFunc",getDrawFunc:"getSceneFunc",setDrawFunc:"setSceneFunc",drawHitFunc:"hitFunc",getDrawHitFunc:"getHitFunc",setDrawHitFunc:"setHitFunc"});Konva.Collection.mapMethods(Konva.Shape)})(Konva);(function(){"use strict";var STAGE="Stage",STRING="string",PX="px",MOUSEOUT="mouseout",MOUSELEAVE="mouseleave",MOUSEOVER="mouseover",MOUSEENTER="mouseenter",MOUSEMOVE="mousemove",MOUSEDOWN="mousedown",MOUSEUP="mouseup",CLICK="click",DBL_CLICK="dblclick",TOUCHSTART="touchstart",TOUCHEND="touchend",TAP="tap",DBL_TAP="dbltap",TOUCHMOVE="touchmove",DOMMOUSESCROLL="DOMMouseScroll",MOUSEWHEEL="mousewheel",WHEEL="wheel",CONTENT_MOUSEOUT="contentMouseout",CONTENT_MOUSEOVER="contentMouseover",CONTENT_MOUSEMOVE="contentMousemove",CONTENT_MOUSEDOWN="contentMousedown",CONTENT_MOUSEUP="contentMouseup",CONTENT_CLICK="contentClick",CONTENT_DBL_CLICK="contentDblclick",CONTENT_TOUCHSTART="contentTouchstart",CONTENT_TOUCHEND="contentTouchend",CONTENT_DBL_TAP="contentDbltap",CONTENT_TAP="contentTap",CONTENT_TOUCHMOVE="contentTouchmove",CONTENT_WHEEL="contentWheel",DIV="div",RELATIVE="relative",KONVA_CONTENT="konvajs-content",SPACE=" ",UNDERSCORE="_",CONTAINER="container",EMPTY_STRING="",EVENTS=[MOUSEDOWN,MOUSEMOVE,MOUSEUP,MOUSEOUT,TOUCHSTART,TOUCHMOVE,TOUCHEND,MOUSEOVER,DOMMOUSESCROLL,MOUSEWHEEL,WHEEL],eventsLength=EVENTS.length;function addEvent(ctx,eventName){ctx.content.addEventListener(eventName,function(evt){ctx[UNDERSCORE+eventName](evt)},false)}Konva.Stage=function(config){this.___init(config)};Konva.Util.addMethods(Konva.Stage,{___init:function(config){this.nodeType=STAGE;Konva.Container.call(this,config);this._id=Konva.idCounter++;this._buildDOM();this._bindContentEvents();this._enableNestedTransforms=false;Konva.stages.push(this)},_validateAdd:function(child){if(child.getType()!=="Layer"){Konva.Util.throw("You may only add layers to the stage.")}},setContainer:function(container){if(typeof container===STRING){if(container.charAt(0)==="."){var className=container.slice(1);container=Konva.document.getElementsByClassName(className)[0]}else{var id;if(container.charAt(0)!=="#"){id=container}else{id=container.slice(1)}container=Konva.document.getElementById(id)}if(!container){throw"Can not find container in document with id "+id}}this._setAttr(CONTAINER,container);return this},shouldDrawHit:function(){return true},draw:function(){Konva.Node.prototype.draw.call(this);return this},setHeight:function(height){Konva.Node.prototype.setHeight.call(this,height);this._resizeDOM();return this},setWidth:function(width){Konva.Node.prototype.setWidth.call(this,width);this._resizeDOM();return this},clear:function(){var layers=this.children,len=layers.length,n;for(n=0;n-1){Konva.stages.splice(index,1)}return this},getPointerPosition:function(){return this.pointerPos},getStage:function(){return this},getContent:function(){return this.content},toDataURL:function(config){config=config||{};var mimeType=config.mimeType||null,quality=config.quality||null,x=config.x||0,y=config.y||0,canvas=new Konva.SceneCanvas({width:config.width||this.getWidth(),height:config.height||this.getHeight(),pixelRatio:config.pixelRatio}),_context=canvas.getContext()._context,layers=this.children;if(x||y){_context.translate(-1*x,-1*y)}layers.each(function(layer){var width=layer.getCanvas().getWidth();var height=layer.getCanvas().getHeight();var ratio=layer.getCanvas().getPixelRatio();_context.drawImage(layer.getCanvas()._canvas,0,0,width/ratio,height/ratio)});var src=canvas.toDataURL(mimeType,quality);if(config.callback){config.callback(src)}return src},toImage:function(config){var cb=config.callback;config.callback=function(dataUrl){Konva.Util._getImage(dataUrl,function(img){cb(img)})};this.toDataURL(config)},getIntersection:function(pos,selector){var layers=this.getChildren(),len=layers.length,end=len-1,n,shape;for(n=end;n>=0;n--){shape=layers[n].getIntersection(pos,selector);if(shape){return shape}}return null},_resizeDOM:function(){if(this.content){var width=this.getWidth(),height=this.getHeight(),layers=this.getChildren(),len=layers.length,n,layer;this.content.style.width=width+PX;this.content.style.height=height+PX;this.bufferCanvas.setSize(width,height);this.bufferHitCanvas.setSize(width,height);for(n=0;n1){for(var i=0;i0){var touch=evt.touches[0];x=touch.clientX-contentPosition.left;y=touch.clientY-contentPosition.top}}else{x=evt.clientX-contentPosition.left;y=evt.clientY-contentPosition.top}if(x!==null&&y!==null){this.pointerPos={x:x,y:y}}},_getContentPosition:function(){var rect=this.content.getBoundingClientRect?this.content.getBoundingClientRect():{top:0,left:0};return{top:rect.top,left:rect.left}},_buildDOM:function(){var container=this.getContainer();if(!container){if(Konva.Util.isBrowser()){throw"Stage has no container. A container is required."}else{container=Konva.document.createElement(DIV)}}container.innerHTML=EMPTY_STRING;this.content=Konva.document.createElement(DIV);this.content.style.position=RELATIVE;this.content.className=KONVA_CONTENT;this.content.setAttribute("role","presentation");container.appendChild(this.content);this.bufferCanvas=new Konva.SceneCanvas;this.bufferHitCanvas=new Konva.HitCanvas({pixelRatio:1});this._resizeDOM()},_onContent:function(typesStr,handler){var types=typesStr.split(SPACE),len=types.length,n,baseEvent;for(n=0;n0){return{antialiased:true}}return{}},drawScene:function(can,top){var layer=this.getLayer(),canvas=can||layer&&layer.getCanvas();this._fire(BEFORE_DRAW,{node:this});if(this.getClearBeforeDraw()){canvas.getContext().clear()}Konva.Container.prototype.drawScene.call(this,canvas,top);this._fire(DRAW,{node:this});return this},drawHit:function(can,top){var layer=this.getLayer(),canvas=can||layer&&layer.hitCanvas;if(layer&&layer.getClearBeforeDraw()){layer.getHitCanvas().getContext().clear()}Konva.Container.prototype.drawHit.call(this,canvas,top);this.imageData=null;return this},clear:function(bounds){Konva.BaseLayer.prototype.clear.call(this,bounds);this.getHitCanvas().getContext().clear(bounds);this.imageData=null;return this},setVisible:function(visible){Konva.Node.prototype.setVisible.call(this,visible);if(visible){this.getCanvas()._canvas.style.display="block";this.hitCanvas._canvas.style.display="block"}else{this.getCanvas()._canvas.style.display="none";this.hitCanvas._canvas.style.display="none"}return this},enableHitGraph:function(){this.setHitGraphEnabled(true);return this},disableHitGraph:function(){this.setHitGraphEnabled(false);return this},setSize:function(width,height){Konva.BaseLayer.prototype.setSize.call(this,width,height);this.hitCanvas.setSize(width,height);return this}});Konva.Util.extend(Konva.Layer,Konva.BaseLayer);Konva.Factory.addGetterSetter(Konva.Layer,"hitGraphEnabled",true);Konva.Collection.mapMethods(Konva.Layer)})();(function(){"use strict";Konva.FastLayer=function(config){this.____init(config)};Konva.Util.addMethods(Konva.FastLayer,{____init:function(config){this.nodeType="Layer";this.canvas=new Konva.SceneCanvas;Konva.BaseLayer.call(this,config)},_validateAdd:function(child){var type=child.getType();if(type!=="Shape"){Konva.Util.throw("You may only add shapes to a fast layer.")}},_setCanvasSize:function(width,height){this.canvas.setSize(width,height)},hitGraphEnabled:function(){return false},getIntersection:function(){return null},drawScene:function(can){var layer=this.getLayer(),canvas=can||layer&&layer.getCanvas();if(this.getClearBeforeDraw()){canvas.getContext().clear()}Konva.Container.prototype.drawScene.call(this,canvas);return this},draw:function(){this.drawScene();return this},setVisible:function(visible){Konva.Node.prototype.setVisible.call(this,visible);if(visible){this.getCanvas()._canvas.style.display="block"}else{this.getCanvas()._canvas.style.display="none"}return this}});Konva.Util.extend(Konva.FastLayer,Konva.BaseLayer);Konva.Collection.mapMethods(Konva.FastLayer)})();(function(){"use strict";Konva.Group=function(config){this.___init(config)};Konva.Util.addMethods(Konva.Group,{___init:function(config){this.nodeType="Group";Konva.Container.call(this,config)},_validateAdd:function(child){var type=child.getType();if(type!=="Group"&&type!=="Shape"){Konva.Util.throw("You may only add groups and shapes to groups.")}}});Konva.Util.extend(Konva.Group,Konva.Container);Konva.Collection.mapMethods(Konva.Group)})();(function(Konva){"use strict";var now=function(){if(Konva.global.performance&&Konva.global.performance.now){return function(){return Konva.global.performance.now()}}return function(){return(new Date).getTime()}}();function FRAF(callback){setTimeout(callback,1e3/60)}var RAF=function(){return Konva.global.requestAnimationFrame||Konva.global.webkitRequestAnimationFrame||Konva.global.mozRequestAnimationFrame||Konva.global.oRequestAnimationFrame||Konva.global.msRequestAnimationFrame||FRAF}();function requestAnimFrame(){return RAF.apply(Konva.global,arguments)}Konva.Animation=function(func,layers){var Anim=Konva.Animation;this.func=func;this.setLayers(layers);this.id=Anim.animIdCounter++;this.frame={time:0,timeDiff:0,lastTime:now()}};Konva.Animation.prototype={setLayers:function(layers){var lays=[];if(!layers){lays=[]}else if(layers.length>0){lays=layers}else{lays=[layers]}this.layers=lays;return this},getLayers:function(){return this.layers},addLayer:function(layer){var layers=this.layers,len=layers.length,n;for(n=0;nthis.duration){if(this.yoyo){this._time=this.duration;this.reverse()}else{this.finish()}}else if(t<0){if(this.yoyo){this._time=0;this.play()}else{this.reset()}}else{this._time=t;this.update()}},getTime:function(){return this._time},setPosition:function(p){this.prevPos=this._pos;this.propFunc(p);this._pos=p},getPosition:function(t){if(t===undefined){t=this._time}return this.func(t,this.begin,this._change,this.duration)},play:function(){this.state=PLAYING;this._startTime=this.getTimer()-this._time;this.onEnterFrame();this.fire("onPlay")},reverse:function(){this.state=REVERSING;this._time=this.duration-this._time;this._startTime=this.getTimer()-this._time;this.onEnterFrame();this.fire("onReverse")},seek:function(t){this.pause();this._time=t;this.update();this.fire("onSeek")},reset:function(){this.pause();this._time=0;this.update();this.fire("onReset")},finish:function(){this.pause();this._time=this.duration;this.update();this.fire("onFinish")},update:function(){this.setPosition(this.getPosition(this._time))},onEnterFrame:function(){var t=this.getTimer()-this._startTime;if(this.state===PLAYING){this.setTime(t)}else if(this.state===REVERSING){this.setTime(this.duration-t)}},pause:function(){this.state=PAUSED;this.fire("onPause")},getTimer:function(){return(new Date).getTime()}};Konva.Tween=function(config){var that=this,node=config.node,nodeId=node._id,duration,easing=config.easing||Konva.Easings.Linear,yoyo=!!config.yoyo,key;if(typeof config.duration==="undefined"){duration=1}else if(config.duration===0){duration=.001}else{duration=config.duration}this.node=node;this._id=idCounter++;var layers=node.getLayer()||(node instanceof Konva.Stage?node.getLayers():null);if(!layers){Konva.Util.error("Tween constructor have `node` that is not in a layer. Please add node into layer first.")}this.anim=new Konva.Animation(function(){that.tween.onEnterFrame()},layers);this.tween=new Tween(key,function(i){that._tweenFunc(i)},easing,0,1,duration*1e3,yoyo);this._addListeners();if(!Konva.Tween.attrs[nodeId]){Konva.Tween.attrs[nodeId]={}}if(!Konva.Tween.attrs[nodeId][this._id]){Konva.Tween.attrs[nodeId][this._id]={}}if(!Konva.Tween.tweens[nodeId]){Konva.Tween.tweens[nodeId]={}}for(key in config){if(blacklist[key]===undefined){this._addAttr(key,config[key])}}this.reset();this.onFinish=config.onFinish;this.onReset=config.onReset};Konva.Tween.attrs={};Konva.Tween.tweens={};Konva.Tween.prototype={_addAttr:function(key,end){var node=this.node,nodeId=node._id,start,diff,tweenId,n,len,trueEnd,trueStart;tweenId=Konva.Tween.tweens[nodeId][key];if(tweenId){delete Konva.Tween.attrs[nodeId][tweenId][key]}start=node.getAttr(key);if(Konva.Util._isArray(end)){diff=[];len=Math.max(end.length,start.length);if(key==="points"&&end.length!==start.length){if(end.length>start.length){trueStart=start;start=Konva.Util._prepareArrayForTween(start,end,node.closed())}else{trueEnd=end;end=Konva.Util._prepareArrayForTween(end,start,node.closed())}}for(n=0;nmaxWidth){while(line.length>0){var low=0,high=line.length,match="",matchWidth=0;while(low>>1,substr=line.slice(0,mid+1),substrWidth=this._getTextWidth(substr);if(substrWidth<=maxWidth){low=mid+1;match=substr;matchWidth=substrWidth}else{high=mid}}if(match){if(wrapAtWord){var wrapIndex=Math.max(match.lastIndexOf(SPACE),match.lastIndexOf(DASH))+1;if(wrapIndex>0){low=wrapIndex;match=match.slice(0,low);matchWidth=this._getTextWidth(match)}}this._addTextLine(match,matchWidth);textWidth=Math.max(textWidth,matchWidth);currentHeightPx+=lineHeightPx;if(!shouldWrap||fixedHeight&¤tHeightPx+lineHeightPx>maxHeightPx){break}line=line.slice(low);if(line.length>0){lineWidth=this._getTextWidth(line);if(lineWidth<=maxWidth){this._addTextLine(line,lineWidth);currentHeightPx+=lineHeightPx;textWidth=Math.max(textWidth,lineWidth);break}}}else{break}}}else{this._addTextLine(line,lineWidth);currentHeightPx+=lineHeightPx;textWidth=Math.max(textWidth,lineWidth)}if(fixedHeight&¤tHeightPx+lineHeightPx>maxHeightPx){break}}dummyContext.restore();this.textHeight=fontSize;this.textWidth=textWidth}};Konva.Util.extend(Konva.Text,Konva.Shape);Konva.Factory.addGetterSetter(Konva.Text,"fontFamily","Arial");Konva.Factory.addGetterSetter(Konva.Text,"fontSize",12);Konva.Factory.addGetterSetter(Konva.Text,"fontStyle",NORMAL);Konva.Factory.addGetterSetter(Konva.Text,"fontVariant",NORMAL);Konva.Factory.addGetterSetter(Konva.Text,"padding",0);Konva.Factory.addGetterSetter(Konva.Text,"align",LEFT);Konva.Factory.addGetterSetter(Konva.Text,"lineHeight",1);Konva.Factory.addGetterSetter(Konva.Text,"wrap",WORD);Konva.Factory.addGetter(Konva.Text,"text",EMPTY_STRING);Konva.Factory.addOverloadedGetterSetter(Konva.Text,"text");Konva.Collection.mapMethods(Konva.Text)})();(function(){"use strict";Konva.Line=function(config){this.___init(config)};Konva.Line.prototype={___init:function(config){Konva.Shape.call(this,config);this.className="Line";this.on("pointsChange.konva tensionChange.konva closedChange.konva",function(){this._clearCache("tensionPoints")});this.sceneFunc(this._sceneFunc)},_sceneFunc:function(context){var points=this.getPoints(),length=points.length,tension=this.getTension(),closed=this.getClosed(),tp,len,n;if(!length){return}context.beginPath();context.moveTo(points[0],points[1]);if(tension!==0&&length>4){tp=this.getTensionPoints();len=tp.length;n=closed?0:4;if(!closed){context.quadraticCurveTo(tp[0],tp[1],tp[2],tp[3])}while(nry?rx:ry;var scaleX=rx>ry?1:rx/ry;var scaleY=rx>ry?ry/rx:1;context.translate(cx,cy);context.rotate(psi);context.scale(scaleX,scaleY);context.arc(0,0,r,theta,theta+dTheta,1-fs);context.scale(1/scaleX,1/scaleY);context.rotate(-psi);context.translate(-cx,-cy);break;case"z":context.closePath();break}}context.fillStrokeShape(this)},getSelfRect:function(){var points=[];this.dataArray.forEach(function(data){points=points.concat(data.points)});var minX=points[0];var maxX=points[0];var minY=points[1];var maxY=points[1];var x,y;for(var i=0;i0&&p[0]===""){p.shift()}for(var i=0;i0){if(isNaN(p[0])){break}var cmd=null;var points=[];var startX=cpx,startY=cpy;var prevCmd,ctlPtx,ctlPty;var rx,ry,psi,fa,fs,x1,y1;switch(c){case"l":cpx+=p.shift();cpy+=p.shift();cmd="L";points.push(cpx,cpy);break;case"L":cpx=p.shift();cpy=p.shift();points.push(cpx,cpy);break;case"m":var dx=p.shift();var dy=p.shift();cpx+=dx;cpy+=dy;cmd="M";if(ca.length>2&&ca[ca.length-1].command==="z"){for(var idx=ca.length-2;idx>=0;idx--){if(ca[idx].command==="M"){cpx=ca[idx].points[0]+dx;cpy=ca[idx].points[1]+dy;break}}}points.push(cpx,cpy);c="l";break;case"M":cpx=p.shift();cpy=p.shift();cmd="M";points.push(cpx,cpy);c="L";break;case"h":cpx+=p.shift();cmd="L";points.push(cpx,cpy);break;case"H":cpx=p.shift();cmd="L";points.push(cpx,cpy);break;case"v":cpy+=p.shift();cmd="L";points.push(cpx,cpy);break;case"V":cpy=p.shift();cmd="L";points.push(cpx,cpy);break;case"C":points.push(p.shift(),p.shift(),p.shift(),p.shift());cpx=p.shift();cpy=p.shift();points.push(cpx,cpy);break;case"c":points.push(cpx+p.shift(),cpy+p.shift(),cpx+p.shift(),cpy+p.shift());cpx+=p.shift();cpy+=p.shift();cmd="C";points.push(cpx,cpy);break;case"S":ctlPtx=cpx;ctlPty=cpy;prevCmd=ca[ca.length-1];if(prevCmd.command==="C"){ctlPtx=cpx+(cpx-prevCmd.points[2]);ctlPty=cpy+(cpy-prevCmd.points[3])}points.push(ctlPtx,ctlPty,p.shift(),p.shift());cpx=p.shift();cpy=p.shift();cmd="C";points.push(cpx,cpy);break;case"s":ctlPtx=cpx;ctlPty=cpy;prevCmd=ca[ca.length-1];if(prevCmd.command==="C"){ctlPtx=cpx+(cpx-prevCmd.points[2]);ctlPty=cpy+(cpy-prevCmd.points[3])}points.push(ctlPtx,ctlPty,cpx+p.shift(),cpy+p.shift());cpx+=p.shift();cpy+=p.shift();cmd="C";points.push(cpx,cpy); +break;case"Q":points.push(p.shift(),p.shift());cpx=p.shift();cpy=p.shift();points.push(cpx,cpy);break;case"q":points.push(cpx+p.shift(),cpy+p.shift());cpx+=p.shift();cpy+=p.shift();cmd="Q";points.push(cpx,cpy);break;case"T":ctlPtx=cpx;ctlPty=cpy;prevCmd=ca[ca.length-1];if(prevCmd.command==="Q"){ctlPtx=cpx+(cpx-prevCmd.points[0]);ctlPty=cpy+(cpy-prevCmd.points[1])}cpx=p.shift();cpy=p.shift();cmd="Q";points.push(ctlPtx,ctlPty,cpx,cpy);break;case"t":ctlPtx=cpx;ctlPty=cpy;prevCmd=ca[ca.length-1];if(prevCmd.command==="Q"){ctlPtx=cpx+(cpx-prevCmd.points[0]);ctlPty=cpy+(cpy-prevCmd.points[1])}cpx+=p.shift();cpy+=p.shift();cmd="Q";points.push(ctlPtx,ctlPty,cpx,cpy);break;case"A":rx=p.shift();ry=p.shift();psi=p.shift();fa=p.shift();fs=p.shift();x1=cpx;y1=cpy;cpx=p.shift();cpy=p.shift();cmd="A";points=this.convertEndpointToCenterParameterization(x1,y1,cpx,cpy,fa,fs,rx,ry,psi);break;case"a":rx=p.shift();ry=p.shift();psi=p.shift();fa=p.shift();fs=p.shift();x1=cpx;y1=cpy;cpx+=p.shift();cpy+=p.shift();cmd="A";points=this.convertEndpointToCenterParameterization(x1,y1,cpx,cpy,fa,fs,rx,ry,psi);break}ca.push({command:cmd||c,points:points,start:{x:startX,y:startY},pathLength:this.calcLength(startX,startY,cmd||c,points)})}if(c==="z"||c==="Z"){ca.push({command:"z",points:[],start:undefined,pathLength:0})}}return ca};Konva.Path.calcLength=function(x,y,cmd,points){var len,p1,p2,t;var path=Konva.Path;switch(cmd){case"L":return path.getLineLength(x,y,points[0],points[1]);case"C":len=0;p1=path.getPointOnCubicBezier(0,x,y,points[0],points[1],points[2],points[3],points[4],points[5]);for(t=.01;t<=1;t+=.01){p2=path.getPointOnCubicBezier(t,x,y,points[0],points[1],points[2],points[3],points[4],points[5]);len+=path.getLineLength(p1.x,p1.y,p2.x,p2.y);p1=p2}return len;case"Q":len=0;p1=path.getPointOnQuadraticBezier(0,x,y,points[0],points[1],points[2],points[3]);for(t=.01;t<=1;t+=.01){p2=path.getPointOnQuadraticBezier(t,x,y,points[0],points[1],points[2],points[3]);len+=path.getLineLength(p1.x,p1.y,p2.x,p2.y);p1=p2}return len;case"A":len=0;var start=points[4];var dTheta=points[5];var end=points[4]+dTheta;var inc=Math.PI/180;if(Math.abs(start-end)end;t-=inc){p2=path.getPointOnEllipticalArc(points[0],points[1],points[2],points[3],t,0);len+=path.getLineLength(p1.x,p1.y,p2.x,p2.y);p1=p2}}else{for(t=start+inc;t1){rx*=Math.sqrt(lambda);ry*=Math.sqrt(lambda)}var f=Math.sqrt((rx*rx*(ry*ry)-rx*rx*(yp*yp)-ry*ry*(xp*xp))/(rx*rx*(yp*yp)+ry*ry*(xp*xp)));if(fa===fs){f*=-1}if(isNaN(f)){f=0}var cxp=f*rx*yp/ry;var cyp=f*-ry*xp/rx;var cx=(x1+x2)/2+Math.cos(psi)*cxp-Math.sin(psi)*cyp;var cy=(y1+y2)/2+Math.sin(psi)*cxp+Math.cos(psi)*cyp;var vMag=function(v){return Math.sqrt(v[0]*v[0]+v[1]*v[1])};var vRatio=function(u,v){return(u[0]*v[0]+u[1]*v[1])/(vMag(u)*vMag(v))};var vAngle=function(u,v){return(u[0]*v[1]=1){dTheta=0}if(fs===0&&dTheta>0){dTheta=dTheta-2*Math.PI}if(fs===1&&dTheta<0){dTheta=dTheta+2*Math.PI}return[cx,cy,rx,ry,theta,dTheta,psi,fs]};Konva.Factory.addGetterSetter(Konva.Path,"data");Konva.Collection.mapMethods(Konva.Path)})();(function(){"use strict";var EMPTY_STRING="",NORMAL="normal";Konva.TextPath=function(config){this.___init(config)};function _fillFunc(context){context.fillText(this.partialText,0,0)}function _strokeFunc(context){context.strokeText(this.partialText,0,0)}Konva.TextPath.prototype={___init:function(config){var that=this;this.dummyCanvas=Konva.Util.createCanvasElement();this.dataArray=[];Konva.Shape.call(this,config);this._fillFunc=_fillFunc;this._strokeFunc=_strokeFunc;this._fillFuncHit=_fillFunc;this._strokeFuncHit=_strokeFunc;this.className="TextPath";this.dataArray=Konva.Path.parsePathData(this.attrs.data);this.on("dataChange.konva",function(){that.dataArray=Konva.Path.parsePathData(this.attrs.data)});this.on("textChange.konva textStroke.konva textStrokeWidth.konva",that._setTextData);that._setTextData();this.sceneFunc(this._sceneFunc)},_sceneFunc:function(context){context.setAttr("font",this._getContextFont());context.setAttr("textBaseline","middle");context.setAttr("textAlign","left");context.save();var glyphInfo=this.glyphInfo;for(var i=0;i0){pIndex=j;return pathData[j]}else if(pathData[j].command==="M"){p0={x:pathData[j].points[0],y:pathData[j].points[1]}}}return{}};var findSegmentToFitCharacter=function(c){var glyphWidth=that._getTextSize(c).width;var currLen=0;var attempts=0;p1=undefined;while(Math.abs(glyphWidth-currLen)/glyphWidth>.01&&attempts<25){attempts++;var cumulativePathLength=currLen;while(pathCmd===undefined){pathCmd=getNextPathSegment();if(pathCmd&&cumulativePathLength+pathCmd.pathLengthglyphWidth){p1=Konva.Path.getPointOnLine(glyphWidth,p0.x,p0.y,pathCmd.points[0],pathCmd.points[1],p0.x,p0.y)}else{pathCmd=undefined}break;case"A":var start=pathCmd.points[4];var dTheta=pathCmd.points[5];var end=pathCmd.points[4]+dTheta;if(currentT===0){currentT=start+1e-8}else if(glyphWidth>currLen){currentT+=Math.PI/180*dTheta/Math.abs(dTheta)}else{currentT-=Math.PI/360*dTheta/Math.abs(dTheta)}if(dTheta<0&¤tT=0&¤tT>end){currentT=end;needNewSegment=true}p1=Konva.Path.getPointOnEllipticalArc(pathCmd.points[0],pathCmd.points[1],pathCmd.points[2],pathCmd.points[3],currentT,pathCmd.points[6]);break;case"C":if(currentT===0){if(glyphWidth>pathCmd.pathLength){currentT=1e-8}else{currentT=glyphWidth/pathCmd.pathLength}}else if(glyphWidth>currLen){currentT+=(glyphWidth-currLen)/pathCmd.pathLength}else{currentT-=(currLen-glyphWidth)/pathCmd.pathLength}if(currentT>1){currentT=1;needNewSegment=true}p1=Konva.Path.getPointOnCubicBezier(currentT,pathCmd.start.x,pathCmd.start.y,pathCmd.points[0],pathCmd.points[1],pathCmd.points[2],pathCmd.points[3],pathCmd.points[4],pathCmd.points[5]);break;case"Q":if(currentT===0){currentT=glyphWidth/pathCmd.pathLength}else if(glyphWidth>currLen){currentT+=(glyphWidth-currLen)/pathCmd.pathLength}else{currentT-=(currLen-glyphWidth)/pathCmd.pathLength}if(currentT>1){currentT=1;needNewSegment=true}p1=Konva.Path.getPointOnQuadraticBezier(currentT,pathCmd.start.x,pathCmd.start.y,pathCmd.points[0],pathCmd.points[1],pathCmd.points[2],pathCmd.points[3]);break}if(p1!==undefined){currLen=Konva.Path.getLineLength(p0.x,p0.y,p1.x,p1.y)}if(needNewSegment){needNewSegment=false;pathCmd=undefined}}};for(var i=0;i kineticObj.getAttrs().minCachePixelSizeThreshold ) && + ( kineticObj.height() > kineticObj.getAttrs().minCachePixelSizeThreshold ) ) { + kineticObj.cache(); + kineticObj.drawHitFromCache(); + } + return true; + } + return false; } + }; + // turns on logger debugger console messages + this.debug = { + "creation": false, + "native": false, + "initializing": false, + "parenting": false, + "deleting": false, + "properties": false, + "setting": false, + "getting": false, + "methods": false, + "events": false, + "prototypes": false + }; + + }, - if ( value === undefined && kineticObj instanceof Kinetic.Ellipse ) { - - switch ( propertyName ) { - case "radius": - value = kineticObj.radius(); - break; - } - } + // == Model API ============================================================================ - if ( value === undefined && kineticObj instanceof Kinetic.Image ) { - - switch ( propertyName ) { + // -- creatingNode ------------------------------------------------------------------------ + + creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ) { - case "image": - var imageObj = kineticObj.image(); - if ( imageObj !== undefined ) { - value = imageObj.src; - } - break; + var appID = this.kernel.application(); - case "crop": - value = kineticObj.crop(); - break; + if ( this.debug.creation ) { + this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); + } - case "scaleOnLoad": - value = node.scaleOnLoad; - break; - - } + // If the node being created is a prototype, construct it and add it to the array of prototypes, + // and then return + var prototypeID = utility.ifPrototypeGetId( appID, this.state.prototypes, nodeID, childID ); + if ( prototypeID !== undefined ) { + + if ( this.debug.prototypes ) { + this.logger.infox( "prototype: ", prototypeID ); } - if ( value === undefined && kineticObj instanceof Kinetic.Line ) { - - switch ( propertyName ) { - - case "points": - value = kineticObj.points(); - break; + this.state.prototypes[ prototypeID ] = { + parentID: nodeID, + ID: childID, + extendsID: childExtendsID, + implementsID: childImplementsIDs, + source: childSource, + type: childType, + name: childName + }; + return; + } - case "tension": - value = kineticObj.tension(); - break; + var protos = getPrototypes( this.kernel, childExtendsID ); - case "closed": - value = kineticObj.closed(); - break; - } - } + var node; - if ( value === undefined && kineticObj instanceof Kinetic.Path ) { - - switch ( propertyName ) { - - case "data": - value = kineticObj.data(); - break; + if ( this.state.isKineticComponent( protos ) ) { - } + if ( this.debug.native ) { + this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); } - - if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { - - switch ( propertyName ) { - - case "cornerRadius": - value = kineticObj.cornerRadius(); - break; - } + + // Create the local copy of the node properties + if ( this.state.nodes[ childID ] === undefined ){ + this.state.nodes[ childID ] = this.state.createLocalNode( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ); } - if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { - - switch ( propertyName ) { - - case "sides": - value = kineticObj.sides(); - break; + node = this.state.nodes[ childID ]; + + node.prototypes = protos; - case "radius": - value = kineticObj.radius(); - break; - } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { - - switch ( propertyName ) { - - case "innerRadius": - value = kineticObj.innerRadius(); - break; + if ( !isNodeInHierarchy( node ) ) { + node.kineticObj = createKineticObject( node ); - case "outerRadius": - value = kineticObj.outerRadius(); - break; - } + // If the kineticObj was created, attach it to the parent kineticObj + // (if the parent is a kinetic container) + // (if a kineticObj is created asynchronously ... like an Image, it will be + // undefined here, but will be added to its parent in the appropriate callback) + this.state.addNodeToHierarchy( node ); } - - if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { - - switch ( propertyName ) { - - case "animation": - value = kineticObj.animation(); - break; - case "animations": - value = JSON.stringify( kineticObj.animations() ); - break; + } + + }, - case "frameIndex": - value = kineticObj.frameIndex(); - break; + // initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + // childSource, childType, childIndex, childName ) { - case "image": - var imageObj = kineticObj.image(); - if ( imageObj !== undefined ) { - value = imageObj.src; - } - break; + // if ( this.debug.initializing ) { + // this.logger.infox( "initializingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName ); + // } - case "scaleOnLoad": - value = node.scaleOnLoad; - break; - } - } - if ( value === undefined && kineticObj instanceof Kinetic.Star ) { - - switch ( propertyName ) { - - case "numPoints": - value = kineticObj.animation(); - break; - - case "innerRadius": - value = kineticObj.innerRadius(); - break; + // }, + + // -- deletingNode ------------------------------------------------------------------------- - case "outerRadius": - value = kineticObj.outerRadius(); - break; - } - } + deletingNode: function( nodeID ) { + if ( this.debug.deleting ) { + this.logger.infox( "deletingNode", nodeID ); + } - if ( value === undefined && kineticObj instanceof Kinetic.Text ) { - - switch ( propertyName ) { - - case "fontFamily": - value = kineticObj.fontFamily(); - break; + if ( this.state.nodes[ nodeID ] !== undefined ) { + + var node = this.state.nodes[ nodeID ]; + if ( node.kineticObj !== undefined ) { + // Uncache object + if ( node.kineticObj.attrs.hitGraphFromCache ) { + node.kineticObj.clearCache(); + } + // removes and destroys object + node.kineticObj.remove(); + node.kineticObj.destroy(); + node.kineticObj = undefined; + } - case "fontSize": - value = kineticObj.fontSize(); - break; + delete this.state.nodes[ nodeID ]; + } + + }, - case "fontStyle": - value = kineticObj.fontStyle(); - break; + // -- addingChild ------------------------------------------------------------------------ + + // addingChild: function( nodeID, childID, childName ) { + // if ( this.debug.parenting ) { + // this.logger.infox( "addingChild", nodeID, childID, childName ); + // } + // }, - case "fontVariant": - value = kineticObj.fontVariant(); - break; - case "text": - value = kineticObj.text(); - break; + // -- movingChild ------------------------------------------------------------------------ + + movingChild: function( nodeID, childID, childName ) { + + if ( this.debug.parenting ) { + this.logger.infox( "movingChild", nodeID, childID, childName ); + } - case "align": - value = kineticObj.align(); - break; + if ( this.state.nodes[ childID ] !== undefined ) { + + if ( this.state.nodes[ nodeID ] !== undefined ) { + var parentNode = this.state.nodes[ nodeID ]; + + if ( isContainerDefinition( parentNode.prototypes ) && parentNode.kineticObj ) { + + var node = this.state.nodes[ childID ]; + if ( node.kineticObj !== undefined ) { + // removes object only + node.kineticObj.remove(); + parentNode.kineticObj.add( node.kineticObj ); + } + } + } + } - case "padding": - value = kineticObj.padding(); - break; + }, - case "width": - value = kineticObj.width(); - break; - case "height": - value = kineticObj.height(); - break; + // -- removingChild ------------------------------------------------------------------------ + + // removingChild: function( nodeID, childID, childName ) { + // if ( this.debug.parenting ) { + // this.logger.infox( "removingChild", nodeID, childID, childName ); + // } + // }, - case "lineHeight": - value = kineticObj.lineHeight(); - break; + // -- creatingProperty --------------------------------------------------------------------- - case "wrap": - value = kineticObj.wrap(); - break; - } - } + creatingProperty: function( nodeID, propertyName, propertyValue ) { - if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { - - switch ( propertyName ) { - - case "fontFamily": - value = kineticObj.fontFamily(); - break; + if ( this.debug.properties ) { + this.logger.infox( "C === creatingProperty ", nodeID, propertyName, propertyValue ); + } + return this.settingProperty( nodeID, propertyName, propertyValue );; + }, - case "fontSize": - value = kineticObj.fontSize(); - break; + // -- initializingProperty ----------------------------------------------------------------- - case "fontStyle": - value = kineticObj.fontStyle(); - break; + initializingProperty: function( nodeID, propertyName, propertyValue ) { - case "fontVariant": - value = kineticObj.fontVariant(); - break; + if ( this.debug.properties ) { + this.logger.infox( " I === initializingProperty ", nodeID, propertyName, propertyValue ); + } + return this.settingProperty( nodeID, propertyName, propertyValue );; + + }, + // -- settingProperty ---------------------------------------------------------------------- - case "text": - value = kineticObj.text(); - break; + settingProperty: function( nodeID, propertyName, propertyValue ) { + + if ( this.debug.properties || this.debug.setting ) { + this.logger.infox( " S === settingProperty ", nodeID, propertyName, propertyValue ); + } + var node = this.state.nodes[ nodeID ]; + var value = undefined; + if ( node && utility.validObject( propertyValue ) ) { + if ( node.kineticObj ) { + + // If we don't have a specially stored model value for this property, + // then the model and view are in sync, + // and we can update the konva object directly (seen by the view) + // Else, the view has diverged from the model, and we handle that specially + if ( node.model[ propertyName ] === undefined ) { + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + + // We automatically create a "model" copy of the position property + // because it is used with ignoreNextPositionUpdate + // to remove latency from the view + switch ( propertyName ) { + case "position": + if ( node.kineticObj.nodeType !== "Stage" ) { + node.model[ propertyName ] = { + "value": propertyValue, + "modelChangeShouldUpdateView": true + }; + } + break; - case "data": - value = kineticObj.data(); - break; + default: + break; + } + } else { + var property = node.model[ propertyName ]; + property.value = propertyValue; + if ( property.ignoreNextPositionUpdate ) { + property.ignoreNextPositionUpdate = false; + } else if ( property.modelChangeShouldUpdateView ) { + value = this.state.setProperty( + node.kineticObj, + propertyName, + property.value ); + } } + } else { + node.model[ propertyName ] = propertyValue; } + + } + return value; + }, - if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { - - switch ( propertyName ) { - - case "angle": - value = kineticObj.angle(); - break; + // -- gettingProperty ---------------------------------------------------------------------- - case "radius": - value = kineticObj.radius(); - break; + gettingProperty: function( nodeID, propertyName, propertyValue ) { - case "clockwise": - kineticObj.clockwise(); - break; - } - } + if ( this.debug.properties || this.debug.getting ) { + this.logger.infox( " G === gettingProperty ", nodeID, propertyName ); + } + + var node = this.state.nodes[nodeID]; + var value = undefined; + if ( node && node.kineticObj ) { + var kineticObj = node.kineticObj; + if ( node.model[ propertyName ] ) { + value = node.model[ propertyName ].value; + } else { + value = this.state.getProperty( kineticObj, propertyName ); + } } if ( value !== undefined ) { propertyValue = value; @@ -2073,6 +1954,36 @@ define( [ "module", if ( this.debug.methods ) { this.logger.infox( " M === callingMethod ", nodeID, methodName ); } + + switch( methodName ) { + case "moveToTop": + case "moveToBottom": + var node = this.state.nodes[ nodeID ]; + var toTop = ( methodName === "moveToTop" ); + var params = null; + if ( methodParameters.length > 0 ) { + params = methodParameters[0]; + } + if ( node && ( this.kernel.client() === this.kernel.moniker() ) ) { + if ( node.kineticObj ) { + if ( params && params[ "includeParent" ] && node.kineticObj.parent ) { + ( toTop ? node.kineticObj.parent.moveToTop() : node.kineticObj.parent.moveToBottom() ); + } + ( toTop ? node.kineticObj.moveToTop() : node.kineticObj.moveToBottom() ); + if ( params && ( params[ "orderChildren" ].length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { + // Search for children with these names and elevate them to top + for ( var i = 0; i < params.orderChildren.length; i++ ) { + for ( var j = 0; j < node.kineticObj.children.length; j++ ) { + if ( node.kineticObj.children[ j ] && ( node.kineticObj.children[ j ].name() === params.orderChildren[ i ] ) ) { + ( toTop ? node.kineticObj.children[ j ].moveToTop() : node.kineticObj.children[ j ].moveToBottom() ); + } + } + } + } + } + } + break; + } }, // -- executing ------------------------------------------------------------------------------ @@ -2103,51 +2014,51 @@ define( [ "module", var protos = node.prototypes; var kineticObj = undefined; - if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { - kineticObj = new Kinetic.Arc( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { - kineticObj = new Kinetic.BaseLayer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { - kineticObj = new Kinetic.Canvas( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { - kineticObj = new Kinetic.Circle( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { - kineticObj = new Kinetic.Ellipse( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { - kineticObj = new Kinetic.FastLayer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { - kineticObj = new Kinetic.Group( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { + if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { + kineticObj = new Konva.Arc( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { + kineticObj = new Konva.BaseLayer( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { + kineticObj = new Konva.Canvas( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { + kineticObj = new Konva.Circle( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { + kineticObj = new Konva.Ellipse( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { + kineticObj = new Konva.FastLayer( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { + kineticObj = new Konva.Group( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { var imageObj = new Image(); - node.scaleOnLoad = false; - kineticObj = new Kinetic.Image( { + //node.scaleOnLoad = true; + kineticObj = new Konva.Image( { image: imageObj } ); if ( node.source !== undefined ) { imageObj.src = node.source; } - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { - kineticObj = new Kinetic.Layer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { - kineticObj = new Kinetic.Line( config || { "points": [] } ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { - kineticObj = new Kinetic.Path( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { - kineticObj = new Kinetic.Rect( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { - kineticObj = new Kinetic.RegularPolygon( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { - kineticObj = new Kinetic.Ring( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { + kineticObj = new Konva.Layer( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { + kineticObj = new Konva.Line( config || { "points": [] } ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { + kineticObj = new Konva.Path( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { + kineticObj = new Konva.Rect( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { + kineticObj = new Konva.RegularPolygon( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { + kineticObj = new Konva.Ring( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { var imageObj = new Image(); - node.scaleOnLoad = false; - kineticObj = new Kinetic.Sprite( { + //node.scaleOnLoad = false; + kineticObj = new Konva.Sprite( { image: imageObj } ); if ( node.source !== undefined ) { imageObj.src = node.source; } - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; var stageContainer = ( config && config.container ) || 'vwf-root'; @@ -2158,22 +2069,22 @@ define( [ "module", "width": stageWidth, "height": stageHeight }; - kineticObj = new Kinetic.Stage( stageDef ); - self.state.stages[ node.ID ] = kineticObj; - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { - kineticObj = new Kinetic.Star( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { - kineticObj = new Kinetic.Text( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { - kineticObj = new Kinetic.TextPath( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { - kineticObj = new Kinetic.Wedge( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { - kineticObj = new Kinetic.Shape( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { - kineticObj = new Kinetic.Container( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { - kineticObj = new Kinetic.Node( config || {} ); + kineticObj = new Konva.Stage( stageDef ); + modelDriver.state.stages[ node.ID ] = kineticObj; + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { + kineticObj = new Konva.Star( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { + kineticObj = new Konva.Text( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { + kineticObj = new Konva.TextPath( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { + kineticObj = new Konva.Wedge( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { + kineticObj = new Konva.Shape( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { + kineticObj = new Konva.Container( config || {} ); + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { + kineticObj = new Konva.Node( config || {} ); } return kineticObj; @@ -2191,30 +2102,22 @@ define( [ "module", } return stage; - } + } - function addNodeToHierarchy( node ) { - - if ( node.kineticObj ) { - if ( self.state.nodes[ node.parentID ] !== undefined ) { - var parent = self.state.nodes[ node.parentID ]; - if ( parent.kineticObj && isContainerDefinition( parent.prototypes ) ) { - - if ( parent.children === undefined ) { - parent.children = []; - } - parent.children.push( node.ID ); - //console.info( "Adding child: " + childID + " to " + nodeID ); - parent.kineticObj.add( node.kineticObj ); + function isNodeInHierarchy( node ) { + var foundNode = false; + + if ( modelDriver.state.nodes[ node.parentID ] ) { + var parent = modelDriver.state.nodes[ node.parentID ]; + if ( parent.children ) { + for ( var i = 0; i < parent.children.length && !foundNode; i++ ) { + foundNode = ( parent.children[ i ] === node.ID ); } } - node.kineticObj.setId( node.ID ); - node.kineticObj.name( node.name ); - - node.stage = findStage( node.kineticObj ); } - } + return foundNode; + } function isStageDefinition( prototypes ) { var found = false; @@ -2271,40 +2174,82 @@ define( [ "module", return found; } - function loadImage( node, url ) { - if ( node && node.kineticObj ) { - var kineticObj = node.kineticObj; - var imageObj = kineticObj.image(); - var validImage = ( imageObj !== undefined ); - var width = kineticObj.width(); - var height = kineticObj.height(); - + function isSymbolDefinition( prototypes ) { + var found = false; + if ( prototypes ) { + for ( var i = 0; i < prototypes.length && !found; i++ ) { + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/unitIcon.vwf" ); + } + } + return found; + } + + function loadImage( kineticObj, url ) { + + // Ensure that the url is valid + var onePixelTransparentImage = + "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; + var url = url || onePixelTransparentImage; + + var imageObj = kineticObj.image(); + var validImage = ( imageObj && ( imageObj !== undefined ) && ( imageObj instanceof Image ) ); + var width = kineticObj.width(); + var height = kineticObj.height(); + var nodeID = kineticObj.id(); + var node = modelDriver.state.nodes[ nodeID ]; + + if ( isSymbolDefinition( node.prototypes ) ) { + kineticObj.setZIndex( 100 ); + } + + if ( !validImage ) { + imageObj = new Image(); + } + + imageObj.onload = function() { + + // If the image was set to the one pixel transparent image, + // then the intent was to null it out - + // Do not do the rest of the work + if ( url === onePixelTransparentImage ) { + return; + } + if ( !validImage ) { - imageObj = new Image(); + kineticObj.image( imageObj ); } + if ( node.scaleOnLoad ) { - imageObj.onload = function() { - if ( !validImage ) { - kineticObj.image( imageObj ); + if ( width > height ) { + kineticObj.scale( { "x": width / imageObj.width ,"y": width / imageObj.width } ); + } else { + kineticObj.scale( { "x": height / imageObj.height ,"y": height / imageObj.height } ); } - if ( node.scaleOnLoad ) { - - if ( width > height ) { - kineticObj.scale( { "x": width / imageObj.width ,"y": width / imageObj.width } ); - } else { - kineticObj.scale( { "x": height / imageObj.height ,"y": height / imageObj.height } ); - } + } else { + var kImg = kineticObj.image(); + if ( kImg.width !== imageObj.width ) { + kineticObj.width( imageObj.width ); + } + if ( kImg.height !== imageObj.height ) { + kineticObj.height( imageObj.height ); } - self.kernel.fireEvent( node.ID, "imageLoaded", [ url ] ); - } - imageObj.onerror = function() { - self.logger.errorx( "loadImage", "Invalid image url:", url ); - imageObj.src = oldSrc; - self.kernel.fireEvent( node.ID, "imageLoadError", [ url ] ); } - var oldSrc = imageObj.src; + + modelDriver.state.refreshHitGraphFromCache( kineticObj ); + kineticObj.draw(); + + modelDriver.kernel.fireEvent( nodeID, "imageLoaded", [ url ] ); + } + imageObj.onerror = function() { + modelDriver.logger.errorx( "loadImage", "Invalid image url:", url ); + imageObj.src = oldSrc; + modelDriver.kernel.fireEvent( nodeID, "imageLoadError", [ url ] ); + } + + var oldSrc = imageObj.src; + if ( url !== oldSrc ) { imageObj.src = url; - - } + } } + }); diff --git a/support/client/lib/vwf/model/mil-sym.js b/support/client/lib/vwf/model/mil-sym.js index f30941d0e..2d7a6cf03 100644 --- a/support/client/lib/vwf/model/mil-sym.js +++ b/support/client/lib/vwf/model/mil-sym.js @@ -24,7 +24,8 @@ define( [ "module", "jquery" ], function( module, model, utility, Color, cws, $ ) { - var self; + var modelDriver; + var _pausedRenderNodes = []; return model.load( module, { @@ -34,7 +35,7 @@ define( [ "module", initialize: function( options ) { - self = this; + modelDriver = this; this.arguments = Array.prototype.slice.call( arguments ); @@ -55,9 +56,12 @@ define( [ "module", "type": childType, "name": childName }; - } - }; + }, + // Public functions + "getModifierActualName": getModifierActualName, + "convertModifierValue": convertModifierValue + }; // turns on logger debugger console messages this.debug = { @@ -70,7 +74,6 @@ define( [ "module", "getting": false, "prototypes": false }; - }, creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, @@ -102,15 +105,18 @@ define( [ "module", source: childSource, type: childType, uri: childURI, - name: childName, + name: childName }; return; } var protos = getPrototypes( childExtendsID ); var node = this.state.nodes[ childID ]; + if ( node === undefined ) { + _pausedRenderNodes.push( childID ); + if ( isUnitNode( protos ) ) { this.state.nodes[ childID ] = node = this.state.createNode( "unit", nodeID, childID, childExtendsID, childImplementsIDs, @@ -125,6 +131,29 @@ define( [ "module", node.fullName = undefined; node.echelon = undefined; node.affiliation = undefined; + node.unitStatus = undefined; + node.mobility = undefined; + node.taskForce = undefined; + node.installation = undefined; + + } else if ( isMissionGfxNode( protos ) ) { + + this.state.nodes[ childID ] = node = this.state.createNode( "missionGfx", nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ); + + // additional members for the missionGfx components + node.symbolID = undefined; + node.symbolType = undefined; + node.modifiers = {}; + node.description = undefined; + node.tagName = undefined; + node.fullName = undefined; + node.affiliation = undefined; + node.controlPts = []; + node.x = undefined; + node.y = undefined; + node.width = undefined; + node.height = undefined; } else if ( isModifierNode( protos ) ) { @@ -139,10 +168,9 @@ define( [ "module", initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ) { - if ( this.debug.initializing ) { - this.logger.infox( "initializingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName ); + if ( _pausedRenderNodes.includes( childID ) ) { + _pausedRenderNodes.splice( _pausedRenderNodes.indexOf( childID ), 1 ); } - }, deletingNode: function( nodeID ) { @@ -207,7 +235,7 @@ define( [ "module", var renderImage = false; if ( node !== undefined && ( utility.validObject( propertyValue ) ) ) { - if ( node.nodeType === "unit" ) { + if ( ( node.nodeType === "unit" ) || ( node.nodeType === "missionGfx" ) ) { switch ( propertyName ) { @@ -219,11 +247,25 @@ define( [ "module", if ( node.affiliation !== undefined ) { node.symbolID = cws.addAffiliationToSymbolId( node.symbolID, node.affiliation ); } + if ( node.unitStatus !== undefined ) { + node.symbolID = cws.addUnitStatusToSymbolId( node.symbolID, node.unitStatus ); + } + if ( node.mobility !== undefined ) { + node.symbolID = cws.addMobilityToSymbolId( node.symbolID, node.mobility ); + } + if ( node.taskForce !== undefined ) { + node.symbolID = cws.addTaskForceToSymbolId( node.symbolID, node.taskForce ); + } + if ( node.installation !== undefined ) { + node.symbolID = cws.addInstallationToSymbolId( node.symbolID, node.installation ); + } renderImage = true; break; case "image": - value = node.image = propertyValue; + if ( node.nodeType === "unit" ) { + value = node.image = propertyValue; + } break; case "description": @@ -269,6 +311,9 @@ define( [ "module", node.symbolID = cws.addEchelonToSymbolId( node.symbolID, propertyValue ); } node.echelon = propertyValue; + if ( !!node.installation ) { + node.installation = "none"; + } renderImage = true; break; @@ -300,13 +345,139 @@ define( [ "module", } break; + case "unitStatus": + if ( node.unitStatus !== propertyValue ) { + switch( propertyValue ) { + case "anticipated": + case "present": + case "capable": + case "damaged": + case "destroyed": + case "full": + if ( node.symbolID !== undefined ) { + node.symbolID = cws.addUnitStatusToSymbolId( node.symbolID, propertyValue ); + } + node.unitStatus = propertyValue; + renderImage = true; + break; + + default: + this.logger.warnx( "incorrect unitStatus property value: " + propertyValue ); + break; + } + } + break; + + case "mobility": + if ( node.mobility !== propertyValue ) { + switch( propertyValue ) { + case "none": + case "wheeled limited cross-country": + case "cross-country": + case "tracked": + case "wheeled and tracked": + case "towed": + case "rail": + case "over snow": + case "sled": + case "pack animals": + case "barge": + case "amphibious": + if ( node.symbolID !== undefined ) { + node.symbolID = cws.addMobilityToSymbolId( node.symbolID, propertyValue ); + } + node.mobility = propertyValue; + node.installation = "none"; + renderImage = true; + break; + + default: + this.logger.warnx( "incorrect mobility property value: " + propertyValue ); + break; + } + } + break; + + case "taskForce": + if ( node.taskForce !== propertyValue ) { + switch( propertyValue ) { + case "none": + case "HQ": + case "TF HQ": + case "FD HQ": + case "FD-TF HQ": + case "TF": + case "FD": + case "FD-TF": + if ( node.symbolID !== undefined ) { + node.symbolID = cws.addTaskForceToSymbolId( node.symbolID, propertyValue ); + } + node.taskForce = propertyValue; + node.installation = "none"; + + renderImage = true; + break; + + default: + this.logger.warnx( "incorrect taskForce property value: " + propertyValue ); + break; + } + } + break; + + case "installation": + if ( node.installation !== propertyValue ) { + switch( propertyValue ) { + case "none": + case "installation": + case "feint-dummy": + if ( node.symbolID !== undefined ) { + node.symbolID = cws.addInstallationToSymbolId( node.symbolID, propertyValue ); + } + node.installation = propertyValue; + node.taskForce = "none"; + node.echelon = "none"; + node.mobility = "none"; + renderImage = true; + break; + + default: + this.logger.warnx( "incorrect installation property value: " + propertyValue ); + break; + } + } + break; + + case "x": + case "y": + case "width": + case "height": + case "rotation": + case "controlPts": + case "symbolType": + case "bounds": + if ( node.nodeType === "missionGfx" && propertyValue !== undefined && propertyValue !== null ) { + node[ propertyName ] = propertyValue; + renderImage = basicPropertiesMet( node ); + } + break; + + case "attributes": + if ( node.nodeType === "missionGfx" && !!propertyValue ) { + var attrs = propertyValue; + var image = renderMsnGfx( node ); + renderImage = basicPropertiesMet( node ); + if ( !!image ) { + attrs.image = image; + modelDriver.kernel.setProperty( node.ID, propertyName, attrs ); + } + } + break; } } else if ( node.nodeType === "modifier" ) { var unit = this.state.nodes[ node.parentID ]; - var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes; - var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits; if ( unit === undefined ) { return undefined; @@ -314,7 +485,16 @@ define( [ "module", // Render image if modifier is valid renderImage = setModifier( unit, propertyName, propertyValue ); - + + // Because rendering the image will set other properties + // (image, height, width, symbolCenter, etc), + // the kernel will interpret modifiers that were set as having been delegated, + // and no satProperty will be issued. + // We force an actual delegation here, + // so the object driver will issue the satProperty. + if ( renderImage ) { + modelDriver.kernel.setProperty( node.ID, propertyName, propertyValue ); + } } } @@ -344,37 +524,39 @@ define( [ "module", //this driver has no representation of this node, so there is nothing to do. if( node === undefined ) return value; - if ( node.nodeType === "unit" ) { + if ( ( node.nodeType === "unit" ) || ( node.nodeType === "missionGfx" ) ) { switch ( propertyName ) { - case "symbolID": - value = node.symbolID; - break; - case "image": - value = node.image; + if ( node.nodeType === "unit" ) { + value = node[ propertyName ]; + } break; + case "symbolID": case "description": - value = node.description; - break; - case "fullName": - value = node.fullName; - break; - case "tagName": - value = node.tagName; + case "echelon": + case "affiliation": + case "unitStatus": + case "mobility": + case "taskForce": + case "installation": + case "x": + case "y": + case "width": + case "height": + case "controlPts": + case "symbolType": + value = node[ propertyName ]; break; - } } else if ( node.nodeType === "modifier" ) { var unit = this.state.nodes[ node.parentID ]; - var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes; - var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits; if ( unit === undefined ) { return undefined; @@ -388,24 +570,15 @@ define( [ "module", return value; }, - // -- callingMethod -------------------------------------------------------------------------- - callingMethod: function( nodeID, methodName /* [, parameter1, parameter2, ... ] */ ) { // TODO: parameters - - var node = this.state.nodes[ nodeID ]; - var value = undefined; - - switch( methodName ) { - case "render": - value = render( node ); - break; + callingMethod: function( nodeID, methodName /* [, parameter1, parameter2, ... ] */ ) { + if ( methodName === "render" ) { + return render( modelDriver.state.nodes[ nodeID ] ); } - - return value; + return; }, - // TODO: creatingEvent, deltetingEvent, firingEvent // -- executing ------------------------------------------------------------------------------ @@ -420,8 +593,6 @@ define( [ "module", // } - - } ); function getPrototypes( extendsID ) { @@ -430,7 +601,7 @@ define( [ "module", while ( id !== undefined ) { prototypes.push( id ); - id = self.kernel.prototype( id ); + id = modelDriver.kernel.prototype( id ); } return prototypes; @@ -440,7 +611,17 @@ define( [ "module", var found = false; if ( prototypes ) { for ( var i = 0; i < prototypes.length && !found; i++ ) { - found = ( prototypes[i] == "unit.vwf" ); + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/unit.vwf" ); + } + } + return found; + } + + function isMissionGfxNode( prototypes ) { + var found = false; + if ( prototypes ) { + for ( var i = 0; i < prototypes.length && !found; i++ ) { + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/missionGfx.vwf" ); } } return found; @@ -450,86 +631,152 @@ define( [ "module", var found = false; if ( prototypes ) { for ( var i = 0; i < prototypes.length && !found; i++ ) { - found = ( prototypes[i] == "modifier.vwf" ); + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/modifier.vwf" ); } } return found; } + function render( node ) { + + if ( !( node || {} ).symbolID ) { + return; + } + if ( _pausedRenderNodes.includes( node.ID ) ) { + return; + } - function render( node ) { var value = undefined; - if ( node !== undefined && node.nodeType === "unit" && node.symbolID !== undefined ) { - var iconRender = armyc2.c2sd.renderer.MilStdIconRenderer; - var img = iconRender.Render( node.symbolID, node.modifiers ); - - var centerPt = img.getCenterPoint(); - var imgSize = img.getImageBounds(); - var symbolBounds = img.getSymbolBounds(); + switch( node.nodeType ) { + case "unit": + var iconRender = armyc2.c2sd.renderer.MilStdIconRenderer; + var img = iconRender.Render( node.symbolID, node.modifiers ); + + var centerPt = img.getCenterPoint(); + var imgSize = img.getImageBounds(); + var symbolBounds = img.getSymbolBounds(); + + value = node.image = img.toDataUrl(); + + // we should really use the event, but we're having troubles + // getting the events to replicate, this should be switched + // back to the event when the replication is fixed. handleRender + // can then be completely removed + //modelDriver.kernel.fireEvent( node.ID, "imageRendered", [ node.image, imgSize, centerPt, symbolBounds ] ); + + modelDriver.kernel.callMethod( node.ID, "handleRender", + [ node.image, imgSize, centerPt, symbolBounds ] ); + break; + case "missionGfx": + value = renderMsnGfx( node ); + if ( value ) { + modelDriver.kernel.setProperty( node.ID, "image", value.toDataURL() ); + } + break; + default: + console.warn( "render: Cannot render node of type '", node.nodeType, "'" ); + break; + } + + return value; + } - value = node.image = img.toDataUrl(); + function renderMsnGfx( node ) { + var value = undefined; - // we should really use the event, but we're having troubles - // getting the events to replicate, this should be switched - // back to the event when the replication is fixed. handleRender - // can then be completely removed - //self.kernel.fireEvent( node.ID, "imageRendered", [ node.image, imgSize, centerPt, symbolBounds ] ); + if ( basicPropertiesMet( node ) ) { + // Convert control points from Konva style array to mil-sym string + var controlPts = getMilSymControlPts( node.controlPts ); + var rendererMP = sec.web.renderer.SECWebRenderer; + var scale = 100.0; + var renderer = armyc2.c2sd.renderer; + var rs = renderer.utilities.RendererSettings; + var symUtil = renderer.utilities.SymbolUtilities; + var symbolCode = node.symbolID; + var format = 3; // GeoCanvas - self.kernel.callMethod( node.ID, "handleRender", [ node.image, imgSize, centerPt, symbolBounds ] ); + // Set affiliation in symbol id + if ( !!node.affiliation ) { + symbolCode = cws.addAffiliationToSymbolId( node.symbolID, node.affiliation ); + } + + var img = rendererMP.RenderSymbol2D(node.ID,node.fullName,node.description, symbolCode, controlPts, node.bounds[0], node.bounds[1], null, node.modifiers, format); - } + //if ( !!img && !!img.image ) { + if ( ( img || {} ).image ) { + value = img.image; + } + } - return value; + return value; + } + + function getModifierActualName( modObj ) { + var modifierActualName; + var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes; + var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits; + var mtg = armyc2.c2sd.renderer.utilities.ModifiersTG; + + switch ( modObj.type ) { + case "ModifiersUnits": + modifierActualName = mu[ modObj.modifier ]; + break; + + case "MilStdAttributes": + modifierActualName = msa[ modObj.modifier ]; + break; + + case "ModifiersTG": + modifierActualName = mtg[ modObj.modifier ]; + break; + } + + return modifierActualName; + } + + function convertModifierValue( modObj, modifierValue ) { + var retValue; + switch ( modObj.valueType ) { + case "Boolean": + retValue = Boolean( modifierValue ); + break; + + case "Number": + retValue = Number( modifierValue ); + break; + + case "Array": + case "Text": + default: + retValue = modifierValue; + break; + } + + return retValue; } function setModifier( unit, modifierAlias, modifierValue ) { var modObj = cws.modifierByAlias( modifierAlias ); - var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes; - var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits; var modifierSet = false; if ( modObj !== undefined ) { - var modifierActualName; - - switch ( modObj.type ) { - case "ModifiersUnits": - modifierActualName = mu[ modObj.modifier ]; - break; - - case "MilStdAttributes": - modifierActualName = msa[ modObj.modifier ]; - break; - - default: - self.logger.errorx( "setModifier", "Unknown type (", modObj.type, ") specified." ); - return modifierSet; + var modifierActualName = getModifierActualName( modObj ); + if ( !modifierActualName ) { + modelDriver.logger.errorx( "setModifier", "Unknown type (", modObj.type, ") specified." ); + return modifierSet; } - + if ( modifierValue === "" ) { if ( unit.modifiers[ modifierActualName ] !== undefined ) { delete unit.modifiers[ modifierActualName ]; modifierSet = true; } } else { - switch ( modObj.valueType ) { - case "Boolean": - unit.modifiers[ modifierActualName ] = Boolean(modifierValue); - break; - - case "Number": - unit.modifiers[ modifierActualName ] = Number(modifierValue); - break; - - case "Array": - case "Text": - default: - unit.modifiers[ modifierActualName ] = modifierValue; - break; - } + unit.modifiers[ modifierActualName ] = convertModifierValue( modObj, modifierValue ); modifierSet = true; } } @@ -540,32 +787,76 @@ define( [ "module", function getModifier( unit, modifierAlias ) { var modObj = cws.modifierByAlias( modifierAlias ); - var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes; - var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits; var value = undefined; if ( modObj !== undefined ) { - var modifierActualName; - - switch ( modObj.type ) { - case "ModifiersUnits": - modifierActualName = mu[ modObj.modifier ]; - break; - - case "MilStdAttributes": - modifierActualName = msa[ modObj.modifier ]; - break; - - default: - self.logger.errorx( "getModifier", "Unknown type (", modObj.type, ") specified." ); - return value; + var modifierActualName = getModifierActualName( modObj ); + if ( !modifierActualName ) { + modelDriver.logger.errorx( "getModifier", "Unknown type (", modObj.type, ") specified." ); + return value; } - + value = unit.modifiers[ modifierActualName ]; } return value; } + + function computeRelativeControlPts( controlPts, width, height ) { + var newControlPts = []; + + if ( ( !!width && !!height ) && ( width > 0 ) && ( height > 0 ) ) { + // Some control points are computed relative to the width and height of the containing object + // Compute and return the adjusted control points in this instance + for ( var i = 0; i < controlPts.length; i+2 ) { + var x = konvaControlPts[i] * width; + var y = konvaControlPts[i+1] * height; + newControlPts.push( x ); + newControlPts.push( y ); + } + } + + return newControlPts; + } + + function getMilSymControlPts( konvaControlPts ) { + var milSymControlPts = ""; + // konva-style is composed of an array where even numbered elements are x and odd are y + // mil-sym style is a string where pairs of x and y are separated by spaces + for ( var i = 0; i < konvaControlPts.length; i=i+2 ) { + milSymControlPts = milSymControlPts + konvaControlPts[i] + "," + konvaControlPts[i+1]; + if ( i < konvaControlPts.length-2 ) { + milSymControlPts = milSymControlPts + " "; + } + } + + return milSymControlPts; + } + + function basicPropertiesMet( node ) { + var basicsMet = false; + + if ( node !== undefined ) { + switch (node.nodeType) { + case "unit": + break; + case "missionGfx": + basicsMet = ( + ( node.symbolID !== undefined ) && + ( node.x !== undefined ) && + ( node.y !== undefined ) && + ( node.bounds !== undefined ) && + ( node.bounds.length === 2 ) && + ( node.bounds[0] > 0 ) && + ( node.bounds[1] > 0 ) && + (!!node.controlPts && ( node.controlPts.length > 0 ) ) + ); + break; + } + } + + return basicsMet; + } } ); diff --git a/support/client/lib/vwf/model/mil-sym/sm-bc.min.js b/support/client/lib/vwf/model/mil-sym/sm-bc.min.js deleted file mode 100644 index ab1c04096..000000000 --- a/support/client/lib/vwf/model/mil-sym/sm-bc.min.js +++ /dev/null @@ -1,7451 +0,0 @@ - -var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SinglePointMappingsB={"SINGLEPOINTMAPPINGS":{"SYMBOL":[{"SYMBOLID":"NBCNUCFILL****X","MAPPINGP":"1900","MAPPINGA":"1900","DESCRIPTION":"Nuclear Symbol Fill","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"NBCBIOFILL****X","MAPPINGP":"1901","MAPPINGA":"1901","DESCRIPTION":"Bio Symbol Fill","WIDTH":"28","HEIGHT":"39"},{"SYMBOLID":"NBCCMLFILL****X","MAPPINGP":"1902","MAPPINGA":"1902","DESCRIPTION":"Chem Symbol Fill","WIDTH":"22","HEIGHT":"39"},{"SYMBOLID":"SONOBYFILL****X","MAPPINGP":"1904","MAPPINGA":"1904","DESCRIPTION":"Sonobuoy Fill","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"CPOINTFILL****X","MAPPINGP":"1903","MAPPINGA":"1903","DESCRIPTION":"Small circle point fill","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"CHKPNTFILL****X","MAPPINGP":"1905","MAPPINGA":"1905","DESCRIPTION":"Action Points Fill","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"REFPNTFILL****X","MAPPINGP":"1908","MAPPINGA":"1908","DESCRIPTION":"Reference Points Fill","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"DECPNTFILL****X","MAPPINGP":"1909","MAPPINGA":"1909","DESCRIPTION":"Decision Point Fill","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*F*PTS---****X","MAPPINGP":"2162","MAPPINGA":"3162","DESCRIPTION":"Point Single Target","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*T*G-----****X","MAPPINGP":"1999","MAPPINGA":"1999","DESCRIPTION":"Suppress","WIDTH":"62","HEIGHT":"35"},{"SYMBOLID":"G*G*GPPN--****X","MAPPINGP":"2196","MAPPINGA":"3196","DESCRIPTION":"Entry Control Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PTN---****X","MAPPINGP":"2163","MAPPINGA":"3163","DESCRIPTION":"Nuclear Target","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*F*PTC---****X","MAPPINGP":"34","MAPPINGA":"34","DESCRIPTION":"Circular Target","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"G*F*PTR---****X","MAPPINGP":"35","MAPPINGA":"35","DESCRIPTION":"Rectangular Target","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"G*F*PCF---****X","MAPPINGP":"2164","MAPPINGA":"3164","DESCRIPTION":"Fire Support Station","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*F*PCS---****X","MAPPINGP":"2165","MAPPINGA":"3165","DESCRIPTION":"Survey Control Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCB---****X","MAPPINGP":"2166","MAPPINGA":"3166","DESCRIPTION":"Firing Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCR---****X","MAPPINGP":"2167","MAPPINGA":"3167","DESCRIPTION":"Reload Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCH---****X","MAPPINGP":"2168","MAPPINGA":"3168","DESCRIPTION":"Hide Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCL---****X","MAPPINGP":"2169","MAPPINGA":"3169","DESCRIPTION":"Launch Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PX----****X","MAPPINGP":"2170","MAPPINGA":"3170","DESCRIPTION":"Ambulance Exchange Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PC----****X","MAPPINGP":"2171","MAPPINGA":"3171","DESCRIPTION":"Cannibalization Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PY----****X","MAPPINGP":"2172","MAPPINGA":"3172","DESCRIPTION":"Casualty Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PT----****X","MAPPINGP":"2173","MAPPINGA":"3173","DESCRIPTION":"Civilian Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PD----****X","MAPPINGP":"2174","MAPPINGA":"3174","DESCRIPTION":"Detainee Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PE----****X","MAPPINGP":"2175","MAPPINGA":"3175","DESCRIPTION":"Enemy Prisoner of War (EPW) Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PL----****X","MAPPINGP":"2176","MAPPINGA":"3176","DESCRIPTION":"Logistics Release Point (LRP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PM----****X","MAPPINGP":"2177","MAPPINGA":"3177","DESCRIPTION":"Maintenance Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PR----****X","MAPPINGP":"2178","MAPPINGA":"3178","DESCRIPTION":"Refuel and Resupply Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PU----****X","MAPPINGP":"2179","MAPPINGA":"3179","DESCRIPTION":"Refuel on the Move (ROM) Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PO----****X","MAPPINGP":"2180","MAPPINGA":"3180","DESCRIPTION":"Traffic Control Post (TCP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PI----****X","MAPPINGP":"2181","MAPPINGA":"3181","DESCRIPTION":"Trailer Transfer Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PN----****X","MAPPINGP":"2182","MAPPINGA":"3182","DESCRIPTION":"Unit Maintenance Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSZ---****X","MAPPINGP":"2183","MAPPINGA":"3183","DESCRIPTION":"Supply Points_General","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSA---****X","MAPPINGP":"2184","MAPPINGA":"3184","DESCRIPTION":"Supply Points_Class I","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSB---****X","MAPPINGP":"2185","MAPPINGA":"3185","DESCRIPTION":"Supply Points_Class II","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSC---****X","MAPPINGP":"2186","MAPPINGA":"3186","DESCRIPTION":"Supply Points_Class III","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSD---****X","MAPPINGP":"2187","MAPPINGA":"3187","DESCRIPTION":"Supply Points_Class IV","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSE---****X","MAPPINGP":"2188","MAPPINGA":"3188","DESCRIPTION":"Supply Points_Class V","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSF---****X","MAPPINGP":"2189","MAPPINGA":"3189","DESCRIPTION":"Supply Points_Class VI","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSG---****X","MAPPINGP":"2190","MAPPINGA":"3190","DESCRIPTION":"Supply Points_Class VII","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSH---****X","MAPPINGP":"2191","MAPPINGA":"3191","DESCRIPTION":"Supply Points_Class VIII","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSI---****X","MAPPINGP":"2192","MAPPINGA":"3192","DESCRIPTION":"Supply Points_Class IX","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSJ---****X","MAPPINGP":"2193","MAPPINGA":"3191","DESCRIPTION":"Supply Points_Class X","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PAS---****X","MAPPINGP":"2194","MAPPINGA":"3194","DESCRIPTION":"Ammunition Supply Point (ASP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PAT---****X","MAPPINGP":"2195","MAPPINGA":"3195","DESCRIPTION":"Ammunition Transfer Point (ATP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PP----****X","MAPPINGP":"2214","MAPPINGA":"3214","DESCRIPTION":"Medevac Pick-Up Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*DPO---****X","MAPPINGP":"2122","MAPPINGA":"3122","DESCRIPTION":"Observation Post/Outpost","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*G*GPPK--****X","MAPPINGP":"2081","MAPPINGA":"3081","DESCRIPTION":"Checkpoint","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPC--****X","MAPPINGP":"2082","MAPPINGA":"3082","DESCRIPTION":"Contact Point","WIDTH":"22","HEIGHT":"31"},{"SYMBOLID":"G*G*GPPO--****X","MAPPINGP":"2083","MAPPINGA":"3083","DESCRIPTION":"Coordination Point","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPL--****X","MAPPINGP":"2085","MAPPINGA":"3085","DESCRIPTION":"Link-Up Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*OAOF--****X","MAPPINGP":"2129","MAPPINGA":"2129","DESCRIPTION":"Fixed and Prefabricated Obstacles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*OAOM--****X","MAPPINGP":"2130","MAPPINGA":"3130","DESCRIPTION":"Moveable Obstacles","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*M*OAOP--****X","MAPPINGP":"2131","MAPPINGA":"3131","DESCRIPTION":"Moveable and Prefabricated Obstacles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APP---****X","MAPPINGP":"2116","MAPPINGA":"3116","DESCRIPTION":"Air Control Point (ACP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APC---****X","MAPPINGP":"2117","MAPPINGA":"3117","DESCRIPTION":"Communications Checkpoint (CCP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPP--****X","MAPPINGP":"2086","MAPPINGA":"3086","DESCRIPTION":"Passage Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPE--****X","MAPPINGP":"2088","MAPPINGA":"3088","DESCRIPTION":"Release Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPS--****X","MAPPINGP":"2089","MAPPINGA":"3089","DESCRIPTION":"Start Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*OPP---****X","MAPPINGP":"2128","MAPPINGA":"3128","DESCRIPTION":"Point of Departure","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*APU---****X","MAPPINGP":"2118","MAPPINGA":"3118","DESCRIPTION":"Pull-Up Point (PUP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APD---****X","MAPPINGP":"2119","MAPPINGA":"3119","DESCRIPTION":"Downed Aircrew Pickup-Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPP---****X","MAPPINGP":"2080","MAPPINGA":"3080","DESCRIPTION":"Action Points (General)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPD--****X","MAPPINGP":"2084","MAPPINGA":"3084","DESCRIPTION":"Decision Point","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPR--****X","MAPPINGP":"2087","MAPPINGA":"3087","DESCRIPTION":"Rally Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPW--****X","MAPPINGP":"2090","MAPPINGA":"3090","DESCRIPTION":"Waypoint","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*NEB---****X","MAPPINGP":"2149","MAPPINGA":"3149","DESCRIPTION":"Biological","WIDTH":"28","HEIGHT":"39"},{"SYMBOLID":"G*M*NEC---****X","MAPPINGP":"2150","MAPPINGA":"3150","DESCRIPTION":"Chemical","WIDTH":"22","HEIGHT":"39"},{"SYMBOLID":"G*M*NDP---****X","MAPPINGP":"2151","MAPPINGA":"3151","DESCRIPTION":"DECON Site/Point (Unspecified)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDT---****X","MAPPINGP":"2153","MAPPINGA":"3153","DESCRIPTION":"DECON Site/Point (Troops)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDE---****X","MAPPINGP":"2154","MAPPINGA":"3154","DESCRIPTION":"DECON Site/Point (Equipment)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDB---****X","MAPPINGP":"2155","MAPPINGA":"3155","DESCRIPTION":"DECON Site/Point (Equipment and Troops)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDD---****X","MAPPINGP":"2157","MAPPINGA":"3157","DESCRIPTION":"DECON Site/Point (Thorough Decontamination)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDA---****X","MAPPINGP":"2152","MAPPINGA":"3152","DESCRIPTION":"Alternate DECON Site/Point (Unspecified)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDO---****X","MAPPINGP":"2156","MAPPINGA":"3156","DESCRIPTION":"DECON Site/Point (Operational Decontamination)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*T*D-----****X","MAPPINGP":"4000","MAPPINGA":"4000","DESCRIPTION":"Destroy","WIDTH":"62","HEIGHT":"35"},{"SYMBOLID":"G*T*I-----****X","MAPPINGP":"4001","MAPPINGA":"4501","DESCRIPTION":"Interdict","WIDTH":"60","HEIGHT":"38"},{"SYMBOLID":"G*T*N-----****X","MAPPINGP":"4002","MAPPINGA":"4502","DESCRIPTION":"Neutralize","WIDTH":"62","HEIGHT":"35"},{"SYMBOLID":"G*G*PN----****X","MAPPINGP":"2120","MAPPINGA":"3120","DESCRIPTION":"Dummy Minefield - Static","WIDTH":"48","HEIGHT":"41"},{"SYMBOLID":"G*G*DPT---****X","MAPPINGP":"2121","MAPPINGA":"3121","DESCRIPTION":"Target Reference","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*DPOC--****X","MAPPINGP":"2123","MAPPINGA":"3123","DESCRIPTION":"Combat Outpost","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"G*G*DPOR--****X","MAPPINGP":"2124","MAPPINGA":"3124","DESCRIPTION":"Observation Post Occupied by Dismounted Scouts or Reconnaissance","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPOF--****X","MAPPINGP":"2125","MAPPINGA":"3125","DESCRIPTION":"Forward Observation Position","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPOS--****X","MAPPINGP":"2126","MAPPINGA":"3126","DESCRIPTION":"Sensor Outpost/Listening Post (OP/LP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPON--****X","MAPPINGP":"2127","MAPPINGA":"3127","DESCRIPTION":"NBC Observation Post (Dismounted)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*OB----****X","MAPPINGP":"2132","MAPPINGA":"3132","DESCRIPTION":"Booby Trap","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"G*M*OMU---****X","MAPPINGP":"2133","MAPPINGA":"2133","DESCRIPTION":"Unspecified Mine","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*M*OMT---****X","MAPPINGP":"2134","MAPPINGA":"2134","DESCRIPTION":"Antitank Mine (AT)","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*M*OMD---****X","MAPPINGP":"2135","MAPPINGA":"2135","DESCRIPTION":"Antitank Mine with Antihandling Device","WIDTH":"24","HEIGHT":"44"},{"SYMBOLID":"G*M*OME---****X","MAPPINGP":"2136","MAPPINGA":"2136","DESCRIPTION":"Antitank Mine (Directional)","WIDTH":"24","HEIGHT":"53"},{"SYMBOLID":"G*M*OMP---****X","MAPPINGP":"2137","MAPPINGA":"2137","DESCRIPTION":"Antipersonnel (AP) Mines","WIDTH":"34","HEIGHT":"30"},{"SYMBOLID":"G*M*OMW---****X","MAPPINGP":"2138","MAPPINGA":"2138","DESCRIPTION":"Wide Area Mines","WIDTH":"40","HEIGHT":"33"},{"SYMBOLID":"G*M*OFS---****X","MAPPINGP":"2139","MAPPINGA":"3139","DESCRIPTION":"Static Depiction","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"G*M*BCP---****X","MAPPINGP":"2142","MAPPINGA":"3142","DESCRIPTION":"Engineer Regulating Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*SE----****X","MAPPINGP":"2143","MAPPINGA":"2143","DESCRIPTION":"Small Trench or Fortification","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*M*SF----****X","MAPPINGP":"2144","MAPPINGA":"3144","DESCRIPTION":"Fort","WIDTH":"44","HEIGHT":"48"},{"SYMBOLID":"G*M*SS----****X","MAPPINGP":"2145","MAPPINGA":"2145","DESCRIPTION":"Surface Shelter","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"G*M*SU----****X","MAPPINGP":"2146","MAPPINGA":"2146","DESCRIPTION":"Underground Shelter","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"G*M*NZ----****X","MAPPINGP":"2147","MAPPINGA":"3147","DESCRIPTION":"Nuclear Detonations Ground Zero","WIDTH":"31","HEIGHT":"39"},{"SYMBOLID":"G*M*NF----****X","MAPPINGP":"2148","MAPPINGA":"3148","DESCRIPTION":"Fallout Producing","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"G*G*GPWI--****X","MAPPINGP":"2038","MAPPINGA":"2038","DESCRIPTION":"Impact Point","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-PL----P----","MAPPINGP":"5000","DESCRIPTION":"Low Pressure Center","WIDTH":"24","HEIGHT":"33"},{"SYMBOLID":"WAS-PH----P----","MAPPINGP":"5003","DESCRIPTION":"High Pressure Center","WIDTH":"26","HEIGHT":"34"},{"SYMBOLID":"WAS-TL----P----","MAPPINGP":"5006","DESCRIPTION":"Light Turbulence","WIDTH":"38","HEIGHT":"22"},{"SYMBOLID":"WAS-TM----P----","MAPPINGP":"5007","DESCRIPTION":"Moderate Turbulence","WIDTH":"46","HEIGHT":"22"},{"SYMBOLID":"WAS-TS----P----","MAPPINGP":"5008","DESCRIPTION":"Severe Turbulence","WIDTH":"46","HEIGHT":"28"},{"SYMBOLID":"WAS-TE----P----","MAPPINGP":"5009","DESCRIPTION":"Extreme Turbulence","WIDTH":"46","HEIGHT":"34"},{"SYMBOLID":"WAS-ICL---P----","MAPPINGP":"5011","DESCRIPTION":"Light Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-ICM---P----","MAPPINGP":"5012","DESCRIPTION":"Moderate Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-ICS---P----","MAPPINGP":"5013","DESCRIPTION":"Severe Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRL---P----","MAPPINGP":"5014","DESCRIPTION":"Light Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRM---P----","MAPPINGP":"5015","DESCRIPTION":"Moderate Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRS---P----","MAPPINGP":"5016","DESCRIPTION":"Severe Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IML---P----","MAPPINGP":"5017","DESCRIPTION":"Light Mixed Icing","WIDTH":"48","HEIGHT":"54"},{"SYMBOLID":"WAS-IMM---P----","MAPPINGP":"5018","DESCRIPTION":"Moderate Mixed Icing","WIDTH":"60","HEIGHT":"35"},{"SYMBOLID":"WAS-IMS---P----","MAPPINGP":"5019","DESCRIPTION":"Severe Mixed Icing","WIDTH":"60","HEIGHT":"34"},{"SYMBOLID":"WA--W----------","MAPPINGP":"10136","MAPPINGA":"10136","DESCRIPTION":"Wind Barb","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WC----P----","MAPPINGP":"5020","DESCRIPTION":"Calm Winds","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WAS-CCCSCSP----","MAPPINGP":"5021","DESCRIPTION":"Clear Sky (SKC)","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSBCP----","MAPPINGP":"5024","DESCRIPTION":"Broken Coverage (BKN)","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WAS-WST-FCP----","MAPPINGP":"5072","DESCRIPTION":"Funnel Cloud (FC) Tornado / Waterspout","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-GSI---P----","MAPPINGP":"5107","DESCRIPTION":"Predominately Ice Covered","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"WAS-WSDD--P----","MAPPINGP":"5087","DESCRIPTION":"Dust Devil","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSFU--P----","MAPPINGP":"5083","DESCRIPTION":"Smoke","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSDB--P----","MAPPINGP":"5088","DESCRIPTION":"Blowing Dust or Sand","WIDTH":"28","HEIGHT":"48"},{"SYMBOLID":"G*O*SS----****X","MAPPINGP":"2210","MAPPINGA":"2210","DESCRIPTION":"Sea Anomaly [Wake, Current, Knuckle]","WIDTH":"39","HEIGHT":"31"},{"SYMBOLID":"G*O*SM----****X","MAPPINGP":"2209","MAPPINGA":"2209","DESCRIPTION":"Marine Life","WIDTH":"35","HEIGHT":"12"},{"SYMBOLID":"G*O*SBW---****X","MAPPINGP":"2207","MAPPINGA":"2207","DESCRIPTION":"Wreck, Non-Dangerous","WIDTH":"44","HEIGHT":"24"},{"SYMBOLID":"G*O*SBWD--****X","MAPPINGP":"2208","MAPPINGA":"2208","DESCRIPTION":"Wreck, Dangerous","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"G*O*SBN---****X","MAPPINGP":"2206","MAPPINGA":"2206","DESCRIPTION":"Seabed Rock/Stone, Obstacle, Other","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*SBM---****X","MAPPINGP":"2205","MAPPINGA":"2205","DESCRIPTION":"Installation/Manmade","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*SB----****X","MAPPINGP":"2204","MAPPINGA":"2204","DESCRIPTION":"Bottom Return/Nombo","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*HM----****X","MAPPINGP":"2201","MAPPINGA":"2201","DESCRIPTION":"Sea Mine-Like","WIDTH":"22","HEIGHT":"22"},{"SYMBOLID":"G*O*HO----****X","MAPPINGP":"2203","MAPPINGA":"2203","DESCRIPTION":"Oil Rig","WIDTH":"30","HEIGHT":"18"},{"SYMBOLID":"G*O*HI----****X","MAPPINGP":"2202","MAPPINGA":"2202","DESCRIPTION":"Iceberg","WIDTH":"36","HEIGHT":"27"},{"SYMBOLID":"G*O*FO----****X","MAPPINGP":"2213","MAPPINGA":"2213","DESCRIPTION":"Electro-Optical","WIDTH":"30","HEIGHT":"29"},{"SYMBOLID":"G*O*FE----****X","MAPPINGP":"2212","MAPPINGA":"2212","DESCRIPTION":"Electro-Magnetic","WIDTH":"31","HEIGHT":"29"},{"SYMBOLID":"G*O*FA----****X","MAPPINGP":"2211","MAPPINGA":"2211","DESCRIPTION":"Acoustic","WIDTH":"28","HEIGHT":"29"},{"SYMBOLID":"G*O*EP----****X","MAPPINGP":"2199","MAPPINGA":"2199","DESCRIPTION":"Person In Water","WIDTH":"32","HEIGHT":"20"},{"SYMBOLID":"G*O*ED----****X","MAPPINGP":"2198","MAPPINGA":"2198","DESCRIPTION":"Ditched Aircraft","WIDTH":"44","HEIGHT":"35"},{"SYMBOLID":"G*O*ES----****X","MAPPINGP":"2197","MAPPINGA":"3197","DESCRIPTION":"Emergency Distress Call","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*O*EV----****X","MAPPINGP":"2200","MAPPINGA":"2200","DESCRIPTION":"Distressed Vessel","WIDTH":"52","HEIGHT":"37"},{"SYMBOLID":"G*G*GPWP--****X","MAPPINGP":"2039","MAPPINGA":"2039","DESCRIPTION":"Predicted Impact Point","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"G*G*GPWM--****X","MAPPINGP":"2037","MAPPINGA":"3037","DESCRIPTION":"MSL Detect Point","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"G*G*GPWG--****X","MAPPINGP":"2036","MAPPINGA":"2036","DESCRIPTION":"Ground Zero","WIDTH":"34","HEIGHT":"43"},{"SYMBOLID":"G*G*GPWE--****X","MAPPINGP":"2035","MAPPINGA":"3035","DESCRIPTION":"Entry Point","WIDTH":"62","HEIGHT":"34"},{"SYMBOLID":"G*G*GPWD--****X","MAPPINGP":"2034","MAPPINGA":"3034","DESCRIPTION":"Drop Point","WIDTH":"44","HEIGHT":"38"},{"SYMBOLID":"G*G*GPWA--****X","MAPPINGP":"2033","MAPPINGA":"3033","DESCRIPTION":"Aim Point","WIDTH":"47","HEIGHT":"47"},{"SYMBOLID":"G*G*GPUUS-****X","MAPPINGP":"2006","MAPPINGA":"2006","DESCRIPTION":"Sinker","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*G*GPUUL-****X","MAPPINGP":"2005","MAPPINGA":"2005","DESCRIPTION":"Lost Contact","WIDTH":"24","HEIGHT":"30"},{"SYMBOLID":"G*G*GPUUD-****X","MAPPINGP":"2003","MAPPINGA":"2003","DESCRIPTION":"Datum","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"G*G*GPUUB-****X","MAPPINGP":"2004","MAPPINGA":"2004","DESCRIPTION":"Brief Contact","WIDTH":"24","HEIGHT":"30"},{"SYMBOLID":"G*G*GPUYV-****X","MAPPINGP":"2015","MAPPINGA":"3015","DESCRIPTION":"Vertical Line Array DIFAR (VLAD)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYR-****X","MAPPINGP":"2017","MAPPINGA":"3017","DESCRIPTION":"Range Only [RO]","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYP-****X","MAPPINGP":"2008","MAPPINGA":"3008","DESCRIPTION":"Pattern Center","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYL-****X","MAPPINGP":"2010","MAPPINGA":"3010","DESCRIPTION":"Low Frequency Analyzing and Recording (LOFAR)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYC-****X","MAPPINGP":"2011","MAPPINGA":"3011","DESCRIPTION":"Command Active Sonobouy System (CASS)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYK-****X","MAPPINGP":"2018","MAPPINGA":"3018","DESCRIPTION":"Kingpin","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYD-****X","MAPPINGP":"2009","MAPPINGA":"3009","DESCRIPTION":"Directional Frequency Analyzing and Recording (DIFAR)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYS-****X","MAPPINGP":"2012","MAPPINGA":"3012","DESCRIPTION":"Directional Command Active Sonobuoy System [DICASS]","WIDTH":"25","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYB-****X","MAPPINGP":"2013","MAPPINGA":"3013","DESCRIPTION":"Bathythermograph Transmitting [BT]","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYT-****X","MAPPINGP":"2016","MAPPINGA":"3016","DESCRIPTION":"ATAC","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYA-****X","MAPPINGP":"2014","MAPPINGA":"3014","DESCRIPTION":"ANM","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUSC-****X","MAPPINGP":"2023","MAPPINGA":"2023","DESCRIPTION":"Search Center","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*GPUSA-****X","MAPPINGP":"2021","MAPPINGA":"2021","DESCRIPTION":"Search Area","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPUSD-****X","MAPPINGP":"2022","MAPPINGA":"2022","DESCRIPTION":"Dip Position","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPOW--****X","MAPPINGP":"2049","MAPPINGA":"3049","DESCRIPTION":"Waypoint","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPOZ--****X","MAPPINGP":"2047","MAPPINGA":"3047","DESCRIPTION":"Rendezvous","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"G*G*GPOR--****X","MAPPINGP":"2051","MAPPINGA":"3051","DESCRIPTION":"Point R","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPOP--****X","MAPPINGP":"2050","MAPPINGA":"3050","DESCRIPTION":"PIM","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"G*G*GPOD--****X","MAPPINGP":"2048","MAPPINGA":"3048","DESCRIPTION":"Diversions","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPRS--****X","MAPPINGP":"4003","MAPPINGA":"4003","DESCRIPTION":"Special Point","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPRI--****X","MAPPINGP":"2032","MAPPINGA":"2032","DESCRIPTION":"Point of Interest","WIDTH":"24","HEIGHT":"43"},{"SYMBOLID":"G*G*GPRN--****X","MAPPINGP":"4004","MAPPINGA":"4004","DESCRIPTION":"Nav Reference","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPRD--****X","MAPPINGP":"4005","MAPPINGA":"4005","DESCRIPTION":"DLRP","WIDTH":"31","HEIGHT":"31"},{"SYMBOLID":"G*G*GPHY--****X","MAPPINGP":"2044","MAPPINGA":"3044","DESCRIPTION":"Point Y","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHX--****X","MAPPINGP":"2045","MAPPINGA":"3045","DESCRIPTION":"Point X","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHQ--****X","MAPPINGP":"2042","MAPPINGA":"3042","DESCRIPTION":"Point Q","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHA--****X","MAPPINGP":"2043","MAPPINGA":"3043","DESCRIPTION":"Point A","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPAO--****X","MAPPINGP":"4010","MAPPINGA":"4510","DESCRIPTION":"Tomcat","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAK--****X","MAPPINGP":"4007","MAPPINGA":"4507","DESCRIPTION":"Tanking","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAT--****X","MAPPINGP":"4006","MAPPINGA":"4506","DESCRIPTION":"TACAN","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAS--****X","MAPPINGP":"4014","MAPPINGA":"4514","DESCRIPTION":"Strike IP","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAR--****X","MAPPINGP":"4011","MAPPINGA":"4511","DESCRIPTION":"Rescue","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAL--****X","MAPPINGP":"4012","MAPPINGA":"4512","DESCRIPTION":"Replenish","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAM--****X","MAPPINGP":"4013","MAPPINGA":"4513","DESCRIPTION":"Marshall","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAC--****X","MAPPINGP":"4015","MAPPINGA":"4515","DESCRIPTION":"Corridor Tab","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAP--****X","MAPPINGP":"2053","MAPPINGA":"3053","DESCRIPTION":"Combat Air Patrol (CAP)","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAH--****X","MAPPINGP":"4009","MAPPINGA":"4509","DESCRIPTION":"Antisubmarine Warfare, Rotary Wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAA--****X","MAPPINGP":"4008","MAPPINGA":"4508","DESCRIPTION":"Antisubmarine Warfare, Fixed Wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAW--****X","MAPPINGP":"2054","MAPPINGA":"3054","DESCRIPTION":"Airborne Early Warning (AEW)","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"WAS-PC----P----","MAPPINGP":"5001","DESCRIPTION":"Cyclone Center","WIDTH":"26","HEIGHT":"33"},{"SYMBOLID":"WAS-PLT---P----","MAPPINGP":"5002","DESCRIPTION":"Tropopause Low","WIDTH":"28","HEIGHT":"26"},{"SYMBOLID":"WAS-PA----P----","MAPPINGP":"5004","DESCRIPTION":"Anticyclone Center","WIDTH":"26","HEIGHT":"33"},{"SYMBOLID":"WAS-PHT---P----","MAPPINGP":"5005","DESCRIPTION":"Tropopause High","WIDTH":"28","HEIGHT":"26"},{"SYMBOLID":"WAS-T-MW--P----","MAPPINGP":"5010","DESCRIPTION":"Mountain Waves","WIDTH":"24","HEIGHT":"12"},{"SYMBOLID":"WAS-CCCSFCP----","MAPPINGP":"5022","DESCRIPTION":"Few Coverage","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSSCP----","MAPPINGP":"5023","DESCRIPTION":"Scattered Coverage","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WAS-CCCSOCP----","MAPPINGP":"5025","DESCRIPTION":"Overcast Coverage","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSOBP----","MAPPINGP":"5026","DESCRIPTION":"Sky Totally or Partially Obscured","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-WSR-LIP----","MAPPINGP":"5027","DESCRIPTION":"Intermittent Light Rain","WIDTH":"10","HEIGHT":"10"},{"SYMBOLID":"WAS-WSR-LCP----","MAPPINGP":"5028","DESCRIPTION":"Continuous Light Rain","WIDTH":"36","HEIGHT":"10"},{"SYMBOLID":"WAS-WSR-MIP----","MAPPINGP":"5029","DESCRIPTION":"Intermittent Moderate Rain","WIDTH":"10","HEIGHT":"27"},{"SYMBOLID":"WAS-WSR-MCP----","MAPPINGP":"5030","DESCRIPTION":"Continuous Moderate Rain","WIDTH":"26","HEIGHT":"22"},{"SYMBOLID":"WAS-WSR-HIP----","MAPPINGP":"5031","DESCRIPTION":"Intermittent Heavy Rain","WIDTH":"10","HEIGHT":"30"},{"SYMBOLID":"WAS-WSR-HCP----","MAPPINGP":"5032","DESCRIPTION":"Continuous Heavy Rain","WIDTH":"34","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRFL-P----","MAPPINGP":"5033","DESCRIPTION":"Light Freezing Rain","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSRFMHP----","MAPPINGP":"5034","DESCRIPTION":"Moderate/Heavy Freezing Rain","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSRSL-P----","MAPPINGP":"5035","DESCRIPTION":"Light Rain Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRSMHP----","MAPPINGP":"5036","DESCRIPTION":"Moderate/Heavy Rain Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRST-P----","MAPPINGP":"5037","DESCRIPTION":"Torrential Rain Showers","WIDTH":"12","HEIGHT":"37"},{"SYMBOLID":"WAS-WSD-LIP----","MAPPINGP":"5038","DESCRIPTION":"Intermittent Light Drizzle","WIDTH":"8","HEIGHT":"14"},{"SYMBOLID":"WAS-WSD-LCP----","MAPPINGP":"5039","DESCRIPTION":"Continuous Light Drizzle","WIDTH":"21","HEIGHT":"14"},{"SYMBOLID":"WAS-WSD-MIP----","MAPPINGP":"5040","DESCRIPTION":"Intermittent Moderate Drizzle","WIDTH":"8","HEIGHT":"32"},{"SYMBOLID":"WAS-WSD-MCP----","MAPPINGP":"5041","DESCRIPTION":"Continuous Moderate Drizzle","WIDTH":"21","HEIGHT":"29"},{"SYMBOLID":"WAS-WSD-HIP----","MAPPINGP":"5042","DESCRIPTION":"Intermittent Heavy Drizzle","WIDTH":"8","HEIGHT":"44"},{"SYMBOLID":"WAS-WSD-HCP----","MAPPINGP":"5043","DESCRIPTION":"Continuous Heavy Drizzle","WIDTH":"27","HEIGHT":"34"},{"SYMBOLID":"WAS-WSDFL-P----","MAPPINGP":"5044","DESCRIPTION":"Light Freezing Drizzle","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSDFMHP----","MAPPINGP":"5045","DESCRIPTION":"Moderate/Heavy Freezing Drizzle","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSM-L-P----","MAPPINGP":"5046","DESCRIPTION":"Light Rain or Drizzle and Snow","WIDTH":"16","HEIGHT":"33"},{"SYMBOLID":"WAS-WSM-MHP----","MAPPINGP":"5047","DESCRIPTION":"Moderate Heavy Rain or Drizzle and Snow","WIDTH":"16","HEIGHT":"52"},{"SYMBOLID":"WAS-WSMSL-P----","MAPPINGP":"5048","DESCRIPTION":"Light Rain and Snow Showers","WIDTH":"16","HEIGHT":"53"},{"SYMBOLID":"WAS-WSMSMHP----","MAPPINGP":"5049","DESCRIPTION":"Moderate/Heavy Rain and Snow Showers","WIDTH":"16","HEIGHT":"52"},{"SYMBOLID":"WAS-WSS-LIP----","MAPPINGP":"5050","DESCRIPTION":"Intermittent Light Snow","WIDTH":"16","HEIGHT":"18"},{"SYMBOLID":"WAS-WSS-LCP----","MAPPINGP":"5051","DESCRIPTION":"Continuous Light Snow","WIDTH":"35","HEIGHT":"18"},{"SYMBOLID":"WAS-WSS-MIP----","MAPPINGP":"5052","DESCRIPTION":"Intermittent Moderate Snow","WIDTH":"16","HEIGHT":"39"},{"SYMBOLID":"WAS-WSS-MCP----","MAPPINGP":"5053","DESCRIPTION":"Continuous Moderate Snow","WIDTH":"35","HEIGHT":"40"},{"SYMBOLID":"WAS-WSS-HIP----","MAPPINGP":"5054","DESCRIPTION":"Intermittent Heavy Snow","WIDTH":"16","HEIGHT":"60"},{"SYMBOLID":"WAS-WSS-HCP----","MAPPINGP":"5055","DESCRIPTION":"Continuous Heavy Snow","WIDTH":"35","HEIGHT":"60"},{"SYMBOLID":"WAS-WSSBLMP----","MAPPINGP":"5056","DESCRIPTION":"Light/Moderate Blowing Snow","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"WAS-WSSBH-P----","MAPPINGP":"5057","DESCRIPTION":"Heavy Blowing Snow","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"WAS-WSSG--P----","MAPPINGP":"5058","DESCRIPTION":"Snow Grains (SG)","WIDTH":"42","HEIGHT":"19"},{"SYMBOLID":"WAS-WSSSL-P----","MAPPINGP":"5059","DESCRIPTION":"Light Snow Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSSSMHP----","MAPPINGP":"5060","DESCRIPTION":"Moderate/Heavy Snow Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSGRL-P----","MAPPINGP":"5061","DESCRIPTION":"Hail - Light not Associated With Thunder","WIDTH":"12","HEIGHT":"28"},{"SYMBOLID":"WAS-WSGRMHP----","MAPPINGP":"5062","DESCRIPTION":"Hail - Moderate/Heavy not Associated With Thunder","WIDTH":"12","HEIGHT":"28"},{"SYMBOLID":"WAS-WSIC--P----","MAPPINGP":"5063","DESCRIPTION":"Ice Crystals (DD)","WIDTH":"50","HEIGHT":"14"},{"SYMBOLID":"WAS-WSPLL-P----","MAPPINGP":"5064","DESCRIPTION":"Light Ice Pellets","WIDTH":"24","HEIGHT":"19"},{"SYMBOLID":"WAS-WSPLM-P----","MAPPINGP":"5065","DESCRIPTION":"Moderate Ice Pellets","WIDTH":"33","HEIGHT":"30"},{"SYMBOLID":"WAS-WSPLH-P----","MAPPINGP":"5066","DESCRIPTION":"Heavy Ice Pellets","WIDTH":"34","HEIGHT":"41"},{"SYMBOLID":"WAS-WST-NPP----","MAPPINGP":"5067","DESCRIPTION":"Thunderstorm - No Precipitation","WIDTH":"49","HEIGHT":"42"},{"SYMBOLID":"WAS-WSTMR-P----","MAPPINGP":"5068","DESCRIPTION":"Thunderstorm Light to Moderate With Rain/Snow - No Hail","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTHR-P----","MAPPINGP":"5069","DESCRIPTION":"Thunderstorm Heavy With Rain/Snow - No Hail","WIDTH":"28","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTMH-P----","MAPPINGP":"5070","DESCRIPTION":"Thunderstorm Light to Moderate - With Hail","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTHH-P----","MAPPINGP":"5071","DESCRIPTION":"Thunderstorm Heavy - With Hail","WIDTH":"25","HEIGHT":"48"},{"SYMBOLID":"WAS-WST-SQP----","MAPPINGP":"5073","DESCRIPTION":"Squall","WIDTH":"24","HEIGHT":"28"},{"SYMBOLID":"WAS-WST-LGP----","MAPPINGP":"5074","DESCRIPTION":"Lightning","WIDTH":"32","HEIGHT":"42"},{"SYMBOLID":"WAS-WSFGPSP----","MAPPINGP":"5075","DESCRIPTION":"Fog - Shallow Patches","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGCSP----","MAPPINGP":"5076","MAPPINGA":"7","DESCRIPTION":"Fog - Shallow Continuous","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGP-P----","MAPPINGP":"5077","DESCRIPTION":"Fog - Patchy","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGSVP----","MAPPINGP":"5078","DESCRIPTION":"Fog - Sky Visible","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGSOP----","MAPPINGP":"5079","DESCRIPTION":"Fog - Sky Obscured","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGFVP----","MAPPINGP":"5080","DESCRIPTION":"Fog - Freezing, Sky Visible","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGFOP----","MAPPINGP":"5081","DESCRIPTION":"Fog - Freezing, Sky Not Visible","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WAS-WSBR--P----","MAPPINGP":"5082","DESCRIPTION":"Mist","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WSHZ--P----","MAPPINGP":"5084","DESCRIPTION":"Haze","WIDTH":"48","HEIGHT":"22"},{"SYMBOLID":"WAS-WSDSLMP----","MAPPINGP":"5085","DESCRIPTION":"Light to Moderate Dust/Sand Storm","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-WSDSS-P----","MAPPINGP":"5086","DESCRIPTION":"Severe Dust/Sand Storm","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-WSBD--P----","MAPPINGP":"349","MAPPINGA":"349","DESCRIPTION":"Blowing Dust or Sand","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WSTSD-P----","MAPPINGP":"5089","DESCRIPTION":"Tropical Depression","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"WAS-WSTSS-P----","MAPPINGP":"5090","DESCRIPTION":"Tropical Storm","WIDTH":"32","HEIGHT":"52"},{"SYMBOLID":"WAS-WSTSH-P----","MAPPINGP":"5091","DESCRIPTION":"Hurricane/Typhoon","WIDTH":"32","HEIGHT":"52"},{"SYMBOLID":"WAS-WSVE--P----","MAPPINGP":"5092","DESCRIPTION":"Volcanic Eruption","WIDTH":"31","HEIGHT":"37"},{"SYMBOLID":"WAS-WSVA--P----","MAPPINGP":"5093","DESCRIPTION":"Volcanic Ash","WIDTH":"26","HEIGHT":"27"},{"SYMBOLID":"WAS-WST-LVP----","MAPPINGP":"5094","DESCRIPTION":"Tropopause Level","WIDTH":"50","HEIGHT":"28"},{"SYMBOLID":"WAS-WSF-LVP----","MAPPINGP":"5095","DESCRIPTION":"Freezing Level","WIDTH":"50","HEIGHT":"28"},{"SYMBOLID":"WAS-WSUKP-P----","MAPPINGP":"5096","DESCRIPTION":"Precipitation of Unknown Type and Intensity","WIDTH":"48","HEIGHT":"25"},{"SYMBOLID":"WAS-GND-NCP----","MAPPINGP":"5097","DESCRIPTION":"Loose Sand","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNM---P----","MAPPINGP":"5098","DESCRIPTION":"Surface Moist","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNW-SWP----","MAPPINGP":"5099","DESCRIPTION":"Surface Wet, Standing Water in Small or Large Pools","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNFL--P----","MAPPINGP":"5100","DESCRIPTION":"Surface Flooded","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNFZ--P----","MAPPINGP":"5101","DESCRIPTION":"Surface Frozen","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNG-TIP----","MAPPINGP":"5102","DESCRIPTION":"Glaze (Thin Ice) on Ground","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNLDN-P----","MAPPINGP":"5103","DESCRIPTION":"Loose Dry Dust or Sand not Covering Ground Completely","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GNLDTCP----","MAPPINGP":"5104","DESCRIPTION":"Thin Loose Dry Dust or Sand Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNLDMCP----","MAPPINGP":"5105","DESCRIPTION":"Moderae/Thick Loose Dry Dust or Sand Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNDEWCP----","MAPPINGP":"5106","DESCRIPTION":"Extremely Dry With Cracks","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSCL-P----","MAPPINGP":"5108","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering Less than One-Half of Ground","WIDTH":"33","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSCH-P----","MAPPINGP":"5109","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering At Least One-Half Ground, but Ground not Completely Covered","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSCCEP----","MAPPINGP":"5110","DESCRIPTION":"Even Layer of Compact or Wet Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSCCUP----","MAPPINGP":"5111","DESCRIPTION":"Uneven Layer of Compact or Wet Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSLL-P----","MAPPINGP":"5112","DESCRIPTION":"Loose Dry Snow Covering Less than One-Half of Ground","WIDTH":"33","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSLH-P----","MAPPINGP":"5113","DESCRIPTION":"Loose Dry Snow Covering at Least One-Half Ground, but Ground not Completely Covered","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSLCEP----","MAPPINGP":"5114","DESCRIPTION":"Even Layer of Loose Dry Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSLCUP----","MAPPINGP":"5115","DESCRIPTION":"Uneven Layer of Loose Dry Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSDC-P----","MAPPINGP":"5116","DESCRIPTION":"Snow Covering Ground Completely; Deep Drifts","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WOS-IB----P----","MAPPINGP":"5117","DESCRIPTION":"Icebergs","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBM---P----","MAPPINGP":"5118","DESCRIPTION":"Many Icebergs","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-IBBS--P----","MAPPINGP":"5119","DESCRIPTION":"Belts and Strips","WIDTH":"36","HEIGHT":"10"},{"SYMBOLID":"WOS-IBG---P----","MAPPINGP":"5120","DESCRIPTION":"Iceberg - General","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBMG--P----","MAPPINGP":"5121","DESCRIPTION":"Many Icebergs - General","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBBB--P----","MAPPINGP":"5122","DESCRIPTION":"Bergy Bit","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-IBBBM-P----","MAPPINGP":"5123","DESCRIPTION":"Many Bergy Bits","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-IBGL--P----","MAPPINGP":"5124","DESCRIPTION":"Growler","WIDTH":"30","HEIGHT":"24"},{"SYMBOLID":"WOS-IBGLM-P----","MAPPINGP":"5125","DESCRIPTION":"Many Growlers","WIDTH":"30","HEIGHT":"24"},{"SYMBOLID":"WOS-IBF---P----","MAPPINGP":"5126","DESCRIPTION":"Floeberg","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-IBII--P----","MAPPINGP":"5127","DESCRIPTION":"Ice Island","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-ICWB--P----","MAPPINGP":"5128","DESCRIPTION":"Bergy Water","WIDTH":"48","HEIGHT":"17"},{"SYMBOLID":"WOS-ICWR--P----","MAPPINGP":"5129","DESCRIPTION":"Water With Radar Targets","WIDTH":"48","HEIGHT":"16"},{"SYMBOLID":"WOS-ICIF--P----","MAPPINGP":"5130","DESCRIPTION":"Ice Free","WIDTH":"36","HEIGHT":"14"},{"SYMBOLID":"WOS-IDC---P----","MAPPINGP":"5131","DESCRIPTION":"Convergence","WIDTH":"42","HEIGHT":"8"},{"SYMBOLID":"WOS-IDD---P----","MAPPINGP":"5132","DESCRIPTION":"Divergence","WIDTH":"42","HEIGHT":"8"},{"SYMBOLID":"WOS-IDS---P----","MAPPINGP":"5133","DESCRIPTION":"Shearing or Shear Zone","WIDTH":"20","HEIGHT":"18"},{"SYMBOLID":"WO-DIDID---L---","MAPPINGP":"5134","DESCRIPTION":"Ice Drift (Direction)","WIDTH":"20","HEIGHT":"8"},{"SYMBOLID":"WOS-II----P----","MAPPINGP":"5135","DESCRIPTION":"Sea Ice","WIDTH":"25","HEIGHT":"24"},{"SYMBOLID":"WOS-IITM--P----","MAPPINGP":"5136","DESCRIPTION":"Ice Thickness (Observed)","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"WOS-IITE--P----","MAPPINGP":"5137","DESCRIPTION":"Ice Thickness (Estimated)","WIDTH":"45","HEIGHT":"40"},{"SYMBOLID":"WOS-IIP---P----","MAPPINGP":"5138","DESCRIPTION":"Melt Puddles or Flooded Ice","WIDTH":"39","HEIGHT":"14"},{"SYMBOLID":"WOS-ISC---P----","MAPPINGP":"5139","DESCRIPTION":"Snow Cover","WIDTH":"17","HEIGHT":"29"},{"SYMBOLID":"WOS-ISS---P----","MAPPINGP":"5140","DESCRIPTION":"Sastrugi (With Orientation)","WIDTH":"29","HEIGHT":"44"},{"SYMBOLID":"WOS-ITRH--P----","MAPPINGP":"5141","DESCRIPTION":"Ridges or Hummocks","WIDTH":"36","HEIGHT":"18"},{"SYMBOLID":"WOS-ITR---P----","MAPPINGP":"5142","DESCRIPTION":"Rafting","WIDTH":"36","HEIGHT":"26"},{"SYMBOLID":"WOS-ITBB--P----","MAPPINGP":"5143","DESCRIPTION":"Jammed Brash Barrier","WIDTH":"36","HEIGHT":"18"},{"SYMBOLID":"WOS-HDS---P----","MAPPINGP":"5144","MAPPINGA":"404","DESCRIPTION":"Soundings","WIDTH":"30","HEIGHT":"32"},{"SYMBOLID":"WOS-HPB-O-P----","MAPPINGP":"5145","DESCRIPTION":"Berths (Onshore)","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-HPB-A-P----","MAPPINGP":"5146","DESCRIPTION":"Berths (Anchor)","WIDTH":"46","HEIGHT":"44"},{"SYMBOLID":"WOS-HPBA--P----","MAPPINGP":"5147","DESCRIPTION":"Anchorage","WIDTH":"46","HEIGHT":"44"},{"SYMBOLID":"WOS-HPCP--P----","MAPPINGP":"5148","DESCRIPTION":"Call in Point","WIDTH":"19","HEIGHT":"36"},{"SYMBOLID":"WOS-HPFH--P----","MAPPINGP":"5149","DESCRIPTION":"Fishing Harbor","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"WOS-HPFS--P----","MAPPINGP":"5150","DESCRIPTION":"Fish Stakes/Traps/Weirs","WIDTH":"34","HEIGHT":"32"},{"SYMBOLID":"WOS-HPFS---L---","MAPPINGP":"5151","DESCRIPTION":"Fish Stakes","WIDTH":"36","HEIGHT":"31"},{"SYMBOLID":"WOS-HPML--P----","MAPPINGP":"5152","DESCRIPTION":"Landing Place","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WO-DHPMO--P----","MAPPINGP":"5153","DESCRIPTION":"Offshore Loading Facility 1","WIDTH":"35","HEIGHT":"33"},{"SYMBOLID":"WO-DHPMO---L---","MAPPINGP":"5154","DESCRIPTION":"Offshore Loading Facility 2","WIDTH":"36","HEIGHT":"4"},{"SYMBOLID":"WOS-HPM-R-P----","MAPPINGP":"5155","MAPPINGA":"5156","DESCRIPTION":"Landing Ring","WIDTH":"36","HEIGHT":"20"},{"SYMBOLID":"WOS-HPM-FC-L---","MAPPINGP":"5157","DESCRIPTION":"Ferry Crossing","WIDTH":"38","HEIGHT":"10"},{"SYMBOLID":"WOS-HPM-CC-L---","MAPPINGP":"5158","DESCRIPTION":"Cable Ferry Crossing","WIDTH":"38","HEIGHT":"10"},{"SYMBOLID":"WOS-HPD---P----","MAPPINGP":"5159","MAPPINGA":"5160","DESCRIPTION":"Dolphin","WIDTH":"36","HEIGHT":"20"},{"SYMBOLID":"WOS-HABA--P----","MAPPINGP":"5161","DESCRIPTION":"Beacon","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WOS-HABB--P----","MAPPINGP":"5162","MAPPINGA":"5163","DESCRIPTION":"Buoy Default","WIDTH":"52","HEIGHT":"34"},{"SYMBOLID":"WOS-HABM--P----","MAPPINGP":"5164","DESCRIPTION":"Marker","WIDTH":"24","HEIGHT":"32"},{"SYMBOLID":"WOS-HABP--P----","MAPPINGP":"5165","DESCRIPTION":"Perches/Stakes","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"WOS-HAL---P----","MAPPINGP":"5166","DESCRIPTION":"Light","WIDTH":"40","HEIGHT":"36"},{"SYMBOLID":"WOS-HALV--P----","MAPPINGP":"5167","DESCRIPTION":"Light Vessel/Lightship","WIDTH":"36","HEIGHT":"32"},{"SYMBOLID":"WOS-HALH--P----","MAPPINGP":"5168","DESCRIPTION":"Lighthouse","WIDTH":"28","HEIGHT":"36"},{"SYMBOLID":"WOS-HHRS--P----","MAPPINGP":"5169","MAPPINGA":"5170","DESCRIPTION":"Rock Submerged","WIDTH":"26","HEIGHT":"26"},{"SYMBOLID":"WOS-HHRA--P----","MAPPINGP":"5171","DESCRIPTION":"Rock Awashed","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDF--P----","MAPPINGP":"5172","DESCRIPTION":"Foul Ground","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WO-DHHDK--P----","MAPPINGP":"5173","DESCRIPTION":"Kelp/Seaweed","WIDTH":"38","HEIGHT":"13"},{"SYMBOLID":"WOS-HHDMDBP----","MAPPINGP":"5174","DESCRIPTION":"Mine-Naval (Doubtful)","WIDTH":"24","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDMDFP----","MAPPINGP":"5175","DESCRIPTION":"Mine-Naval (Definite)","WIDTH":"24","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDS--P----","MAPPINGP":"5176","MAPPINGA":"5177","DESCRIPTION":"Snags/Stumps","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-HHDWA-P----","MAPPINGP":"5178","DESCRIPTION":"Wreck (Uncovers)","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"WOS-HHDWB-P----","MAPPINGP":"5179","MAPPINGA":"5180","DESCRIPTION":"Wreck (Submerged)","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-HHDE--P----","MAPPINGP":"5181","DESCRIPTION":"Eddies/Overfalls/Tide Rips","WIDTH":"59","HEIGHT":"20"},{"SYMBOLID":"WOS-BFC-S-P----","MAPPINGP":"5182","DESCRIPTION":"Sand","WIDTH":"28","HEIGHT":"37"},{"SYMBOLID":"WOS-BFC-M-P----","MAPPINGP":"5183","DESCRIPTION":"Mud","WIDTH":"38","HEIGHT":"26"},{"SYMBOLID":"WOS-BFC-CLP----","MAPPINGP":"5184","DESCRIPTION":"Clay","WIDTH":"36","HEIGHT":"30"},{"SYMBOLID":"WOS-BFC-SIP----","MAPPINGP":"5185","DESCRIPTION":"Silt","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"WOS-BFC-STP----","MAPPINGP":"5186","DESCRIPTION":"Stones","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"WOS-BFC-G-P----","MAPPINGP":"5187","DESCRIPTION":"Gravel","WIDTH":"40","HEIGHT":"42"},{"SYMBOLID":"WOS-BFC-P-P----","MAPPINGP":"5188","DESCRIPTION":"Pebbles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-BFC-CBP----","MAPPINGP":"5189","DESCRIPTION":"Cobbles","WIDTH":"36","HEIGHT":"26"},{"SYMBOLID":"WOS-BFC-R-P----","MAPPINGP":"5190","DESCRIPTION":"Rock","WIDTH":"30","HEIGHT":"34"},{"SYMBOLID":"WOS-BFC-COP----","MAPPINGP":"5191","DESCRIPTION":"Coral","WIDTH":"36","HEIGHT":"25"},{"SYMBOLID":"WOS-BFC-SHP----","MAPPINGP":"5192","DESCRIPTION":"Shell","WIDTH":"36","HEIGHT":"28"},{"SYMBOLID":"WOS-BFQ-F-P----","MAPPINGP":"5193","DESCRIPTION":"Fine","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WOS-BFQ-M-P----","MAPPINGP":"5194","DESCRIPTION":"Medium","WIDTH":"36","HEIGHT":"25"},{"SYMBOLID":"WOS-BFQ-C-P----","MAPPINGP":"5195","DESCRIPTION":"Coarse","WIDTH":"32","HEIGHT":"36"},{"SYMBOLID":"WOS-TCCW--P----","MAPPINGP":"5196","DESCRIPTION":"Water Turbulence","WIDTH":"60","HEIGHT":"21"},{"SYMBOLID":"WOS-TCCTD-P----","MAPPINGP":"5197","DESCRIPTION":"Tide Data Point","WIDTH":"30","HEIGHT":"36"},{"SYMBOLID":"WOS-TCCTG-P----","MAPPINGP":"5198","MAPPINGA":"5199","DESCRIPTION":"Tide Gauge","WIDTH":"33","HEIGHT":"20"},{"SYMBOLID":"WOS-MF----P----","MAPPINGP":"5200","DESCRIPTION":"Ford","WIDTH":"12","HEIGHT":"34"},{"SYMBOLID":"WOS-ML----P----","MAPPINGP":"5201","DESCRIPTION":"Lock","WIDTH":"22","HEIGHT":"26"},{"SYMBOLID":"WOS-MOA---P----","MAPPINGP":"5202","DESCRIPTION":"Oil/Gas Rig","WIDTH":"31","HEIGHT":"42"},{"SYMBOLID":"WOS-MPA---P----","MAPPINGP":"5203","DESCRIPTION":"Pile/Piling/Post","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*G*GPUY--****X","MAPPINGP":"2007","MAPPINGA":"3007","DESCRIPTION":"Sonobuoy","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUS--****X","MAPPINGP":"2020","MAPPINGA":"2020","DESCRIPTION":"Search","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPF---****X","MAPPINGP":"2040","MAPPINGA":"3040","DESCRIPTION":"Formation","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*GPH---****X","MAPPINGP":"2041","MAPPINGA":"3041","DESCRIPTION":"Harbor (General)","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPO---****X","MAPPINGP":"2046","MAPPINGA":"3046","DESCRIPTION":"Route","WIDTH":"36","HEIGHT":"24"},{"SYMBOLID":"G*G*GPPA--****X","MAPPINGP":"2091","MAPPINGA":"3091","DESCRIPTION":"Amnesty Point","WIDTH":"25","HEIGHT":"45"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SymbolConstantsB={"SYMBOLCONSTANTS":{"SYMBOL":[{"SYMBOLID":"BS_BASIC_SHAPES","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Basic Shapes","HIERARCHY":"0.X","ALPHAHIERARCHY":"BS"},{"SYMBOLID":"BS_LINE--------","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line","HIERARCHY":"0.X.1","ALPHAHIERARCHY":"BS.LINE","PATH":"Basic Shapes"},{"SYMBOLID":"BS_AREA--------","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area","HIERARCHY":"0.X.2","ALPHAHIERARCHY":"BS.AREA","PATH":"Basic Shapes"},{"SYMBOLID":"BS_CROSS--------","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cross","HIERARCHY":"0.X.3","ALPHAHIERARCHY":"BS.CROSS","PATH":"Basic Shapes"},{"SYMBOLID":"BS_ELLIPSE-----","GEOMETRY":"area","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ellipse","HIERARCHY":"0.X.4","ALPHAHIERARCHY":"BS.ELLIPSE","PATH":"Basic Shapes"},{"SYMBOLID":"BS_RECTANGLE---","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Rectangle","HIERARCHY":"0.X.5","ALPHAHIERARCHY":"BS.RECTANGLE","PATH":"Basic Shapes"},{"SYMBOLID":"BUFFERED_SHAPES","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"AM.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6","ALPHAHIERARCHY":"BS.BBS"},{"SYMBOLID":"BBS_LINE-------","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Line","HIERARCHY":"0.X.6.1","ALPHAHIERARCHY":"BS.BBS.LINE"},{"SYMBOLID":"BBS_AREA-------","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6.2","ALPHAHIERARCHY":"BS.BBS.AREA"},{"SYMBOLID":"BBS_POINT------","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6.2","ALPHAHIERARCHY":"BS.BBS.POINT"},{"SYMBOLID":"BBS_RECTANGLE--","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Rectangle","HIERARCHY":"0.X.6.3","ALPHAHIERARCHY":"BS.BBS.RECT"},{"SYMBOLID":"G*-*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tactical Graphics","HIERARCHY":"2.X"},{"SYMBOLID":"G*T*------****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tasks","HIERARCHY":"2.X.1","PATH":"Tactical Graphics"},{"SYMBOLID":"G*T*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Block Task","HIERARCHY":"2.X.1.1","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*H-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Breach","HIERARCHY":"2.X.1.2","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*Y-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass","HIERARCHY":"2.X.1.3","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*C-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Canalize","HIERARCHY":"2.X.1.4","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*X-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Clear","HIERARCHY":"2.X.1.5","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*J-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Contain","HIERARCHY":"2.X.1.6","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*K-----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Counterattack (CATK)","HIERARCHY":"2.X.1.7","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*KF----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Counterattack by Fire","HIERARCHY":"2.X.1.7.1","PATH":"Tactical Graphics/Tasks/Counterattack (CATK)"},{"SYMBOLID":"G*T*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"W","DESCRIPTION":"Delay","HIERARCHY":"2.X.1.8","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*D-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Destroy","HIERARCHY":"2.X.1.9","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*T-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Disrupt Tasks","HIERARCHY":"2.X.1.10","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*F-----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Fix Task","HIERARCHY":"2.X.1.11","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*A-----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T","DESCRIPTION":"Follow and Assume","HIERARCHY":"2.X.1.12","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*AS----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Follow and Support","HIERARCHY":"2.X.1.12.1","PATH":"Tactical Graphics/Tasks/Follow and Assume"},{"SYMBOLID":"G*T*I-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Interdict","HIERARCHY":"2.X.1.13","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*E-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Isolate","HIERARCHY":"2.X.1.14","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*N-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Neutralize","HIERARCHY":"2.X.1.15","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*O-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Occupy","HIERARCHY":"2.X.1.16","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*P-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Penetrate","HIERARCHY":"2.X.1.17","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*R-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Relief in Place","HIERARCHY":"2.X.1.18","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*Q-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Retain","HIERARCHY":"2.X.1.19","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*M-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Retirement","HIERARCHY":"2.X.1.20","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*S-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Secure","HIERARCHY":"2.X.1.21","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*U-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Security","HIERARCHY":"2.X.1.22","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*US----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Screen","HIERARCHY":"2.X.1.22.1","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*UG----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Guard","HIERARCHY":"2.X.1.22.2","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*UC----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Cover","HIERARCHY":"2.X.1.22.3","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*Z-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Seize","HIERARCHY":"2.X.1.23","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*W-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Withdraw","HIERARCHY":"2.X.1.24","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*WP----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Withdraw Under Pressure","HIERARCHY":"2.X.1.24.1","PATH":"Tactical Graphics/Tasks/Withdraw"},{"SYMBOLID":"G*T*V-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Cordon and Search","HIERARCHY":"2.X.1.25","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*2-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Cordon and Knock","HIERARCHY":"2.X.1.26","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*G-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Suppress","HIERARCHY":"2.X.1.27","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*G*GPPN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.H.W.W1.N.","DESCRIPTION":"Entry Control Point","HIERARCHY":"2.X.1.28","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*G*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control and General Maneuver","HIERARCHY":"2.X.2","PATH":"Tactical Graphics"},{"SYMBOLID":"G*G*G-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"General","HIERARCHY":"2.X.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*GP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GPU---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Under Sea Warfare","HIERARCHY":"2.X.2.1.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPUU--****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Underwater","HIERARCHY":"2.X.2.1.1.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUUD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Datum","HIERARCHY":"2.X.2.1.1.1.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUB-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Brief Contact","HIERARCHY":"2.X.2.1.1.1.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUL-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Lost Contact","HIERARCHY":"2.X.2.1.1.1.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Sinker","HIERARCHY":"2.X.2.1.1.1.1.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUY--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy","HIERARCHY":"2.X.2.1.1.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUYP-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Pattern Center","HIERARCHY":"2.X.2.1.1.1.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Directional Frequency Analyzing and Recording (DIFAR)","HIERARCHY":"2.X.2.1.1.1.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYL-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Low Frequency Analyzing and Recording (LOFAR)","HIERARCHY":"2.X.2.1.1.1.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYC-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Command Active Sonobuoy System (CASS)","HIERARCHY":"2.X.2.1.1.1.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Directional Command Active Sonobuoy System (DICASS)","HIERARCHY":"2.X.2.1.1.1.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYB-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Bathythermograph Transmitting (BT)","HIERARCHY":"2.X.2.1.1.1.2.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy ANM","HIERARCHY":"2.X.2.1.1.1.2.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYV-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Vertical Line Array DIFAR (VLAD)","HIERARCHY":"2.X.2.1.1.1.2.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYT-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy ATAC","HIERARCHY":"2.X.2.1.1.1.2.9","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYR-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Range Only (RO)","HIERARCHY":"2.X.2.1.1.1.2.10","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYK-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Kingpin","HIERARCHY":"2.X.2.1.1.1.2.11","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search","HIERARCHY":"2.X.2.1.1.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUSA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search Area","HIERARCHY":"2.X.2.1.1.1.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPUSD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dip Position","HIERARCHY":"2.X.2.1.1.1.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPUSC-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search Center","HIERARCHY":"2.X.2.1.1.1.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPR---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Reference Point","HIERARCHY":"2.X.2.1.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPRS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Special Point","HIERARCHY":"2.X.2.1.1.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Nav Reference Point","HIERARCHY":"2.X.2.1.1.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"DLRP","HIERARCHY":"2.X.2.1.1.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRI--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Point of Interest","HIERARCHY":"2.X.2.1.1.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPW---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Weapon","HIERARCHY":"2.X.2.1.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPWA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Aim Point","HIERARCHY":"2.X.2.1.1.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Drop Point","HIERARCHY":"2.X.2.1.1.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Entry Point","HIERARCHY":"2.X.2.1.1.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWG--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ground Zero","HIERARCHY":"2.X.2.1.1.3.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"MSL Detect Point","HIERARCHY":"2.X.2.1.1.3.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWI--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Impact Point","HIERARCHY":"2.X.2.1.1.3.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Predicted Impact Point","HIERARCHY":"2.X.2.1.1.3.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Formation","HIERARCHY":"2.X.2.1.1.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.","DESCRIPTION":"Harbor General","HIERARCHY":"2.X.2.1.1.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPHQ--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point Q","HIERARCHY":"2.X.2.1.1.5.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point A","HIERARCHY":"2.X.2.1.1.5.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHY--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point Y","HIERARCHY":"2.X.2.1.1.5.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHX--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point X","HIERARCHY":"2.X.2.1.1.5.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route","HIERARCHY":"2.X.2.1.1.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPOZ--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Rendezvous","HIERARCHY":"2.X.2.1.1.6.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Diversions","HIERARCHY":"2.X.2.1.1.6.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Waypoint","HIERARCHY":"2.X.2.1.1.6.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route PIM","HIERARCHY":"2.X.2.1.1.6.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Point R","HIERARCHY":"2.X.2.1.1.6.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPA---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Air Control","HIERARCHY":"2.X.2.1.1.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPAP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Combat Air Patrol (CAP)","HIERARCHY":"2.X.2.1.1.7.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Airborne Early Warning (AEW)","HIERARCHY":"2.X.2.1.1.7.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAT--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control TACAN","HIERARCHY":"2.X.2.1.1.7.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAK--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Tanking","HIERARCHY":"2.X.2.1.1.7.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Antisubmarine Warfare- Fixed Wing","HIERARCHY":"2.X.2.1.1.7.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAH--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Antisubmarine Warfare- Rotary Wing","HIERARCHY":"2.X.2.1.1.7.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAO--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Tomcat","HIERARCHY":"2.X.2.1.1.7.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Rescue","HIERARCHY":"2.X.2.1.1.7.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAL--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Replenish","HIERARCHY":"2.X.2.1.1.7.9","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Marshall","HIERARCHY":"2.X.2.1.1.7.10","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Strike IP","HIERARCHY":"2.X.2.1.1.7.11","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Corridor TAB","HIERARCHY":"2.X.2.1.1.7.12","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.H1.T.W.W1.N.","DESCRIPTION":"Action Point","HIERARCHY":"2.X.2.1.1.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPPK--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Check Point","HIERARCHY":"2.X.2.1.1.8.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Contact Point","HIERARCHY":"2.X.2.1.1.8.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPO--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"N.","DESCRIPTION":"Coordination Point","HIERARCHY":"2.X.2.1.1.8.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Decision Point","HIERARCHY":"2.X.2.1.1.8.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPL--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Linkup Point","HIERARCHY":"2.X.2.1.1.8.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Passage Point","HIERARCHY":"2.X.2.1.1.8.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Rally Point","HIERARCHY":"2.X.2.1.1.8.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Release Point (RP)","HIERARCHY":"2.X.2.1.1.8.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Start Point (SP)","HIERARCHY":"2.X.2.1.1.8.9","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Waypoint","HIERARCHY":"2.X.2.1.1.8.10","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Amnesty Point","HIERARCHY":"2.X.2.1.1.8.11","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Points"},{"SYMBOLID":"G*G*GL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GLB---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"B.N.T.T1.","DESCRIPTION":"Boundary","HIERARCHY":"2.X.2.1.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Forward Line of Own Troops","HIERARCHY":"2.X.2.1.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"N.","DESCRIPTION":"Line of Contact (LC)","HIERARCHY":"2.X.2.1.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLP---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Phase Line","HIERARCHY":"2.X.2.1.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Light Line","HIERARCHY":"2.X.2.1.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GAG---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"General Area","HIERARCHY":"2.X.2.1.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Assembly Area","HIERARCHY":"2.X.2.1.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Engagement Area (General)","HIERARCHY":"2.X.2.1.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Fortified Area","HIERARCHY":"2.X.2.1.3.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Drop Zone","HIERARCHY":"2.X.2.1.3.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAX---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Extraction Zone","HIERARCHY":"2.X.2.1.3.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAL---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Landing Zone (LZ)","HIERARCHY":"2.X.2.1.3.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAP---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Pickup Zone (PZ)","HIERARCHY":"2.X.2.1.3.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAS---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Search Area/Reconnaissance Area","HIERARCHY":"2.X.2.1.3.9","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAY---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Limited Access Area","HIERARCHY":"2.X.2.1.3.10","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAZ---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Airfield Zone","HIERARCHY":"2.X.2.1.3.11","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*A-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Aviation","HIERARCHY":"2.X.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*AP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*APP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Air Control Point (ACP)","HIERARCHY":"2.X.2.2.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Communications Checkpoint (CCP)","HIERARCHY":"2.X.2.2.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APU---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pull-Up Point (PUP)","HIERARCHY":"2.X.2.2.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"N.","DESCRIPTION":"Downed Aircrew Pickup Point","HIERARCHY":"2.X.2.2.1.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*AL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*ALC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"H.H1.H2.T.T1.W.W1.","DESCRIPTION":"Air Corridor","HIERARCHY":"2.X.2.2.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"W.W1.H.H1.H2","DESCRIPTION":"Minimum Risk Route (MRR)","HIERARCHY":"2.X.2.2.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALS---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"H.H1.H2.T.","DESCRIPTION":"Standard-Use Army Aircraft Flight Route (SAAFR)","HIERARCHY":"2.X.2.2.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALU---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"W.W1.H.H1.H2","DESCRIPTION":"Unmanned Aerial Vehicle (UAV) Route","HIERARCHY":"2.X.2.2.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"W.W1.T.H.H1.H2.","DESCRIPTION":"Low Level Transit Route (LLTR)","HIERARCHY":"2.X.2.2.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*AA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*AAR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"Restricted Operations Zone (ROZ)","HIERARCHY":"2.X.2.2.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"Forward Area Air Defense Zone (FAADEZ)","HIERARCHY":"2.X.2.2.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAH---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"High Density Airspace Control Zone (HIDACZ)","HIERARCHY":"2.X.2.2.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAM---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"Missile Engagement Zone (MEZ)","HIERARCHY":"2.X.2.2.3.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAML--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"Low Altitude MEZ","HIERARCHY":"2.X.2.2.3.4.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas/Missile Engagement Zone (MEZ)"},{"SYMBOLID":"G*G*AAMH--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.T.W.W1.","DESCRIPTION":"High Altitude MEZ","HIERARCHY":"2.X.2.2.3.4.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas/Missile Engagement Zone (MEZ)"},{"SYMBOLID":"G*G*AAW---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Weapons Free Zone","HIERARCHY":"2.X.2.2.3.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*P-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Deception","HIERARCHY":"2.X.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*PD----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Dummy (Deception/Decoy)","HIERARCHY":"2.X.2.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PA----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Axis of Advance for Feint","HIERARCHY":"2.X.2.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PF----****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Direction of Attack for Feint","HIERARCHY":"2.X.2.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PM----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Decoy Mined Area","HIERARCHY":"2.X.2.3.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PY----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Decoy Mined Area, Fenced","HIERARCHY":"2.X.2.3.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PN----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dummy Minefield - Static","HIERARCHY":"2.X.2.3.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PC----****X","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.N.","DESCRIPTION":"Dummy Minefield - Dynamic","HIERARCHY":"2.X.2.3.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*D-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Defense","HIERARCHY":"2.X.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*DP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.4.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DPT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Target Reference","HIERARCHY":"2.X.2.4.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points"},{"SYMBOLID":"G*G*DPO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Observation Post (OP)/Outpost","HIERARCHY":"2.X.2.4.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points"},{"SYMBOLID":"G*G*DPOC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Combat Outpost","HIERARCHY":"2.X.2.4.1.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Observation Post Occupied Dismounted Recon","HIERARCHY":"2.X.2.4.1.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOF--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Forward Observer Position Outpost","HIERARCHY":"2.X.2.4.1.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sensor Outpost/Listening Post (OP/LP)","HIERARCHY":"2.X.2.4.1.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPON--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"NBC Observation Post Dismounted","HIERARCHY":"2.X.2.4.1.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.4.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Forward Edge of Battle Area","HIERARCHY":"2.X.2.4.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Lines"},{"SYMBOLID":"G*G*DLP---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Principal Direction of Fire (PDF)","HIERARCHY":"2.X.2.4.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Lines"},{"SYMBOLID":"G*G*DA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.4.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DAB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.N.T.","DESCRIPTION":"Battle Position","HIERARCHY":"2.X.2.4.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas"},{"SYMBOLID":"G*G*DABP--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.N.T.","DESCRIPTION":"Battle Position Prepared but not Occupied","HIERARCHY":"2.X.2.4.3.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas/Battle Position"},{"SYMBOLID":"G*G*DAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Engagement Area (Defense)","HIERARCHY":"2.X.2.4.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas"},{"SYMBOLID":"G*G*O-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Offense","HIERARCHY":"2.X.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*OP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.5.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OPP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Point of Departure","HIERARCHY":"2.X.2.5.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Points"},{"SYMBOLID":"G*G*OL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.5.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OLA---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Axis of Advance","HIERARCHY":"2.X.2.5.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLAV--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Aviation","HIERARCHY":"2.X.2.5.2.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAA--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Axis of Advance Airborne","HIERARCHY":"2.X.2.5.2.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAR--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Attack, Rotary Wing","HIERARCHY":"2.X.2.5.2.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAG--****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Axis of Advance Ground","HIERARCHY":"2.X.2.5.2.1.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAGM-****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Ground Main Attack","HIERARCHY":"2.X.2.5.2.1.4.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance/Axis of Advance Ground"},{"SYMBOLID":"G*G*OLAGS-****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Ground Supporting Attack","HIERARCHY":"2.X.2.5.2.1.4.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance/Axis of Advance Ground"},{"SYMBOLID":"G*G*OLK---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Direction of Attack","HIERARCHY":"2.X.2.5.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLKA--****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"N.","DESCRIPTION":"Direction of Attack Aviation","HIERARCHY":"2.X.2.5.2.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack"},{"SYMBOLID":"G*G*OLKG--****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Direction of Attack Ground","HIERARCHY":"2.X.2.5.2.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack"},{"SYMBOLID":"G*G*OLKGM-****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Direction of Attack Ground Main Attack","HIERARCHY":"2.X.2.5.2.2.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack/Direction of Attack Ground"},{"SYMBOLID":"G*G*OLKGS-****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Direction of Attack Ground Supporting Attack","HIERARCHY":"2.X.2.5.2.2.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack/Direction of Attack Ground"},{"SYMBOLID":"G*G*OLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Final Coordination Line","HIERARCHY":"2.X.2.5.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLI---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Infiltration Lane","HIERARCHY":"2.X.2.5.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Limit Of Advance (LOA)","HIERARCHY":"2.X.2.5.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLT---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line of Departure (LD)","HIERARCHY":"2.X.2.5.2.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line of Departure/Line of Contact (LD/LC)","HIERARCHY":"2.X.2.5.2.7","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLP---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Probable Line of Deployment (PLD)","HIERARCHY":"2.X.2.5.2.8","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.5.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Assault Position","HIERARCHY":"2.X.2.5.3.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAK---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Attack Position","HIERARCHY":"2.X.2.5.3.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAF---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Attack by Fire Position","HIERARCHY":"2.X.2.5.3.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAS---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Support by Fire Position","HIERARCHY":"2.X.2.5.3.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAO---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Objective","HIERARCHY":"2.X.2.5.3.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAP---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Penetration Box","HIERARCHY":"2.X.2.5.3.6","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*S-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Special","HIERARCHY":"2.X.2.6","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*SL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Line","HIERARCHY":"2.X.2.6.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special"},{"SYMBOLID":"G*G*SLA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ambush","HIERARCHY":"2.X.2.6.1.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLH---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Holding Line","HIERARCHY":"2.X.2.6.1.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Release Line","HIERARCHY":"2.X.2.6.1.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLB---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Bridgehead","HIERARCHY":"2.X.2.6.1.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Area","HIERARCHY":"2.X.2.6.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special"},{"SYMBOLID":"G*G*SAO---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area of Operations (AO)","HIERARCHY":"2.X.2.6.2.1","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Airhead","HIERARCHY":"2.X.2.6.2.2","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Encirclement","HIERARCHY":"2.X.2.6.2.3","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAN---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Named Area of Interest (NAI)","HIERARCHY":"2.X.2.6.2.4","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAT---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Targeted Area of Interest (TAI)","HIERARCHY":"2.X.2.6.2.5","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*M*------****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mobility/Survivability","HIERARCHY":"2.X.3","PATH":"Tactical Graphics"},{"SYMBOLID":"G*M*O-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacles","HIERARCHY":"2.X.3.1","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*OG----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"General (Obstacles)","HIERARCHY":"2.X.3.1.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OGB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.T1.","DESCRIPTION":"Obstacle Belt","HIERARCHY":"2.X.3.1.1.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Obstacle Line","HIERARCHY":"2.X.3.1.1.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGZ---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Obstacle Zone","HIERARCHY":"2.X.3.1.1.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Obstacle Free Area","HIERARCHY":"2.X.3.1.1.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Obstacle Restricted Area","HIERARCHY":"2.X.3.1.1.5","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OS----****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Abatis","HIERARCHY":"2.X.3.1.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OA----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Obstacles","HIERARCHY":"2.X.3.1.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OAD---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Ditch","HIERARCHY":"2.X.3.1.3.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OADU--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Under Construction","HIERARCHY":"2.X.3.1.3.1.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Ditch"},{"SYMBOLID":"G*M*OADC--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Complete","HIERARCHY":"2.X.3.1.3.1.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Ditch"},{"SYMBOLID":"G*M*OAR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Reinforced with Antitank Mines","HIERARCHY":"2.X.3.1.3.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OAO---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles","HIERARCHY":"2.X.3.1.3.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OAOF--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Fixed and Prefabricated","HIERARCHY":"2.X.3.1.3.3.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAOM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Moveable","HIERARCHY":"2.X.3.1.3.3.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAOP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Moveable and Prefabricated","HIERARCHY":"2.X.3.1.3.3.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAW---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Wall","HIERARCHY":"2.X.3.1.3.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OB----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Booby Trap","HIERARCHY":"2.X.3.1.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OM----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mines","HIERARCHY":"2.X.3.1.5","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OMU---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Unspecified Mine","HIERARCHY":"2.X.3.1.5.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine","HIERARCHY":"2.X.3.1.5.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine With Antihandling Device","HIERARCHY":"2.X.3.1.5.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OME---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine, Directional","HIERARCHY":"2.X.3.1.5.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antipersonnel Mine","HIERARCHY":"2.X.3.1.5.5","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMW---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wide Area Mines","HIERARCHY":"2.X.3.1.5.6","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMC---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Mine Cluster","HIERARCHY":"2.X.3.1.5.7","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OF----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Minefields","HIERARCHY":"2.X.3.1.6","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OFS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.W.","DESCRIPTION":"Minefield (Static)","HIERARCHY":"2.X.3.1.6.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.N.W.","DESCRIPTION":"Minefield (Dynamic)","HIERARCHY":"2.X.3.1.6.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFG---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","MODIFIERS":"W.W1.","DESCRIPTION":"Minefields Gap","HIERARCHY":"2.X.3.1.6.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Mined Area","HIERARCHY":"2.X.3.1.6.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OE----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Effect","HIERARCHY":"2.X.3.1.7","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OEB---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Block Obstacle Effect","HIERARCHY":"2.X.3.1.7.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OEF---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Fix (Obstacle Effect)","HIERARCHY":"2.X.3.1.7.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OET---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Turn","HIERARCHY":"2.X.3.1.7.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OED---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Disrupt Obstacle Effect","HIERARCHY":"2.X.3.1.7.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OU----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Unexploded Ordnance Area (UXO)","HIERARCHY":"2.X.3.1.8","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OR----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Roadblocks, Craters, and Blown Bridges","HIERARCHY":"2.X.3.1.9","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*ORP---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Planned","HIERARCHY":"2.X.3.1.9.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORS---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Explosives State of Readiness 1 (Safe)","HIERARCHY":"2.X.3.1.9.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Explosives State of Readiness 2 (Armed - but Passable)","HIERARCHY":"2.X.3.1.9.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORC---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Roadblock Complete (Executed)","HIERARCHY":"2.X.3.1.9.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*OT----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Trip Wire","HIERARCHY":"2.X.3.1.10","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OW----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Wire Obstacle","HIERARCHY":"2.X.3.1.11","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OWU---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Unspecified","HIERARCHY":"2.X.3.1.11.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWS---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Single Fence","HIERARCHY":"2.X.3.1.11.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWD---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Fence","HIERARCHY":"2.X.3.1.11.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWA---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Apron Fence","HIERARCHY":"2.X.3.1.11.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Low Wire Fence","HIERARCHY":"2.X.3.1.11.5","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWH---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle High Wire Fence","HIERARCHY":"2.X.3.1.11.6","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWC---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Concertina","HIERARCHY":"2.X.3.1.11.7","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWCS--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Single Concertina","HIERARCHY":"2.X.3.1.11.7.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*OWCD--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Strand Concertina","HIERARCHY":"2.X.3.1.11.7.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*OWCT--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Triple Strand Concertina","HIERARCHY":"2.X.3.1.11.7.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Bypass","HIERARCHY":"2.X.3.2","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*BD----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Bypass Difficulty","HIERARCHY":"2.X.3.2.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass"},{"SYMBOLID":"G*M*BDE---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Easy","HIERARCHY":"2.X.3.2.1.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BDD---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Difficult","HIERARCHY":"2.X.3.2.1.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BDI---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Impossible","HIERARCHY":"2.X.3.2.1.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Crossing Site/Water Crossing","HIERARCHY":"2.X.3.2.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass"},{"SYMBOLID":"G*M*BCA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Assault Crossing Area","HIERARCHY":"2.X.3.2.2.1","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCB---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Bridge or Gap","HIERARCHY":"2.X.3.2.2.2","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCF---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Ferry","HIERARCHY":"2.X.3.2.2.3","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCE---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ford Easy","HIERARCHY":"2.X.3.2.2.4","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCD---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ford Difficult","HIERARCHY":"2.X.3.2.2.5","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCL---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Lane","HIERARCHY":"2.X.3.2.2.6","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCR---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Raft Site","HIERARCHY":"2.X.3.2.2.7","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Engineer Regulating Point","HIERARCHY":"2.X.3.2.2.8","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*S-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Survivability","HIERARCHY":"2.X.3.3","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*SE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Earthwork, Small Trench or Fortification","HIERARCHY":"2.X.3.3.1","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SF----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fort","HIERARCHY":"2.X.3.3.2","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SL----****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Fortified Line","HIERARCHY":"2.X.3.3.3","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SW----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Foxhole, Emplacement or Weapon Site","HIERARCHY":"2.X.3.3.4","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SP----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.T.","DESCRIPTION":"Strong Point","HIERARCHY":"2.X.3.3.5","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SS----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Shelter","HIERARCHY":"2.X.3.3.6","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SU----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underground Shelter","HIERARCHY":"2.X.3.3.7","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*N-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Nuclear, Biological, and Chemical","HIERARCHY":"2.X.3.4","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*NM----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Minimum Safe Distance Zones","HIERARCHY":"2.X.3.4.1","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NZ----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"C.H.N.Q.T.V.W.Y.","DESCRIPTION":"Nuclear Detonations Ground Zero","HIERARCHY":"2.X.3.4.2","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NF----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fallout Producing","HIERARCHY":"2.X.3.4.3","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NR----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Radioactive Area","HIERARCHY":"2.X.3.4.4","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NB----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Biologically Contaminated Area","HIERARCHY":"2.X.3.4.5","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NC----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Chemically Contaminated Area","HIERARCHY":"2.X.3.4.6","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NE----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Release Events","HIERARCHY":"2.X.3.4.7","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NEB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.Q.T.W.Y.","DESCRIPTION":"Biological Event","HIERARCHY":"2.X.3.4.7.1","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Release Events"},{"SYMBOLID":"G*M*NEC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.Q.T.W.Y.","DESCRIPTION":"Chemical Event","HIERARCHY":"2.X.3.4.7.2","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Release Events"},{"SYMBOLID":"G*M*ND----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Decontamination (DECON) Points","HIERARCHY":"2.X.3.4.8","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NDP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Unspecified","HIERARCHY":"2.X.3.4.8.1","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDA---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Alternate Decon Site/Point Unspecified","HIERARCHY":"2.X.3.4.8.2","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Troops","HIERARCHY":"2.X.3.4.8.3","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDE---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Equipment","HIERARCHY":"2.X.3.4.8.4","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Equipment and Troops","HIERARCHY":"2.X.3.4.8.5","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Operational Decontamination","HIERARCHY":"2.X.3.4.8.6","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Thorough Decontamination","HIERARCHY":"2.X.3.4.8.7","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NL----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Dose Rate Contour Lines","HIERARCHY":"2.X.3.4.9","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*F*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fire Support","HIERARCHY":"2.X.4","PATH":"Tactical Graphics"},{"SYMBOLID":"G*F*P-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.4.1","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*PT----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target","HIERARCHY":"2.X.4.1.1","PATH":"Tactical Graphics/Fire Support/Points"},{"SYMBOLID":"G*F*PTS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.H1.T.","DESCRIPTION":"Point/Single Target","HIERARCHY":"2.X.4.1.1.1","PATH":"Tactical Graphics/Fire Support/Points/Target"},{"SYMBOLID":"G*F*PTN---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Nuclear Target","HIERARCHY":"2.X.4.1.1.2","PATH":"Tactical Graphics/Fire Support/Points/Target"},{"SYMBOLID":"G*F*PC----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control","HIERARCHY":"2.X.4.1.2","PATH":"Tactical Graphics/Fire Support/Points"},{"SYMBOLID":"G*F*PCF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Fire Support Station","HIERARCHY":"2.X.4.1.2.1","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Survey Control Point","HIERARCHY":"2.X.4.1.2.2","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Firing Point","HIERARCHY":"2.X.4.1.2.3","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCR---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Reload Point","HIERARCHY":"2.X.4.1.2.4","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Hide Point","HIERARCHY":"2.X.4.1.2.5","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCL---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Launch Point","HIERARCHY":"2.X.4.1.2.6","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.4.2","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*LT----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Linear Target","HIERARCHY":"2.X.4.2.1","PATH":"Tactical Graphics/Fire Support/Lines"},{"SYMBOLID":"G*F*LTS---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Linear Smoke Target","HIERARCHY":"2.X.4.2.1.1","PATH":"Tactical Graphics/Fire Support/Lines/Linear Target"},{"SYMBOLID":"G*F*LTF---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.T1.","DESCRIPTION":"Final Protective Fire","HIERARCHY":"2.X.4.2.1.2","PATH":"Tactical Graphics/Fire Support/Lines/Linear Target"},{"SYMBOLID":"G*F*LC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control Lines","HIERARCHY":"2.X.4.2.2","PATH":"Tactical Graphics/Fire Support/Lines"},{"SYMBOLID":"G*F*LCF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Fire Support Coordination Line","HIERARCHY":"2.X.4.2.2.1","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Coordinated Fire Line (CFL)","HIERARCHY":"2.X.4.2.2.2","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCN---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"No-Fire Line (NFL)","HIERARCHY":"2.X.4.2.2.3","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Restrictive Fire Line (RFL)","HIERARCHY":"2.X.4.2.2.4","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"W.W1.","DESCRIPTION":"Munition Flight Path (MFP)","HIERARCHY":"2.X.4.2.2.5","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*A-----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.4.3","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*AT----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area Target","HIERARCHY":"2.X.4.3.1","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*ATR---****X","GEOMETRY":"area","DRAWCATEGORY":"17","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.AM.AN.","DESCRIPTION":"Rectangular Target","HIERARCHY":"2.X.4.3.1.1","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATC---****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.AM.","DESCRIPTION":"Circular Target","HIERARCHY":"2.X.4.3.1.2","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATG---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Group of Targets","HIERARCHY":"2.X.4.3.1.3","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATS---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.","DESCRIPTION":"Smoke Area","HIERARCHY":"2.X.4.3.1.4","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bomb Area","HIERARCHY":"2.X.4.3.1.5","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*AC----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control Areas","HIERARCHY":"2.X.4.3.2","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*ACS---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"T.W.W1.","DESCRIPTION":"Fire Support Area (FSA)","HIERARCHY":"2.X.4.3.2.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACSI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Fire Support Area (FSA) Irregular","HIERARCHY":"2.X.4.3.2.1.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACSR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.H.AM.","DESCRIPTION":"Fire Support Area (FSA) Rectangular","HIERARCHY":"2.X.4.3.2.1.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACSC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Fire Support Area (FSA) Circular","HIERARCHY":"2.X.4.3.2.1.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACA---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Airspace Coordination Area (ACA)","HIERARCHY":"2.X.4.3.2.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACAI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.H2.T.W.W1.","DESCRIPTION":"Airspace Coordination Area (ACA) Irregular","HIERARCHY":"2.X.4.3.2.2.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACAR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.H.H1.H2.W.W1.AM.","DESCRIPTION":"Airspace Coordination Area (ACA) Rectangular","HIERARCHY":"2.X.4.3.2.2.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACAC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.H.H1.H2.W.W1.AM.","DESCRIPTION":"Airspace Coordination Area (ACA) Circular","HIERARCHY":"2.X.4.3.2.2.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACF---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"T.W.W1.","DESCRIPTION":"Free Fire Area (FFA)","HIERARCHY":"2.X.4.3.2.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACFI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Free Fire Area (FFA) Irregular","HIERARCHY":"2.X.4.3.2.3.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACFR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Free Fire Area (FFA) Rectangular","HIERARCHY":"2.X.4.3.2.3.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACFC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Free Fire Area (FFA) Circular","HIERARCHY":"2.X.4.3.2.3.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACN---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"NFA Shapes","HIERARCHY":"2.X.4.3.2.4","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACNI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"No-Fire Area (NFA) Irregular","HIERARCHY":"2.X.4.3.2.4.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA) Shapes"},{"SYMBOLID":"G*F*ACNR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"No-Fire Area (NFA) Rectangular","HIERARCHY":"2.X.4.3.2.4.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA) Shapes"},{"SYMBOLID":"G*F*ACNC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"No-Fire Area (NFA) Circular","HIERARCHY":"2.X.4.3.2.4.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA) Shapes"},{"SYMBOLID":"G*F*ACR---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"RFA Shapes","HIERARCHY":"2.X.4.3.2.5","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACRI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Restrictive Fire Area (RFA) Irregular","HIERARCHY":"2.X.4.3.2.5.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA) Shapes"},{"SYMBOLID":"G*F*ACRR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Restrictive Fire Area (RFA) Rectangular","HIERARCHY":"2.X.4.3.2.5.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA) Shapes"},{"SYMBOLID":"G*F*ACRC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Restrictive Fire Area (RFA) Circular","HIERARCHY":"2.X.4.3.2.5.3","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA) Shapes"},{"SYMBOLID":"G*F*ACP---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Position Area for Artillery (PAA)","HIERARCHY":"2.X.4.3.2.6","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACPR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"AM.","DESCRIPTION":"Position Area for Artillery (PAA) Rectangular","HIERARCHY":"2.X.4.3.2.6.1","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Position Area for Artillery (PAA)"},{"SYMBOLID":"G*F*ACPC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"AM.","DESCRIPTION":"Position Area For Artillery (PAA) Circular","HIERARCHY":"2.X.4.3.2.6.2","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Position Area for Artillery (PAA)"},{"SYMBOLID":"G*F*AZ----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Acquisition Zones","HIERARCHY":"2.X.4.3.3","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*AZI---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"ATI Shapes","HIERARCHY":"2.X.4.3.3.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZII--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Irregular","HIERARCHY":"2.X.4.3.3.1.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI) Shapes"},{"SYMBOLID":"G*F*AZIR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Rectangular","HIERARCHY":"2.X.4.3.3.1.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI) Shapes"},{"SYMBOLID":"G*F*AZIC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Circular","HIERARCHY":"2.X.4.3.3.1.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI) Shapes"},{"SYMBOLID":"G*F*AZX---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Call for Fire Zone","HIERARCHY":"2.X.4.3.3.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZXI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Call For Fire Zone (CFFZ) Irregular","HIERARCHY":"2.X.4.3.3.2.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone"},{"SYMBOLID":"G*F*AZXR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Call For Fire Zone (CFFZ) Rectangular","HIERARCHY":"2.X.4.3.3.2.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone"},{"SYMBOLID":"G*F*AZXC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM","DESCRIPTION":"Call For Fire Zone (CFFZ) Circular","HIERARCHY":"2.X.4.3.3.2.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone"},{"SYMBOLID":"G*F*AZS---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Sensor Shapes","HIERARCHY":"2.X.4.3.3.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZSI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Sensor Zone Irregular","HIERARCHY":"2.X.4.3.3.3.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Sensor Zone Shapes"},{"SYMBOLID":"G*F*AZSR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Sensor Zone Rectangular","HIERARCHY":"2.X.4.3.3.3.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Sensor Zone Shapes"},{"SYMBOLID":"G*F*AZSC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Sensor Zone Circular","HIERARCHY":"2.X.4.3.3.3.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Sensor Zone Shapes"},{"SYMBOLID":"G*F*AZC---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Censor Shapes","HIERARCHY":"2.X.4.3.3.4","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZCI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Censor Zone Irregular","HIERARCHY":"2.X.4.3.3.4.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Shapes"},{"SYMBOLID":"G*F*AZCR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM","DESCRIPTION":"Censor Zone Rectangular","HIERARCHY":"2.X.4.3.3.4.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Shapes"},{"SYMBOLID":"G*F*AZCC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Censor Zone Circular","HIERARCHY":"2.X.4.3.3.4.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Shapes"},{"SYMBOLID":"G*F*AZD---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dead Space Area","HIERARCHY":"2.X.4.3.3.5","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZDI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Dead Space Area (DA) Irregular","HIERARCHY":"2.X.4.3.3.5.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Dead Space Area"},{"SYMBOLID":"G*F*AZDR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Dead Space Area (DA) Rectangular","HIERARCHY":"2.X.4.3.3.5.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Dead Space Area"},{"SYMBOLID":"G*F*AZDC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Dead Space Area (DA) Circular","HIERARCHY":"2.X.4.3.3.5.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Dead Space Area"},{"SYMBOLID":"G*F*AZF---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Critical Friendly Zone Shapes","HIERARCHY":"2.X.4.3.3.6","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZFI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Critical Friendly Zone (CFZ) Irregular","HIERARCHY":"2.X.4.3.3.6.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone Shapes"},{"SYMBOLID":"G*F*AZFR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Critical Friendly Zone (CFZ) Rectangular","HIERARCHY":"2.X.4.3.3.6.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone Shapes"},{"SYMBOLID":"G*F*AZFC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Critical Friendly Zone (CFZ) Circular","HIERARCHY":"2.X.4.3.3.6.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone Shapes"},{"SYMBOLID":"G*F*AZZ---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Zone of Responsibility","HIERARCHY":"2.X.4.3.3.7","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZZI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Zone Of Responsibility (ZOR) Irregular","HIERARCHY":"2.X.4.3.3.7.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Zone Of Responsibility (ZOR) "},{"SYMBOLID":"G*F*AZZR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Zone Of Responsibility (ZOR) Rectangular","HIERARCHY":"2.X.4.3.3.7.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Zone Of Responsibility (ZOR) "},{"SYMBOLID":"G*F*AZZC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Zone Of Responsibility (ZOR) Circular","HIERARCHY":"2.X.4.3.3.7.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Zone Of Responsibility (ZOR) "},{"SYMBOLID":"G*F*AZB---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Build-Up Area (TBA) ","HIERARCHY":"2.X.4.3.3.8","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZBI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Target Build-Up Area (TBA) Irregular","HIERARCHY":"2.X.4.3.3.8.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Build-Up Area (TBA) "},{"SYMBOLID":"G*F*AZBR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Target Build-Up Area (TBA) Rectangular","HIERARCHY":"2.X.4.3.3.8.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Build-Up Area (TBA) "},{"SYMBOLID":"G*F*AZBC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Target Build-Up Area (TBA) Circular","HIERARCHY":"2.X.4.3.3.8.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Build-Up Area (TBA) "},{"SYMBOLID":"G*F*AZV---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Value Area (TVAR) ","HIERARCHY":"2.X.4.3.3.9","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZVI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Target Value Area (TVAR) Irregular","HIERARCHY":"2.X.4.3.3.9.1","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Value Area (TVAR) "},{"SYMBOLID":"G*F*AZVR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Target Value Area (TVAR) Rectangular","HIERARCHY":"2.X.4.3.3.9.2","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Value Area (TVAR) "},{"SYMBOLID":"G*F*AZVC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Target Value Area (TVAR) Circular","HIERARCHY":"2.X.4.3.3.9.3","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Target Value Area (TVAR) "},{"SYMBOLID":"G*F*AX----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Radar Range Fans","HIERARCHY":"2.X.4.3.4","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*AXC---****X","GEOMETRY":"area","DRAWCATEGORY":"19","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.AM.","DESCRIPTION":"Circular Range Fan","HIERARCHY":"2.X.4.3.4.1","PATH":"Tactical Graphics/Fire Support/Areas/Radar Range Fans"},{"SYMBOLID":"G*F*AXS---****X","GEOMETRY":"area","DRAWCATEGORY":"18","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.AM.AN.","DESCRIPTION":"Sector Range Fan","HIERARCHY":"2.X.4.3.4.2","PATH":"Tactical Graphics/Fire Support/Areas/Radar Range Fans"},{"SYMBOLID":"G*S*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Combat Service Support","HIERARCHY":"2.X.5","PATH":"Tactical Graphics"},{"SYMBOLID":"G*S*P-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.5.1","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*PX----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.T1.W.W1.N.","DESCRIPTION":"Ambulance Exchange Point","HIERARCHY":"2.X.5.1.1","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PC----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Cannibalization Point","HIERARCHY":"2.X.5.1.2","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PY----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Casualty Collection Point","HIERARCHY":"2.X.5.1.3","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PT----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Civilian Collection Point","HIERARCHY":"2.X.5.1.4","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PD----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Detainee Collection Point","HIERARCHY":"2.X.5.1.5","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Enemy Prisoner of War Collection Point","HIERARCHY":"2.X.5.1.6","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PL----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Logistics Release Point","HIERARCHY":"2.X.5.1.7","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Maintenance Collection Point","HIERARCHY":"2.X.5.1.8","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PR----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Rearm, Refuel and Resupply Point","HIERARCHY":"2.X.5.1.9","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PU----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Refuel on the Move Point","HIERARCHY":"2.X.5.1.10","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Traffic Control Point (TCP)","HIERARCHY":"2.X.5.1.11","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PI----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Trailer Transfer Point","HIERARCHY":"2.X.5.1.12","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PN----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Unit Maintenance Collection Point","HIERARCHY":"2.X.5.1.13","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PS----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Supply Points","HIERARCHY":"2.X.5.1.14","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PSZ---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point General","HIERARCHY":"2.X.5.1.14.1","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSA---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class I","HIERARCHY":"2.X.5.1.14.2","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class II","HIERARCHY":"2.X.5.1.14.3","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class III","HIERARCHY":"2.X.5.1.14.4","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class IV","HIERARCHY":"2.X.5.1.14.5","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSE---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class V","HIERARCHY":"2.X.5.1.14.6","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VI","HIERARCHY":"2.X.5.1.14.7","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSG---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VII","HIERARCHY":"2.X.5.1.14.8","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VIII","HIERARCHY":"2.X.5.1.14.9","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSI---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class IX","HIERARCHY":"2.X.5.1.14.10","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSJ---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class X","HIERARCHY":"2.X.5.1.14.11","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PA----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ammunition Points","HIERARCHY":"2.X.5.1.15","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PAS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Ammunition Supply Point (ASP)","HIERARCHY":"2.X.5.1.15.1","PATH":"Tactical Graphics/Combat Service Support/Points/Ammunition Points"},{"SYMBOLID":"G*S*PAT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Ammunition Transfer Point (ATP)","HIERARCHY":"2.X.5.1.15.2","PATH":"Tactical Graphics/Combat Service Support/Points/Ammunition Points"},{"SYMBOLID":"G*S*PP----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.T1.W.W1.","DESCRIPTION":"Medevac Pick-Up Point","HIERARCHY":"2.X.5.1.16","ALPHAHIERARCHY":"TACGRP.CSS.PNT.MPP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.5.2","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*LC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Convoys","HIERARCHY":"2.X.5.2.1","PATH":"Tactical Graphics/Combat Service Support/Lines"},{"SYMBOLID":"G*S*LCM---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"A.H.H1.W.W1.","DESCRIPTION":"Moving Convoy","HIERARCHY":"2.X.5.2.1.1","PATH":"Tactical Graphics/Combat Service Support/Lines/Convoys"},{"SYMBOLID":"G*S*LCH---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"A.H.H1.W.W1.","DESCRIPTION":"Halted Convoy","HIERARCHY":"2.X.5.2.1.2","PATH":"Tactical Graphics/Combat Service Support/Lines/Convoys"},{"SYMBOLID":"G*S*LR----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Supply Routes","HIERARCHY":"2.X.5.2.2","PATH":"Tactical Graphics/Combat Service Support/Lines"},{"SYMBOLID":"G*S*LRM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Main Supply Route","HIERARCHY":"2.X.5.2.2.1","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRA---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Alternate Supply Route","HIERARCHY":"2.X.5.2.2.2","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRO---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route One-Way Traffic","HIERARCHY":"2.X.5.2.2.3","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRT---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route Alternating Traffic","HIERARCHY":"2.X.5.2.2.4","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRW---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route Two-Way Traffic","HIERARCHY":"2.X.5.2.2.5","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*A-----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Area","HIERARCHY":"2.X.5.3","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*AD----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Detainee Holding Area","HIERARCHY":"2.X.5.3.1","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AE----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Enemy Prisoner of War Holding Area","HIERARCHY":"2.X.5.3.2","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AR----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Forward Arming and Refueling Area","HIERARCHY":"2.X.5.3.3","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AH----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Refugee Holding Area","HIERARCHY":"2.X.5.3.4","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AS----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Support Areas","HIERARCHY":"2.X.5.3.5","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*ASB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Brigade Support Area (BSA)","HIERARCHY":"2.X.5.3.5.1","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*S*ASD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Division Support Area (DSA)","HIERARCHY":"2.X.5.3.5.2","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*S*ASR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Regimental Support Area (RSA)","HIERARCHY":"2.X.5.3.5.3","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*O*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Other","HIERARCHY":"2.X.6","PATH":"Tactical Graphics"},{"SYMBOLID":"G*O*E-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Emergency","HIERARCHY":"2.X.6.1","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*ED----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ditched Aircraft","HIERARCHY":"2.X.6.1.1","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*EP----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Person in Water","HIERARCHY":"2.X.6.1.2","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*ES----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.T1.H.W.W1.N.","DESCRIPTION":"Emergency Distress Call","HIERARCHY":"2.X.6.1.4","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*EV----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Distressed Vessel","HIERARCHY":"2.X.6.1.3","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*H-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hazard","HIERARCHY":"2.X.6.2","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*HM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Mine-Like Hazard","HIERARCHY":"2.X.6.2.1","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HN----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Navigational Hazard","HIERARCHY":"2.X.6.2.2","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HI----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Iceberg Hazard","HIERARCHY":"2.X.6.2.3","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Oil Rig Hazard","HIERARCHY":"2.X.6.2.4","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*S-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Sea Subsurface Returns","HIERARCHY":"2.X.6.3","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*SB----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bottom Return/Nombo","HIERARCHY":"2.X.6.3.1","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*SBM---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Installation/Manmade","HIERARCHY":"2.X.6.3.1.1","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Nombo"},{"SYMBOLID":"G*O*SBN---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Seabed Rock/Stone Obstacle","HIERARCHY":"2.X.6.3.1.2","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Nombo"},{"SYMBOLID":"G*O*SBW---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck, Nondangerous","HIERARCHY":"2.X.6.3.1.3","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Nombo"},{"SYMBOLID":"G*O*SBWD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck, Dangerous","HIERARCHY":"2.X.6.3.1.3.1","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Nombo/Wreck"},{"SYMBOLID":"G*O*SM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Marine Life","HIERARCHY":"2.X.6.3.2","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*SS----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Anomaly","HIERARCHY":"2.X.6.3.3","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line","HIERARCHY":"2.X.6.4","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*BE----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Electronic","HIERARCHY":"2.X.6.4.1","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BA----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Acoustic","HIERARCHY":"2.X.6.4.2","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BT----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Torpedo","HIERARCHY":"2.X.6.4.3","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BO----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Electro-Optical Intercept","HIERARCHY":"2.X.6.4.4","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*F-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fix","HIERARCHY":"2.X.6.5","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*FA----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Acoustic","HIERARCHY":"2.X.6.5.1","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"G*O*FE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Electro-Magnetic","HIERARCHY":"2.X.6.5.2","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"G*O*FO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Electro-Optical","HIERARCHY":"2.X.6.5.3","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"W--------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"METOC","HIERARCHY":"3.X"},{"SYMBOLID":"WA-------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Atmospheric","HIERARCHY":"3.X.1","PATH":"METOC"},{"SYMBOLID":"WA--P----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Pressure Systems","HIERARCHY":"3.X.1.1","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-PL----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Low Pressure Center","HIERARCHY":"3.X.1.1.1","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WAS-PC----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cyclone Center","HIERARCHY":"3.X.1.1.1.1","PATH":"METOC/Atmospheric/Pressure Systems/Low Pressure Center"},{"SYMBOLID":"WAS-PLT---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause Low","HIERARCHY":"3.X.1.1.1.2","PATH":"METOC/Atmospheric/Pressure Systems/Low Pressure Center"},{"SYMBOLID":"WAS-PH----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"High Pressure Center","HIERARCHY":"3.X.1.1.2","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WAS-PA----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Anticyclone Center","HIERARCHY":"3.X.1.1.2.1","PATH":"METOC/Atmospheric/Pressure Systems/High Pressure Center"},{"SYMBOLID":"WAS-PHT---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause High","HIERARCHY":"3.X.1.1.2.2","PATH":"METOC/Atmospheric/Pressure Systems/High Pressure Center"},{"SYMBOLID":"WA-DPF-----L---","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Frontal Systems","HIERARCHY":"3.X.1.1.3","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WA-DPFC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Front","HIERARCHY":"3.X.1.1.3.1","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFCU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Cold Front","HIERARCHY":"3.X.1.1.3.1.1","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFC-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Frontogenisis","HIERARCHY":"3.X.1.1.3.1.2","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFC-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Frontolysis","HIERARCHY":"3.X.1.1.3.1.3","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFW----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Front","HIERARCHY":"3.X.1.1.3.2","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFWU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Warm Front","HIERARCHY":"3.X.1.1.3.2.1","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFW-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Frontogenisis","HIERARCHY":"3.X.1.1.3.2.2","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFW-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Frontolysis","HIERARCHY":"3.X.1.1.3.2.3","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFO----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Occluded Front","HIERARCHY":"3.X.1.1.3.3","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFOU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Occluded Front","HIERARCHY":"3.X.1.1.3.3.1","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Occluded Front"},{"SYMBOLID":"WA-DPFO-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Occluded Frontolysis","HIERARCHY":"3.X.1.1.3.3.2","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Occluded Front"},{"SYMBOLID":"WA-DPFS----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Front","HIERARCHY":"3.X.1.1.3.4","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFSU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Stationary Front","HIERARCHY":"3.X.1.1.3.4.1","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA-DPFS-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Frontogenesis","HIERARCHY":"3.X.1.1.3.4.2","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA-DPFS-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Frontolysis","HIERARCHY":"3.X.1.1.3.4.3","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA--PX---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"3.X.1.1.4","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WA-DPXT----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Trough Axis","HIERARCHY":"3.X.1.1.4.1","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXR----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ridge Axis","HIERARCHY":"3.X.1.1.4.2","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXSQ---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Severe Squall Line","HIERARCHY":"3.X.1.1.4.3","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXIL---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Instability Line","HIERARCHY":"3.X.1.1.4.4","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXSH---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Shear Line","HIERARCHY":"3.X.1.1.4.5","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXITCZ-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Inter-Tropical Convergance Zone","HIERARCHY":"3.X.1.1.4.6","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXCV---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Convergance Line","HIERARCHY":"3.X.1.1.4.7","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXITD--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Inter-Tropical Discontinuity","HIERARCHY":"3.X.1.1.4.8","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WAS-T----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Turbulence","HIERARCHY":"3.X.1.2","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-TL----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Turbulence","HIERARCHY":"3.X.1.2.1","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TM----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Turbulence","HIERARCHY":"3.X.1.2.2","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TS----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Turbulence","HIERARCHY":"3.X.1.2.3","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TE----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Extreme Turbulence","HIERARCHY":"3.X.1.2.4","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-T-MW--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mountain Waves","HIERARCHY":"3.X.1.2.5","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-I----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Icing","HIERARCHY":"3.X.1.3","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-IC----P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Clear Icing","HIERARCHY":"3.X.1.3.1","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-ICL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Clear Icing","HIERARCHY":"3.X.1.3.1.1","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-ICM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Clear Icing","HIERARCHY":"3.X.1.3.1.2","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-ICS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Clear Icing","HIERARCHY":"3.X.1.3.1.3","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-IR-----P---","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rime Icing","HIERARCHY":"3.X.1.3.2","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-IRL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rime Icing","HIERARCHY":"3.X.1.3.2.1","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IRM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Rime Icing","HIERARCHY":"3.X.1.3.2.2","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IRS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Rime Icing","HIERARCHY":"3.X.1.3.2.3","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IM-----P---","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mixed Icing","HIERARCHY":"3.X.1.3.3","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-IML---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Mixed Icing","HIERARCHY":"3.X.1.3.3.1","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WAS-IMM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Mixed Icing","HIERARCHY":"3.X.1.3.3.2","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WAS-IMS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Mixed Icing","HIERARCHY":"3.X.1.3.3.3","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WA--W----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Winds","HIERARCHY":"3.X.1.4","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-WC----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Calm Winds","HIERARCHY":"3.X.1.4.1","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WAS-WP----P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"Z.Q.","DESCRIPTION":"Wind Plot","HIERARCHY":"3.X.1.4.2","ALPHAHIERARCHY":"METOC.AMPHC.WND.PLT","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA-DWJ-----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jet Stream","HIERARCHY":"3.X.1.4.3","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA-DWS-----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stream Line","HIERARCHY":"3.X.1.4.4","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA--CC---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Cloud Coverage","HIERARCHY":"3.X.1.5","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA--CCCS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Cloud Coverage Symbols","HIERARCHY":"3.X.1.5.1","PATH":"METOC/Atmospheric/Cloud Coverage"},{"SYMBOLID":"WAS-CCCSCSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Clear Sky","HIERARCHY":"3.X.1.5.1.1","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSFCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Few Coverage","HIERARCHY":"3.X.1.5.1.2","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSSCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Scattered Coverage","HIERARCHY":"3.X.1.5.1.3","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSBCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Broken Coverage","HIERARCHY":"3.X.1.5.1.4","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSOCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Overcast Coverage","HIERARCHY":"3.X.1.5.1.5","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSOBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sky Totally or Partially Obscured","HIERARCHY":"3.X.1.5.1.6","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WA--WS---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Weather Symbols","HIERARCHY":"3.X.1.6","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-WSR--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain","HIERARCHY":"3.X.1.6.1","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSR-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Rain","HIERARCHY":"3.X.1.6.1.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Rain","HIERARCHY":"3.X.1.6.1.1.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Light Rain"},{"SYMBOLID":"WAS-WSR-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Rain","HIERARCHY":"3.X.1.6.1.2","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Rain","HIERARCHY":"3.X.1.6.1.2.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Moderate Rain"},{"SYMBOLID":"WAS-WSR-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Rain","HIERARCHY":"3.X.1.6.1.3","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Rain","HIERARCHY":"3.X.1.6.1.3.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Heavy Rain"},{"SYMBOLID":"WAS-WSRF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Freezing Rain","HIERARCHY":"3.X.1.6.2","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSRFL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Freezing Rain","HIERARCHY":"3.X.1.6.2.1","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Rain"},{"SYMBOLID":"WAS-WSRFMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Freezing Rain","HIERARCHY":"3.X.1.6.2.2","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Rain"},{"SYMBOLID":"WAS-WSRS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain Showers","HIERARCHY":"3.X.1.6.3","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSRSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain Showers","HIERARCHY":"3.X.1.6.3.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSRSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Rain Showers","HIERARCHY":"3.X.1.6.3.2","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSRST-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Torrential Rain Showers","HIERARCHY":"3.X.1.6.3.3","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSD--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Drizzle","HIERARCHY":"3.X.1.6.4","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSD-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Drizzle","HIERARCHY":"3.X.1.6.4.1","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Drizzle","HIERARCHY":"3.X.1.6.4.1.1","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Light Drizzle"},{"SYMBOLID":"WAS-WSD-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Drizzle","HIERARCHY":"3.X.1.6.4.2","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Drizzle","HIERARCHY":"3.X.1.6.4.2.1","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Moderate Drizzle"},{"SYMBOLID":"WAS-WSD-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Drizzle","HIERARCHY":"3.X.1.6.4.3","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Drizzle","HIERARCHY":"3.X.1.6.4.3.1","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Heavy Drizzle"},{"SYMBOLID":"WAS-WSDF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Freezing Drizzle","HIERARCHY":"3.X.1.6.5","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSDFL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Freezing Drizzle","HIERARCHY":"3.X.1.6.5.1","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Drizzle"},{"SYMBOLID":"WAS-WSDFMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Freezing Drizzle","HIERARCHY":"3.X.1.6.5.2","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Drizzle"},{"SYMBOLID":"WAS-WSM--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain and Snow Mixed","HIERARCHY":"3.X.1.6.6","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSM-L-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain or Drizzle and Snow","HIERARCHY":"3.X.1.6.6.1","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSM-MHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Heavy Rain or Drizzle and Snow","HIERARCHY":"3.X.1.6.6.2","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSMSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain and Snow Showers","HIERARCHY":"3.X.1.6.6.3","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSMSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Rain and Snow Showers","HIERARCHY":"3.X.1.6.6.4","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSS--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Snow","HIERARCHY":"3.X.1.6.7","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSS-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Snow","HIERARCHY":"3.X.1.6.7.1","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Snow","HIERARCHY":"3.X.1.6.7.1.1","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Light Snow"},{"SYMBOLID":"WAS-WSS-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Snow","HIERARCHY":"3.X.1.6.7.2","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Snow","HIERARCHY":"3.X.1.6.7.2.1","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Moderate Snow"},{"SYMBOLID":"WAS-WSS-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Snow","HIERARCHY":"3.X.1.6.7.3","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Snow","HIERARCHY":"3.X.1.6.7.3.1","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Heavy Snow"},{"SYMBOLID":"WAS-WSSBLMP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light/Moderate Blowing Snow","HIERARCHY":"3.X.1.6.7.4","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSSBH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Heavy Blowing Snow","HIERARCHY":"3.X.1.6.7.5","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSSG--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Grains","HIERARCHY":"3.X.1.6.8","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSSS--P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Snow Showers","HIERARCHY":"3.X.1.6.9","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSSSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Snow Showers","HIERARCHY":"3.X.1.6.9.1","PATH":"METOC/Atmospheric/Weather Symbols/Snow Showers"},{"SYMBOLID":"WAS-WSSSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Snow Showers","HIERARCHY":"3.X.1.6.9.2","PATH":"METOC/Atmospheric/Weather Symbols/Snow Showers"},{"SYMBOLID":"WAS-WSGR-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hail","HIERARCHY":"3.X.1.6.10","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSGRL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hail - Light not Associated With Thunder","HIERARCHY":"3.X.1.6.10.1","PATH":"METOC/Atmospheric/Weather Symbols/Hail"},{"SYMBOLID":"WAS-WSGRMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hail - Moderate/Heavy not Associated With Thunder","HIERARCHY":"3.X.1.6.10.2","PATH":"METOC/Atmospheric/Weather Symbols/Hail"},{"SYMBOLID":"WAS-WSIC--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Crystals","HIERARCHY":"3.X.1.6.11","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSPL-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Pellets","HIERARCHY":"3.X.1.6.12","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSPLL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Ice Pellets","HIERARCHY":"3.X.1.6.12.1","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WSPLM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Ice Pellets","HIERARCHY":"3.X.1.6.12.2","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WSPLH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Heavy Ice Pellets","HIERARCHY":"3.X.1.6.12.3","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WST--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Storms","HIERARCHY":"3.X.1.6.13","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WST-NPP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm - No Precipitation","HIERARCHY":"3.X.1.6.13.1","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTMR-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Light to Moderate With Rain/Snow - No Hail","HIERARCHY":"3.X.1.6.13.2","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTHR-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Heavy With Rain/Snow - No Hail","HIERARCHY":"3.X.1.6.13.3","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTMH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Light to Moderate - With Hail","HIERARCHY":"3.X.1.6.13.4","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTHH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Heavy - With Hail","HIERARCHY":"3.X.1.6.13.5","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-FCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Funnel Cloud (Tornado/Waterspout)","HIERARCHY":"3.X.1.6.13.6","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-SQP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Squall","HIERARCHY":"3.X.1.6.13.7","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-LGP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lightning","HIERARCHY":"3.X.1.6.13.8","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSFG-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fog","HIERARCHY":"3.X.1.6.14","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSFGPSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Shallow Patches","HIERARCHY":"3.X.1.6.14.1","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGCSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Shallow Continuous","HIERARCHY":"3.X.1.6.14.2","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGP-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Patchy","HIERARCHY":"3.X.1.6.14.3","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGSVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Sky Visible","HIERARCHY":"3.X.1.6.14.4","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGSOP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Sky Obscured","HIERARCHY":"3.X.1.6.14.5","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGFVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Freezing, Sky Visible","HIERARCHY":"3.X.1.6.14.6","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGFOP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Freezing, Sky Not Visible","HIERARCHY":"3.X.1.6.14.7","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSBR--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mist","HIERARCHY":"3.X.1.6.15","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSFU--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Smoke Point","HIERARCHY":"3.X.1.6.16","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSHZ--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Haze","HIERARCHY":"3.X.1.6.17","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS--SD--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dust or Sand","HIERARCHY":"3.X.1.6.18","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSDSLMP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light to Moderate Dust/Sand Storm","HIERARCHY":"3.X.1.6.18.1","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDSS-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Dust/Sand Storm","HIERARCHY":"3.X.1.6.18.2","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDD--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dust Devil","HIERARCHY":"3.X.1.6.18.3","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Blowing Dust or Sand","HIERARCHY":"3.X.1.6.18.4","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSTS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tropical Storm Systems","HIERARCHY":"3.X.1.6.19","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSTSD-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Depression","HIERARCHY":"3.X.1.6.19.1","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSTSS-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Storm","HIERARCHY":"3.X.1.6.19.2","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSTSH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hurricane/Typhoon","HIERARCHY":"3.X.1.6.19.3","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSVE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Eruption","HIERARCHY":"3.X.1.6.20","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSVA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Ash","HIERARCHY":"3.X.1.6.20.1","PATH":"METOC/Atmospheric/Weather Symbols/Volcanic Eruption"},{"SYMBOLID":"WAS-WST-LVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause Level","HIERARCHY":"3.X.1.6.21","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSF-LVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Freezing Level","HIERARCHY":"3.X.1.6.22","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSUKP-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Precipiation of Unknown Type and Intensity","HIERARCHY":"3.X.1.6.23","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WA--BA---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bounded Areas of Weather","HIERARCHY":"3.X.1.7","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA-DBAIF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"IFR","HIERARCHY":"3.X.1.7.1","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAMV----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"MVFR","HIERARCHY":"3.X.1.7.2","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBATB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Turbulence","HIERARCHY":"3.X.1.7.3","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAI-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Icing","HIERARCHY":"3.X.1.7.4","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBALPNC--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Precipiation Non-Convective","HIERARCHY":"3.X.1.7.5","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBALPC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Precipitation Convective","HIERARCHY":"3.X.1.7.5.1","PATH":"METOC/Atmospheric/Bounded Areas of Weather/Precipiation Non-Convective"},{"SYMBOLID":"WA-DBAFP----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Frozen Precipitation","HIERARCHY":"3.X.1.7.6","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAT-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Thunderstorm","HIERARCHY":"3.X.1.7.7","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAFG----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Weather Fog","HIERARCHY":"3.X.1.7.8","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAD-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Weather Sand","HIERARCHY":"3.X.1.7.9","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAFF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Freeform","HIERARCHY":"3.X.1.7.10","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA--IP---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Isopleths","HIERARCHY":"3.X.1.8","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA-DIPIB---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isobar Surface","HIERARCHY":"3.X.1.8.1","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPCO---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Air","HIERARCHY":"3.X.1.8.2","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPIS---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isotherm","HIERARCHY":"3.X.1.8.3","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPIT---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isotach","HIERARCHY":"3.X.1.8.4","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPID---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isodrosotherm","HIERARCHY":"3.X.1.8.5","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPTH---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isopleths Thickness","HIERARCHY":"3.X.1.8.6","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPFF---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Operator Freeform","HIERARCHY":"3.X.1.8.7","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WAS-G----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"State of the Ground","HIERARCHY":"3.X.1.9","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-GN---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Without Snow or Measureable Ice Cover","HIERARCHY":"3.X.1.9.1","PATH":"METOC/Atmospheric/State of the Ground"},{"SYMBOLID":"WAS-GND-NCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Sand","HIERARCHY":"3.X.1.9.1.1","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Moist","HIERARCHY":"3.X.1.9.1.2","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNW-SWP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Wet, Standing Water in Small or Large Pools","HIERARCHY":"3.X.1.9.1.3","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNFL--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Flooded","HIERARCHY":"3.X.1.9.1.4","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNFZ--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Frozen","HIERARCHY":"3.X.1.9.1.5","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNG-TIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Glaze (Thin Ice) on Ground","HIERARCHY":"3.X.1.9.1.6","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDN-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Dust or Sand not Covering Ground Completely","HIERARCHY":"3.X.1.9.1.7","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDTCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thin Loose Dry Dust or Sand Covering Ground Completely","HIERARCHY":"3.X.1.9.1.8","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDMCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Thick Loose Dry Dust or Sand Covering Ground Completely","HIERARCHY":"3.X.1.9.1.9","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNDEWCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Extremely Dry With Cracks","HIERARCHY":"3.X.1.9.1.10","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GS---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"With Snow or Measureable Ice Cover","HIERARCHY":"3.X.1.9.2","PATH":"METOC/Atmospheric/State of the Ground"},{"SYMBOLID":"WAS-GSI---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Predominately Ice Covered","HIERARCHY":"3.X.1.9.2.1","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering Less than One-Hald of Ground","HIERARCHY":"3.X.1.9.2.2","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Compact or Wet Snow Covering At Least One-Half Ground, but Ground not Completely Covered","HIERARCHY":"3.X.1.9.2.3","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCCEP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Even Layer of Compact or Wet Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.4","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCCUP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Uneven Layer of Compact or Wet Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.5","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Snow Covering Less than One-Half of Ground","HIERARCHY":"3.X.1.9.2.6","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Snow Covering at Least One-Half Ground, but not Completely Covered","HIERARCHY":"3.X.1.9.2.7","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLCEP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Even Layer of Loose Dry Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.8","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLCUP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Uneven Layer of Loose Dry Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.9","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSDC-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Covering Ground Completely, Deep Drifts","HIERARCHY":"3.X.1.9.2.10","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WO-------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Oceanic","HIERARCHY":"3.X.2","PATH":"METOC"},{"SYMBOLID":"WO--I----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Systems","HIERARCHY":"3.X.2.1","PATH":"METOC/Oceanic"},{"SYMBOLID":"WOS-IB----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Icebergs","HIERARCHY":"3.X.2.1.1","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IBM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Icebergs","HIERARCHY":"3.X.2.1.1.1","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Belts and Strips","HIERARCHY":"3.X.2.1.1.2","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBG---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Iceberg - General","HIERARCHY":"3.X.2.1.1.3","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBMG--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Icebergs - General","HIERARCHY":"3.X.2.1.1.4","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bergy Bit","HIERARCHY":"3.X.2.1.1.5","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBBM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Bergy Bits","HIERARCHY":"3.X.2.1.1.6","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBGL--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Growler","HIERARCHY":"3.X.2.1.1.7","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBGLM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Growlers","HIERARCHY":"3.X.2.1.1.8","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBF---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Floeberg","HIERARCHY":"3.X.2.1.1.9","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBII--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Island","HIERARCHY":"3.X.2.1.1.10","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IC---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Concentration","HIERARCHY":"3.X.2.1.2","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ICWB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bergy Water","HIERARCHY":"3.X.2.1.2.1","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ICWR--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Water With Radar Targets","HIERARCHY":"3.X.2.1.2.2","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ICIF--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Free","HIERARCHY":"3.X.2.1.2.3","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ID---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dynamic Processes","HIERARCHY":"3.X.2.1.3","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IDC---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Convergence","HIERARCHY":"3.X.2.1.3.1","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-IDD---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Divergence","HIERARCHY":"3.X.2.1.3.2","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-IDS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Shearing or Shear Zone","HIERARCHY":"3.X.2.1.3.3","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WO-DIDID---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Drift (Direction)","HIERARCHY":"3.X.2.1.3.4","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-II----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Ice","HIERARCHY":"3.X.2.1.4","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IITM--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Thickness (Observed)","HIERARCHY":"3.X.2.1.4.1","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WOS-IITE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Thickness (Estimated)","HIERARCHY":"3.X.2.1.4.2","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WOS-IIP---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Melt Puddles or Flooded Ice","HIERARCHY":"3.X.2.1.4.3","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WO--IL---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Limits","HIERARCHY":"3.X.2.1.5","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WO-DILOV---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Visual Observation","HIERARCHY":"3.X.2.1.5.1","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILUC---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Undercast","HIERARCHY":"3.X.2.1.5.2","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILOR---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Radar Observation","HIERARCHY":"3.X.2.1.5.3","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIEO--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Observed Ice Edge","HIERARCHY":"3.X.2.1.5.4","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIEE--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Estimated Ice Edge","HIERARCHY":"3.X.2.1.5.5","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIER--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ice Edge From Radar","HIERARCHY":"3.X.2.1.5.6","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO--IO---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Openings in the Ice","HIERARCHY":"3.X.2.1.6","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WO-DIOC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cracks","HIERARCHY":"3.X.2.1.6.1","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOCS---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cracks Specific-Location","HIERARCHY":"3.X.2.1.6.2","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOL----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ice Openings-Lead","HIERARCHY":"3.X.2.1.6.3","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOLF---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Frozen Lead","HIERARCHY":"3.X.2.1.6.4","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WOS-ISC---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Cover","HIERARCHY":"3.X.2.1.7","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ISS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sastrugi","HIERARCHY":"3.X.2.1.7.1","PATH":"METOC/Oceanic/Ice Systems/Snow Cover"},{"SYMBOLID":"WOS-IT---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Topographical Features","HIERARCHY":"3.X.2.1.8","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ITRH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ridges or Hummocks","HIERARCHY":"3.X.2.1.8.1","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WOS-ITR---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rafting","HIERARCHY":"3.X.2.1.8.2","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WOS-ITBB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Jammed Brash Barrier","HIERARCHY":"3.X.2.1.8.3","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WO--H----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hydrography","HIERARCHY":"3.X.2.2","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--HD---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Depth","HIERARCHY":"3.X.2.2.1","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HDS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Soundings","HIERARCHY":"3.X.2.2.1.1","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDL---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Depth Curve","HIERARCHY":"3.X.2.2.1.2","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDC---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Depth Contour","HIERARCHY":"3.X.2.2.1.3","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Depth Area","HIERARCHY":"3.X.2.2.1.4","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO--HC---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Coastal Hydrography","HIERARCHY":"3.X.2.2.2","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WO-DHCC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Coastline","HIERARCHY":"3.X.2.2.2.1","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCI-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Island","HIERARCHY":"3.X.2.2.2.2","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCB-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach","HIERARCHY":"3.X.2.2.2.3","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCW-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Water","HIERARCHY":"3.X.2.2.2.4","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCF--------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Foreshore","HIERARCHY":"3.X.2.2.2.5","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCF----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Foreshore Line","HIERARCHY":"3.X.2.2.2.5.1","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography/Foreshore"},{"SYMBOLID":"WO-DHCF-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Foreshore Area","HIERARCHY":"3.X.2.2.2.5.2","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography/Foreshore"},{"SYMBOLID":"WO-DHP---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ports and Harbors","HIERARCHY":"3.X.2.2.3","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WO--HPB--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ports","HIERARCHY":"3.X.2.2.3.1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WOS-HPB-O-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Berths (Onshore)","HIERARCHY":"3.X.2.2.3.1.1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPB-A-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Berths (Anchor)","HIERARCHY":"3.X.2.2.3.1.2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPBA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Anchorage","HIERARCHY":"3.X.2.2.3.1.3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBA---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Anchorage Line","HIERARCHY":"3.X.2.2.3.1.4","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Anchorage Area","HIERARCHY":"3.X.2.2.3.1.5","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPCP--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Call in Point","HIERARCHY":"3.X.2.2.3.1.6","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBP---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Pier","HIERARCHY":"3.X.2.2.3.1.7","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPF--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fishing","HIERARCHY":"3.X.2.2.3.2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WOS-HPFH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fishing Harbor","HIERARCHY":"3.X.2.2.3.2.1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fish Stakes/Traps/Weirs","HIERARCHY":"3.X.2.2.3.2.2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFS---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fish Stakes","HIERARCHY":"3.X.2.2.3.2.3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Wiers","HIERARCHY":"3.X.2.2.3.2.4","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WO--HPM--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Facilities","HIERARCHY":"3.X.2.2.3.3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WO-DHPMD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Drydock","HIERARCHY":"3.X.2.2.3.3.1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPML--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Landing Place","HIERARCHY":"3.X.2.2.3.3.2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Offshore Loading Facility 1","HIERARCHY":"3.X.2.2.3.3.3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Offshore Loading Facility 2","HIERARCHY":"3.X.2.2.3.3.4","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Offshore Loading Facility Area","HIERARCHY":"3.X.2.2.3.3.5","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMRA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ramp Above Water","HIERARCHY":"3.X.2.2.3.3.6","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMRB--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ramp Below Water","HIERARCHY":"3.X.2.2.3.3.7","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-R-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Landing Ring","HIERARCHY":"3.X.2.2.3.3.8","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-FC-L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ferry Crossing","HIERARCHY":"3.X.2.2.3.3.9","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-CC-L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cable Ferry Crossing","HIERARCHY":"3.X.2.2.3.3.10","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPD---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dolphin","HIERARCHY":"3.X.2.2.3.3.11","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPSP-------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Shoreline Protection","HIERARCHY":"3.X.2.2.3.4","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WO-DHPSPA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jetty Above Water","HIERARCHY":"3.X.2.2.3.4.1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO-DHPSPB--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jetty Below Water","HIERARCHY":"3.X.2.2.3.4.2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO-DHPSPS--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Seawall","HIERARCHY":"3.X.2.2.3.4.3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO--HA---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Aids to Navigation","HIERARCHY":"3.X.2.2.4","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HABA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Beacon","HIERARCHY":"3.X.2.2.4.1","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Buoy Default","HIERARCHY":"3.X.2.2.4.2","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABM--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Marker","HIERARCHY":"3.X.2.2.4.3","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WO--HABP-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Perches/Stakes","HIERARCHY":"3.X.2.2.4.4","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABP--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Perches/Stakes","HIERARCHY":"3.X.2.2.4.4.1","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation/Perches-Stakes"},{"SYMBOLID":"WO-DHABP----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Perches","HIERARCHY":"3.X.2.2.4.4.2","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation/Perches-Stakes"},{"SYMBOLID":"WOS-HAL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light","HIERARCHY":"3.X.2.2.4.5","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WO-DHALLA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Leading Line","HIERARCHY":"3.X.2.2.4.6","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HALV--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Vessel/Lightship","HIERARCHY":"3.X.2.2.4.7","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HALH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lighthouse","HIERARCHY":"3.X.2.2.4.8","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WO--HH---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dangers/Hazards","HIERARCHY":"3.X.2.2.5","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HHRS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock Submerged","HIERARCHY":"3.X.2.2.5.1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHRA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock Awashed","HIERARCHY":"3.X.2.2.5.2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHD-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Underwater Hazard","HIERARCHY":"3.X.2.2.5.3","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO--HHDF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Foul Ground","HIERARCHY":"3.X.2.2.5.4","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDF--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Foul Ground Point","HIERARCHY":"3.X.2.2.5.4.1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Foul Ground"},{"SYMBOLID":"WO-DHHDF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Foul Ground Area","HIERARCHY":"3.X.2.2.5.4.2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Foul Ground"},{"SYMBOLID":"WO-DHHDK-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Kelp/Seaweed","HIERARCHY":"3.X.2.2.5.5","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDK--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Kelp/Seaweed Point","HIERARCHY":"3.X.2.2.5.5.1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDK----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Kelp/Seaweed Area","HIERARCHY":"3.X.2.2.5.5.2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Kelp-Seaweed"},{"SYMBOLID":"WOS-HHDMD------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mine-Naval","HIERARCHY":"3.X.2.2.5.6","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDMDBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mine-Naval (Doubtful)","HIERARCHY":"3.X.2.2.5.6.1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Mine-Naval"},{"SYMBOLID":"WOS-HHDMDFP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mine-Naval (Definite)","HIERARCHY":"3.X.2.2.5.6.2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Mine-Naval"},{"SYMBOLID":"WOS-HHDS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snags/Stumps","HIERARCHY":"3.X.2.2.5.7","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDW--P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Wreck","HIERARCHY":"3.X.2.2.5.8","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDWA-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck (Uncovers)","HIERARCHY":"3.X.2.2.5.8.1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Wreck"},{"SYMBOLID":"WOS-HHDWB-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck (Submerged)","HIERARCHY":"3.X.2.2.5.8.2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Wreck"},{"SYMBOLID":"WO-DHHDB---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Breaker","HIERARCHY":"3.X.2.2.5.9","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDR---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Reef","HIERARCHY":"3.X.2.2.5.10","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Eddies/Overfalls/Tide Rips","HIERARCHY":"3.X.2.2.5.11","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Discolored Water","HIERARCHY":"3.X.2.2.5.12","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO--BF---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Features","HIERARCHY":"3.X.2.2.6","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-BFC--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Characteristics","HIERARCHY":"3.X.2.2.6.1","PATH":"METOC/Oceanic/Hydrography/Bottom Features"},{"SYMBOLID":"WOS-BFC-S-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sand","HIERARCHY":"3.X.2.2.6.1.1","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-M-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mud","HIERARCHY":"3.X.2.2.6.1.2","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-CLP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Clay","HIERARCHY":"3.X.2.2.6.1.3","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-SIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Silt","HIERARCHY":"3.X.2.2.6.1.4","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-STP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Stones","HIERARCHY":"3.X.2.2.6.1.5","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-G-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Gravel","HIERARCHY":"3.X.2.2.6.1.6","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-P-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pebbles","HIERARCHY":"3.X.2.2.6.1.7","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-CBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cobbles","HIERARCHY":"3.X.2.2.6.1.8","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-R-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock","HIERARCHY":"3.X.2.2.6.1.9","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-COP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Coral","HIERARCHY":"3.X.2.2.6.1.10","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-SHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Shell","HIERARCHY":"3.X.2.2.6.1.11","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFQ--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Qualifying Terms","HIERARCHY":"3.X.2.2.6.2","PATH":"METOC/Oceanic/Hydrography/Bottom Features"},{"SYMBOLID":"WOS-BFQ-F-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fine","HIERARCHY":"3.X.2.2.6.2.1","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WOS-BFQ-M-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Medium","HIERARCHY":"3.X.2.2.6.2.2","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WOS-BFQ-C-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Coarse","HIERARCHY":"3.X.2.2.6.2.3","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WO--TCC--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tide and Current","HIERARCHY":"3.X.2.2.7","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-TCCW--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Water Turbulence","HIERARCHY":"3.X.2.2.7.1","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO-DTCCCFE-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ebb Tide","HIERARCHY":"3.X.2.2.7.2","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO-DTCCCFF-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Flood Tide","HIERARCHY":"3.X.2.2.7.3","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WOS-TCCTD-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tide Data Point","HIERARCHY":"3.X.2.2.7.4","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WOS-TCCTG-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tide Gauge","HIERARCHY":"3.X.2.2.7.5","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO--O----------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Oceanography","HIERARCHY":"3.X.2.3","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--OB---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bioluminescence","HIERARCHY":"3.X.2.3.1","PATH":"METOC/Oceanic/Oceanography"},{"SYMBOLID":"WO-DOBVA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 1-2","HIERARCHY":"3.X.2.3.1.1","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 2-3","HIERARCHY":"3.X.2.3.1.2","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVC----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 3-4","HIERARCHY":"3.X.2.3.1.3","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 4-5","HIERARCHY":"3.X.2.3.1.4","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVE----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 5-6","HIERARCHY":"3.X.2.3.1.5","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 6-7","HIERARCHY":"3.X.2.3.1.6","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVG----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 7-8","HIERARCHY":"3.X.2.3.1.7","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVH----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 8-9","HIERARCHY":"3.X.2.3.1.8","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVI----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 9-10","HIERARCHY":"3.X.2.3.1.9","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO--BS---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Beach Slope","HIERARCHY":"3.X.2.3.2","PATH":"METOC/Oceanic/Oceanography"},{"SYMBOLID":"WO-DBSF-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Flat","HIERARCHY":"3.X.2.3.2.1","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBSG-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Gentle","HIERARCHY":"3.X.2.3.2.2","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBSM-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Moderate","HIERARCHY":"3.X.2.3.2.3","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBST-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Steep","HIERARCHY":"3.X.2.3.2.4","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO--G----------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Geophysics/Acoustics","HIERARCHY":"3.X.2.4","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--GM---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mine Warefare Bottom Descriptors","HIERARCHY":"3.X.2.4.1","PATH":"METOC/Oceanic/Geophysics-Acoustics"},{"SYMBOLID":"WO--GMS--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw-Bottom Sediments","HIERARCHY":"3.X.2.4.1.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMSR----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Solid Rock","HIERARCHY":"3.X.2.4.1.1.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSC----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clay","HIERARCHY":"3.X.2.4.1.1.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSVS--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Course Sand","HIERARCHY":"3.X.2.4.1.1.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Coarse Sand","HIERARCHY":"3.X.2.4.1.1.4","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSM---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Medium Sand","HIERARCHY":"3.X.2.4.1.1.5","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Fine Sand","HIERARCHY":"3.X.2.4.1.1.6","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSVF--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Fine Sand","HIERARCHY":"3.X.2.4.1.1.7","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIVF--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Fine Silt","HIERARCHY":"3.X.2.4.1.1.8","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Fine Silt","HIERARCHY":"3.X.2.4.1.1.9","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIM---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Medium Silt","HIERARCHY":"3.X.2.4.1.1.10","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Coarse Silt","HIERARCHY":"3.X.2.4.1.1.11","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Boulders","HIERARCHY":"3.X.2.4.1.1.12","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-CO--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Oyster Shells","HIERARCHY":"3.X.2.4.1.1.13","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-PH--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Pebbles Shells","HIERARCHY":"3.X.2.4.1.1.14","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-SH--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Sand and Shells","HIERARCHY":"3.X.2.4.1.1.15","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGML-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Sediments Land 1","HIERARCHY":"3.X.2.4.1.1.16","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMN-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Sediments Land 2","HIERARCHY":"3.X.2.4.1.1.17","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMR--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Roughness","HIERARCHY":"3.X.2.4.1.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMRS----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Smooth","HIERARCHY":"3.X.2.4.1.2.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMRM----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Moderate","HIERARCHY":"3.X.2.4.1.2.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMRR----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Rough","HIERARCHY":"3.X.2.4.1.2.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMC--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Clutter Low","HIERARCHY":"3.X.2.4.1.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMCL----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter Low","HIERARCHY":"3.X.2.4.1.3.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMCM----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter Medium","HIERARCHY":"3.X.2.4.1.3.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMCH----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter High","HIERARCHY":"3.X.2.4.1.3.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMIB-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Impact Burial","HIERARCHY":"3.X.2.4.1.4","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMIBA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 0","HIERARCHY":"3.X.2.4.1.4.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 10","HIERARCHY":"3.X.2.4.1.4.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 20","HIERARCHY":"3.X.2.4.1.4.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBD---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 75","HIERARCHY":"3.X.2.4.1.4.4","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBE---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 100","HIERARCHY":"3.X.2.4.1.4.5","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMBC-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw Bottom Category","HIERARCHY":"3.X.2.4.1.5","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMBCA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category A","HIERARCHY":"3.X.2.4.1.5.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBCB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category B","HIERARCHY":"3.X.2.4.1.5.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBCC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category C","HIERARCHY":"3.X.2.4.1.5.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBT-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw Bottom Type","HIERARCHY":"3.X.2.4.1.6","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMBTA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A1","HIERARCHY":"3.X.2.4.1.6.1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A2","HIERARCHY":"3.X.2.4.1.6.2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A3","HIERARCHY":"3.X.2.4.1.6.3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTD---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B1","HIERARCHY":"3.X.2.4.1.6.4","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTE---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B2","HIERARCHY":"3.X.2.4.1.6.5","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B3","HIERARCHY":"3.X.2.4.1.6.6","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTG---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C1","HIERARCHY":"3.X.2.4.1.6.7","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTH---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C2","HIERARCHY":"3.X.2.4.1.6.8","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTI---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C3","HIERARCHY":"3.X.2.4.1.6.9","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO--L----------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Limits","HIERARCHY":"3.X.2.5","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO-DL-ML---L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Maritime Limit","HIERARCHY":"3.X.2.5.1","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-MA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Maritime Area","HIERARCHY":"3.X.2.5.2","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-RA---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Restricted Area","HIERARCHY":"3.X.2.5.3","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-SA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Swept Area","HIERARCHY":"3.X.2.5.4","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-TA----A--","GEOMETRY":"area","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Training Area","HIERARCHY":"3.X.2.5.5","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-O-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Operator Defined","HIERARCHY":"3.X.2.5.6","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO--M----------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Man-Made Structures","HIERARCHY":"3.X.2.6","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO-DMCA----L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cable","HIERARCHY":"3.X.2.6.1","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMCC-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Submerged Crib","HIERARCHY":"3.X.2.6.2","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMCD----L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Canal","HIERARCHY":"3.X.2.6.3","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MF----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ford","HIERARCHY":"3.X.2.6.4","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-ML----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lock","HIERARCHY":"3.X.2.6.5","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MOA---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Oil/Gas Rig","HIERARCHY":"3.X.2.6.6","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMOA-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Oil Rig Field","HIERARCHY":"3.X.2.6.7","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMPA----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Pipe","HIERARCHY":"3.X.2.6.8","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MPA---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pile/Piling/Post","HIERARCHY":"3.X.2.6.9","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WS-------------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Space","HIERARCHY":"3.X.3","PATH":"METOC"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitFontMappingsB={"UNITFONTMAPPINGS":{"SYMBOL":[{"SYMBOLID":"S***------*****","DESCRIPTION":"Warfighting Symbology"},{"SYMBOLID":"S*P*------*****","DESCRIPTION":"Space Track"},{"SYMBOLID":"S*P*S-----*****","DESCRIPTION":"Satellite","MAPPING1U":"1000","MAPPING1F":"1000","MAPPING1N":"1000","MAPPING1H":"1000"},{"SYMBOLID":"S*P*V-----*****","DESCRIPTION":"Crewed Space Vehicle","MAPPING1U":"1001","MAPPING1F":"1001","MAPPING1N":"1001","MAPPING1H":"1001"},{"SYMBOLID":"S*P*T-----*****","DESCRIPTION":"Space Station","MAPPING1U":"1002","MAPPING1F":"1002","MAPPING1N":"1002","MAPPING1H":"1002","MAPPING2":"1003","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*P*L-----*****","DESCRIPTION":"Space Launch Vehicle","MAPPING1U":"1004","MAPPING1F":"1004","MAPPING1N":"1004","MAPPING1H":"1004"},{"SYMBOLID":"S*A*------*****","DESCRIPTION":"Air Track"},{"SYMBOLID":"S*A*M-----*****","DESCRIPTION":"Military","MAPPING1U":"1005","MAPPING1F":"1005","MAPPING1N":"1005","MAPPING1H":"1005"},{"SYMBOLID":"S*A*MF----*****","DESCRIPTION":"Fixed Wing","MAPPING1U":"1006","MAPPING1F":"1006","MAPPING1N":"1006","MAPPING1H":"1006"},{"SYMBOLID":"S*A*MFB---*****","DESCRIPTION":"Fixed Wing Bomber","MAPPING1U":"1007","MAPPING1F":"1007","MAPPING1N":"1007","MAPPING1H":"1007"},{"SYMBOLID":"S*A*MFF---*****","DESCRIPTION":"Fixed Wing Fighter","MAPPING1U":"1008","MAPPING1F":"1008","MAPPING1N":"1008","MAPPING1H":"1008"},{"SYMBOLID":"S*A*MFFI--*****","DESCRIPTION":"Fixed Wing Interceptor","MAPPING1U":"1009","MAPPING1F":"1009","MAPPING1N":"1009","MAPPING1H":"1009"},{"SYMBOLID":"S*A*MFT---*****","DESCRIPTION":"Fixed Wing Trainer","MAPPING1U":"1010","MAPPING1F":"1010","MAPPING1N":"1010","MAPPING1H":"1010"},{"SYMBOLID":"S*A*MFA---*****","DESCRIPTION":"Attack/Strike","MAPPING1U":"1011","MAPPING1F":"1011","MAPPING1N":"1011","MAPPING1H":"1011"},{"SYMBOLID":"S*A*MFL---*****","DESCRIPTION":"Fixed Wing VSTOL","MAPPING1U":"1012","MAPPING1F":"1012","MAPPING1N":"1012","MAPPING1H":"1012"},{"SYMBOLID":"S*A*MFK---*****","DESCRIPTION":"Fixed Wing Tanker","MAPPING1U":"1013","MAPPING1F":"1013","MAPPING1N":"1013","MAPPING1H":"1013"},{"SYMBOLID":"S*A*MFKB--*****","DESCRIPTION":"Fixed Wing Tanker Boom-Only","MAPPING1U":"1014","MAPPING1F":"1014","MAPPING1N":"1014","MAPPING1H":"1014"},{"SYMBOLID":"S*A*MFKD--*****","DESCRIPTION":"Fixed Wing Tanker Drouge-Only","MAPPING1U":"1015","MAPPING1F":"1015","MAPPING1N":"1015","MAPPING1H":"1015"},{"SYMBOLID":"S*A*MFC---*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Transport)","MAPPING1U":"1016","MAPPING1F":"1016","MAPPING1N":"1016","MAPPING1H":"1016"},{"SYMBOLID":"S*A*MFCL--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Light)","MAPPING1U":"1017","MAPPING1F":"1017","MAPPING1N":"1017","MAPPING1H":"1017"},{"SYMBOLID":"S*A*MFCM--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Medium)","MAPPING1U":"1018","MAPPING1F":"1018","MAPPING1N":"1018","MAPPING1H":"1018"},{"SYMBOLID":"S*A*MFCH--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Heavy)","MAPPING1U":"1019","MAPPING1F":"1019","MAPPING1N":"1019","MAPPING1H":"1019"},{"SYMBOLID":"S*A*MFJ---*****","DESCRIPTION":"Fixed Wing ECM/Jammer","MAPPING1U":"1020","MAPPING1F":"1020","MAPPING1N":"1020","MAPPING1H":"1020"},{"SYMBOLID":"S*A*MFO---*****","DESCRIPTION":"Fixed Wing MEDEVAC","MAPPING1U":"1021","MAPPING1F":"1021","MAPPING1N":"1021","MAPPING1H":"1021"},{"SYMBOLID":"S*A*MFR---*****","DESCRIPTION":"Fixed Wing Reconnaissance","MAPPING1U":"1022","MAPPING1F":"1022","MAPPING1N":"1022","MAPPING1H":"1022"},{"SYMBOLID":"S*A*MFRW--*****","DESCRIPTION":"Fixed Wing Airborne Early Warning (AEW)","MAPPING1U":"1023","MAPPING1F":"1023","MAPPING1N":"1023","MAPPING1H":"1023"},{"SYMBOLID":"S*A*MFRZ--*****","DESCRIPTION":"Fixed Wing Electronic Surveillance Measures","MAPPING1U":"1024","MAPPING1F":"1024","MAPPING1N":"1024","MAPPING1H":"1024"},{"SYMBOLID":"S*A*MFRX--*****","DESCRIPTION":"Fixed Wing Photographic","MAPPING1U":"1025","MAPPING1F":"1025","MAPPING1N":"1025","MAPPING1H":"1025"},{"SYMBOLID":"S*A*MFP---*****","DESCRIPTION":"Fixed Wing Patrol","MAPPING1U":"1026","MAPPING1F":"1026","MAPPING1N":"1026","MAPPING1H":"1026"},{"SYMBOLID":"S*A*MFPN--*****","DESCRIPTION":"Patrol Antisurface Warfare (ASUW)","MAPPING1U":"1027","MAPPING1F":"1027","MAPPING1N":"1027","MAPPING1H":"1027"},{"SYMBOLID":"S*A*MFPM--*****","DESCRIPTION":"Fixed Wing Mine Countermeasures","MAPPING1U":"1028","MAPPING1F":"1028","MAPPING1N":"1028","MAPPING1H":"1028"},{"SYMBOLID":"S*A*MFU---*****","DESCRIPTION":"Fixed Wing Utility","MAPPING1U":"1029","MAPPING1F":"1029","MAPPING1N":"1029","MAPPING1H":"1029"},{"SYMBOLID":"S*A*MFUL--*****","DESCRIPTION":"Fixed Wing Utility (Light)","MAPPING1U":"1030","MAPPING1F":"1030","MAPPING1N":"1030","MAPPING1H":"1030"},{"SYMBOLID":"S*A*MFUM--*****","DESCRIPTION":"Fixed Wing Utility (Medium)","MAPPING1U":"1031","MAPPING1F":"1031","MAPPING1N":"1031","MAPPING1H":"1031"},{"SYMBOLID":"S*A*MFUH--*****","DESCRIPTION":"Fixed Wing Utility (Heavy)","MAPPING1U":"1032","MAPPING1F":"1032","MAPPING1N":"1032","MAPPING1H":"1032"},{"SYMBOLID":"S*A*MFY---*****","DESCRIPTION":"Fixed Wing Communications (C3I)","MAPPING1U":"1033","MAPPING1F":"1033","MAPPING1N":"1033","MAPPING1H":"1033"},{"SYMBOLID":"S*A*MFH---*****","DESCRIPTION":"Fixed Wing Combat Search and Rescue (CSAR)","MAPPING1U":"1034","MAPPING1F":"1034","MAPPING1N":"1034","MAPPING1H":"1034"},{"SYMBOLID":"S*A*MFD---*****","DESCRIPTION":"Fixed Wing Airborne Command Post (C2)","MAPPING1U":"1035","MAPPING1F":"1035","MAPPING1N":"1035","MAPPING1H":"1035"},{"SYMBOLID":"S*A*MFQ---*****","DESCRIPTION":"Drone (RPV/UAV) Fixed Wing","MAPPING1U":"1036","MAPPING1F":"1036","MAPPING1N":"1036","MAPPING1H":"1036"},{"SYMBOLID":"S*A*MFQA--*****","DESCRIPTION":"Drone Attack","MAPPING1U":"1037","MAPPING1F":"1037","MAPPING1N":"1037","MAPPING1H":"1037"},{"SYMBOLID":"S*A*MFQB--*****","DESCRIPTION":"Drone Bomber","MAPPING1U":"1038","MAPPING1F":"1038","MAPPING1N":"1038","MAPPING1H":"1038"},{"SYMBOLID":"S*A*MFQC--*****","DESCRIPTION":"Drone Cargo","MAPPING1U":"1039","MAPPING1F":"1039","MAPPING1N":"1039","MAPPING1H":"1039"},{"SYMBOLID":"S*A*MFQD--*****","DESCRIPTION":"Drone (RPV/UAV) Airborne Command Post","MAPPING1U":"1040","MAPPING1F":"1040","MAPPING1N":"1040","MAPPING1H":"1040"},{"SYMBOLID":"S*A*MFQF--*****","DESCRIPTION":"Drone Fighter","MAPPING1U":"1041","MAPPING1F":"1041","MAPPING1N":"1041","MAPPING1H":"1041"},{"SYMBOLID":"S*A*MFQH--*****","DESCRIPTION":"Search & Rescue (CSAR)","MAPPING1U":"1042","MAPPING1F":"1042","MAPPING1N":"1042","MAPPING1H":"1042"},{"SYMBOLID":"S*A*MFQJ--*****","DESCRIPTION":"Drone Electronic Countermeasures (Jammer)","MAPPING1U":"1043","MAPPING1F":"1043","MAPPING1N":"1043","MAPPING1H":"1043"},{"SYMBOLID":"S*A*MFQK--*****","DESCRIPTION":"Drone Tanker","MAPPING1U":"1044","MAPPING1F":"1044","MAPPING1N":"1044","MAPPING1H":"1044"},{"SYMBOLID":"S*A*MFQL--*****","DESCRIPTION":"Drone Vstol","MAPPING1U":"1045","MAPPING1F":"1045","MAPPING1N":"1045","MAPPING1H":"1045"},{"SYMBOLID":"S*A*MFQM--*****","DESCRIPTION":"Drone Special Operations Forces (SOF)","MAPPING1U":"1046","MAPPING1F":"1046","MAPPING1N":"1046","MAPPING1H":"1046"},{"SYMBOLID":"S*A*MFQI--*****","DESCRIPTION":"Drone Mine Countermeasures","MAPPING1U":"1047","MAPPING1F":"1047","MAPPING1N":"1047","MAPPING1H":"1047"},{"SYMBOLID":"S*A*MFQN--*****","DESCRIPTION":"Drone Anti-Surface Warfare (ASUW)","MAPPING1U":"1048","MAPPING1F":"1048","MAPPING1N":"1048","MAPPING1H":"1048"},{"SYMBOLID":"S*A*MFQP--*****","DESCRIPTION":"Drone Patrol","MAPPING1U":"1049","MAPPING1F":"1049","MAPPING1N":"1049","MAPPING1H":"1049"},{"SYMBOLID":"S*A*MFQR--*****","DESCRIPTION":"Drone Reconnaissance","MAPPING1U":"1050","MAPPING1F":"1050","MAPPING1N":"1050","MAPPING1H":"1050"},{"SYMBOLID":"S*A*MFQRW-*****","DESCRIPTION":"Drone Airborne Early Warning (AEW)","MAPPING1U":"1051","MAPPING1F":"1051","MAPPING1N":"1051","MAPPING1H":"1051"},{"SYMBOLID":"S*A*MFQRZ-*****","DESCRIPTION":"Drone Electronic Surveillance Measures","MAPPING1U":"1052","MAPPING1F":"1052","MAPPING1N":"1052","MAPPING1H":"1052"},{"SYMBOLID":"S*A*MFQRX-*****","DESCRIPTION":"Drone Photographic","MAPPING1U":"1053","MAPPING1F":"1053","MAPPING1N":"1053","MAPPING1H":"1053"},{"SYMBOLID":"S*A*MFQS--*****","DESCRIPTION":"Drone Anti-Submarine Warfare (ASW)","MAPPING1U":"1054","MAPPING1F":"1054","MAPPING1N":"1054","MAPPING1H":"1054"},{"SYMBOLID":"S*A*MFQT--*****","DESCRIPTION":"Drone Trainer","MAPPING1U":"1055","MAPPING1F":"1055","MAPPING1N":"1055","MAPPING1H":"1055"},{"SYMBOLID":"S*A*MFQU--*****","DESCRIPTION":"Drone Utility Fixed Wing","MAPPING1U":"1056","MAPPING1F":"1056","MAPPING1N":"1056","MAPPING1H":"1056"},{"SYMBOLID":"S*A*MFQY--*****","DESCRIPTION":"Drone Communications (C3I)","MAPPING1U":"1057","MAPPING1F":"1057","MAPPING1N":"1057","MAPPING1H":"1057"},{"SYMBOLID":"S*A*MFQO--*****","DESCRIPTION":"Drone Medevac","MAPPING1U":"1058","MAPPING1F":"1058","MAPPING1N":"1058","MAPPING1H":"1058"},{"SYMBOLID":"S*A*MFS---*****","DESCRIPTION":"Antisubmarine Warfare (ASW) Carrier Based","MAPPING1U":"1059","MAPPING1F":"1059","MAPPING1N":"1059","MAPPING1H":"1059"},{"SYMBOLID":"S*A*MFM---*****","DESCRIPTION":"Fixed Wing Special Operations Forces (SOF)","MAPPING1U":"1060","MAPPING1F":"1060","MAPPING1N":"1060","MAPPING1H":"1060"},{"SYMBOLID":"S*A*MH----*****","DESCRIPTION":"Rotary Wing","MAPPING1U":"1061","MAPPING1F":"1061","MAPPING1N":"1061","MAPPING1H":"1061"},{"SYMBOLID":"S*A*MHA---*****","DESCRIPTION":"Rotary Wing Attack","MAPPING1U":"1062","MAPPING1F":"1062","MAPPING1N":"1062","MAPPING1H":"1062"},{"SYMBOLID":"S*A*MHS---*****","DESCRIPTION":"Antisubmarine Warfare/MPA ROTARY WING","MAPPING1U":"1063","MAPPING1F":"1063","MAPPING1N":"1063","MAPPING1H":"1063"},{"SYMBOLID":"S*A*MHU---*****","DESCRIPTION":"Rotary Wing Utility","MAPPING1U":"1064","MAPPING1F":"1064","MAPPING1N":"1064","MAPPING1H":"1064"},{"SYMBOLID":"S*A*MHUL--*****","DESCRIPTION":"Rotary Wing Utility (Light)","MAPPING1U":"1065","MAPPING1F":"1065","MAPPING1N":"1065","MAPPING1H":"1065"},{"SYMBOLID":"S*A*MHUM--*****","DESCRIPTION":"Rotary Wing Utility (Medium)","MAPPING1U":"1066","MAPPING1F":"1066","MAPPING1N":"1066","MAPPING1H":"1066"},{"SYMBOLID":"S*A*MHUH--*****","DESCRIPTION":"Rotary Wing Utility (Heavy)","MAPPING1U":"1067","MAPPING1F":"1067","MAPPING1N":"1067","MAPPING1H":"1067"},{"SYMBOLID":"S*A*MHI---*****","DESCRIPTION":"Rotary Wing Mine Countermeasures","MAPPING1U":"1068","MAPPING1F":"1068","MAPPING1N":"1068","MAPPING1H":"1068"},{"SYMBOLID":"S*A*MHH---*****","DESCRIPTION":"Rotary Wing Combat Search and Rescue(Military)","MAPPING1U":"1069","MAPPING1F":"1069","MAPPING1N":"1069","MAPPING1H":"1069"},{"SYMBOLID":"S*A*MHR---*****","DESCRIPTION":"Rotary Wing Reconnaissance","MAPPING1U":"1070","MAPPING1F":"1070","MAPPING1N":"1070","MAPPING1H":"1070"},{"SYMBOLID":"S*A*MHQ---*****","DESCRIPTION":"Drone (RPV/UAV) Rotary Wing","MAPPING1U":"1071","MAPPING1F":"1071","MAPPING1N":"1071","MAPPING1H":"1071"},{"SYMBOLID":"S*A*MHC---*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Transport)","MAPPING1U":"1072","MAPPING1F":"1072","MAPPING1N":"1072","MAPPING1H":"1072"},{"SYMBOLID":"S*A*MHCL--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Light)","MAPPING1U":"1073","MAPPING1F":"1073","MAPPING1N":"1073","MAPPING1H":"1073"},{"SYMBOLID":"S*A*MHCM--*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Medium)","MAPPING1U":"1074","MAPPING1F":"1074","MAPPING1N":"1074","MAPPING1H":"1074"},{"SYMBOLID":"S*A*MHCH--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Heavy)","MAPPING1U":"1075","MAPPING1F":"1075","MAPPING1N":"1075","MAPPING1H":"1075"},{"SYMBOLID":"S*A*MHT---*****","DESCRIPTION":"Rotary Wing Trainer","MAPPING1U":"1076","MAPPING1F":"1076","MAPPING1N":"1076","MAPPING1H":"1076"},{"SYMBOLID":"S*A*MHO---*****","DESCRIPTION":"Rotary Wing MEDEVAC","MAPPING1U":"1077","MAPPING1F":"1077","MAPPING1N":"1077","MAPPING1H":"1077"},{"SYMBOLID":"S*A*MHM---*****","DESCRIPTION":"Rotary Wing Special Operations Forces","MAPPING1U":"1078","MAPPING1F":"1078","MAPPING1N":"1078","MAPPING1H":"1078"},{"SYMBOLID":"S*A*MHD---*****","DESCRIPTION":"Rotary Wing Airborne Command Post","MAPPING1U":"1079","MAPPING1F":"1079","MAPPING1N":"1079","MAPPING1H":"1079"},{"SYMBOLID":"S*A*MHK---*****","DESCRIPTION":"Rotary Wing Tanker","MAPPING1U":"1080","MAPPING1F":"1080","MAPPING1N":"1080","MAPPING1H":"1080"},{"SYMBOLID":"S*A*MHJ---*****","DESCRIPTION":"Rotary Wing ECM/Jammer(TANKER)","MAPPING1U":"1081","MAPPING1F":"1081","MAPPING1N":"1081","MAPPING1H":"1081"},{"SYMBOLID":"S*A*ML----*****","DESCRIPTION":"Military Aircraft Lighter Than Air","MAPPING1U":"1082","MAPPING1F":"1082","MAPPING1N":"1082","MAPPING1H":"1082"},{"SYMBOLID":"S*A*W-----*****","DESCRIPTION":"Air Track Weapon","MAPPING1U":"1083","MAPPING1F":"1083","MAPPING1N":"1083","MAPPING1H":"1083","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WM----*****","DESCRIPTION":"Missile In Flight","MAPPING1U":"1083","MAPPING1F":"1083","MAPPING1N":"1083","MAPPING1H":"1083","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMS---*****","DESCRIPTION":"Surface Launched Missile","MAPPING1U":"1085","MAPPING1F":"1085","MAPPING1N":"1085","MAPPING1H":"1085","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSS--*****","DESCRIPTION":"Surface to Surface Missile (SSM)","MAPPING1U":"1086","MAPPING1F":"1086","MAPPING1N":"1086","MAPPING1H":"1086","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSA--*****","DESCRIPTION":"Surface To Air Missile (SAM)","MAPPING1U":"1087","MAPPING1F":"1087","MAPPING1N":"1087","MAPPING1H":"1087","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSU--*****","DESCRIPTION":"Surface to Subsurface Missile","MAPPING1U":"1088","MAPPING1F":"1088","MAPPING1N":"1088","MAPPING1H":"1088","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSB--*****","DESCRIPTION":"Anti-Ballistic Missile (ABM)","MAPPING1U":"1089","MAPPING1F":"1089","MAPPING1N":"1089","MAPPING1H":"1089","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMA---*****","DESCRIPTION":"Air Launched Missile","MAPPING1U":"1090","MAPPING1F":"1090","MAPPING1N":"1090","MAPPING1H":"1090","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAS--*****","DESCRIPTION":"Air To Surface Missile (ASM)","MAPPING1U":"1091","MAPPING1F":"1091","MAPPING1N":"1091","MAPPING1H":"1091","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAA--*****","DESCRIPTION":"Air To Air Missile (AAM)","MAPPING1U":"1093","MAPPING1F":"1093","MAPPING1N":"1093","MAPPING1H":"1093","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAP--*****","DESCRIPTION":"Air to Space Missile","MAPPING1U":"1094","MAPPING1F":"1094","MAPPING1N":"1094","MAPPING1H":"1094","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMU---*****","DESCRIPTION":"Subsurface To Surface Missile (S/SSM)","MAPPING1U":"1095","MAPPING1F":"1095","MAPPING1N":"1095","MAPPING1H":"1095","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMCM--*****","DESCRIPTION":"Cruise Missile","MAPPING1U":"1096","MAPPING1F":"1096","MAPPING1N":"1096","MAPPING1H":"1096","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMB---*****","DESCRIPTION":"Ballistic Missile","MAPPING1U":"1097","MAPPING1F":"1097","MAPPING1N":"1097","MAPPING1H":"1097","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WD----*****","DESCRIPTION":"Decoy","MAPPING1U":"1099","MAPPING1F":"1099","MAPPING1N":"1099","MAPPING1H":"1099"},{"SYMBOLID":"S*A*WB----*****","DESCRIPTION":"Bomb","MAPPING1U":"1098","MAPPING1F":"1098","MAPPING1N":"1098","MAPPING1H":"1098"},{"SYMBOLID":"S*A*C-----*****","DESCRIPTION":"Civil Aircraft","MAPPING1U":"1100","MAPPING1F":"1100","MAPPING1N":"1100","MAPPING1H":"1100"},{"SYMBOLID":"S*A*CF----*****","DESCRIPTION":"Civil Fixed Wing","MAPPING1U":"1101","MAPPING1F":"1101","MAPPING1N":"1101","MAPPING1H":"1101","MAPPING2":"402","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*A*CH----*****","DESCRIPTION":"Civil Rotary Wing","MAPPING1U":"1102","MAPPING1F":"1102","MAPPING1N":"1102","MAPPING1H":"1102","MAPPING2":"403","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*A*CL----*****","DESCRIPTION":"Civil Aircraft Lighter Than Air","MAPPING1U":"1103","MAPPING1F":"1103","MAPPING1N":"1103","MAPPING1H":"1103","MAPPING2":"404","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*------*****","DESCRIPTION":"Ground Track"},{"SYMBOLID":"S*G*U-----*****","DESCRIPTION":"Unit"},{"SYMBOLID":"S*G*UC----*****","DESCRIPTION":"Combat","MAPPING1U":"1104","MAPPING1F":"1104","MAPPING1N":"1104","MAPPING1H":"1104"},{"SYMBOLID":"S*G*UCD---*****","DESCRIPTION":"Air Defense","MAPPING1U":"1105","MAPPING1F":"1106","MAPPING1N":"1107","MAPPING1H":"1108"},{"SYMBOLID":"S*G*UCDS--*****","DESCRIPTION":"Short Range","MAPPING1U":"1109","MAPPING1F":"1110","MAPPING1N":"1111","MAPPING1H":"1112"},{"SYMBOLID":"S*G*UCDSC-*****","DESCRIPTION":"Chaparral","MAPPING1U":"1113","MAPPING1F":"1114","MAPPING1N":"1115","MAPPING1H":"1116"},{"SYMBOLID":"S*G*UCDSS-*****","DESCRIPTION":"Stinger","MAPPING1U":"1117","MAPPING1F":"1118","MAPPING1N":"1119","MAPPING1H":"1120"},{"SYMBOLID":"S*G*UCDSV-*****","DESCRIPTION":"Vulcan","MAPPING1U":"1121","MAPPING1F":"1122","MAPPING1N":"1123","MAPPING1H":"1124"},{"SYMBOLID":"S*G*UCDM--*****","DESCRIPTION":"Air Defense Missile","MAPPING1U":"1125","MAPPING1F":"1126","MAPPING1N":"1127","MAPPING1H":"1128"},{"SYMBOLID":"S*G*UCDML-*****","DESCRIPTION":"Air Defense Missile Light","MAPPING1U":"1129","MAPPING1F":"1130","MAPPING1N":"1131","MAPPING1H":"1132"},{"SYMBOLID":"S*G*UCDMLA*****","DESCRIPTION":"Air Defense Missile Motorized (Avenger)","MAPPING1U":"1133","MAPPING1F":"1134","MAPPING1N":"1135","MAPPING1H":"1136"},{"SYMBOLID":"S*G*UCDMM-*****","DESCRIPTION":"Air Defense Missile Medium","MAPPING1U":"1137","MAPPING1F":"1138","MAPPING1N":"1139","MAPPING1H":"1140"},{"SYMBOLID":"S*G*UCDMH-*****","DESCRIPTION":"Air Defense Missile Heavy","MAPPING1U":"1141","MAPPING1F":"1142","MAPPING1N":"1143","MAPPING1H":"1144"},{"SYMBOLID":"S*G*UCDH--*****","DESCRIPTION":"H/MAD","MAPPING1U":"1145","MAPPING1F":"1146","MAPPING1N":"1147","MAPPING1H":"1148"},{"SYMBOLID":"S*G*UCDHH-*****","DESCRIPTION":"Hawk","MAPPING1U":"1149","MAPPING1F":"1150","MAPPING1N":"1151","MAPPING1H":"1152"},{"SYMBOLID":"S*G*UCDHP-*****","DESCRIPTION":"Patriot","MAPPING1U":"1153","MAPPING1F":"1154","MAPPING1N":"1155","MAPPING1H":"1156"},{"SYMBOLID":"S*G*UCDG--*****","DESCRIPTION":"Gun Unit","MAPPING1U":"1157","MAPPING1F":"1158","MAPPING1N":"1159","MAPPING1H":"1160"},{"SYMBOLID":"S*G*UCDC--*****","DESCRIPTION":"Air Defense Composite","MAPPING1U":"1161","MAPPING1F":"1162","MAPPING1N":"1163","MAPPING1H":"1164"},{"SYMBOLID":"S*G*UCDT--*****","DESCRIPTION":"Targeting Unit","MAPPING1U":"1165","MAPPING1F":"1166","MAPPING1N":"1167","MAPPING1H":"1168"},{"SYMBOLID":"S*G*UCDO--*****","DESCRIPTION":"Theater Missile Defense Unit","MAPPING1U":"1169","MAPPING1F":"1170","MAPPING1N":"1171","MAPPING1H":"1172"},{"SYMBOLID":"S*G*UCA---*****","DESCRIPTION":"Armor","MAPPING1U":"1173","MAPPING1F":"1173","MAPPING1N":"1173","MAPPING1H":"1173"},{"SYMBOLID":"S*G*UCAT--*****","DESCRIPTION":"Armor Track","MAPPING1U":"1173","MAPPING1F":"1173","MAPPING1N":"1173","MAPPING1H":"1173"},{"SYMBOLID":"S*G*UCATA-*****","DESCRIPTION":"Armor Track Airborne","MAPPING1U":"1174","MAPPING1F":"1174","MAPPING1N":"1174","MAPPING1H":"1174"},{"SYMBOLID":"S*G*UCATW-*****","DESCRIPTION":"Armor Track Amphibious","MAPPING1U":"1175","MAPPING1F":"1176","MAPPING1N":"1177","MAPPING1H":"1178"},{"SYMBOLID":"S*G*UCATWR*****","DESCRIPTION":"Armor Track Amphibious Recovery","MAPPING1U":"1179","MAPPING1F":"1180","MAPPING1N":"1181","MAPPING1H":"1182"},{"SYMBOLID":"S*G*UCATL-*****","DESCRIPTION":"Armor Track, Light","MAPPING1U":"1183","MAPPING1F":"1183","MAPPING1N":"1183","MAPPING1H":"1183"},{"SYMBOLID":"S*G*UCATM-*****","DESCRIPTION":"Armor Track, Medium","MAPPING1U":"1184","MAPPING1F":"1184","MAPPING1N":"1184","MAPPING1H":"1184"},{"SYMBOLID":"S*G*UCATH-*****","DESCRIPTION":"Armor Track, Heavy","MAPPING1U":"1185","MAPPING1F":"1185","MAPPING1N":"1185","MAPPING1H":"1185"},{"SYMBOLID":"S*G*UCATR-*****","DESCRIPTION":"Armor Track, Recovery","MAPPING1U":"1186","MAPPING1F":"1186","MAPPING1N":"1186","MAPPING1H":"1186"},{"SYMBOLID":"S*G*UCAW--*****","DESCRIPTION":"Armor, Wheeled","MAPPING1U":"1187","MAPPING1F":"1187","MAPPING1N":"1187","MAPPING1H":"1187"},{"SYMBOLID":"S*G*UCAWS-*****","DESCRIPTION":"Armor, Wheeled Air Assault","MAPPING1U":"1188","MAPPING1F":"1188","MAPPING1N":"1188","MAPPING1H":"1188"},{"SYMBOLID":"S*G*UCAWA-*****","DESCRIPTION":"Armor, Wheeled Airborne","MAPPING1U":"1189","MAPPING1F":"1189","MAPPING1N":"1189","MAPPING1H":"1189"},{"SYMBOLID":"S*G*UCAWW-*****","DESCRIPTION":"Armor, Wheeled Amphibious","MAPPING1U":"1190","MAPPING1F":"1191","MAPPING1N":"1192","MAPPING1H":"1193"},{"SYMBOLID":"S*G*UCAWWR*****","DESCRIPTION":"Armor, Wheeled Amphibious Recovery","MAPPING1U":"1194","MAPPING1F":"1195","MAPPING1N":"1196","MAPPING1H":"1197"},{"SYMBOLID":"S*G*UCAWL-*****","DESCRIPTION":"Armor, Wheeled Light","MAPPING1U":"1198","MAPPING1F":"1198","MAPPING1N":"1198","MAPPING1H":"1198"},{"SYMBOLID":"S*G*UCAWM-*****","DESCRIPTION":"Armor, Wheeled Medium","MAPPING1U":"1199","MAPPING1F":"1199","MAPPING1N":"1199","MAPPING1H":"1199"},{"SYMBOLID":"S*G*UCAWH-*****","DESCRIPTION":"Armor, Wheeled Heavy","MAPPING1U":"1200","MAPPING1F":"1200","MAPPING1N":"1200","MAPPING1H":"1200"},{"SYMBOLID":"S*G*UCAWR-*****","DESCRIPTION":"Armor, Wheeled Recovery","MAPPING1U":"1201","MAPPING1F":"1201","MAPPING1N":"1201","MAPPING1H":"1201"},{"SYMBOLID":"S*G*UCAA--*****","DESCRIPTION":"Anti Armor","MAPPING1U":"1202","MAPPING1F":"1203","MAPPING1N":"1204","MAPPING1H":"1205"},{"SYMBOLID":"S*G*UCAAD-*****","DESCRIPTION":"Anti Armor Dismounted","MAPPING1U":"1202","MAPPING1F":"1203","MAPPING1N":"1204","MAPPING1H":"1205"},{"SYMBOLID":"S*G*UCAAL-*****","DESCRIPTION":"Anti Armor Light","MAPPING1U":"1206","MAPPING1F":"1207","MAPPING1N":"1208","MAPPING1H":"1209"},{"SYMBOLID":"S*G*UCAAM-*****","DESCRIPTION":"Anti Armor Airborne","MAPPING1U":"1210","MAPPING1F":"1211","MAPPING1N":"1212","MAPPING1H":"1213"},{"SYMBOLID":"S*G*UCAAS-*****","DESCRIPTION":"Anti Armor Air Assault","MAPPING1U":"1214","MAPPING1F":"1215","MAPPING1N":"1216","MAPPING1H":"1217"},{"SYMBOLID":"S*G*UCAAU-*****","DESCRIPTION":"Anti Armor Mountain","MAPPING1U":"1218","MAPPING1F":"1219","MAPPING1N":"1220","MAPPING1H":"1221"},{"SYMBOLID":"S*G*UCAAC-*****","DESCRIPTION":"Anti Armor Arctic","MAPPING1U":"1222","MAPPING1F":"1223","MAPPING1N":"1224","MAPPING1H":"1225"},{"SYMBOLID":"S*G*UCAAA-*****","DESCRIPTION":"Anti Armor Armored","MAPPING1U":"1226","MAPPING1F":"1227","MAPPING1N":"1228","MAPPING1H":"1229"},{"SYMBOLID":"S*G*UCAAAT*****","DESCRIPTION":"Anti Armor Armored Tracked","MAPPING1U":"1226","MAPPING1F":"1227","MAPPING1N":"1228","MAPPING1H":"1229"},{"SYMBOLID":"S*G*UCAAAW*****","DESCRIPTION":"Anti Armor Armored Wheeled","MAPPING1U":"1230","MAPPING1F":"1231","MAPPING1N":"1232","MAPPING1H":"1233"},{"SYMBOLID":"S*G*UCAAAS*****","DESCRIPTION":"Anti Armor Armored Air Assault","MAPPING1U":"1234","MAPPING1F":"1235","MAPPING1N":"1236","MAPPING1H":"1237"},{"SYMBOLID":"S*G*UCAAO-*****","DESCRIPTION":"Anti Armor Motorized","MAPPING1U":"1238","MAPPING1F":"1239","MAPPING1N":"1240","MAPPING1H":"1241"},{"SYMBOLID":"S*G*UCAAOS*****","DESCRIPTION":"Anti Armor Motorized Air Assault","MAPPING1U":"1242","MAPPING1F":"1243","MAPPING1N":"1244","MAPPING1H":"1245"},{"SYMBOLID":"S*G*UCV---*****","DESCRIPTION":"Aviation","MAPPING1U":"1246","MAPPING1F":"1246","MAPPING1N":"1246","MAPPING1H":"1246"},{"SYMBOLID":"S*G*UCVF--*****","DESCRIPTION":"Aviation Fixed Wing","MAPPING1U":"1247","MAPPING1F":"1247","MAPPING1N":"1247","MAPPING1H":"1247"},{"SYMBOLID":"S*G*UCVFU-*****","DESCRIPTION":"Utility Fixed Wing","MAPPING1U":"1248","MAPPING1F":"1248","MAPPING1N":"1248","MAPPING1H":"1248"},{"SYMBOLID":"S*G*UCVFA-*****","DESCRIPTION":"Fixed Wing Attack","MAPPING1U":"1249","MAPPING1F":"1249","MAPPING1N":"1249","MAPPING1H":"1249"},{"SYMBOLID":"S*G*UCVFR-*****","DESCRIPTION":"Recon Fixed Wing","MAPPING1U":"1250","MAPPING1F":"1250","MAPPING1N":"1250","MAPPING1H":"1250"},{"SYMBOLID":"S*G*UCVR--*****","DESCRIPTION":"Aviation Rotary Wing","MAPPING1U":"1251","MAPPING1F":"1251","MAPPING1N":"1251","MAPPING1H":"1251"},{"SYMBOLID":"S*G*UCVRA-*****","DESCRIPTION":"Attack Rotary Wing","MAPPING1U":"1252","MAPPING1F":"1252","MAPPING1N":"1252","MAPPING1H":"1252"},{"SYMBOLID":"S*G*UCVRS-*****","DESCRIPTION":"Scout Rotary Wing","MAPPING1U":"1253","MAPPING1F":"1253","MAPPING1N":"1253","MAPPING1H":"1253"},{"SYMBOLID":"S*G*UCVRW-*****","DESCRIPTION":"Antisubmarine Warfare Rotary Wing","MAPPING1U":"1254","MAPPING1F":"1254","MAPPING1N":"1254","MAPPING1H":"1254"},{"SYMBOLID":"S*G*UCVRU-*****","DESCRIPTION":"Utility Rotary Wing","MAPPING1U":"1255","MAPPING1F":"1255","MAPPING1N":"1255","MAPPING1H":"1255"},{"SYMBOLID":"S*G*UCVRUL*****","DESCRIPTION":"Light Utility Rotary Wing","MAPPING1U":"1256","MAPPING1F":"1256","MAPPING1N":"1256","MAPPING1H":"1256"},{"SYMBOLID":"S*G*UCVRUM*****","DESCRIPTION":"Medium Utility Rotary Wing","MAPPING1U":"1257","MAPPING1F":"1257","MAPPING1N":"1257","MAPPING1H":"1257"},{"SYMBOLID":"S*G*UCVRUH*****","DESCRIPTION":"Heavy Utility Rotary Wing","MAPPING1U":"1258","MAPPING1F":"1258","MAPPING1N":"1258","MAPPING1H":"1258"},{"SYMBOLID":"S*G*UCVRUC*****","DESCRIPTION":"C2 Rotary Wing","MAPPING1U":"1259","MAPPING1F":"1259","MAPPING1N":"1259","MAPPING1H":"1259"},{"SYMBOLID":"S*G*UCVRUE*****","DESCRIPTION":"Medevac Rotary Wing","MAPPING1U":"1260","MAPPING1F":"1260","MAPPING1N":"1260","MAPPING1H":"1260"},{"SYMBOLID":"S*G*UCVRM-*****","DESCRIPTION":"Mine Countermeasure Rotary Wing","MAPPING1U":"1261","MAPPING1F":"1261","MAPPING1N":"1261","MAPPING1H":"1261"},{"SYMBOLID":"S*G*UCVS--*****","DESCRIPTION":"Search and Rescue","MAPPING1U":"1262","MAPPING1F":"1262","MAPPING1N":"1262","MAPPING1H":"1262"},{"SYMBOLID":"S*G*UCVC--*****","DESCRIPTION":"Aviation Composite","MAPPING1U":"1263","MAPPING1F":"1263","MAPPING1N":"1263","MAPPING1H":"1263"},{"SYMBOLID":"S*G*UCVV--*****","DESCRIPTION":"Vertical/Short Takeoff And Landing (V/Stol)","MAPPING1U":"1264","MAPPING1F":"1264","MAPPING1N":"1264","MAPPING1H":"1264"},{"SYMBOLID":"S*G*UCVU--*****","DESCRIPTION":"Unmanned Aerial Vehicle","MAPPING1U":"1265","MAPPING1F":"1265","MAPPING1N":"1265","MAPPING1H":"1265"},{"SYMBOLID":"S*G*UCVUF-*****","DESCRIPTION":"Unmanned Aerial Vehicle Fixed Wing","MAPPING1U":"1266","MAPPING1F":"1266","MAPPING1N":"1266","MAPPING1H":"1266"},{"SYMBOLID":"S*G*UCVUR-*****","DESCRIPTION":"Unmanned Aerial Vehicle Rotary Wing","MAPPING1U":"1267","MAPPING1F":"1267","MAPPING1N":"1267","MAPPING1H":"1267"},{"SYMBOLID":"S*G*UCI---*****","DESCRIPTION":"Infantry","MAPPING1U":"1268","MAPPING1F":"1269","MAPPING1N":"1270","MAPPING1H":"1271"},{"SYMBOLID":"S*G*UCIL--*****","DESCRIPTION":"Infantry Light","MAPPING1U":"1272","MAPPING1F":"1273","MAPPING1N":"1274","MAPPING1H":"1275"},{"SYMBOLID":"S*G*UCIM--*****","DESCRIPTION":"Infantry Motorized","MAPPING1U":"1276","MAPPING1F":"1277","MAPPING1N":"1278","MAPPING1H":"1279"},{"SYMBOLID":"S*G*UCIO--*****","DESCRIPTION":"Infantry Mountain","MAPPING1U":"1280","MAPPING1F":"1281","MAPPING1N":"1282","MAPPING1H":"1283"},{"SYMBOLID":"S*G*UCIA--*****","DESCRIPTION":"Infantry Airborne","MAPPING1U":"1284","MAPPING1F":"1285","MAPPING1N":"1286","MAPPING1H":"1287"},{"SYMBOLID":"S*G*UCIS--*****","DESCRIPTION":"Infantry Air Assault","MAPPING1U":"1288","MAPPING1F":"1289","MAPPING1N":"1290","MAPPING1H":"1291"},{"SYMBOLID":"S*G*UCIZ--*****","DESCRIPTION":"Infantry Mechanized","MAPPING1U":"1292","MAPPING1F":"1293","MAPPING1N":"1294","MAPPING1H":"1295"},{"SYMBOLID":"S*G*UCIN--*****","DESCRIPTION":"Infantry Naval","MAPPING1U":"1296","MAPPING1F":"1297","MAPPING1N":"1298","MAPPING1H":"1299"},{"SYMBOLID":"S*G*UCII--*****","DESCRIPTION":"Infantry Fighting Vehicle","MAPPING1U":"1300","MAPPING1F":"1301","MAPPING1N":"1302","MAPPING1H":"1303"},{"SYMBOLID":"S*G*UCIC--*****","DESCRIPTION":"Infantry Arctic","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"1092"},{"SYMBOLID":"S*G*UCE---*****","DESCRIPTION":"Engineer","MAPPING1U":"1304","MAPPING1F":"1304","MAPPING1N":"1304","MAPPING1H":"1304"},{"SYMBOLID":"S*G*UCEC--*****","DESCRIPTION":"Engineer Combat","MAPPING1U":"1305","MAPPING1F":"1305","MAPPING1N":"1305","MAPPING1H":"1305"},{"SYMBOLID":"S*G*UCECS-*****","DESCRIPTION":"Engineer Combat Air Assault","MAPPING1U":"1306","MAPPING1F":"1306","MAPPING1N":"1306","MAPPING1H":"1306"},{"SYMBOLID":"S*G*UCECA-*****","DESCRIPTION":"Engineer Combat Airborne","MAPPING1U":"1307","MAPPING1F":"1307","MAPPING1N":"1307","MAPPING1H":"1307"},{"SYMBOLID":"S*G*UCECC-*****","DESCRIPTION":"Engineer Combat Arctic","MAPPING1U":"1308","MAPPING1F":"1308","MAPPING1N":"1308","MAPPING1H":"1308"},{"SYMBOLID":"S*G*UCECL-*****","DESCRIPTION":"Engineer Combat Light (Sapper)","MAPPING1U":"1309","MAPPING1F":"1309","MAPPING1N":"1309","MAPPING1H":"1309"},{"SYMBOLID":"S*G*UCECM-*****","DESCRIPTION":"Engineer Combat Medium","MAPPING1U":"1310","MAPPING1F":"1310","MAPPING1N":"1310","MAPPING1H":"1310"},{"SYMBOLID":"S*G*UCECH-*****","DESCRIPTION":"Engineer Combat Heavy","MAPPING1U":"1311","MAPPING1F":"1311","MAPPING1N":"1311","MAPPING1H":"1311"},{"SYMBOLID":"S*G*UCECT-*****","DESCRIPTION":"Engineer Combat Mechanized (Track)","MAPPING1U":"1312","MAPPING1F":"1312","MAPPING1N":"1312","MAPPING1H":"1312"},{"SYMBOLID":"S*G*UCECW-*****","DESCRIPTION":"Engineer Combat Motorized","MAPPING1U":"1313","MAPPING1F":"1314","MAPPING1N":"1315","MAPPING1H":"1316"},{"SYMBOLID":"S*G*UCECO-*****","DESCRIPTION":"Engineer Combat Mountain","MAPPING1U":"1317","MAPPING1F":"1317","MAPPING1N":"1317","MAPPING1H":"1317"},{"SYMBOLID":"S*G*UCECR-*****","DESCRIPTION":"Engineer Combat Recon","MAPPING1U":"1318","MAPPING1F":"1319","MAPPING1N":"1320","MAPPING1H":"1321"},{"SYMBOLID":"S*G*UCEN--*****","DESCRIPTION":"Engineer Construction","MAPPING1U":"1322","MAPPING1F":"1322","MAPPING1N":"1322","MAPPING1H":"1322"},{"SYMBOLID":"S*G*UCENN-*****","DESCRIPTION":"Engineer Naval Construction","MAPPING1U":"1323","MAPPING1F":"1323","MAPPING1N":"1323","MAPPING1H":"1323"},{"SYMBOLID":"S*G*UCF---*****","DESCRIPTION":"Field Artillery","MAPPING1U":"1324","MAPPING1F":"1324","MAPPING1N":"1324","MAPPING1H":"1324"},{"SYMBOLID":"S*G*UCFH--*****","DESCRIPTION":"Howitzer/Gun","MAPPING1U":"1324","MAPPING1F":"1324","MAPPING1N":"1324","MAPPING1H":"1324"},{"SYMBOLID":"S*G*UCFHE-*****","DESCRIPTION":"Self-Propelled","MAPPING1U":"1325","MAPPING1F":"1325","MAPPING1N":"1325","MAPPING1H":"1325"},{"SYMBOLID":"S*G*UCFHS-*****","DESCRIPTION":"Howitzer/Gun Air Assault","MAPPING1U":"1326","MAPPING1F":"1326","MAPPING1N":"1326","MAPPING1H":"1326"},{"SYMBOLID":"S*G*UCFHA-*****","DESCRIPTION":"Howitzer/Gun Airborne","MAPPING1U":"1327","MAPPING1F":"1327","MAPPING1N":"1327","MAPPING1H":"1327"},{"SYMBOLID":"S*G*UCFHC-*****","DESCRIPTION":"Arctic","MAPPING1U":"1328","MAPPING1F":"1328","MAPPING1N":"1328","MAPPING1H":"1328"},{"SYMBOLID":"S*G*UCFHO-*****","DESCRIPTION":"Howitzer/Gun Mountain","MAPPING1U":"1329","MAPPING1F":"1329","MAPPING1N":"1329","MAPPING1H":"1329"},{"SYMBOLID":"S*G*UCFHL-*****","DESCRIPTION":"Howitzer/Gun Light","MAPPING1U":"1330","MAPPING1F":"1330","MAPPING1N":"1330","MAPPING1H":"1330"},{"SYMBOLID":"S*G*UCFHM-*****","DESCRIPTION":"Howitzer/Gun Medium","MAPPING1U":"1331","MAPPING1F":"1331","MAPPING1N":"1331","MAPPING1H":"1331"},{"SYMBOLID":"S*G*UCFHH-*****","DESCRIPTION":"Heavy","MAPPING1U":"1332","MAPPING1F":"1332","MAPPING1N":"1332","MAPPING1H":"1332"},{"SYMBOLID":"S*G*UCFHX-*****","DESCRIPTION":"Amphibious","MAPPING1U":"1333","MAPPING1F":"1334","MAPPING1N":"1335","MAPPING1H":"1336"},{"SYMBOLID":"S*G*UCFR--*****","DESCRIPTION":"Rocket","MAPPING1U":"1337","MAPPING1F":"1337","MAPPING1N":"1337","MAPPING1H":"1337"},{"SYMBOLID":"S*G*UCFRS-*****","DESCRIPTION":"Rocket Single Rocket Launcher","MAPPING1U":"1338","MAPPING1F":"1338","MAPPING1N":"1338","MAPPING1H":"1338"},{"SYMBOLID":"S*G*UCFRSS*****","DESCRIPTION":"Single Rocket Self-Propelled","MAPPING1U":"1339","MAPPING1F":"1339","MAPPING1N":"1339","MAPPING1H":"1339"},{"SYMBOLID":"S*G*UCFRSR*****","DESCRIPTION":"Single Rocket Truck","MAPPING1U":"1340","MAPPING1F":"1340","MAPPING1N":"1340","MAPPING1H":"1340"},{"SYMBOLID":"S*G*UCFRST*****","DESCRIPTION":"Single Rocket Towed","MAPPING1U":"1341","MAPPING1F":"1341","MAPPING1N":"1341","MAPPING1H":"1341"},{"SYMBOLID":"S*G*UCFRM-*****","DESCRIPTION":"Multi Rocket Launcher","MAPPING1U":"1342","MAPPING1F":"1342","MAPPING1N":"1342","MAPPING1H":"1342"},{"SYMBOLID":"S*G*UCFRMS*****","DESCRIPTION":"Multi Rocket Self-Propelled","MAPPING1U":"1343","MAPPING1F":"1343","MAPPING1N":"1343","MAPPING1H":"1343"},{"SYMBOLID":"S*G*UCFRMR*****","DESCRIPTION":"Multi Rocket Truck","MAPPING1U":"1344","MAPPING1F":"1344","MAPPING1N":"1344","MAPPING1H":"1344"},{"SYMBOLID":"S*G*UCFRMT*****","DESCRIPTION":"Multi Rocket Towed","MAPPING1U":"1345","MAPPING1F":"1345","MAPPING1N":"1345","MAPPING1H":"1345"},{"SYMBOLID":"S*G*UCFT--*****","DESCRIPTION":"Target Acquisition","MAPPING1U":"1346","MAPPING1F":"1346","MAPPING1N":"1346","MAPPING1H":"1346"},{"SYMBOLID":"S*G*UCFTR-*****","DESCRIPTION":"Target Acquisition Radar","MAPPING1U":"1347","MAPPING1F":"1347","MAPPING1N":"1347","MAPPING1H":"1347"},{"SYMBOLID":"S*G*UCFTS-*****","DESCRIPTION":"Sound","MAPPING1U":"1348","MAPPING1F":"1349","MAPPING1N":"1350","MAPPING1H":"1351","MAPPING2":"405","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFTF-*****","DESCRIPTION":"Flash (Optical)","MAPPING1U":"1352","MAPPING1F":"1352","MAPPING1N":"1352","MAPPING1H":"1352"},{"SYMBOLID":"S*G*UCFTC-*****","DESCRIPTION":"Colt/Fist","MAPPING1U":"1353","MAPPING1F":"1354","MAPPING1N":"1355","MAPPING1H":"1356"},{"SYMBOLID":"S*G*UCFTCD*****","DESCRIPTION":"Dismounted Colt/Fist","MAPPING1U":"1357","MAPPING1F":"1358","MAPPING1N":"1359","MAPPING1H":"1360"},{"SYMBOLID":"S*G*UCFTCM*****","DESCRIPTION":"Tracked Colt/Fist","MAPPING1U":"1361","MAPPING1F":"1362","MAPPING1N":"1363","MAPPING1H":"1364"},{"SYMBOLID":"S*G*UCFTA-*****","DESCRIPTION":"Anglico","MAPPING1U":"1365","MAPPING1F":"1366","MAPPING1N":"1367","MAPPING1H":"1368"},{"SYMBOLID":"S*G*UCFM--*****","DESCRIPTION":"Field Artillery Mortar","MAPPING1U":"1369","MAPPING1F":"1369","MAPPING1N":"1369","MAPPING1H":"1369"},{"SYMBOLID":"S*G*UCFMS-*****","DESCRIPTION":"Self-Propelled (SP) Tracked Mortar","MAPPING1U":"1370","MAPPING1F":"1370","MAPPING1N":"1370","MAPPING1H":"1370"},{"SYMBOLID":"S*G*UCFMW-*****","DESCRIPTION":"SP Wheeled Mortar","MAPPING1U":"1371","MAPPING1F":"1371","MAPPING1N":"1371","MAPPING1H":"1371"},{"SYMBOLID":"S*G*UCFMT-*****","DESCRIPTION":"Towed Mortar","MAPPING1U":"1372","MAPPING1F":"1372","MAPPING1N":"1372","MAPPING1H":"1372"},{"SYMBOLID":"S*G*UCFMTA*****","DESCRIPTION":"Towed Airborne Mortar","MAPPING1U":"1373","MAPPING1F":"1373","MAPPING1N":"1373","MAPPING1H":"1373"},{"SYMBOLID":"S*G*UCFMTS*****","DESCRIPTION":"Towed Air Assault Mortar","MAPPING1U":"1374","MAPPING1F":"1374","MAPPING1N":"1374","MAPPING1H":"1374"},{"SYMBOLID":"S*G*UCFMTC*****","DESCRIPTION":"Towed Arctic Mortar","MAPPING1U":"1375","MAPPING1F":"1375","MAPPING1N":"1375","MAPPING1H":"1375"},{"SYMBOLID":"S*G*UCFMTO*****","DESCRIPTION":"Towed Mountain Mortar","MAPPING1U":"1376","MAPPING1F":"1376","MAPPING1N":"1376","MAPPING1H":"1376"},{"SYMBOLID":"S*G*UCFML-*****","DESCRIPTION":"Amphibious Mortar","MAPPING1U":"1377","MAPPING1F":"1378","MAPPING1N":"1379","MAPPING1H":"1380"},{"SYMBOLID":"S*G*UCFS--*****","DESCRIPTION":"Artillery Survey","MAPPING1U":"1381","MAPPING1F":"1381","MAPPING1N":"1381","MAPPING1H":"1381","MAPPING2":"1382","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSS-*****","DESCRIPTION":"Artillery Survey Air Assault","MAPPING1U":"1383","MAPPING1F":"1383","MAPPING1N":"1383","MAPPING1H":"1383","MAPPING2":"1384","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSA-*****","DESCRIPTION":"Artillery Survey Airborne","MAPPING1U":"1385","MAPPING1F":"1385","MAPPING1N":"1385","MAPPING1H":"1385","MAPPING2":"1386","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSL-*****","DESCRIPTION":"Artillery Survey Light","MAPPING1U":"1387","MAPPING1F":"1387","MAPPING1N":"1387","MAPPING1H":"1387","MAPPING2":"1388","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSO-*****","DESCRIPTION":"Artillery Survey Mountain","MAPPING1U":"1389","MAPPING1F":"1389","MAPPING1N":"1389","MAPPING1H":"1389","MAPPING2":"1390","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFO--*****","DESCRIPTION":"Field Artillery Meteorological","MAPPING1U":"1391","MAPPING1F":"1391","MAPPING1N":"1391","MAPPING1H":"1391"},{"SYMBOLID":"S*G*UCFOS-*****","DESCRIPTION":"Air Assault Meteorological","MAPPING1U":"1392","MAPPING1F":"1392","MAPPING1N":"1392","MAPPING1H":"1392"},{"SYMBOLID":"S*G*UCFOA-*****","DESCRIPTION":"Airborne Meteorological","MAPPING1U":"1393","MAPPING1F":"1393","MAPPING1N":"1393","MAPPING1H":"1393"},{"SYMBOLID":"S*G*UCFOL-*****","DESCRIPTION":"Light Meteorological","MAPPING1U":"1394","MAPPING1F":"1394","MAPPING1N":"1394","MAPPING1H":"1394"},{"SYMBOLID":"S*G*UCFOO-*****","DESCRIPTION":"Mountain Meteorological","MAPPING1U":"1395","MAPPING1F":"1395","MAPPING1N":"1395","MAPPING1H":"1395"},{"SYMBOLID":"S*G*UCR---*****","DESCRIPTION":"Combat Reconnaissance","MAPPING1U":"1396","MAPPING1F":"1397","MAPPING1N":"1398","MAPPING1H":"1399"},{"SYMBOLID":"S*G*UCRH--*****","DESCRIPTION":"Reconnaissance Horse","MAPPING1U":"1400","MAPPING1F":"1400","MAPPING1N":"1400","MAPPING1H":"1400"},{"SYMBOLID":"S*G*UCRV--*****","DESCRIPTION":"Reconnaissance Cavalry","MAPPING1U":"1401","MAPPING1F":"1402","MAPPING1N":"1403","MAPPING1H":"1404"},{"SYMBOLID":"S*G*UCRVA-*****","DESCRIPTION":"Reconnaissance Cavalry Armored","MAPPING1U":"1405","MAPPING1F":"1406","MAPPING1N":"1407","MAPPING1H":"1408"},{"SYMBOLID":"S*G*UCRVM-*****","DESCRIPTION":"Reconnaissance Cavalry Motorized","MAPPING1U":"1409","MAPPING1F":"1410","MAPPING1N":"1411","MAPPING1H":"1412"},{"SYMBOLID":"S*G*UCRVG-*****","DESCRIPTION":"Reconnaissance Cavalry Ground","MAPPING1U":"1413","MAPPING1F":"1414","MAPPING1N":"1415","MAPPING1H":"1416"},{"SYMBOLID":"S*G*UCRVO-*****","DESCRIPTION":"Reconnaissance Cavalry Air","MAPPING1U":"1417","MAPPING1F":"1418","MAPPING1N":"1419","MAPPING1H":"1420"},{"SYMBOLID":"S*G*UCRC--*****","DESCRIPTION":"Reconnaissance Arctic","MAPPING1U":"1421","MAPPING1F":"1422","MAPPING1N":"1423","MAPPING1H":"1424"},{"SYMBOLID":"S*G*UCRS--*****","DESCRIPTION":"Reconnaissance Air Assault","MAPPING1U":"1425","MAPPING1F":"1426","MAPPING1N":"1427","MAPPING1H":"1428"},{"SYMBOLID":"S*G*UCRA--*****","DESCRIPTION":"Reconnaissance Airborne","MAPPING1U":"1429","MAPPING1F":"1430","MAPPING1N":"1431","MAPPING1H":"1432"},{"SYMBOLID":"S*G*UCRO--*****","DESCRIPTION":"Reconnaissance Mountain","MAPPING1U":"1433","MAPPING1F":"1434","MAPPING1N":"1435","MAPPING1H":"1436"},{"SYMBOLID":"S*G*UCRL--*****","DESCRIPTION":"Reconnaissance Light","MAPPING1U":"1437","MAPPING1F":"1438","MAPPING1N":"1439","MAPPING1H":"1440"},{"SYMBOLID":"S*G*UCRR--*****","DESCRIPTION":"Reconnaissance Marine","MAPPING1U":"1441","MAPPING1F":"1442","MAPPING1N":"1443","MAPPING1H":"1444"},{"SYMBOLID":"S*G*UCRRD-*****","DESCRIPTION":"Reconnaissance Marine Division","MAPPING1U":"1445","MAPPING1F":"1446","MAPPING1N":"1447","MAPPING1H":"1448"},{"SYMBOLID":"S*G*UCRRF-*****","DESCRIPTION":"Reconnaissance Marine Force","MAPPING1U":"1449","MAPPING1F":"1450","MAPPING1N":"1451","MAPPING1H":"1452"},{"SYMBOLID":"S*G*UCRRL-*****","DESCRIPTION":"Reconnaissance Marine Light Armored (LAR)","MAPPING1U":"1453","MAPPING1F":"1454","MAPPING1N":"1455","MAPPING1H":"1456"},{"SYMBOLID":"S*G*UCRX--*****","DESCRIPTION":"Reconnaissance Long Range Surveillance (LRS)","MAPPING1U":"1457","MAPPING1F":"1458","MAPPING1N":"1459","MAPPING1H":"1460"},{"SYMBOLID":"S*G*UCM---*****","DESCRIPTION":"Missile (Surf-Surf)","MAPPING1U":"1461","MAPPING1F":"1461","MAPPING1N":"1461","MAPPING1H":"1461"},{"SYMBOLID":"S*G*UCMT--*****","DESCRIPTION":"Missile (Surf-Surf) Tactical","MAPPING1U":"1462","MAPPING1F":"1462","MAPPING1N":"1462","MAPPING1H":"1462"},{"SYMBOLID":"S*G*UCMS--*****","DESCRIPTION":"Missile (Surf-Surf) Strategic","MAPPING1U":"1463","MAPPING1F":"1463","MAPPING1N":"1463","MAPPING1H":"1463"},{"SYMBOLID":"S*G*UCS---*****","DESCRIPTION":"Internal Security Forces","MAPPING1U":"1464","MAPPING1F":"1464","MAPPING1N":"1464","MAPPING1H":"1464"},{"SYMBOLID":"S*G*UCSW--*****","DESCRIPTION":"Internal Security Forces Riverine","MAPPING1U":"1465","MAPPING1F":"1466","MAPPING1N":"1467","MAPPING1H":"1468"},{"SYMBOLID":"S*G*UCSG--*****","DESCRIPTION":"Internal Security Forces Ground","MAPPING1U":"1469","MAPPING1F":"1469","MAPPING1N":"1469","MAPPING1H":"1469"},{"SYMBOLID":"S*G*UCSGD-*****","DESCRIPTION":"Internal Security Forces Dismounted","MAPPING1U":"1470","MAPPING1F":"1471","MAPPING1N":"1472","MAPPING1H":"1473"},{"SYMBOLID":"S*G*UCSGM-*****","DESCRIPTION":"Internal Security Forces Motorized","MAPPING1U":"1474","MAPPING1F":"1475","MAPPING1N":"1476","MAPPING1H":"1477"},{"SYMBOLID":"S*G*UCSGA-*****","DESCRIPTION":"Internal Security Forces Mechanized","MAPPING1U":"1478","MAPPING1F":"1478","MAPPING1N":"1478","MAPPING1H":"1478"},{"SYMBOLID":"S*G*UCSM--*****","DESCRIPTION":"Internal Security Forces Wheeled Mechanized","MAPPING1U":"1479","MAPPING1F":"1479","MAPPING1N":"1479","MAPPING1H":"1479"},{"SYMBOLID":"S*G*UCSR--*****","DESCRIPTION":"Internal Security Forces Railroad","MAPPING1U":"1480","MAPPING1F":"1480","MAPPING1N":"1480","MAPPING1H":"1480"},{"SYMBOLID":"S*G*UCSA--*****","DESCRIPTION":"Internal Security Forces Aviation","MAPPING1U":"1481","MAPPING1F":"1481","MAPPING1N":"1481","MAPPING1H":"1481"},{"SYMBOLID":"S*G*UCL---*****","DESCRIPTION":"Surveillance Unit","MAPPING1U":"1890","MAPPING1F":"1890","MAPPING1N":"1890","MAPPING1H":"1890"},{"SYMBOLID":"S*G*UU----*****","DESCRIPTION":"Combat Support","MAPPING1U":"1482","MAPPING1F":"1482","MAPPING1N":"1482","MAPPING1H":"1482"},{"SYMBOLID":"S*G*UUA---*****","DESCRIPTION":"Combat Support NBC","MAPPING1U":"1483","MAPPING1F":"1483","MAPPING1N":"1483","MAPPING1H":"1483"},{"SYMBOLID":"S*G*UUAC--*****","DESCRIPTION":"Combat Support Chemical","MAPPING1U":"1484","MAPPING1F":"1484","MAPPING1N":"1484","MAPPING1H":"1484"},{"SYMBOLID":"S*G*UUACC-*****","DESCRIPTION":"Smoke/Decon","MAPPING1U":"1485","MAPPING1F":"1485","MAPPING1N":"1485","MAPPING1H":"1485"},{"SYMBOLID":"S*G*UUACCK*****","DESCRIPTION":"Mechanized Smoke/Decon","MAPPING1U":"1486","MAPPING1F":"1486","MAPPING1N":"1486","MAPPING1H":"1486"},{"SYMBOLID":"S*G*UUACCM*****","DESCRIPTION":"Motorized Smoke/Decon","MAPPING1U":"1487","MAPPING1F":"1488","MAPPING1N":"1489","MAPPING1H":"1490"},{"SYMBOLID":"S*G*UUACS-*****","DESCRIPTION":"Smoke","MAPPING1U":"1491","MAPPING1F":"1491","MAPPING1N":"1491","MAPPING1H":"1491"},{"SYMBOLID":"S*G*UUACSM*****","DESCRIPTION":"Motorized Smoke","MAPPING1U":"1492","MAPPING1F":"1493","MAPPING1N":"1494","MAPPING1H":"1495"},{"SYMBOLID":"S*G*UUACSA*****","DESCRIPTION":"Armor Smoke","MAPPING1U":"1496","MAPPING1F":"1496","MAPPING1N":"1496","MAPPING1H":"1496"},{"SYMBOLID":"S*G*UUACR-*****","DESCRIPTION":"Chemical Recon","MAPPING1U":"1497","MAPPING1F":"1498","MAPPING1N":"1499","MAPPING1H":"1500"},{"SYMBOLID":"S*G*UUACRW*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle","MAPPING1U":"1501","MAPPING1F":"1502","MAPPING1N":"1503","MAPPING1H":"1504"},{"SYMBOLID":"S*G*UUACRS*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle Reconnaissance Surveillance","MAPPING1U":"1505","MAPPING1F":"1506","MAPPING1N":"1507","MAPPING1H":"1508"},{"SYMBOLID":"S*G*UUAN--*****","DESCRIPTION":"Combat Support NBC Nuclear","MAPPING1U":"1509","MAPPING1F":"1509","MAPPING1N":"1509","MAPPING1H":"1509"},{"SYMBOLID":"S*G*UUAB--*****","DESCRIPTION":"Combat Support NBC Biological","MAPPING1U":"1510","MAPPING1F":"1510","MAPPING1N":"1510","MAPPING1H":"1510"},{"SYMBOLID":"S*G*UUABR-*****","DESCRIPTION":"Recon Equipped","MAPPING1U":"1511","MAPPING1F":"1512","MAPPING1N":"1513","MAPPING1H":"1514"},{"SYMBOLID":"S*G*UUAD--*****","DESCRIPTION":"NBC Decontamination","MAPPING1U":"1515","MAPPING1F":"1515","MAPPING1N":"1515","MAPPING1H":"1515"},{"SYMBOLID":"S*G*UUM---*****","DESCRIPTION":"Military Intelligence","MAPPING1U":"1516","MAPPING1F":"1516","MAPPING1N":"1516","MAPPING1H":"1516"},{"SYMBOLID":"S*G*UUMA--*****","DESCRIPTION":"Aerial Exploitation","MAPPING1U":"1517","MAPPING1F":"1517","MAPPING1N":"1517","MAPPING1H":"1517"},{"SYMBOLID":"S*G*UUMS--*****","DESCRIPTION":"Signal Intelligence (SIGINT)","MAPPING1U":"1518","MAPPING1F":"1518","MAPPING1N":"1518","MAPPING1H":"1518"},{"SYMBOLID":"S*G*UUMSE-*****","DESCRIPTION":"Electronic Warfare","MAPPING1U":"1519","MAPPING1F":"1519","MAPPING1N":"1519","MAPPING1H":"1519"},{"SYMBOLID":"S*G*UUMSEA*****","DESCRIPTION":"Armored Wheeled Vehicle","MAPPING1U":"600","MAPPING1F":"601","MAPPING1N":"602","MAPPING1H":"603","MAPPING2":"1520","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUMSED*****","DESCRIPTION":"Direction Finding","MAPPING1U":"1521","MAPPING1F":"1521","MAPPING1N":"1521","MAPPING1H":"1521"},{"SYMBOLID":"S*G*UUMSEI*****","DESCRIPTION":"Intercept","MAPPING1U":"1522","MAPPING1F":"1522","MAPPING1N":"1522","MAPPING1H":"1522"},{"SYMBOLID":"S*G*UUMSEJ*****","DESCRIPTION":"Jamming","MAPPING1U":"1523","MAPPING1F":"1524","MAPPING1N":"1525","MAPPING1H":"1526"},{"SYMBOLID":"S*G*UUMSET*****","DESCRIPTION":"Theater","MAPPING1U":"1527","MAPPING1F":"1528","MAPPING1N":"1529","MAPPING1H":"1530"},{"SYMBOLID":"S*G*UUMSEC*****","DESCRIPTION":"Corps","MAPPING1U":"1531","MAPPING1F":"1532","MAPPING1N":"1533","MAPPING1H":"1534"},{"SYMBOLID":"S*G*UUMC--*****","DESCRIPTION":"Counter Intelligence","MAPPING1U":"1535","MAPPING1F":"1535","MAPPING1N":"1535","MAPPING1H":"1535"},{"SYMBOLID":"S*G*UUMR--*****","DESCRIPTION":"Counter Intelligence Surveillance","MAPPING1U":"1536","MAPPING1F":"1536","MAPPING1N":"1536","MAPPING1H":"1536"},{"SYMBOLID":"S*G*UUMRG-*****","DESCRIPTION":"Ground Surveillance Radar","MAPPING1U":"1537","MAPPING1F":"1537","MAPPING1N":"1537","MAPPING1H":"1537"},{"SYMBOLID":"S*G*UUMRS-*****","DESCRIPTION":"Surveillance Sensor","MAPPING1U":"1538","MAPPING1F":"1539","MAPPING1N":"1540","MAPPING1H":"1541","MAPPING2":"1542","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUMRSS*****","DESCRIPTION":"Sensor SCM","MAPPING1U":"1543","MAPPING1F":"1544","MAPPING1N":"1545","MAPPING1H":"1546","MAPPING2":"1542","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUMRX-*****","DESCRIPTION":"Ground Station Module","MAPPING1U":"1547","MAPPING1F":"1547","MAPPING1N":"1547","MAPPING1H":"1547"},{"SYMBOLID":"S*G*UUMMO-*****","DESCRIPTION":"Surveillance Meteorological","MAPPING1U":"1548","MAPPING1F":"1548","MAPPING1N":"1548","MAPPING1H":"1548"},{"SYMBOLID":"S*G*UUMO--*****","DESCRIPTION":"Military Intelligence Operations","MAPPING1U":"1549","MAPPING1F":"1549","MAPPING1N":"1549","MAPPING1H":"1549"},{"SYMBOLID":"S*G*UUMT--*****","DESCRIPTION":"Tactical Exploit","MAPPING1U":"1550","MAPPING1F":"1550","MAPPING1N":"1550","MAPPING1H":"1550"},{"SYMBOLID":"S*G*UUMQ--*****","DESCRIPTION":"Interrogation","MAPPING1U":"1551","MAPPING1F":"1551","MAPPING1N":"1551","MAPPING1H":"1551"},{"SYMBOLID":"S*G*UUMJ--*****","DESCRIPTION":"Joint Intelligence Center","MAPPING1U":"1552","MAPPING1F":"1552","MAPPING1N":"1552","MAPPING1H":"1552"},{"SYMBOLID":"S*G*UUL---*****","DESCRIPTION":"Law Enforcement Unit","MAPPING1U":"1553","MAPPING1F":"1553","MAPPING1N":"1553","MAPPING1H":"1553"},{"SYMBOLID":"S*G*UULS--*****","DESCRIPTION":"Shore Patrol","MAPPING1U":"1554","MAPPING1F":"1554","MAPPING1N":"1554","MAPPING1H":"1554"},{"SYMBOLID":"S*G*UULM--*****","DESCRIPTION":"Military Police","MAPPING1U":"1555","MAPPING1F":"1555","MAPPING1N":"1555","MAPPING1H":"1555"},{"SYMBOLID":"S*G*UULC--*****","DESCRIPTION":"Civilian Law Enforcement","MAPPING1U":"1556","MAPPING1F":"1556","MAPPING1N":"1556","MAPPING1H":"1556"},{"SYMBOLID":"S*G*UULF--*****","DESCRIPTION":"Security Police (Air)","MAPPING1U":"1557","MAPPING1F":"1557","MAPPING1N":"1557","MAPPING1H":"1557"},{"SYMBOLID":"S*G*UULD--*****","DESCRIPTION":"Central Intelligence Division (CID)","MAPPING1U":"1558","MAPPING1F":"1558","MAPPING1N":"1558","MAPPING1H":"1558"},{"SYMBOLID":"S*G*UUS---*****","DESCRIPTION":"Signal Unit","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562"},{"SYMBOLID":"S*G*UUSA--*****","DESCRIPTION":"Area","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1563","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSC--*****","DESCRIPTION":"Communication Configured Package","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1564","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSCL-*****","DESCRIPTION":"Large Communication Configured Package (LCCP)","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1565","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSO--*****","DESCRIPTION":"Command Operations","MAPPING1U":"1559","MAPPING2":"1566","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSF--*****","DESCRIPTION":"Forward Communications","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1567","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSM--*****","DESCRIPTION":"Multiple Subscriber Element","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1568","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSMS-*****","DESCRIPTION":"Small Extension Node","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1569","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSML-*****","DESCRIPTION":"Large Extension Node","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1570","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSMN-*****","DESCRIPTION":"Node Center","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1571","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSR--*****","DESCRIPTION":"Radio Unit","MAPPING1U":"1572","MAPPING1F":"1573","MAPPING1N":"1574","MAPPING1H":"1575"},{"SYMBOLID":"S*G*UUSRS-*****","DESCRIPTION":"Tactical Satellite","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1576","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSRT-*****","DESCRIPTION":"Teletype Center","MAPPING1U":"1577","MAPPING1F":"1578","MAPPING1N":"1579","MAPPING1H":"1580"},{"SYMBOLID":"S*G*UUSRW-*****","DESCRIPTION":"Relay","MAPPING1U":"1581","MAPPING1F":"1582","MAPPING1N":"1583","MAPPING1H":"1584"},{"SYMBOLID":"S*G*UUSS--*****","DESCRIPTION":"Signal Support","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1585","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSW--*****","DESCRIPTION":"Telephone Switch","MAPPING1U":"1586","MAPPING1F":"1587","MAPPING1N":"1588","MAPPING1H":"1589"},{"SYMBOLID":"S*G*UUSX--*****","DESCRIPTION":"Electronic Ranging","MAPPING1U":"1590","MAPPING1F":"1590","MAPPING1N":"1590","MAPPING1H":"1590","MAPPING2":"1591","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUI---*****","DESCRIPTION":"Information Warfare Unit","MAPPING1U":"1592","MAPPING1F":"1592","MAPPING1N":"1592","MAPPING1H":"1592"},{"SYMBOLID":"S*G*UUP---*****","DESCRIPTION":"Landing Support","MAPPING1U":"612","MAPPING1F":"613","MAPPING1N":"614","MAPPING1H":"615","MAPPING2":"1593","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUE---*****","DESCRIPTION":"Explosive Ordnance Disposal","MAPPING1U":"1594","MAPPING1F":"1594","MAPPING1N":"1594","MAPPING1H":"1594"},{"SYMBOLID":"S*G*US----*****","DESCRIPTION":"Combat Service Support","MAPPING1U":"1595","MAPPING1F":"1595","MAPPING1N":"1595","MAPPING1H":"1595"},{"SYMBOLID":"S*G*USA---*****","DESCRIPTION":"Administrative (ADMIN)","MAPPING1U":"1596","MAPPING1F":"1596","MAPPING1N":"1596","MAPPING1H":"1596"},{"SYMBOLID":"S*G*USAT--*****","DESCRIPTION":"Admin Theater","MAPPING1U":"1597","MAPPING1F":"1598","MAPPING1N":"1599","MAPPING1H":"1600"},{"SYMBOLID":"S*G*USAC--*****","DESCRIPTION":"Admin Corps","MAPPING1U":"1601","MAPPING1F":"1602","MAPPING1N":"1603","MAPPING1H":"1604"},{"SYMBOLID":"S*G*USAJ--*****","DESCRIPTION":"Judge Advocate General (JAG)","MAPPING1U":"1605","MAPPING1F":"1605","MAPPING1N":"1605","MAPPING1H":"1605"},{"SYMBOLID":"S*G*USAJT-*****","DESCRIPTION":"JAG Theater","MAPPING1U":"1606","MAPPING1F":"1607","MAPPING1N":"1608","MAPPING1H":"1609"},{"SYMBOLID":"S*G*USAJC-*****","DESCRIPTION":"JAG Corps","MAPPING1U":"1610","MAPPING1F":"1611","MAPPING1N":"1612","MAPPING1H":"1613"},{"SYMBOLID":"S*G*USAO--*****","DESCRIPTION":"Postal","MAPPING1U":"1614","MAPPING1F":"1614","MAPPING1N":"1614","MAPPING1H":"1614"},{"SYMBOLID":"S*G*USAOT-*****","DESCRIPTION":"Postal Theater","MAPPING1U":"1615","MAPPING1F":"1616","MAPPING1N":"1617","MAPPING1H":"1618"},{"SYMBOLID":"S*G*USAOC-*****","DESCRIPTION":"Postal Corps","MAPPING1U":"1619","MAPPING1F":"1620","MAPPING1N":"1621","MAPPING1H":"1622"},{"SYMBOLID":"S*G*USAF--*****","DESCRIPTION":"Finance","MAPPING1U":"1623","MAPPING1F":"1623","MAPPING1N":"1623","MAPPING1H":"1623"},{"SYMBOLID":"S*G*USAFT-*****","DESCRIPTION":"Finance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1623","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAFC-*****","DESCRIPTION":"Finance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1623","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAS--*****","DESCRIPTION":"Personnel Services","MAPPING1U":"1624","MAPPING1F":"1624","MAPPING1N":"1624","MAPPING1H":"1624"},{"SYMBOLID":"S*G*USAST-*****","DESCRIPTION":"Personnel Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1624","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USASC-*****","DESCRIPTION":"Personnel Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1624","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAM--*****","DESCRIPTION":"Mortuary/Graves Registry","MAPPING1U":"1625","MAPPING1F":"1625","MAPPING1N":"1625","MAPPING1H":"1625"},{"SYMBOLID":"S*G*USAMT-*****","DESCRIPTION":"Mortuary/Graves Registry Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1625","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAMC-*****","DESCRIPTION":"Mortuary/Graves Registry Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1625","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAR--*****","DESCRIPTION":"Religious/Chaplain","MAPPING1U":"1626","MAPPING1F":"1626","MAPPING1N":"1626","MAPPING1H":"1626"},{"SYMBOLID":"S*G*USART-*****","DESCRIPTION":"Religious/Chaplain Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1626","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USARC-*****","DESCRIPTION":"Religious/Chaplain Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1626","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAP--*****","DESCRIPTION":"Public Affairs","MAPPING1U":"1627","MAPPING1F":"1627","MAPPING1N":"1627","MAPPING1H":"1627"},{"SYMBOLID":"S*G*USAPT-*****","DESCRIPTION":"Public Affairs Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1627","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPC-*****","DESCRIPTION":"Public Affairs Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1627","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPB-*****","DESCRIPTION":"Public Affairs Broadcast","MAPPING1U":"1628","MAPPING1F":"1628","MAPPING1N":"1628","MAPPING1H":"1628"},{"SYMBOLID":"S*G*USAPBT*****","DESCRIPTION":"Public Affairs Broadcast Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1628","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPBC*****","DESCRIPTION":"Public Affairs Broadcast Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1628","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPM-*****","DESCRIPTION":"Public Affairs Joint Information Bureau (JIB)","MAPPING1U":"1630","MAPPING1F":"1630","MAPPING1N":"1630","MAPPING1H":"1630"},{"SYMBOLID":"S*G*USAPMT*****","DESCRIPTION":"Public Affairs JIB Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1630","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPMC*****","DESCRIPTION":"Public Affairs JIB Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1630","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAX--*****","DESCRIPTION":"Replacement Holding Unit (RHU)","MAPPING1U":"1631","MAPPING1F":"1631","MAPPING1N":"1631","MAPPING1H":"1631"},{"SYMBOLID":"S*G*USAXT-*****","DESCRIPTION":"RHU Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1631","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAXC-*****","DESCRIPTION":"RHU Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1631","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAL--*****","DESCRIPTION":"Labor","MAPPING1U":"1633","MAPPING1F":"1633","MAPPING1N":"1633","MAPPING1H":"1633"},{"SYMBOLID":"S*G*USALT-*****","DESCRIPTION":"Labor Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1633","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USALC-*****","DESCRIPTION":"Labor Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1633","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAW--*****","DESCRIPTION":"Morale, Welfare, Recreation (MWR)","MAPPING1U":"1634","MAPPING1F":"1634","MAPPING1N":"1634","MAPPING1H":"1634"},{"SYMBOLID":"S*G*USAWT-*****","DESCRIPTION":"MWR Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1634","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAWC-*****","DESCRIPTION":"MWR Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1634","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAQ--*****","DESCRIPTION":"Quartermaster (Supply)","MAPPING1U":"1636","MAPPING1F":"1636","MAPPING1N":"1636","MAPPING1H":"1636"},{"SYMBOLID":"S*G*USAQT-*****","DESCRIPTION":"Quartermaster (Supply) Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1636","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAQC-*****","DESCRIPTION":"Quartermaster (Supply) Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1636","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USM---*****","DESCRIPTION":"Medical","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640"},{"SYMBOLID":"S*G*USMT--*****","DESCRIPTION":"Medical Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644"},{"SYMBOLID":"S*G*USMC--*****","DESCRIPTION":"Medical Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648"},{"SYMBOLID":"S*G*USMM--*****","DESCRIPTION":"Medical Treatment Facility","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMMT-*****","DESCRIPTION":"Medical Treatment Facility Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMMC-*****","DESCRIPTION":"Medical Treatment Facility Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMV--*****","DESCRIPTION":"Medical Veterinary","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMVT-*****","DESCRIPTION":"Medical Veterinary Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMVC-*****","DESCRIPTION":"Medical Veterinary Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMD--*****","DESCRIPTION":"Medical Dental","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMDT-*****","DESCRIPTION":"Medical Dental Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMDC-*****","DESCRIPTION":"Medical Dental Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMP--*****","DESCRIPTION":"Medical Psychological","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMPT-*****","DESCRIPTION":"Medical Psychological Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMPC-*****","DESCRIPTION":"Medical Psychological Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS---*****","DESCRIPTION":"Supply","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656"},{"SYMBOLID":"S*G*USST--*****","DESCRIPTION":"Supply Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660"},{"SYMBOLID":"S*G*USSC--*****","DESCRIPTION":"Supply Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664"},{"SYMBOLID":"S*G*USS1--*****","DESCRIPTION":"Supply Class I","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS1T-*****","DESCRIPTION":"Supply Class I Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS1C-*****","DESCRIPTION":"Supply Class I Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2--*****","DESCRIPTION":"Supply Class II","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2T-*****","DESCRIPTION":"Supply Class II Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2C-*****","DESCRIPTION":"Supply Class II Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3--*****","DESCRIPTION":"Supply Class III","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3T-*****","DESCRIPTION":"Supply Class III Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3C-*****","DESCRIPTION":"Supply Class III Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3A-*****","DESCRIPTION":"Supply Class III Aviation","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3AT*****","DESCRIPTION":"Supply Class III Aviation Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3AC*****","DESCRIPTION":"Supply Class III Aviation Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4--*****","DESCRIPTION":"Supply Class IV","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4T-*****","DESCRIPTION":"Supply Class IV Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4C-*****","DESCRIPTION":"Supply Class IV Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5--*****","DESCRIPTION":"Supply Class V","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5T-*****","DESCRIPTION":"Supply Class V Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5C-*****","DESCRIPTION":"Supply Class V Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6--*****","DESCRIPTION":"Supply Class VI","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6T-*****","DESCRIPTION":"Supply Class VI Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6C-*****","DESCRIPTION":"Supply Class VI Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7--*****","DESCRIPTION":"Supply Class VII","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7T-*****","DESCRIPTION":"Supply Class VII Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7C-*****","DESCRIPTION":"Supply Class VII Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS8--*****","DESCRIPTION":"Supply Class VIII","MAPPING1U":"1673","MAPPING1F":"1674","MAPPING1N":"1675","MAPPING1H":"1676"},{"SYMBOLID":"S*G*USS8T-*****","DESCRIPTION":"Supply Class VIII Theater","MAPPING1U":"1677","MAPPING1F":"1678","MAPPING1N":"1679","MAPPING1H":"1680"},{"SYMBOLID":"S*G*USS8C-*****","DESCRIPTION":"Supply Class VIII Corps","MAPPING1U":"1681","MAPPING1F":"1682","MAPPING1N":"1683","MAPPING1H":"1684"},{"SYMBOLID":"S*G*USS9--*****","DESCRIPTION":"Supply Class IX","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS9T-*****","DESCRIPTION":"Supply Class IX Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS9C-*****","DESCRIPTION":"Supply Class IX Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSX--*****","DESCRIPTION":"Supply Class X","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSXT-*****","DESCRIPTION":"Supply Class X Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSXC-*****","DESCRIPTION":"Supply Class X Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSL--*****","DESCRIPTION":"Supply Laundry/Bath","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSLT-*****","DESCRIPTION":"Supply Laundry/Bath Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSLC-*****","DESCRIPTION":"Supply Laundry/Bath Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSW--*****","DESCRIPTION":"Supply Water","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWT-*****","DESCRIPTION":"Supply Water Theater","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWC-*****","DESCRIPTION":"Supply Water Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWP-*****","DESCRIPTION":"Supply Water Purification","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWPT*****","DESCRIPTION":"Supply Water Purification Theater","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWPC*****","DESCRIPTION":"Supply Water Purification Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UST---*****","DESCRIPTION":"Transportation","MAPPING1U":"1690","MAPPING1F":"1690","MAPPING1N":"1690","MAPPING1H":"1690"},{"SYMBOLID":"S*G*USTT--*****","DESCRIPTION":"Transportation Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1690","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTC--*****","DESCRIPTION":"Transportation Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1690","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTM--*****","DESCRIPTION":"Movement Control Center (MCC)","MAPPING1U":"1691","MAPPING1F":"1691","MAPPING1N":"1691","MAPPING1H":"1691"},{"SYMBOLID":"S*G*USTMT-*****","DESCRIPTION":"MCC Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1691","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTMC-*****","DESCRIPTION":"MCC Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1691","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTR--*****","DESCRIPTION":"Railhead","MAPPING1U":"1692","MAPPING1F":"1692","MAPPING1N":"1692","MAPPING1H":"1692"},{"SYMBOLID":"S*G*USTRT-*****","DESCRIPTION":"Railhead Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1692","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTRC-*****","DESCRIPTION":"Railhead Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1692","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTS--*****","DESCRIPTION":"SPOD/SPOE","MAPPING1U":"1693","MAPPING1F":"1693","MAPPING1N":"1693","MAPPING1H":"1693"},{"SYMBOLID":"S*G*USTST-*****","DESCRIPTION":"SPOD/SPOE Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1693","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTSC-*****","DESCRIPTION":"SPOD/SPOE Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1693","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTA--*****","DESCRIPTION":"APOD/APOE","MAPPING1U":"1694","MAPPING1F":"1694","MAPPING1N":"1694","MAPPING1H":"1694"},{"SYMBOLID":"S*G*USTAT-*****","DESCRIPTION":"APOD/APOE Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1694","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTAC-*****","DESCRIPTION":"APOD/APOE Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1694","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTI--*****","DESCRIPTION":"Missile","MAPPING1U":"1695","MAPPING1F":"1695","MAPPING1N":"1695","MAPPING1H":"1695"},{"SYMBOLID":"S*G*USTIT-*****","DESCRIPTION":"Missile Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1695","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTIC-*****","DESCRIPTION":"Missile Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1695","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USX---*****","DESCRIPTION":"Maintenance","MAPPING1U":"1696","MAPPING1F":"1696","MAPPING1N":"1696","MAPPING1H":"1696"},{"SYMBOLID":"S*G*USXT--*****","DESCRIPTION":"Maintenance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1696","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXC--*****","DESCRIPTION":"Maintenance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1696","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXH--*****","DESCRIPTION":"Maintenance Heavy","MAPPING1U":"1697","MAPPING1F":"1697","MAPPING1N":"1697","MAPPING1H":"1697"},{"SYMBOLID":"S*G*USXHT-*****","DESCRIPTION":"Maintenance Heavy Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1697","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXHC-*****","DESCRIPTION":"Maintenance Heavy Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1697","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXR--*****","DESCRIPTION":"Maintenance Recovery","MAPPING1U":"1698","MAPPING1F":"1698","MAPPING1N":"1698","MAPPING1H":"1698"},{"SYMBOLID":"S*G*USXRT-*****","DESCRIPTION":"Maintenance Recovery Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1698","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXRC-*****","DESCRIPTION":"Maintenance Recovery Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1698","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXO--*****","DESCRIPTION":"Ordnance","MAPPING1U":"1699","MAPPING1F":"1699","MAPPING1N":"1699","MAPPING1H":"1699"},{"SYMBOLID":"S*G*USXOT-*****","DESCRIPTION":"Ordnance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1699","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOC-*****","DESCRIPTION":"Ordnance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1699","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOM-*****","DESCRIPTION":"Ordnance Missile","MAPPING1U":"1700","MAPPING1F":"1700","MAPPING1N":"1700","MAPPING1H":"1700"},{"SYMBOLID":"S*G*USXOMT*****","DESCRIPTION":"Ordnance Missile Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1700","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOMC*****","DESCRIPTION":"Ordnance Missile Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1700","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXE--*****","DESCRIPTION":"Electro-Optical","MAPPING1U":"1701","MAPPING1F":"1701","MAPPING1N":"1701","MAPPING1H":"1701"},{"SYMBOLID":"S*G*USXET-*****","DESCRIPTION":"Electro-Optical Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1701","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXEC-*****","DESCRIPTION":"Electro-Optical Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1701","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UH----*****","DESCRIPTION":"Special C2 Headquarters Component"},{"SYMBOLID":"S*G*E-----*****","DESCRIPTION":"Ground Track Equipment"},{"SYMBOLID":"S*G*EW----*****","DESCRIPTION":"Weapon"},{"SYMBOLID":"S*G*EWM---*****","DESCRIPTION":"Missile Launcher","MAPPING1U":"1702","MAPPING1F":"1702","MAPPING1N":"1702","MAPPING1H":"1702"},{"SYMBOLID":"S*G*EWMA--*****","DESCRIPTION":"Air Defense (AD) Missile Launcher","MAPPING1U":"1703","MAPPING1F":"1703","MAPPING1N":"1703","MAPPING1H":"1703"},{"SYMBOLID":"S*G*EWMAS-*****","DESCRIPTION":"Short Range AD Missile Launcher","MAPPING1U":"1704","MAPPING1F":"1704","MAPPING1N":"1704","MAPPING1H":"1704"},{"SYMBOLID":"S*G*EWMASR*****","DESCRIPTION":"Short Range Transporter Launcher and Radar (TLAR)","MAPPING1U":"1705","MAPPING1F":"1705","MAPPING1N":"1705","MAPPING1H":"1705"},{"SYMBOLID":"S*G*EWMASE*****","DESCRIPTION":"Short Range Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1706","MAPPING1F":"1706","MAPPING1N":"1706","MAPPING1H":"1706"},{"SYMBOLID":"S*G*EWMAI-*****","DESCRIPTION":"Intermediate Range AD Missile Launcher","MAPPING1U":"1707","MAPPING1F":"1707","MAPPING1N":"1707","MAPPING1H":"1707"},{"SYMBOLID":"S*G*EWMAIR*****","DESCRIPTION":"Intermediate Transporter Launcher and Radar (TLAR)","MAPPING1U":"1708","MAPPING1F":"1708","MAPPING1N":"1708","MAPPING1H":"1708"},{"SYMBOLID":"S*G*EWMAIE*****","DESCRIPTION":"Intermediate Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1709","MAPPING1F":"1709","MAPPING1N":"1709","MAPPING1H":"1709"},{"SYMBOLID":"S*G*EWMAL-*****","DESCRIPTION":"Long Range AD Missile Launcher","MAPPING1U":"1710","MAPPING1F":"1710","MAPPING1N":"1710","MAPPING1H":"1710"},{"SYMBOLID":"S*G*EWMALR*****","DESCRIPTION":"Long Range Transporter Launcher and Radar (TLAR)","MAPPING1U":"1711","MAPPING1F":"1711","MAPPING1N":"1711","MAPPING1H":"1711"},{"SYMBOLID":"S*G*EWMALE*****","DESCRIPTION":"Long Range Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1712","MAPPING1F":"1712","MAPPING1N":"1712","MAPPING1H":"1712"},{"SYMBOLID":"S*G*EWMAT-*****","DESCRIPTION":"AD Missile Launcher Theater","MAPPING1U":"1713","MAPPING1F":"1713","MAPPING1N":"1713","MAPPING1H":"1713"},{"SYMBOLID":"S*G*EWMATR*****","DESCRIPTION":"Theater Transporter Launcher and Radar (TLAR)","MAPPING1U":"1714","MAPPING1F":"1714","MAPPING1N":"1714","MAPPING1H":"1714"},{"SYMBOLID":"S*G*EWMATE*****","DESCRIPTION":"Theater Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1715","MAPPING1F":"1715","MAPPING1N":"1715","MAPPING1H":"1715"},{"SYMBOLID":"S*G*EWMS--*****","DESCRIPTION":"Surf-Surf (SS) Missile Launcher","MAPPING1U":"1716","MAPPING1F":"1716","MAPPING1N":"1716","MAPPING1H":"1716"},{"SYMBOLID":"S*G*EWMSS-*****","DESCRIPTION":"Short Range SS Missile Launcher","MAPPING1U":"1717","MAPPING1F":"1717","MAPPING1N":"1717","MAPPING1H":"1717"},{"SYMBOLID":"S*G*EWMSI-*****","DESCRIPTION":"Intermediate Range SS Missile Launcher","MAPPING1U":"1718","MAPPING1F":"1718","MAPPING1N":"1718","MAPPING1H":"1718"},{"SYMBOLID":"S*G*EWMSL-*****","DESCRIPTION":"Long Range SS Missile Launcher","MAPPING1U":"1719","MAPPING1F":"1719","MAPPING1N":"1719","MAPPING1H":"1719"},{"SYMBOLID":"S*G*EWMT--*****","DESCRIPTION":"Missile Launcher Antitank (AT)","MAPPING1U":"1720","MAPPING1F":"1720","MAPPING1N":"1720","MAPPING1H":"1720"},{"SYMBOLID":"S*G*EWMTL-*****","DESCRIPTION":"Missile Launcher AT Light","MAPPING1U":"1721","MAPPING1F":"1721","MAPPING1N":"1721","MAPPING1H":"1721"},{"SYMBOLID":"S*G*EWMTM-*****","DESCRIPTION":"Missile Launcher AT Medium","MAPPING1U":"1722","MAPPING1F":"1722","MAPPING1N":"1722","MAPPING1H":"1722"},{"SYMBOLID":"S*G*EWMTH-*****","DESCRIPTION":"Missile Launcher AT Heavy","MAPPING1U":"1723","MAPPING1F":"1723","MAPPING1N":"1723","MAPPING1H":"1723"},{"SYMBOLID":"S*G*EWS---*****","DESCRIPTION":"Weapon Single Rocket Launcher","MAPPING1U":"1724","MAPPING1F":"1724","MAPPING1N":"1724","MAPPING1H":"1724"},{"SYMBOLID":"S*G*EWSL--*****","DESCRIPTION":"Single Rocket Launcher Light","MAPPING1U":"1725","MAPPING1F":"1725","MAPPING1N":"1725","MAPPING1H":"1725"},{"SYMBOLID":"S*G*EWSM--*****","DESCRIPTION":"Single Rocket Launcher Medium","MAPPING1U":"1726","MAPPING1F":"1726","MAPPING1N":"1726","MAPPING1H":"1726"},{"SYMBOLID":"S*G*EWSH--*****","DESCRIPTION":"Single Rocket Launcher Heavy","MAPPING1U":"1727","MAPPING1F":"1727","MAPPING1N":"1727","MAPPING1H":"1727"},{"SYMBOLID":"S*G*EWX---*****","DESCRIPTION":"Multiple Rocket Launcher","MAPPING1U":"1728","MAPPING1F":"1728","MAPPING1N":"1728","MAPPING1H":"1728"},{"SYMBOLID":"S*G*EWXL--*****","DESCRIPTION":"Multiple Rocket Launcher Light","MAPPING1U":"1729","MAPPING1F":"1729","MAPPING1N":"1729","MAPPING1H":"1729"},{"SYMBOLID":"S*G*EWXM--*****","DESCRIPTION":"Multiple Rocket Launcher Medium","MAPPING1U":"1730","MAPPING1F":"1730","MAPPING1N":"1730","MAPPING1H":"1730"},{"SYMBOLID":"S*G*EWXH--*****","DESCRIPTION":"Multiple Rocket Launcher Heavy","MAPPING1U":"1731","MAPPING1F":"1731","MAPPING1N":"1731","MAPPING1H":"1731"},{"SYMBOLID":"S*G*EWT---*****","DESCRIPTION":"Anti-Tank Rocket Launcher","MAPPING1U":"1732","MAPPING1F":"1732","MAPPING1N":"1732","MAPPING1H":"1732"},{"SYMBOLID":"S*G*EWTL--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Light","MAPPING1U":"1733","MAPPING1F":"1733","MAPPING1N":"1733","MAPPING1H":"1733"},{"SYMBOLID":"S*G*EWTM--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Medium","MAPPING1U":"1734","MAPPING1F":"1734","MAPPING1N":"1734","MAPPING1H":"1734"},{"SYMBOLID":"S*G*EWTH--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Heavy","MAPPING1U":"1735","MAPPING1F":"1735","MAPPING1N":"1735","MAPPING1H":"1735"},{"SYMBOLID":"S*G*EWR---*****","DESCRIPTION":"Rifle/Automatic Weapon","MAPPING1U":"1736","MAPPING1F":"1736","MAPPING1N":"1736","MAPPING1H":"1736"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Rifle","MAPPING1U":"1737","MAPPING1F":"1737","MAPPING1N":"1737","MAPPING1H":"1737"},{"SYMBOLID":"S*G*EWRL--*****","DESCRIPTION":"Light Machine Gun","MAPPING1U":"1738","MAPPING1F":"1738","MAPPING1N":"1738","MAPPING1H":"1738"},{"SYMBOLID":"S*G*EWRH--*****","DESCRIPTION":"Heavy Machine Gun","MAPPING1U":"1739","MAPPING1F":"1739","MAPPING1N":"1739","MAPPING1H":"1739"},{"SYMBOLID":"S*G*EWZ---*****","DESCRIPTION":"Grenade Launcher","MAPPING1U":"1740","MAPPING1F":"1740","MAPPING1N":"1740","MAPPING1H":"1740"},{"SYMBOLID":"S*G*EWZL--*****","DESCRIPTION":"Grenade Launcher Light","MAPPING1U":"1741","MAPPING1F":"1741","MAPPING1N":"1741","MAPPING1H":"1741"},{"SYMBOLID":"S*G*EWZM--*****","DESCRIPTION":"Grenade Launcher Medium","MAPPING1U":"1742","MAPPING1F":"1742","MAPPING1N":"1742","MAPPING1H":"1742"},{"SYMBOLID":"S*G*EWZH--*****","DESCRIPTION":"Grenade Launcher Heavy","MAPPING1U":"1743","MAPPING1F":"1743","MAPPING1N":"1743","MAPPING1H":"1743"},{"SYMBOLID":"S*G*EWO---*****","DESCRIPTION":"Weapon Mortar","MAPPING1U":"1744","MAPPING1F":"1744","MAPPING1N":"1744","MAPPING1H":"1744"},{"SYMBOLID":"S*G*EWOL--*****","DESCRIPTION":"Mortar Light","MAPPING1U":"1745","MAPPING1F":"1745","MAPPING1N":"1745","MAPPING1H":"1745"},{"SYMBOLID":"S*G*EWOM--*****","DESCRIPTION":"Mortar Medium","MAPPING1U":"1746","MAPPING1F":"1746","MAPPING1N":"1746","MAPPING1H":"1746"},{"SYMBOLID":"S*G*EWOH--*****","DESCRIPTION":"Mortar Heavy","MAPPING1U":"1747","MAPPING1F":"1747","MAPPING1N":"1747","MAPPING1H":"1747"},{"SYMBOLID":"S*G*EWH---*****","DESCRIPTION":"Howitzer","MAPPING1U":"1748","MAPPING1F":"1748","MAPPING1N":"1748","MAPPING1H":"1748"},{"SYMBOLID":"S*G*EWHL--*****","DESCRIPTION":"Howitzer Light","MAPPING1U":"1749","MAPPING1F":"1749","MAPPING1N":"1749","MAPPING1H":"1749"},{"SYMBOLID":"S*G*EWHLS-*****","DESCRIPTION":"Howitzer Light Self-Propelled","MAPPING1U":"1750","MAPPING1F":"1750","MAPPING1N":"1750","MAPPING1H":"1750"},{"SYMBOLID":"S*G*EWHM--*****","DESCRIPTION":"Howitzer Medium","MAPPING1U":"1751","MAPPING1F":"1751","MAPPING1N":"1751","MAPPING1H":"1751"},{"SYMBOLID":"S*G*EWHMS-*****","DESCRIPTION":"Howitzer Medium Self-Propelled","MAPPING1U":"1752","MAPPING1F":"1752","MAPPING1N":"1752","MAPPING1H":"1752"},{"SYMBOLID":"S*G*EWHH--*****","DESCRIPTION":"Howitzer Heavy","MAPPING1U":"1753","MAPPING1F":"1753","MAPPING1N":"1753","MAPPING1H":"1753"},{"SYMBOLID":"S*G*EWHHS-*****","DESCRIPTION":"Howitzer Heavy Self-Propelled","MAPPING1U":"1754","MAPPING1F":"1754","MAPPING1N":"1754","MAPPING1H":"1754"},{"SYMBOLID":"S*G*EWG---*****","DESCRIPTION":"Anti-Tank Gun","MAPPING1U":"1755","MAPPING1F":"1755","MAPPING1N":"1755","MAPPING1H":"1755"},{"SYMBOLID":"S*G*EWGL--*****","DESCRIPTION":"Anti-Tank Gun Light","MAPPING1U":"1756","MAPPING1F":"1756","MAPPING1N":"1756","MAPPING1H":"1756"},{"SYMBOLID":"S*G*EWGM--*****","DESCRIPTION":"Anti-Tank Gun Medium","MAPPING1U":"1757","MAPPING1F":"1757","MAPPING1N":"1757","MAPPING1H":"1757"},{"SYMBOLID":"S*G*EWGH--*****","DESCRIPTION":"Anti-Tank Gun Heavy","MAPPING1U":"1758","MAPPING1F":"1758","MAPPING1N":"1758","MAPPING1H":"1758"},{"SYMBOLID":"S*G*EWGR--*****","DESCRIPTION":"Anti-Tank Gun Recoilless","MAPPING1U":"1759","MAPPING1F":"1759","MAPPING1N":"1759","MAPPING1H":"1759"},{"SYMBOLID":"S*G*EWD---*****","DESCRIPTION":"Direct Fire Gun","MAPPING1U":"1760","MAPPING1F":"1760","MAPPING1N":"1760","MAPPING1H":"1760"},{"SYMBOLID":"S*G*EWDL--*****","DESCRIPTION":"Direct Fire Gun Light","MAPPING1U":"1761","MAPPING1F":"1761","MAPPING1N":"1761","MAPPING1H":"1761"},{"SYMBOLID":"S*G*EWDLS-*****","DESCRIPTION":"Direct Fire Gun Light Self-Propelled","MAPPING1U":"1762","MAPPING1F":"1762","MAPPING1N":"1762","MAPPING1H":"1762"},{"SYMBOLID":"S*G*EWDM--*****","DESCRIPTION":"Direct Fire Gun Medium","MAPPING1U":"1763","MAPPING1F":"1763","MAPPING1N":"1763","MAPPING1H":"1763"},{"SYMBOLID":"S*G*EWDMS-*****","DESCRIPTION":"Direct Fire Gun Medium Self-Propelled","MAPPING1U":"1764","MAPPING1F":"1764","MAPPING1N":"1764","MAPPING1H":"1764"},{"SYMBOLID":"S*G*EWDH--*****","DESCRIPTION":"Direct Fire Gun Heavy","MAPPING1U":"1765","MAPPING1F":"1765","MAPPING1N":"1765","MAPPING1H":"1765"},{"SYMBOLID":"S*G*EWDHS-*****","DESCRIPTION":"Direct Fire Gun Heavy Self-Propelled","MAPPING1U":"1766","MAPPING1F":"1766","MAPPING1N":"1766","MAPPING1H":"1766"},{"SYMBOLID":"S*G*EWA---*****","DESCRIPTION":"Air Defense Gun","MAPPING1U":"1767","MAPPING1F":"1767","MAPPING1N":"1767","MAPPING1H":"1767"},{"SYMBOLID":"S*G*EWAL--*****","DESCRIPTION":"Air Defense Gun Light","MAPPING1U":"1768","MAPPING1F":"1768","MAPPING1N":"1768","MAPPING1H":"1768"},{"SYMBOLID":"S*G*EWAM--*****","DESCRIPTION":"Air Defense Gun Medium","MAPPING1U":"1769","MAPPING1F":"1769","MAPPING1N":"1769","MAPPING1H":"1769"},{"SYMBOLID":"S*G*EWAH--*****","DESCRIPTION":"Air Defense Gun Heavy","MAPPING1U":"1770","MAPPING1F":"1770","MAPPING1N":"1770","MAPPING1H":"1770"},{"SYMBOLID":"S*G*EV----*****","DESCRIPTION":"Ground Vehicle","MAPPING1U":"1771","MAPPING1F":"1771","MAPPING1N":"1771","MAPPING1H":"1771"},{"SYMBOLID":"S*G*EVA---*****","DESCRIPTION":"Armored Vehicle","MAPPING1U":"1772","MAPPING1F":"1772","MAPPING1N":"1772","MAPPING1H":"1772"},{"SYMBOLID":"S*G*EVAT--*****","DESCRIPTION":"Tank","MAPPING1U":"1773","MAPPING1F":"1773","MAPPING1N":"1773","MAPPING1H":"1773"},{"SYMBOLID":"S*G*EVATL-*****","DESCRIPTION":"Tank Light","MAPPING1U":"1774","MAPPING1F":"1774","MAPPING1N":"1774","MAPPING1H":"1774"},{"SYMBOLID":"S*G*EVATLR*****","DESCRIPTION":"Tank Light Recovery","MAPPING1U":"1775","MAPPING1F":"1775","MAPPING1N":"1775","MAPPING1H":"1775"},{"SYMBOLID":"S*G*EVATM-*****","DESCRIPTION":"Tank Medium","MAPPING1U":"1776","MAPPING1F":"1776","MAPPING1N":"1776","MAPPING1H":"1776"},{"SYMBOLID":"S*G*EVATMR*****","DESCRIPTION":"Tank Medium Recovery","MAPPING1U":"1777","MAPPING1F":"1777","MAPPING1N":"1777","MAPPING1H":"1777"},{"SYMBOLID":"S*G*EVATH-*****","DESCRIPTION":"Tank Heavy","MAPPING1U":"1778","MAPPING1F":"1778","MAPPING1N":"1778","MAPPING1H":"1778"},{"SYMBOLID":"S*G*EVATHR*****","DESCRIPTION":"Tank Heavy Recovery","MAPPING1U":"1779","MAPPING1F":"1779","MAPPING1N":"1779","MAPPING1H":"1779"},{"SYMBOLID":"S*G*EVAA--*****","DESCRIPTION":"Armored Personnel Carrier","MAPPING1U":"1780","MAPPING1F":"1780","MAPPING1N":"1780","MAPPING1H":"1780"},{"SYMBOLID":"S*G*EVAAR-*****","DESCRIPTION":"Armored Personnel Carrier Recovery","MAPPING1U":"1781","MAPPING1F":"1781","MAPPING1N":"1781","MAPPING1H":"1781"},{"SYMBOLID":"S*G*EVAI--*****","DESCRIPTION":"Armored Infantry","MAPPING1U":"1782","MAPPING1F":"1782","MAPPING1N":"1782","MAPPING1H":"1782"},{"SYMBOLID":"S*G*EVAC--*****","DESCRIPTION":"C2V/ACV","MAPPING1U":"1783","MAPPING1F":"1783","MAPPING1N":"1783","MAPPING1H":"1783"},{"SYMBOLID":"S*G*EVAS--*****","DESCRIPTION":"Combat Service Support Vehicle","MAPPING1U":"1784","MAPPING1F":"1784","MAPPING1N":"1784","MAPPING1H":"1784"},{"SYMBOLID":"S*G*EVAL--*****","DESCRIPTION":"Light Armored Vehicle","MAPPING1U":"1785","MAPPING1F":"1785","MAPPING1N":"1785","MAPPING1H":"1785"},{"SYMBOLID":"S*G*EVU---*****","DESCRIPTION":"Utility Vehicle","MAPPING1U":"1786","MAPPING1F":"1786","MAPPING1N":"1786","MAPPING1H":"1786"},{"SYMBOLID":"S*G*EVUB--*****","DESCRIPTION":"Bus","MAPPING1U":"1787","MAPPING1F":"1787","MAPPING1N":"1787","MAPPING1H":"1787"},{"SYMBOLID":"S*G*EVUS--*****","DESCRIPTION":"Semi","MAPPING1U":"1788","MAPPING1F":"1788","MAPPING1N":"1788","MAPPING1H":"1788"},{"SYMBOLID":"S*G*EVUSL-*****","DESCRIPTION":"Semi Light","MAPPING1U":"1789","MAPPING1F":"1789","MAPPING1N":"1789","MAPPING1H":"1789"},{"SYMBOLID":"S*G*EVUSM-*****","DESCRIPTION":"Semi Medium","MAPPING1U":"1790","MAPPING1F":"1790","MAPPING1N":"1790","MAPPING1H":"1790"},{"SYMBOLID":"S*G*EVUSH-*****","DESCRIPTION":"Semi Heavy","MAPPING1U":"1791","MAPPING1F":"1791","MAPPING1N":"1791","MAPPING1H":"1791"},{"SYMBOLID":"S*G*EVUL--*****","DESCRIPTION":"Limited Cross-Country Truck","MAPPING1U":"1792","MAPPING1F":"1792","MAPPING1N":"1792","MAPPING1H":"1792"},{"SYMBOLID":"S*G*EVUX--*****","DESCRIPTION":"Cross-Country Truck","MAPPING1U":"1793","MAPPING1F":"1793","MAPPING1N":"1793","MAPPING1H":"1793"},{"SYMBOLID":"S*G*EVUR--*****","DESCRIPTION":"Water Craft","MAPPING1U":"1794","MAPPING1F":"1794","MAPPING1N":"1794","MAPPING1H":"1794"},{"SYMBOLID":"S*G*EVUT--*****","DESCRIPTION":"Tow Truck","MAPPING1U":"1795","MAPPING1F":"1795","MAPPING1N":"1795","MAPPING1H":"1795"},{"SYMBOLID":"S*G*EVUTL-*****","DESCRIPTION":"Tow Truck Light","MAPPING1U":"1796","MAPPING1F":"1796","MAPPING1N":"1796","MAPPING1H":"1796"},{"SYMBOLID":"S*G*EVUTH-*****","DESCRIPTION":"Tow Truck Heavy","MAPPING1U":"1797","MAPPING1F":"1797","MAPPING1N":"1797","MAPPING1H":"1797"},{"SYMBOLID":"S*G*EVUA--*****","DESCRIPTION":"Ambulance","MAPPING1U":"1798","MAPPING1F":"1798","MAPPING1N":"1798","MAPPING1H":"1798"},{"SYMBOLID":"S*G*EVUAA-*****","DESCRIPTION":"Ambulance Armored","MAPPING1U":"1799","MAPPING1F":"1799","MAPPING1N":"1799","MAPPING1H":"1799"},{"SYMBOLID":"S*G*EVE---*****","DESCRIPTION":"Engineer Vehicle","MAPPING1U":"1800","MAPPING1F":"1800","MAPPING1N":"1800","MAPPING1H":"1800"},{"SYMBOLID":"S*G*EVEB--*****","DESCRIPTION":"Engineer Vehicle Bridge","MAPPING1U":"1894","MAPPING1F":"1894","MAPPING1N":"1894","MAPPING1H":"1894"},{"SYMBOLID":"S*G*EVEE--*****","DESCRIPTION":"Earthmover","MAPPING1U":"1801","MAPPING1F":"1801","MAPPING1N":"1801","MAPPING1H":"1801"},{"SYMBOLID":"S*G*EVEC--*****","DESCRIPTION":"Construction Vehicle","MAPPING1U":"1802","MAPPING1F":"1802","MAPPING1N":"1802","MAPPING1H":"1802"},{"SYMBOLID":"S*G*EVEM--*****","DESCRIPTION":"Mine Laying Vehicle","MAPPING1U":"1803","MAPPING1F":"1803","MAPPING1N":"1803","MAPPING1H":"1803"},{"SYMBOLID":"S*G*EVEMV-*****","DESCRIPTION":"Armored Carrier with Volcano","MAPPING1U":"1804","MAPPING1F":"1804","MAPPING1N":"1804","MAPPING1H":"1804"},{"SYMBOLID":"S*G*EVEML-*****","DESCRIPTION":"Truck Mounted with Volcano","MAPPING1U":"1805","MAPPING1F":"1805","MAPPING1N":"1805","MAPPING1H":"1805"},{"SYMBOLID":"S*G*EVEA--*****","DESCRIPTION":"Mine Clearing Vehicle","MAPPING1U":"1806","MAPPING1F":"1806","MAPPING1N":"1806","MAPPING1H":"1806"},{"SYMBOLID":"S*G*EVEAA-*****","DESCRIPTION":"Armored Mounted Mine Clearing Vehicle","MAPPING1U":"1807","MAPPING1F":"1807","MAPPING1N":"1807","MAPPING1H":"1807"},{"SYMBOLID":"S*G*EVEAT-*****","DESCRIPTION":"Trailer Mounted Mine Clearing Vehicle","MAPPING1U":"1808","MAPPING1F":"1808","MAPPING1N":"1808","MAPPING1H":"1808"},{"SYMBOLID":"S*G*EVED--*****","DESCRIPTION":"Dozer","MAPPING1U":"1809","MAPPING1F":"1809","MAPPING1N":"1809","MAPPING1H":"1809"},{"SYMBOLID":"S*G*EVEDA-*****","DESCRIPTION":"Armored Dozer","MAPPING1U":"1810","MAPPING1F":"1810","MAPPING1N":"1810","MAPPING1H":"1810"},{"SYMBOLID":"S*G*EVES--*****","DESCRIPTION":"Armored Assault","MAPPING1U":"1811","MAPPING1F":"1811","MAPPING1N":"1811","MAPPING1H":"1811"},{"SYMBOLID":"S*G*EVER--*****","DESCRIPTION":"Armored Engineer Recon Vehicle (AERV)","MAPPING1U":"1812","MAPPING1F":"1812","MAPPING1N":"1812","MAPPING1H":"1812"},{"SYMBOLID":"S*G*EVEH--*****","DESCRIPTION":"Backhoe","MAPPING1U":"1813","MAPPING1F":"1813","MAPPING1N":"1813","MAPPING1H":"1813"},{"SYMBOLID":"S*G*EVEF--*****","DESCRIPTION":"Ferry Transporter","MAPPING1U":"1814","MAPPING1F":"1814","MAPPING1N":"1814","MAPPING1H":"1814"},{"SYMBOLID":"S*G*EVT---*****","DESCRIPTION":"Train Locomotive","MAPPING1U":"1815","MAPPING1F":"1815","MAPPING1N":"1815","MAPPING1H":"1815"},{"SYMBOLID":"S*G*EVC---*****","DESCRIPTION":"Civilian Vehicle","MAPPING1U":"1816","MAPPING1F":"1816","MAPPING1N":"1816","MAPPING1H":"1816"},{"SYMBOLID":"S*G*EVCA--*****","DESCRIPTION":"Civilian Automobile","MAPPING1U":"1817","MAPPING1F":"1817","MAPPING1N":"1817","MAPPING1H":"1817","MAPPING2":"1818","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAL-*****","DESCRIPTION":"Civilian Compact Automobile","MAPPING1U":"1819","MAPPING1F":"1819","MAPPING1N":"1819","MAPPING1H":"1819","MAPPING2":"1820","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAM-*****","DESCRIPTION":"Civilian Midsize Automobile","MAPPING1U":"1821","MAPPING1F":"1821","MAPPING1N":"1821","MAPPING1H":"1821","MAPPING2":"1822","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAH-*****","DESCRIPTION":"Civilian Automobile Sedan","MAPPING1U":"1823","MAPPING1F":"1823","MAPPING1N":"1823","MAPPING1H":"1823","MAPPING2":"1824","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCO--*****","DESCRIPTION":"Civilian Open-Bed Truck","MAPPING1U":"1825","MAPPING1F":"1825","MAPPING1N":"1825","MAPPING1H":"1825","MAPPING2":"1826","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOL-*****","DESCRIPTION":"Civilian Pickup Truck","MAPPING1U":"1827","MAPPING1F":"1827","MAPPING1N":"1827","MAPPING1H":"1827","MAPPING2":"1828","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOM-*****","DESCRIPTION":"Civilian Small Open-Bed Truck","MAPPING1U":"1829","MAPPING1F":"1829","MAPPING1N":"1829","MAPPING1H":"1829","MAPPING2":"1830","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOH-*****","DESCRIPTION":"Civilian Large Open-Bed Truck","MAPPING1U":"1831","MAPPING1F":"1831","MAPPING1N":"1831","MAPPING1H":"1831","MAPPING2":"1832","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCM--*****","DESCRIPTION":"Civilian Multi-Passenger Vehicle","MAPPING1U":"1833","MAPPING1F":"1833","MAPPING1N":"1833","MAPPING1H":"1833","MAPPING2":"1834","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCML-*****","DESCRIPTION":"Civilian Multi-Passenger Van","MAPPING1U":"1835","MAPPING1F":"1835","MAPPING1N":"1835","MAPPING1H":"1835","MAPPING2":"1836","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCMM-*****","DESCRIPTION":"Civilian Small Bus","MAPPING1U":"1837","MAPPING1F":"1837","MAPPING1N":"1837","MAPPING1H":"1837","MAPPING2":"1838","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCMH-*****","DESCRIPTION":"Civilian Large Bus","MAPPING1U":"1839","MAPPING1F":"1839","MAPPING1N":"1839","MAPPING1H":"1839","MAPPING2":"1840","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCU--*****","DESCRIPTION":"Civilian Utility Vehicle","MAPPING1U":"1841","MAPPING1F":"1841","MAPPING1N":"1841","MAPPING1H":"1841","MAPPING2":"1842","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUL-*****","DESCRIPTION":"Civilian Sport Utility Vehicle (SUV)","MAPPING1U":"1843","MAPPING1F":"1843","MAPPING1N":"1843","MAPPING1H":"1843","MAPPING2":"1844","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUM-*****","DESCRIPTION":"Civilian Utility Small Box Truck","MAPPING1U":"1845","MAPPING1F":"1845","MAPPING1N":"1845","MAPPING1H":"1845","MAPPING2":"1846","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUH-*****","DESCRIPTION":"Civilian Utility Large Box Truck","MAPPING1U":"1847","MAPPING1F":"1847","MAPPING1N":"1847","MAPPING1H":"1847","MAPPING2":"1848","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJ--*****","DESCRIPTION":"Civilian Jeep Type Vehicle","MAPPING1U":"1849","MAPPING1F":"1849","MAPPING1N":"1849","MAPPING1H":"1849","MAPPING2":"1850","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJL-*****","DESCRIPTION":"Civilian Small/Light Jeep Type Vehicle","MAPPING1U":"1851","MAPPING1F":"1851","MAPPING1N":"1851","MAPPING1H":"1851","MAPPING2":"1852","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJM-*****","DESCRIPTION":"Civilian Medium Jeep Type Vehicle","MAPPING1U":"1853","MAPPING1F":"1853","MAPPING1N":"1853","MAPPING1H":"1853","MAPPING2":"1854","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJH-*****","DESCRIPTION":"Civilian Large/Heavy Jeep Type Vehicle","MAPPING1U":"1855","MAPPING1F":"1855","MAPPING1N":"1855","MAPPING1H":"1855","MAPPING2":"1856","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCT--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Box Trailer","MAPPING1U":"1857","MAPPING1F":"1857","MAPPING1N":"1857","MAPPING1H":"1857","MAPPING2":"1858","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTL-*****","DESCRIPTION":"Civilian Small/Light Box Trailer","MAPPING1U":"1859","MAPPING1F":"1859","MAPPING1N":"1859","MAPPING1H":"1859","MAPPING2":"1860","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTM-*****","DESCRIPTION":"Civilian Medium Box Trailer","MAPPING1U":"1861","MAPPING1F":"1861","MAPPING1N":"1861","MAPPING1H":"1861","MAPPING2":"1862","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTH-*****","DESCRIPTION":"Civilian Large/Heavy Box Trailer","MAPPING1U":"1863","MAPPING1F":"1863","MAPPING1N":"1863","MAPPING1H":"1863","MAPPING2":"1864","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCF--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Flatbed Trailer","MAPPING1U":"1865","MAPPING1F":"1865","MAPPING1N":"1865","MAPPING1H":"1865","MAPPING2":"1866","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFL-*****","DESCRIPTION":"Civilian Small/Light Flatbed Trailer","MAPPING1U":"1867","MAPPING1F":"1867","MAPPING1N":"1867","MAPPING1H":"1867","MAPPING2":"1868","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFM-*****","DESCRIPTION":"Civilian Medium Flatbed Trailer","MAPPING1U":"1869","MAPPING1F":"1869","MAPPING1N":"1869","MAPPING1H":"1869","MAPPING2":"1870","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFH-*****","DESCRIPTION":"Civilian Large/Heavy Flatbed Trailer","MAPPING1U":"1871","MAPPING1F":"1871","MAPPING1N":"1871","MAPPING1H":"1871","MAPPING2":"1872","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVS---*****","DESCRIPTION":"Missile Support","MAPPING1U":"1874","MAPPING1F":"1874","MAPPING1N":"1874","MAPPING1H":"1874"},{"SYMBOLID":"S*G*EVST--*****","DESCRIPTION":"Transloader","MAPPING1U":"1875","MAPPING1F":"1875","MAPPING1N":"1875","MAPPING1H":"1875"},{"SYMBOLID":"S*G*EVSR--*****","DESCRIPTION":"Transporter"},{"SYMBOLID":"S*G*EVSC--*****","DESCRIPTION":"Crane/Loading Device","MAPPING1U":"1877","MAPPING1F":"1877","MAPPING1N":"1877","MAPPING1H":"1877"},{"SYMBOLID":"S*G*EVSP--*****","DESCRIPTION":"Propellant Transporter","MAPPING1U":"1878","MAPPING1F":"1878","MAPPING1N":"1878","MAPPING1H":"1878"},{"SYMBOLID":"S*G*EVSW--*****","DESCRIPTION":"Warhead Transporter","MAPPING1U":"1879","MAPPING1F":"1879","MAPPING1N":"1879","MAPPING1H":"1879"},{"SYMBOLID":"S*G*EVM---*****","DESCRIPTION":"Pack Animal (S)","MAPPING1U":"1873","MAPPING1F":"1873","MAPPING1N":"1873","MAPPING1H":"1873"},{"SYMBOLID":"S*G*ES----*****","DESCRIPTION":"Equipment Sensor","MAPPING1U":"1880","MAPPING1F":"1880","MAPPING1N":"1880","MAPPING1H":"1880"},{"SYMBOLID":"S*G*ESR---*****","DESCRIPTION":"Sensor Radar","MAPPING1U":"1881","MAPPING1F":"1881","MAPPING1N":"1881","MAPPING1H":"1881"},{"SYMBOLID":"S*G*ESE---*****","DESCRIPTION":"Emplaced Sensor","MAPPING1U":"1882","MAPPING1F":"1882","MAPPING1N":"1882","MAPPING1H":"1882"},{"SYMBOLID":"S*G*EX----*****","DESCRIPTION":"Special"},{"SYMBOLID":"S*G*EXL---*****","DESCRIPTION":"Laser","MAPPING1U":"1884","MAPPING1F":"1884","MAPPING1N":"1884","MAPPING1H":"1884"},{"SYMBOLID":"S*G*EXN---*****","DESCRIPTION":"NBC Equipment","MAPPING1U":"1885","MAPPING1F":"1885","MAPPING1N":"1885","MAPPING1H":"1885"},{"SYMBOLID":"S*G*EXF---*****","DESCRIPTION":"Flame Thrower","MAPPING1U":"1886","MAPPING1F":"1886","MAPPING1N":"1886","MAPPING1H":"1886"},{"SYMBOLID":"S*G*EXM---*****","DESCRIPTION":"Land Mines","MAPPING1U":"1887","MAPPING1F":"1887","MAPPING1N":"1887","MAPPING1H":"1887"},{"SYMBOLID":"S*G*EXMC--*****","DESCRIPTION":"Claymore","MAPPING1U":"1888","MAPPING1F":"1888","MAPPING1N":"1888","MAPPING1H":"1888"},{"SYMBOLID":"S*G*EXML--*****","DESCRIPTION":"Less Than Lethal","MAPPING1U":"1889","MAPPING1F":"1889","MAPPING1N":"1889","MAPPING1H":"1889"},{"SYMBOLID":"S*G*EXI---*****","DESCRIPTION":"Improvised Explosive Device (IED)","MAPPING1U":"1883","MAPPING1F":"1883","MAPPING1N":"1883","MAPPING1H":"1883"},{"SYMBOLID":"IH8CK6F75V69VCF","DESCRIPTION":"BLANK"},{"SYMBOLID":"S*G*EXI---MO***","DESCRIPTION":"Vehicle Borne Improvised Explosive Device"},{"SYMBOLID":"S*G*I-----*****","DESCRIPTION":"Installation"},{"SYMBOLID":"S*G*IR----*****","DESCRIPTION":"Raw Material Production/Storage","MAPPING1U":"1897","MAPPING1F":"1897","MAPPING1N":"1897","MAPPING1H":"1897"},{"SYMBOLID":"S*G*IRM---*****","DESCRIPTION":"Raw Material Production/Storage Mine","MAPPING1U":"1898","MAPPING1F":"1898","MAPPING1N":"1898","MAPPING1H":"1898"},{"SYMBOLID":"S*G*IRP---*****","DESCRIPTION":"Petroleum/Gas/Oil","MAPPING1U":"1899","MAPPING1F":"1899","MAPPING1N":"1899","MAPPING1H":"1899"},{"SYMBOLID":"S*G*IRN---*****","DESCRIPTION":"NBC","MAPPING1U":"1900","MAPPING1F":"1900","MAPPING1N":"1900","MAPPING1H":"1900"},{"SYMBOLID":"S*G*IRNB--*****","DESCRIPTION":"Production/Storage NBC Biological","MAPPING1U":"1901","MAPPING1F":"1901","MAPPING1N":"1901","MAPPING1H":"1901"},{"SYMBOLID":"S*G*IRNC--*****","DESCRIPTION":"Production/Storage NBC Chemical","MAPPING1U":"1902","MAPPING1F":"1902","MAPPING1N":"1902","MAPPING1H":"1902"},{"SYMBOLID":"S*G*IRNN--*****","DESCRIPTION":"Production/Storage NBC Nuclear","MAPPING1U":"1903","MAPPING1F":"1903","MAPPING1N":"1903","MAPPING1H":"1903"},{"SYMBOLID":"S*G*IP----*****","DESCRIPTION":"Processing Facility","MAPPING1U":"1904","MAPPING1F":"1904","MAPPING1N":"1904","MAPPING1H":"1904"},{"SYMBOLID":"S*G*IPD---*****","DESCRIPTION":"Processing Facility Decontamination","MAPPING1U":"1905","MAPPING1F":"1905","MAPPING1N":"1905","MAPPING1H":"1905"},{"SYMBOLID":"S*G*IE----*****","DESCRIPTION":"Equipment Manufacture","MAPPING1U":"1906","MAPPING1F":"1906","MAPPING1N":"1906","MAPPING1H":"1906"},{"SYMBOLID":"S*G*IU----*****","DESCRIPTION":"Service, Reasearch, Utility Facility","MAPPING1U":"1907","MAPPING1F":"1907","MAPPING1N":"1907","MAPPING1H":"1907"},{"SYMBOLID":"S*G*IUR---*****","DESCRIPTION":"Technological Research Facility","MAPPING1U":"1908","MAPPING1F":"1908","MAPPING1N":"1908","MAPPING1H":"1908"},{"SYMBOLID":"S*G*IUT---*****","DESCRIPTION":"Telecommunications Facility","MAPPING1U":"1909","MAPPING1F":"1909","MAPPING1N":"1909","MAPPING1H":"1909"},{"SYMBOLID":"S*G*IUE---*****","DESCRIPTION":"Electric Power Facility","MAPPING1U":"1910","MAPPING1F":"1910","MAPPING1N":"1910","MAPPING1H":"1910"},{"SYMBOLID":"S*G*IUEN--*****","DESCRIPTION":"Nuclear Plant","MAPPING1U":"1911","MAPPING1F":"1911","MAPPING1N":"1911","MAPPING1H":"1911"},{"SYMBOLID":"S*G*IUED--*****","DESCRIPTION":"Dam","MAPPING1U":"1912","MAPPING1F":"1912","MAPPING1N":"1912","MAPPING1H":"1912"},{"SYMBOLID":"S*G*IUEF--*****","DESCRIPTION":"Fossil Fuel","MAPPING1U":"1913","MAPPING1F":"1913","MAPPING1N":"1913","MAPPING1H":"1913"},{"SYMBOLID":"S*G*IUP---*****","DESCRIPTION":"Public Water Services","MAPPING1U":"1914","MAPPING1F":"1914","MAPPING1N":"1914","MAPPING1H":"1914"},{"SYMBOLID":"S*G*IM----*****","DESCRIPTION":"Military Materiel Facility"},{"SYMBOLID":"S*G*IMF---*****","DESCRIPTION":"Nuclear Energy","MAPPING1U":"1915","MAPPING1F":"1915","MAPPING1N":"1915","MAPPING1H":"1915"},{"SYMBOLID":"S*G*IMFA--*****","DESCRIPTION":"Atomic Energy Reactor","MAPPING1U":"1916","MAPPING1F":"1916","MAPPING1N":"1916","MAPPING1H":"1916"},{"SYMBOLID":"S*G*IMFP--*****","DESCRIPTION":"Nuclear Material Production","MAPPING1U":"1917","MAPPING1F":"1917","MAPPING1N":"1917","MAPPING1H":"1917"},{"SYMBOLID":"S*G*IMFPW-*****","DESCRIPTION":"Weapons Grade","MAPPING1U":"1918","MAPPING1F":"1918","MAPPING1N":"1918","MAPPING1H":"1918"},{"SYMBOLID":"S*G*IMFS--*****","DESCRIPTION":"Nuclear Material Storage","MAPPING1U":"1919","MAPPING1F":"1919","MAPPING1N":"1919","MAPPING1H":"1919"},{"SYMBOLID":"S*G*IMA---*****","DESCRIPTION":"Aircraft Production & Assembly","MAPPING1U":"1920","MAPPING1F":"1920","MAPPING1N":"1920","MAPPING1H":"1920"},{"SYMBOLID":"S*G*IME---*****","DESCRIPTION":"Ammunition And Explosives Production","MAPPING1U":"1921","MAPPING1F":"1921","MAPPING1N":"1921","MAPPING1H":"1921"},{"SYMBOLID":"S*G*IMG---*****","DESCRIPTION":"Armament Production","MAPPING1U":"1922","MAPPING1F":"1922","MAPPING1N":"1922","MAPPING1H":"1922"},{"SYMBOLID":"S*G*IMV---*****","DESCRIPTION":"Military Vehicle Production","MAPPING1U":"1923","MAPPING1F":"1923","MAPPING1N":"1923","MAPPING1H":"1923"},{"SYMBOLID":"S*G*IMN---*****","DESCRIPTION":"Engineering Equipment Production","MAPPING1U":"1924","MAPPING1F":"1924","MAPPING1N":"1924","MAPPING1H":"1924"},{"SYMBOLID":"S*G*IMNB--*****","DESCRIPTION":"Engineering Equipment Production Bridge","MAPPING1U":"1925","MAPPING1F":"1925","MAPPING1N":"1925","MAPPING1H":"1925"},{"SYMBOLID":"S*G*IMC---*****","DESCRIPTION":"Chemical & Biological Warfare Production","MAPPING1U":"1926","MAPPING1F":"1926","MAPPING1N":"1926","MAPPING1H":"1926"},{"SYMBOLID":"S*G*IMS---*****","DESCRIPTION":"Ship Construction","MAPPING1U":"1927","MAPPING1F":"1927","MAPPING1N":"1927","MAPPING1H":"1927"},{"SYMBOLID":"S*G*IMM---*****","DESCRIPTION":"Missile & Space System Production","MAPPING1U":"1928","MAPPING1F":"1928","MAPPING1N":"1928","MAPPING1H":"1928"},{"SYMBOLID":"S*G*IG----*****","DESCRIPTION":"Government Leadership","MAPPING1U":"1929","MAPPING1F":"1929","MAPPING1N":"1929","MAPPING1H":"1929"},{"SYMBOLID":"S*G*IB----*****","DESCRIPTION":"Military Base/Facility","MAPPING1U":"1930","MAPPING1F":"1930","MAPPING1N":"1930","MAPPING1H":"1930"},{"SYMBOLID":"S*G*IBA---*****","DESCRIPTION":"Airport/Airbase","MAPPING1U":"1931","MAPPING1F":"1931","MAPPING1N":"1931","MAPPING1H":"1931"},{"SYMBOLID":"S*G*IBN---*****","DESCRIPTION":"Seaport/Naval Base","MAPPING1U":"1932","MAPPING1F":"1932","MAPPING1N":"1932","MAPPING1H":"1932"},{"SYMBOLID":"S*G*IT----*****","DESCRIPTION":"Transport Facility","MAPPING1U":"1933","MAPPING1F":"1933","MAPPING1N":"1933","MAPPING1H":"1933"},{"SYMBOLID":"S*G*IX----*****","DESCRIPTION":"Medical Facility","MAPPING1U":"660","MAPPING1F":"661","MAPPING1N":"662","MAPPING1H":"663"},{"SYMBOLID":"S*G*IXH---*****","DESCRIPTION":"Hospital","MAPPING1U":"660","MAPPING1F":"661","MAPPING1N":"662","MAPPING1H":"663","MAPPING2":"1935","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*IC----*****","DESCRIPTION":"Tented Camp","MAPPING1U":"1891","MAPPING1F":"1891","MAPPING1N":"1891","MAPPING1H":"1891"},{"SYMBOLID":"S*G*ICD---*****","DESCRIPTION":"Tented Camp, Displaced Persons/Refugees","MAPPING1U":"1892","MAPPING1F":"1892","MAPPING1N":"1892","MAPPING1H":"1892"},{"SYMBOLID":"S*G*ICT---*****","DESCRIPTION":"Tented Training Camp","MAPPING1U":"1893","MAPPING1F":"1893","MAPPING1N":"1893","MAPPING1H":"1893"},{"SYMBOLID":"S*G*IW----*****","DESCRIPTION":"Warehouse/Storage Facility","MAPPING1U":"1895","MAPPING1F":"1895","MAPPING1N":"1895","MAPPING1H":"1895"},{"SYMBOLID":"S*S*------*****","DESCRIPTION":"Sea Surface Track"},{"SYMBOLID":"S*S*C-----*****","DESCRIPTION":"Sea Surface Track Combatant","MAPPING1U":"1936","MAPPING1F":"1936","MAPPING1N":"1936","MAPPING1H":"1936","MAPPING2":"1937","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*CL----*****","DESCRIPTION":"Line","MAPPING1U":"1938","MAPPING1F":"1938","MAPPING1N":"1938","MAPPING1H":"1938"},{"SYMBOLID":"S*S*CLCV--*****","DESCRIPTION":"Carrier","MAPPING1U":"1939","MAPPING1F":"1939","MAPPING1N":"1939","MAPPING1H":"1939"},{"SYMBOLID":"S*S*CLBB--*****","DESCRIPTION":"Battleship","MAPPING1U":"1940","MAPPING1F":"1940","MAPPING1N":"1940","MAPPING1H":"1940"},{"SYMBOLID":"S*S*CLCC--*****","DESCRIPTION":"Cruiser","MAPPING1U":"1941","MAPPING1F":"1941","MAPPING1N":"1941","MAPPING1H":"1941"},{"SYMBOLID":"S*S*CLDD--*****","DESCRIPTION":"Destroyer","MAPPING1U":"1942","MAPPING1F":"1942","MAPPING1N":"1942","MAPPING1H":"1942"},{"SYMBOLID":"S*S*CLFF--*****","DESCRIPTION":"Frigate/Corvette","MAPPING1U":"1943","MAPPING1F":"1943","MAPPING1N":"1943","MAPPING1H":"1943"},{"SYMBOLID":"S*S*CLLL--*****","DESCRIPTION":"Littoral Combatant","MAPPING1U":"1944","MAPPING1F":"1944","MAPPING1N":"1944","MAPPING1H":"1944"},{"SYMBOLID":"S*S*CLLLAS*****","DESCRIPTION":"Antisubmarine Warfare Mission Package","MAPPING1U":"1945","MAPPING1F":"1945","MAPPING1N":"1945","MAPPING1H":"1945"},{"SYMBOLID":"S*S*CLLLMI*****","DESCRIPTION":"Mine Warfare Mission Package","MAPPING1U":"1946","MAPPING1F":"1946","MAPPING1N":"1946","MAPPING1H":"1946"},{"SYMBOLID":"S*S*CLLLSU*****","DESCRIPTION":"Surface Warfare (SUW) Mission Package","MAPPING1U":"1947","MAPPING1F":"1947","MAPPING1N":"1947","MAPPING1H":"1947"},{"SYMBOLID":"S*S*CA----*****","DESCRIPTION":"Amphibious Warfare Ship","MAPPING1U":"1948","MAPPING1F":"1948","MAPPING1N":"1948","MAPPING1H":"1948"},{"SYMBOLID":"S*S*CALA--*****","DESCRIPTION":"Assault Vessel","MAPPING1U":"1949","MAPPING1F":"1949","MAPPING1N":"1949","MAPPING1H":"1949"},{"SYMBOLID":"S*S*CALS--*****","DESCRIPTION":"Landing Ship","MAPPING1U":"1950","MAPPING1F":"1950","MAPPING1N":"1950","MAPPING1H":"1950"},{"SYMBOLID":"S*S*CALSM-*****","DESCRIPTION":"Landing Ship Medium","MAPPING1U":"1951","MAPPING1F":"1951","MAPPING1N":"1951","MAPPING1H":"1951"},{"SYMBOLID":"S*S*CALST-*****","DESCRIPTION":"Landing Ship Tank","MAPPING1U":"1952","MAPPING1F":"1952","MAPPING1N":"1952","MAPPING1H":"1952"},{"SYMBOLID":"S*S*CALC--*****","DESCRIPTION":"Landing Craft","MAPPING1U":"1953","MAPPING1F":"1953","MAPPING1N":"1953","MAPPING1H":"1953"},{"SYMBOLID":"S*S*CM----*****","DESCRIPTION":"Mine Warfare Vessel","MAPPING1U":"1954","MAPPING1F":"1954","MAPPING1N":"1954","MAPPING1H":"1954"},{"SYMBOLID":"S*S*CMML--*****","DESCRIPTION":"Minelayer","MAPPING1U":"1955","MAPPING1F":"1955","MAPPING1N":"1955","MAPPING1H":"1955"},{"SYMBOLID":"S*S*CMMS--*****","DESCRIPTION":"Minesweeper","MAPPING1U":"1956","MAPPING1F":"1956","MAPPING1N":"1956","MAPPING1H":"1956"},{"SYMBOLID":"S*S*CMMH--*****","DESCRIPTION":"Minehunter","MAPPING1U":"1957","MAPPING1F":"1957","MAPPING1N":"1957","MAPPING1H":"1957"},{"SYMBOLID":"S*S*CMMA--*****","DESCRIPTION":"MCM Support","MAPPING1U":"1958","MAPPING1F":"1958","MAPPING1N":"1958","MAPPING1H":"1958"},{"SYMBOLID":"S*S*CP----*****","DESCRIPTION":"Sea Surface Combatant Patrol","MAPPING1U":"1959","MAPPING1F":"1959","MAPPING1N":"1959","MAPPING1H":"1959"},{"SYMBOLID":"S*S*CPSB--*****","DESCRIPTION":"Antisubmarine Warfare","MAPPING1U":"1960","MAPPING1F":"1960","MAPPING1N":"1960","MAPPING1H":"1960"},{"SYMBOLID":"S*S*CPSU--*****","DESCRIPTION":"Antisurface Warfare","MAPPING1U":"1961","MAPPING1F":"1961","MAPPING1N":"1961","MAPPING1H":"1961"},{"SYMBOLID":"S*S*CPSUM-*****","DESCRIPTION":"Anti-Ship Missile","MAPPING1U":"1962","MAPPING1F":"1962","MAPPING1N":"1962","MAPPING1H":"1962"},{"SYMBOLID":"S*S*CPSUT-*****","DESCRIPTION":"Torpedo(Antisurface Warfare)","MAPPING1U":"1963","MAPPING1F":"1963","MAPPING1N":"1963","MAPPING1H":"1963"},{"SYMBOLID":"S*S*CPSUG-*****","DESCRIPTION":"Antisurface Warfare Gun","MAPPING1U":"1964","MAPPING1F":"1964","MAPPING1N":"1964","MAPPING1H":"1964"},{"SYMBOLID":"S*S*CH----*****","DESCRIPTION":"Combatant Hovercraft","MAPPING1U":"1965","MAPPING1F":"1965","MAPPING1N":"1965","MAPPING1H":"1965"},{"SYMBOLID":"S*S*S-----*****","DESCRIPTION":"Sea Surface Station","MAPPING1U":"1966","MAPPING1F":"1966","MAPPING1N":"1966","MAPPING1H":"1966"},{"SYMBOLID":"S*S*SP----*****","DESCRIPTION":"Picket","MAPPING1U":"1967","MAPPING1F":"1967","MAPPING1N":"1967","MAPPING1H":"1967"},{"SYMBOLID":"S*S*SA----*****","DESCRIPTION":"ASW Ship","MAPPING1U":"1968","MAPPING1F":"1968","MAPPING1N":"1968","MAPPING1H":"1968"},{"SYMBOLID":"S*S*G-----*****","DESCRIPTION":"Navy Group","MAPPING1U":"1969","MAPPING1F":"1969","MAPPING1N":"1969","MAPPING1H":"1969"},{"SYMBOLID":"S*S*GT----*****","DESCRIPTION":"Navy Task Force","MAPPING1U":"1970","MAPPING1F":"1970","MAPPING1N":"1970","MAPPING1H":"1970"},{"SYMBOLID":"S*S*GG----*****","DESCRIPTION":"Navy Task Group","MAPPING1U":"1971","MAPPING1F":"1971","MAPPING1N":"1971","MAPPING1H":"1971"},{"SYMBOLID":"S*S*GU----*****","DESCRIPTION":"Navy Task Unit","MAPPING1U":"1972","MAPPING1F":"1972","MAPPING1N":"1972","MAPPING1H":"1972"},{"SYMBOLID":"S*S*GC----*****","DESCRIPTION":"Convoy","MAPPING1U":"1973","MAPPING1F":"1973","MAPPING1N":"1973","MAPPING1H":"1973"},{"SYMBOLID":"S*S*CD----*****","DESCRIPTION":"Surface Decoy","MAPPING1U":"1974","MAPPING1F":"1974","MAPPING1N":"1974","MAPPING1H":"1974"},{"SYMBOLID":"S*S*CU----*****","DESCRIPTION":"Unmanned Surface Vehicle (USV)","MAPPING1U":"1975","MAPPING1F":"1975","MAPPING1N":"1975","MAPPING1H":"1975"},{"SYMBOLID":"S*S*CUM---*****","DESCRIPTION":"USV Mine Countermeasures","MAPPING1U":"1976","MAPPING1F":"1976","MAPPING1N":"1976","MAPPING1H":"1976"},{"SYMBOLID":"S*S*CUS---*****","DESCRIPTION":"USV Antisubmarine Warfare","MAPPING1U":"1977","MAPPING1F":"1977","MAPPING1N":"1977","MAPPING1H":"1977"},{"SYMBOLID":"S*S*CUN---*****","DESCRIPTION":"USV Antisurface Warfare","MAPPING1U":"1978","MAPPING1F":"1978","MAPPING1N":"1978","MAPPING1H":"1978"},{"SYMBOLID":"S*S*CUR---*****","DESCRIPTION":"USV Remote Multimission Vehicle","MAPPING1U":"1979","MAPPING1F":"1979","MAPPING1N":"1979","MAPPING1H":"1979"},{"SYMBOLID":"S*S*N-----*****","DESCRIPTION":"Noncombatant","MAPPING1U":"1980","MAPPING1F":"1980","MAPPING1N":"1980","MAPPING1H":"1980"},{"SYMBOLID":"S*S*NR----*****","DESCRIPTION":"Underway Replenishment","MAPPING1U":"1981","MAPPING1F":"1981","MAPPING1N":"1981","MAPPING1H":"1981"},{"SYMBOLID":"S*S*NF----*****","DESCRIPTION":"Fleet Support","MAPPING1U":"1982","MAPPING1F":"1982","MAPPING1N":"1982","MAPPING1H":"1982"},{"SYMBOLID":"S*S*NI----*****","DESCRIPTION":"Intelligence","MAPPING1U":"1983","MAPPING1F":"1983","MAPPING1N":"1983","MAPPING1H":"1983"},{"SYMBOLID":"S*S*NS----*****","DESCRIPTION":"Service & Support Harbor","MAPPING1U":"1984","MAPPING1F":"1984","MAPPING1N":"1984","MAPPING1H":"1984"},{"SYMBOLID":"S*S*NM----*****","DESCRIPTION":"Hospital Ship","MAPPING1U":"1985","MAPPING1F":"1985","MAPPING1N":"1985","MAPPING1H":"1985"},{"SYMBOLID":"S*S*NH----*****","DESCRIPTION":"Noncombatant Hovercraft","MAPPING1U":"1986","MAPPING1F":"1986","MAPPING1N":"1986","MAPPING1H":"1986","MAPPING2":"1987","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*NN----*****","DESCRIPTION":"Noncombatant Station","MAPPING1U":"1988","MAPPING1F":"1988","MAPPING1N":"1988","MAPPING1H":"1988"},{"SYMBOLID":"S*S*NNR---*****","DESCRIPTION":"Rescue","MAPPING1U":"1989","MAPPING1F":"1989","MAPPING1N":"1989","MAPPING1H":"1989"},{"SYMBOLID":"S*S*X-----*****","DESCRIPTION":"Non-Military"},{"SYMBOLID":"S*S*XM----*****","DESCRIPTION":"Merchant","MAPPING1U":"1990","MAPPING1F":"1990","MAPPING1N":"1990","MAPPING1H":"1990","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMC---*****","DESCRIPTION":"Subsurface Non-military Cargo","MAPPING1U":"1992","MAPPING1F":"1992","MAPPING1N":"1992","MAPPING1H":"1992","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMR---*****","DESCRIPTION":"Roll On/Roll Off","MAPPING1U":"1993","MAPPING1F":"1993","MAPPING1N":"1993","MAPPING1H":"1993","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMO---*****","DESCRIPTION":"Oiler/Tanker","MAPPING1U":"1994","MAPPING1F":"1994","MAPPING1N":"1994","MAPPING1H":"1994","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMTU--*****","DESCRIPTION":"Tug","MAPPING1U":"1995","MAPPING1F":"1995","MAPPING1N":"1995","MAPPING1H":"1995","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMF---*****","DESCRIPTION":"Ferry","MAPPING1U":"1996","MAPPING1F":"1996","MAPPING1N":"1996","MAPPING1H":"1996","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMP---*****","DESCRIPTION":"Passenger","MAPPING1U":"1997","MAPPING1F":"1997","MAPPING1N":"1997","MAPPING1H":"1997","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMH---*****","DESCRIPTION":"Hazardous Materials (HAZMAT)","MAPPING1U":"1998","MAPPING1F":"1998","MAPPING1N":"1998","MAPPING1H":"1998","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMTO--*****","DESCRIPTION":"Towing Vessel","MAPPING1U":"1999","MAPPING1F":"1999","MAPPING1N":"1999","MAPPING1H":"1999","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XF----*****","DESCRIPTION":"Fishing","MAPPING1U":"2000","MAPPING1F":"2000","MAPPING1N":"2000","MAPPING1H":"2000","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFDF--*****","DESCRIPTION":"Drifter","MAPPING1U":"2002","MAPPING1F":"2002","MAPPING1N":"2002","MAPPING1H":"2002","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFDR--*****","DESCRIPTION":"Dredge","MAPPING1U":"2003","MAPPING1F":"2003","MAPPING1N":"2003","MAPPING1H":"2003","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFTR--*****","DESCRIPTION":"Trawler","MAPPING1U":"2004","MAPPING1F":"2004","MAPPING1N":"2004","MAPPING1H":"2004","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XR----*****","DESCRIPTION":"Leisure Craft","MAPPING1U":"2005","MAPPING1F":"2005","MAPPING1N":"2005","MAPPING1H":"2005","MAPPING2":"2006","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XL----*****","DESCRIPTION":"Law Enforcement Vessel","MAPPING1U":"2007","MAPPING1F":"2007","MAPPING1N":"2007","MAPPING1H":"2007","MAPPING2":"2008","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XH----*****","DESCRIPTION":"Non-military Hovercraft","MAPPING1U":"2009","MAPPING1F":"2009","MAPPING1N":"2009","MAPPING1H":"2009","MAPPING2":"2010","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*O-----*****","DESCRIPTION":"Own Track"},{"SYMBOLID":"S*U*------*****","DESCRIPTION":"Subsurface Track"},{"SYMBOLID":"S*U*S-----*****","DESCRIPTION":"Submarine","MAPPING1U":"2017","MAPPING1F":"2017","MAPPING1N":"2017","MAPPING1H":"2017"},{"SYMBOLID":"S*U*SN----*****","DESCRIPTION":"Nuclear Propulsion","MAPPING1U":"2022","MAPPING1F":"2022","MAPPING1N":"2022","MAPPING1H":"2022"},{"SYMBOLID":"S*U*SNF---*****","DESCRIPTION":"Submarine Nuclear Surfaced","MAPPING1U":"2023","MAPPING1F":"2023","MAPPING1N":"2023","MAPPING1H":"2023"},{"SYMBOLID":"S*U*SNA---*****","DESCRIPTION":"Submarine Nuclear Attack (SSN)","MAPPING1U":"2024","MAPPING1F":"2024","MAPPING1N":"2024","MAPPING1H":"2024","MAPPING2":"2025","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNM---*****","DESCRIPTION":"Submarine Nuclear Missile Type Unknown","MAPPING1U":"2026","MAPPING1F":"2026","MAPPING1N":"2026","MAPPING1H":"2026","MAPPING2":"2027","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNG---*****","DESCRIPTION":"Submarine Nuclear Guided Missile (SSGN)","MAPPING1U":"2028","MAPPING1F":"2028","MAPPING1N":"2028","MAPPING1H":"2028","MAPPING2":"2029","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNB---*****","DESCRIPTION":"Ballistic Missile Submarine (SSB)","MAPPING1U":"2030","MAPPING1F":"2030","MAPPING1N":"2030","MAPPING1H":"2030","MAPPING2":"2031","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SC----*****","DESCRIPTION":"Conventional Propulsion","MAPPING1U":"2032","MAPPING1F":"2032","MAPPING1N":"2032","MAPPING1H":"2032"},{"SYMBOLID":"S*U*SCF---*****","DESCRIPTION":"Conventional Propulsion Surfaced","MAPPING1U":"2033","MAPPING1F":"2033","MAPPING1N":"2033","MAPPING1H":"2033"},{"SYMBOLID":"S*U*SCA---*****","DESCRIPTION":"Attack Submarine (SS)","MAPPING1U":"2034","MAPPING1F":"2034","MAPPING1N":"2034","MAPPING1H":"2034","MAPPING2":"2035","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCM---*****","DESCRIPTION":"Conventional Propulsion Missile Submarine (TYPE UNKNOWN)","MAPPING1U":"2036","MAPPING1F":"2036","MAPPING1N":"2036","MAPPING1H":"2036","MAPPING2":"2037","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCG---*****","DESCRIPTION":"Guided Missile Submarine (SSG)","MAPPING1U":"2038","MAPPING1F":"2038","MAPPING1N":"2038","MAPPING1H":"2038","MAPPING2":"2039","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCB---*****","DESCRIPTION":"Conventional Propulsion Ballistic Missile (SSB)","MAPPING1U":"2040","MAPPING1F":"2040","MAPPING1N":"2040","MAPPING1H":"2040","MAPPING2":"2041","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SO----*****","DESCRIPTION":"Other Submersible","MAPPING1U":"2042","MAPPING1F":"2042","MAPPING1N":"2042","MAPPING1H":"2042"},{"SYMBOLID":"S*U*SOF---*****","DESCRIPTION":"Other Submersible Surfaced","MAPPING1U":"2043","MAPPING1F":"2043","MAPPING1N":"2043","MAPPING1H":"2043"},{"SYMBOLID":"S*U*SU----*****","DESCRIPTION":"Unmanned Underwater Vehicle (UUV)","MAPPING1U":"2046","MAPPING1F":"2046","MAPPING1N":"2046","MAPPING1H":"2046"},{"SYMBOLID":"S*U*SUM---*****","DESCRIPTION":"UUV Mine Warfare","MAPPING1U":"2047","MAPPING1F":"2047","MAPPING1N":"2047","MAPPING1H":"2047"},{"SYMBOLID":"S*U*SUS---*****","DESCRIPTION":"UUV Antisubmarine Warfare","MAPPING1U":"2048","MAPPING1F":"2048","MAPPING1N":"2048","MAPPING1H":"2048"},{"SYMBOLID":"S*U*SUN---*****","DESCRIPTION":"UUV Antisurface Warfare","MAPPING1U":"2049","MAPPING1F":"2049","MAPPING1N":"2049","MAPPING1H":"2049"},{"SYMBOLID":"S*U*SS----*****","DESCRIPTION":"Submarine Station","MAPPING1U":"2044","MAPPING1F":"2044","MAPPING1N":"2044","MAPPING1H":"2044"},{"SYMBOLID":"S*U*SSA---*****","DESCRIPTION":"ASW Submarine","MAPPING1U":"2045","MAPPING1F":"2045","MAPPING1N":"2045","MAPPING1H":"2045"},{"SYMBOLID":"S*U*SF----*****","DESCRIPTION":"Submarine Station Surfaced","MAPPING1U":"2018","MAPPING1F":"2018","MAPPING1N":"2018","MAPPING1H":"2018"},{"SYMBOLID":"S*U*W-----*****","DESCRIPTION":"Underwater Weapon","MAPPING1U":"2056","MAPPING1F":"2056","MAPPING1N":"2056","MAPPING1H":"2056"},{"SYMBOLID":"S*U*WT----*****","DESCRIPTION":"Torpedo","MAPPING1U":"2057","MAPPING1F":"2057","MAPPING1N":"2057","MAPPING1H":"2057"},{"SYMBOLID":"S*U*WM----*****","DESCRIPTION":"Sea Mine","MAPPING1U":"2058","MAPPING1F":"2058","MAPPING1N":"2058","MAPPING1H":"2058"},{"SYMBOLID":"S*U*WMD---*****","DESCRIPTION":"Sea Mine Dealt","MAPPING1U":"2060","MAPPING1F":"2060","MAPPING1N":"2060","MAPPING1H":"2060"},{"SYMBOLID":"S*U*WMG---*****","DESCRIPTION":"Sea Mine (Ground)","MAPPING1U":"2061","MAPPING1F":"2061","MAPPING1N":"2061","MAPPING1H":"2061"},{"SYMBOLID":"S*U*WMGD--*****","DESCRIPTION":"Sea Mine (Ground) Dealt","MAPPING1U":"2063","MAPPING1F":"2063","MAPPING1N":"2063","MAPPING1H":"2063"},{"SYMBOLID":"S*U*WMM---*****","DESCRIPTION":"Sea Mine (Moored)","MAPPING1U":"2072","MAPPING1F":"2072","MAPPING1N":"2072","MAPPING1H":"2072"},{"SYMBOLID":"S*U*WMMD--*****","DESCRIPTION":"Sea Mine (Moored) Dealt","MAPPING1U":"2074","MAPPING1F":"2074","MAPPING1N":"2074","MAPPING1H":"2074"},{"SYMBOLID":"S*U*WMF---*****","DESCRIPTION":"Sea Mine (Floating)","MAPPING1U":"2083","MAPPING1F":"2083","MAPPING1N":"2083","MAPPING1H":"2083"},{"SYMBOLID":"S*U*WMFD--*****","DESCRIPTION":"Sea Mine (Floating) Dealt","MAPPING1U":"2085","MAPPING1F":"2085","MAPPING1N":"2085","MAPPING1H":"2085"},{"SYMBOLID":"S*U*WMO---*****","DESCRIPTION":"Sea Mine (Other Position)","MAPPING1U":"2093","MAPPING1F":"2093","MAPPING1N":"2093","MAPPING1H":"2093"},{"SYMBOLID":"S*U*WMOD--*****","DESCRIPTION":"Sea Mine (Other Position) Dealt","MAPPING1U":"2095","MAPPING1F":"2095","MAPPING1N":"2095","MAPPING1H":"2095"},{"SYMBOLID":"S*U*WD----*****","DESCRIPTION":"Underwater Decoy","MAPPING1U":"2113","MAPPING1F":"2113","MAPPING1N":"2113","MAPPING1H":"2113"},{"SYMBOLID":"S*U*WDM---*****","DESCRIPTION":"Sea Mine Decoy","MAPPING1U":"2114","MAPPING1F":"2114","MAPPING1N":"2114","MAPPING1H":"2114"},{"SYMBOLID":"S*U*N-----*****","DESCRIPTION":"Non-Submarine"},{"SYMBOLID":"S*U*ND----*****","DESCRIPTION":"Diver","MAPPING1U":"2120","MAPPING1F":"2120","MAPPING1N":"2120","MAPPING1H":"2120"},{"SYMBOLID":"S*U*X-----*****","DESCRIPTION":"Unexploded Ordnance Area (Subsurface)","MAPPING2":"2126","MAPPING2COLOR":"#FF0000"},{"SYMBOLID":"S*F*------*****","DESCRIPTION":"Special Operations Forces (SOF) Unit","MAPPING1U":"2131","MAPPING1F":"2131","MAPPING1N":"2131","MAPPING1H":"2131"},{"SYMBOLID":"S*F*A-----*****","DESCRIPTION":"SOF Unit Aviation","MAPPING1U":"2132","MAPPING1F":"2132","MAPPING1N":"2132","MAPPING1H":"2132"},{"SYMBOLID":"S*F*AF----*****","DESCRIPTION":"SOF Unit Fixed Wing","MAPPING1U":"2133","MAPPING1F":"2133","MAPPING1N":"2133","MAPPING1H":"2133"},{"SYMBOLID":"S*F*AFA---*****","DESCRIPTION":"SOF Unit Fixed Wing Attack","MAPPING1U":"2134","MAPPING1F":"2134","MAPPING1N":"2134","MAPPING1H":"2134"},{"SYMBOLID":"S*F*AFK---*****","DESCRIPTION":"SOF Unit Refuel","MAPPING1U":"2135","MAPPING1F":"2135","MAPPING1N":"2135","MAPPING1H":"2135"},{"SYMBOLID":"S*F*AFU---*****","DESCRIPTION":"SOF Unit Fixed Wing Utility","MAPPING1U":"2136","MAPPING1F":"2136","MAPPING1N":"2136","MAPPING1H":"2136"},{"SYMBOLID":"S*F*AFUL--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Light)","MAPPING1U":"2137","MAPPING1F":"2137","MAPPING1N":"2137","MAPPING1H":"2137"},{"SYMBOLID":"S*F*AFUM--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Medium)","MAPPING1U":"2138","MAPPING1F":"2138","MAPPING1N":"2138","MAPPING1H":"2138"},{"SYMBOLID":"S*F*AFUH--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Heavy)","MAPPING1U":"2139","MAPPING1F":"2139","MAPPING1N":"2139","MAPPING1H":"2139"},{"SYMBOLID":"S*F*AV----*****","DESCRIPTION":"SOF Unit V/STOL","MAPPING1U":"2140","MAPPING1F":"2140","MAPPING1N":"2140","MAPPING1H":"2140"},{"SYMBOLID":"S*F*AH----*****","DESCRIPTION":"SOF Unit Rotary Wing","MAPPING1U":"2141","MAPPING1F":"2141","MAPPING1N":"2141","MAPPING1H":"2141"},{"SYMBOLID":"S*F*AHH---*****","DESCRIPTION":"SOF Unit Rotary Wing Combat Search & Rescue","MAPPING1U":"2142","MAPPING1F":"2142","MAPPING1N":"2142","MAPPING1H":"2142"},{"SYMBOLID":"S*F*AHA---*****","DESCRIPTION":"SOF Unit Rotary Wing Attack","MAPPING1U":"2143","MAPPING1F":"2143","MAPPING1N":"2143","MAPPING1H":"2143"},{"SYMBOLID":"S*F*AHU---*****","DESCRIPTION":"SOF Unit Rotary Wing Utility","MAPPING1U":"2144","MAPPING1F":"2144","MAPPING1N":"2144","MAPPING1H":"2144"},{"SYMBOLID":"S*F*AHUL--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Light)","MAPPING1U":"2145","MAPPING1F":"2145","MAPPING1N":"2145","MAPPING1H":"2145"},{"SYMBOLID":"S*F*AHUM--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Medium)","MAPPING1U":"2146","MAPPING1F":"2146","MAPPING1N":"2146","MAPPING1H":"2146"},{"SYMBOLID":"S*F*AHUH--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Heavy)","MAPPING1U":"2147","MAPPING1F":"2147","MAPPING1N":"2147","MAPPING1H":"2147"},{"SYMBOLID":"S*F*N-----*****","DESCRIPTION":"SOF Unit SOF Unit Naval","MAPPING1U":"2148","MAPPING1F":"2148","MAPPING1N":"2148","MAPPING1H":"2148"},{"SYMBOLID":"S*F*NS----*****","DESCRIPTION":"SOF Unit Seal","MAPPING1U":"2149","MAPPING1F":"2149","MAPPING1N":"2149","MAPPING1H":"2149"},{"SYMBOLID":"S*F*NU----*****","DESCRIPTION":"SOF Unit Underwater Demolition Team","MAPPING1U":"2150","MAPPING1F":"2150","MAPPING1N":"2150","MAPPING1H":"2150"},{"SYMBOLID":"S*F*NB----*****","DESCRIPTION":"SOF Unit Special Boat","MAPPING1U":"2151","MAPPING1F":"2151","MAPPING1N":"2151","MAPPING1H":"2151","MAPPING2":"2152","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*NN----*****","DESCRIPTION":"SOF Unit Special SSNR","MAPPING1U":"2153","MAPPING1F":"2153","MAPPING1N":"2153","MAPPING1H":"2153"},{"SYMBOLID":"S*F*G-----*****","DESCRIPTION":"SOF Unit Ground","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"2154","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*F*GS----*****","DESCRIPTION":"SOF Unit Special Forces","MAPPING1U":"2158","MAPPING1F":"2158","MAPPING1N":"2158","MAPPING1H":"2158"},{"SYMBOLID":"S*F*GR----*****","DESCRIPTION":"SOF Unit Ranger","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"2159","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*F*GP----*****","DESCRIPTION":"SOF Unit Psychological Operations (PSYOP)","MAPPING1U":"2161","MAPPING1F":"2161","MAPPING1N":"2161","MAPPING1H":"2161","MAPPING2":"2162","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*GPA---*****","DESCRIPTION":"SOF Unit Fixed Wing Aviation (PSYOP)","MAPPING1U":"2163","MAPPING1F":"2163","MAPPING1N":"2163","MAPPING1H":"2163","MAPPING2":"2164","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*GC----*****","DESCRIPTION":"SOF Unit Civil Affairs","MAPPING1U":"2165","MAPPING1F":"2165","MAPPING1N":"2165","MAPPING1H":"2165"},{"SYMBOLID":"S*F*B-----*****","DESCRIPTION":"SOF Unit Support","MAPPING1U":"2166","MAPPING1F":"2166","MAPPING1N":"2166","MAPPING1H":"2166"},{"SYMBOLID":"S*Z*------*****","DESCRIPTION":"Unknown Battle Dimension","MAPPING1U":"999","MAPPING1F":"999","MAPPING1N":"999","MAPPING1H":"999"},{"SYMBOLID":"I*-*------*****","DESCRIPTION":"Signals Intelligence"},{"SYMBOLID":"I*P*------*****","DESCRIPTION":"Space Track"},{"SYMBOLID":"I*P*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*P*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*P*SCD---*****","DESCRIPTION":"Satellite Down-Link","MAPPING1U":"3000","MAPPING1F":"3000","MAPPING1N":"3000","MAPPING1H":"3000"},{"SYMBOLID":"I*P*SR----*****","DESCRIPTION":"Radar(Signal Intercept)"},{"SYMBOLID":"I*P*SRD---*****","DESCRIPTION":"Data Transmission(SPACE TRACK)","MAPPING1U":"3001","MAPPING1F":"3001","MAPPING1N":"3001","MAPPING1H":"3001"},{"SYMBOLID":"I*P*SRE---*****","DESCRIPTION":"Earth Surveillance","MAPPING1U":"3002","MAPPING1F":"3002","MAPPING1N":"3002","MAPPING1H":"3002"},{"SYMBOLID":"I*P*SRI---*****","DESCRIPTION":"IFF (Transponder)(SPACE TRACK)","MAPPING1U":"3003","MAPPING1F":"3003","MAPPING1N":"3003","MAPPING1H":"3003"},{"SYMBOLID":"I*P*SRM---*****","DESCRIPTION":"Multi-function(SPACE TRACK)","MAPPING1U":"3004","MAPPING1F":"3004","MAPPING1N":"3004","MAPPING1H":"3004"},{"SYMBOLID":"I*P*SRT---*****","DESCRIPTION":"Target Acquisition(Space Track)","MAPPING1U":"3005","MAPPING1F":"3005","MAPPING1N":"3005","MAPPING1H":"3005"},{"SYMBOLID":"I*P*SRS---*****","DESCRIPTION":"Space","MAPPING1U":"3006","MAPPING1F":"3006","MAPPING1N":"3006","MAPPING1H":"3006"},{"SYMBOLID":"I*P*SRU---*****","DESCRIPTION":"Unknown(Space Track)","MAPPING1U":"3007","MAPPING1F":"3007","MAPPING1N":"3007","MAPPING1H":"3007"},{"SYMBOLID":"I*A*------*****","DESCRIPTION":"Air Track"},{"SYMBOLID":"I*A*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*A*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*A*SCC---*****","DESCRIPTION":"Cellular/Mobile(AIR TRACK)","MAPPING1U":"3008","MAPPING1F":"3008","MAPPING1N":"3008","MAPPING1H":"3008"},{"SYMBOLID":"I*A*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(AIR TRACK)","MAPPING1U":"3009","MAPPING1F":"3009","MAPPING1N":"3009","MAPPING1H":"3009"},{"SYMBOLID":"I*A*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Air Track)","MAPPING1U":"3010","MAPPING1F":"3010","MAPPING1N":"3010","MAPPING1H":"3010"},{"SYMBOLID":"I*A*SCS---*****","DESCRIPTION":"Satellite Up-Link(Air Track)","MAPPING1U":"3011","MAPPING1F":"3011","MAPPING1N":"3011","MAPPING1H":"3011"},{"SYMBOLID":"I*A*SR----*****","DESCRIPTION":"Radar"},{"SYMBOLID":"I*A*SRAI--*****","DESCRIPTION":"Airborne Intercept","MAPPING1U":"3012","MAPPING1F":"3012","MAPPING1N":"3012","MAPPING1H":"3012"},{"SYMBOLID":"I*A*SRAS--*****","DESCRIPTION":"Airborne Search and Bombing","MAPPING1U":"3013","MAPPING1F":"3013","MAPPING1N":"3013","MAPPING1H":"3013"},{"SYMBOLID":"I*A*SRC---*****","DESCRIPTION":"Controlled Intercept(AIR TRACK)","MAPPING1U":"3014","MAPPING1F":"3014","MAPPING1N":"3014","MAPPING1H":"3014"},{"SYMBOLID":"I*A*SRD---*****","DESCRIPTION":"Data Transmission(AIR TRACK)","MAPPING1U":"3015","MAPPING1F":"3015","MAPPING1N":"3015","MAPPING1H":"3015"},{"SYMBOLID":"I*A*SRE---*****","DESCRIPTION":"Early Warning(AIR TRACK)","MAPPING1U":"3016","MAPPING1F":"3016","MAPPING1N":"3016","MAPPING1H":"3016"},{"SYMBOLID":"I*A*SRF---*****","DESCRIPTION":"Fire Control(AIR TRACK)","MAPPING1U":"3017","MAPPING1F":"3017","MAPPING1N":"3017","MAPPING1H":"3017"},{"SYMBOLID":"I*A*SRI---*****","DESCRIPTION":"IFF (Transponder)(AIR TRACK)","MAPPING1U":"3018","MAPPING1F":"3018","MAPPING1N":"3018","MAPPING1H":"3018"},{"SYMBOLID":"I*A*SRMA--*****","DESCRIPTION":"Missile Acquisition(AIR TRACK)","MAPPING1U":"3019","MAPPING1F":"3019","MAPPING1N":"3019","MAPPING1H":"3019"},{"SYMBOLID":"I*A*SRMD--*****","DESCRIPTION":"Missile Downlink","MAPPING1U":"3020","MAPPING1F":"3020","MAPPING1N":"3020","MAPPING1H":"3020"},{"SYMBOLID":"I*A*SRMG--*****","DESCRIPTION":"Missile Guidance(AIR TRACK)","MAPPING1U":"3021","MAPPING1F":"3021","MAPPING1N":"3021","MAPPING1H":"3021"},{"SYMBOLID":"I*A*SRMT--*****","DESCRIPTION":"Missile Tracking(AIR TRACK)","MAPPING1U":"3022","MAPPING1F":"3022","MAPPING1N":"3022","MAPPING1H":"3022"},{"SYMBOLID":"I*A*SRMF--*****","DESCRIPTION":"Multi-Function(AIR TRACK)","MAPPING1U":"3023","MAPPING1F":"3023","MAPPING1N":"3023","MAPPING1H":"3023"},{"SYMBOLID":"I*A*SRTI--*****","DESCRIPTION":"Target Illuminator(Air Track)","MAPPING1U":"3024","MAPPING1F":"3024","MAPPING1N":"3024","MAPPING1H":"3024"},{"SYMBOLID":"I*A*SRTA--*****","DESCRIPTION":"Target Acquisition(Air Track)","MAPPING1U":"3025","MAPPING1F":"3025","MAPPING1N":"3025","MAPPING1H":"3025"},{"SYMBOLID":"I*A*SRTT--*****","DESCRIPTION":"Target Tracking(Air Track)","MAPPING1U":"3026","MAPPING1F":"3026","MAPPING1N":"3026","MAPPING1H":"3026"},{"SYMBOLID":"I*A*SRU---*****","DESCRIPTION":"Unknown(Air Track)","MAPPING1U":"3027","MAPPING1F":"3027","MAPPING1N":"3027","MAPPING1H":"3027"},{"SYMBOLID":"I*G*------*****","DESCRIPTION":"Ground Track"},{"SYMBOLID":"I*G*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*G*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*G*SCC---*****","DESCRIPTION":"Cellular/Mobile(GROUND TRACK)","MAPPING1U":"3028","MAPPING1F":"3028","MAPPING1N":"3028","MAPPING1H":"3028"},{"SYMBOLID":"I*G*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(GROUND TRACK)","MAPPING1U":"3029","MAPPING1F":"3029","MAPPING1N":"3029","MAPPING1H":"3029"},{"SYMBOLID":"I*G*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Ground Track)","MAPPING1U":"3030","MAPPING1F":"3030","MAPPING1N":"3030","MAPPING1H":"3030"},{"SYMBOLID":"I*G*SCS---*****","DESCRIPTION":"Satellite Up-Link(Ground Track)","MAPPING1U":"3031","MAPPING1F":"3031","MAPPING1N":"3031","MAPPING1H":"3031"},{"SYMBOLID":"I*G*SCT---*****","DESCRIPTION":"Tropospheric Scatter","MAPPING1U":"3032","MAPPING1F":"3032","MAPPING1N":"3032","MAPPING1H":"3032"},{"SYMBOLID":"I*G*SR----*****","DESCRIPTION":"Radar(Signals Intelligence)"},{"SYMBOLID":"I*G*SRAT--*****","DESCRIPTION":"Air Traffic Control(GROUND TRACK)","MAPPING1U":"3033","MAPPING1F":"3033","MAPPING1N":"3033","MAPPING1H":"3033"},{"SYMBOLID":"I*G*SRAA--*****","DESCRIPTION":"Anti-Aircraft(GROUND TRACK)","MAPPING1U":"3034","MAPPING1F":"3034","MAPPING1N":"3034","MAPPING1H":"3034"},{"SYMBOLID":"I*G*SRB---*****","DESCRIPTION":"Battlefield Surveillance","MAPPING1U":"3035","MAPPING1F":"3035","MAPPING1N":"3035","MAPPING1H":"3035"},{"SYMBOLID":"I*G*SRCS--*****","DESCRIPTION":"Coastal Surveillance","MAPPING1U":"3036","MAPPING1F":"3036","MAPPING1N":"3036","MAPPING1H":"3036"},{"SYMBOLID":"I*G*SRCA--*****","DESCRIPTION":"Controlled Approach(GROUND TRACK)","MAPPING1U":"3037","MAPPING1F":"3037","MAPPING1N":"3037","MAPPING1H":"3037"},{"SYMBOLID":"I*G*SRD---*****","DESCRIPTION":"Data Transmission(GROUND TRACK)","MAPPING1U":"3038","MAPPING1F":"3038","MAPPING1N":"3038","MAPPING1H":"3038"},{"SYMBOLID":"I*G*SRE---*****","DESCRIPTION":"Early Warning(GROUND TRACK)","MAPPING1U":"3039","MAPPING1F":"3039","MAPPING1N":"3039","MAPPING1H":"3039"},{"SYMBOLID":"I*G*SRF---*****","DESCRIPTION":"Fire Control(GROUND TRACK)","MAPPING1U":"3040","MAPPING1F":"3040","MAPPING1N":"3040","MAPPING1H":"3040"},{"SYMBOLID":"I*G*SRH---*****","DESCRIPTION":"Height Finding(GROUND TRACK)","MAPPING1U":"3041","MAPPING1F":"3041","MAPPING1N":"3041","MAPPING1H":"3041"},{"SYMBOLID":"I*G*SRI---*****","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(GROUND TRACK)","MAPPING1U":"3042","MAPPING1F":"3042","MAPPING1N":"3042","MAPPING1H":"3042"},{"SYMBOLID":"I*G*SRMM--*****","DESCRIPTION":"Meteorological (Military)(GROUND TRACK)","MAPPING1U":"3043","MAPPING1F":"3043","MAPPING1N":"3043","MAPPING1H":"3043"},{"SYMBOLID":"I*G*SRMA--*****","DESCRIPTION":"Missile Acquisition(GROUND TRACK)","MAPPING1U":"3044","MAPPING1F":"3044","MAPPING1N":"3044","MAPPING1H":"3044"},{"SYMBOLID":"I*G*SRMG--*****","DESCRIPTION":"Missile Guidance(GROUND TRACK)","MAPPING1U":"3045","MAPPING1F":"3045","MAPPING1N":"3045","MAPPING1H":"3045"},{"SYMBOLID":"I*G*SRMT--*****","DESCRIPTION":"Missile Tracking(GROUND TRACK)","MAPPING1U":"3046","MAPPING1F":"3046","MAPPING1N":"3046","MAPPING1H":"3046"},{"SYMBOLID":"I*G*SRMF--*****","DESCRIPTION":"Multi-Function(GROUND TRACK)","MAPPING1U":"3047","MAPPING1F":"3047","MAPPING1N":"3047","MAPPING1H":"3047"},{"SYMBOLID":"I*G*SRS---*****","DESCRIPTION":"Shell Tracking","MAPPING1U":"3048","MAPPING1F":"3048","MAPPING1N":"3048","MAPPING1H":"3048"},{"SYMBOLID":"I*G*SRTA--*****","DESCRIPTION":"Target Acquisition(Radar)","MAPPING1U":"3049","MAPPING1F":"3049","MAPPING1N":"3049","MAPPING1H":"3049"},{"SYMBOLID":"I*G*SRTI--*****","DESCRIPTION":"Target Illuminator(Ground Track)","MAPPING1U":"3050","MAPPING1F":"3050","MAPPING1N":"3050","MAPPING1H":"3050"},{"SYMBOLID":"I*G*SRTT--*****","DESCRIPTION":"Target Tracking(Ground Track)","MAPPING1U":"3051","MAPPING1F":"3051","MAPPING1N":"3051","MAPPING1H":"3051"},{"SYMBOLID":"I*G*SRU---*****","DESCRIPTION":"Unknown(Ground Track)","MAPPING1U":"3052","MAPPING1F":"3052","MAPPING1N":"3052","MAPPING1H":"3052"},{"SYMBOLID":"I*S*------*****","DESCRIPTION":"Sea Surface Track"},{"SYMBOLID":"I*S*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*S*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*S*SCC---*****","DESCRIPTION":"Cellular/Mobile(SEA SURFACE TRACK)","MAPPING1U":"3053","MAPPING1F":"3053","MAPPING1N":"3053","MAPPING1H":"3053"},{"SYMBOLID":"I*S*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SEA SURFACE TRACK)","MAPPING1U":"3054","MAPPING1F":"3054","MAPPING1N":"3054","MAPPING1H":"3054"},{"SYMBOLID":"I*S*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Sea Surface Track)","MAPPING1U":"3055","MAPPING1F":"3055","MAPPING1N":"3055","MAPPING1H":"3055"},{"SYMBOLID":"I*S*SCS---*****","DESCRIPTION":"Satellite Up-Link(Sea Surface Track)","MAPPING1U":"3056","MAPPING1F":"3056","MAPPING1N":"3056","MAPPING1H":"3056"},{"SYMBOLID":"I*S*SR----*****","DESCRIPTION":"Radar(Sea Surface Track)"},{"SYMBOLID":"I*S*SRAT--*****","DESCRIPTION":"Air Traffic Control(SEA SURFACE TRACK)","MAPPING1U":"3057","MAPPING1F":"3057","MAPPING1N":"3057","MAPPING1H":"3057"},{"SYMBOLID":"I*S*SRAA--*****","DESCRIPTION":"Anti-Aircraft(SEA SURFACE TRACK)","MAPPING1U":"3058","MAPPING1F":"3058","MAPPING1N":"3058","MAPPING1H":"3058"},{"SYMBOLID":"I*S*SRCA--*****","DESCRIPTION":"Controlled Approach(SEA SURFACE TRACK)","MAPPING1U":"3059","MAPPING1F":"3059","MAPPING1N":"3059","MAPPING1H":"3059"},{"SYMBOLID":"I*S*SRCI--*****","DESCRIPTION":"Controlled Intercept(SEA SURFACE TRACK)","MAPPING1U":"3060","MAPPING1F":"3060","MAPPING1N":"3060","MAPPING1H":"3060"},{"SYMBOLID":"I*S*SRD---*****","DESCRIPTION":"Data Transmission(SEA SURFACE TRACK)","MAPPING1U":"3061","MAPPING1F":"3061","MAPPING1N":"3061","MAPPING1H":"3061"},{"SYMBOLID":"I*S*SRE---*****","DESCRIPTION":"Early Warning(SEA SURFACE TRACK)","MAPPING1U":"3062","MAPPING1F":"3062","MAPPING1N":"3062","MAPPING1H":"3062"},{"SYMBOLID":"I*S*SRF---*****","DESCRIPTION":"Fire Control(SEA SURFACE TRACK)","MAPPING1U":"3063","MAPPING1F":"3063","MAPPING1N":"3063","MAPPING1H":"3063"},{"SYMBOLID":"I*S*SRH---*****","DESCRIPTION":"Height Finding(SEA SURFACE TRACK)","MAPPING1U":"3064","MAPPING1F":"3064","MAPPING1N":"3064","MAPPING1H":"3064"},{"SYMBOLID":"I*S*SRI---*****","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(SEA SURFACE TRACK)","MAPPING1U":"3065","MAPPING1F":"3065","MAPPING1N":"3065","MAPPING1H":"3065"},{"SYMBOLID":"I*S*SRMM--*****","DESCRIPTION":"Meteorological (Military)(SEA SURFACE TRACK)","MAPPING1U":"3066","MAPPING1F":"3066","MAPPING1N":"3066","MAPPING1H":"3066"},{"SYMBOLID":"I*S*SRMA--*****","DESCRIPTION":"Missile Acquisition(SEA SURFACE TRACK)","MAPPING1U":"3067","MAPPING1F":"3067","MAPPING1N":"3067","MAPPING1H":"3067"},{"SYMBOLID":"I*S*SRMG--*****","DESCRIPTION":"Missile Guidance(SEA SURFACE TRACK)","MAPPING1U":"3068","MAPPING1F":"3068","MAPPING1N":"3068","MAPPING1H":"3068"},{"SYMBOLID":"I*S*SRMT--*****","DESCRIPTION":"Missile Tracking(SEA SURFACE TRACK)","MAPPING1U":"3069","MAPPING1F":"3069","MAPPING1N":"3069","MAPPING1H":"3069"},{"SYMBOLID":"I*S*SRMF--*****","DESCRIPTION":"Multi-Function(SEA SURFACE TRACK)","MAPPING1U":"3070","MAPPING1F":"3070","MAPPING1N":"3070","MAPPING1H":"3070"},{"SYMBOLID":"I*S*SRS---*****","DESCRIPTION":"Surface Search(Sea Surface Track)","MAPPING1U":"3071","MAPPING1F":"3071","MAPPING1N":"3071","MAPPING1H":"3071"},{"SYMBOLID":"I*S*SRTA--*****","DESCRIPTION":"Target Acquisition(Sea Surface Track)","MAPPING1U":"3072","MAPPING1F":"3072","MAPPING1N":"3072","MAPPING1H":"3072"},{"SYMBOLID":"I*S*SRTI--*****","DESCRIPTION":"Target Illuminator(Sea Surface Track)","MAPPING1U":"3073","MAPPING1F":"3073","MAPPING1N":"3073","MAPPING1H":"3073"},{"SYMBOLID":"I*S*SRTT--*****","DESCRIPTION":"Target Tracking(Sea Surface Track)","MAPPING1U":"3074","MAPPING1F":"3074","MAPPING1N":"3074","MAPPING1H":"3074"},{"SYMBOLID":"I*S*SRU---*****","DESCRIPTION":"Unknown(Sea Surface Track)","MAPPING1U":"3075","MAPPING1F":"3075","MAPPING1N":"3075","MAPPING1H":"3075"},{"SYMBOLID":"I*U*------*****","DESCRIPTION":"Subsurface Track"},{"SYMBOLID":"I*U*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*U*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*U*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SUBSURFACE TRACK)","MAPPING1U":"3076","MAPPING1F":"3076","MAPPING1N":"3076","MAPPING1H":"3076"},{"SYMBOLID":"I*U*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Subsurface Track)","MAPPING1U":"3077","MAPPING1F":"3077","MAPPING1N":"3077","MAPPING1H":"3077"},{"SYMBOLID":"I*U*SCS---*****","DESCRIPTION":"Satellite Up-Link(Subsurface Track)","MAPPING1U":"3078","MAPPING1F":"3078","MAPPING1N":"3078","MAPPING1H":"3078"},{"SYMBOLID":"I*U*SR----*****","DESCRIPTION":"Radar(Subsurface Track)"},{"SYMBOLID":"I*U*SRD---*****","DESCRIPTION":"Data Transmission(SUBSURFACE TRACK)","MAPPING1U":"3079","MAPPING1F":"3079","MAPPING1N":"3079","MAPPING1H":"3079"},{"SYMBOLID":"I*U*SRE---*****","DESCRIPTION":"Early Warning(SUBSURFACE TRACK)","MAPPING1U":"3080","MAPPING1F":"3080","MAPPING1N":"3080","MAPPING1H":"3080"},{"SYMBOLID":"I*U*SRM---*****","DESCRIPTION":"Multi-Function(Subsurface Track)","MAPPING1U":"3081","MAPPING1F":"3081","MAPPING1N":"3081","MAPPING1H":"3081"},{"SYMBOLID":"I*U*SRS---*****","DESCRIPTION":"Surface Search(Subsurface Track)","MAPPING1U":"3082","MAPPING1F":"3082","MAPPING1N":"3082","MAPPING1H":"3082"},{"SYMBOLID":"I*U*SRT---*****","DESCRIPTION":"Target Acquisition(Subsurface Track)","MAPPING1U":"3083","MAPPING1F":"3083","MAPPING1N":"3083","MAPPING1H":"3083"},{"SYMBOLID":"I*U*SRU---*****","DESCRIPTION":"Unknown(Subsurface Track)","MAPPING1U":"3084","MAPPING1F":"3084","MAPPING1N":"3084","MAPPING1H":"3084"},{"SYMBOLID":"O*-*------*****","DESCRIPTION":"Stability Operations"},{"SYMBOLID":"O*V*------*****","DESCRIPTION":"Violent Activities"},{"SYMBOLID":"O*V*A-----*****","DESCRIPTION":"Arson/Fire","MAPPING1U":"3999","MAPPING1F":"3999","MAPPING1N":"3999","MAPPING1H":"3999"},{"SYMBOLID":"O*V*M-----*****","DESCRIPTION":"Killing (General)","MAPPING1U":"4001","MAPPING1F":"4002","MAPPING1N":"4003","MAPPING1H":"4004"},{"SYMBOLID":"O*V*MA----*****","DESCRIPTION":"Murder","MAPPING1U":"4005","MAPPING1F":"4006","MAPPING1N":"4007","MAPPING1H":"4008"},{"SYMBOLID":"O*V*MB----*****","DESCRIPTION":"Execution","MAPPING1U":"4009","MAPPING1F":"4010","MAPPING1N":"4011","MAPPING1H":"4012"},{"SYMBOLID":"O*V*MC----*****","DESCRIPTION":"Assassination","MAPPING1U":"4013","MAPPING1F":"4014","MAPPING1N":"4015","MAPPING1H":"4016"},{"SYMBOLID":"O*V*B-----*****","DESCRIPTION":"Bomb/Bombing","MAPPING1U":"4017","MAPPING1F":"4017","MAPPING1N":"4017","MAPPING1H":"4017"},{"SYMBOLID":"O*V*Y-----*****","DESCRIPTION":"Booby Trap","MAPPING1U":"4018","MAPPING1F":"4018","MAPPING1N":"4018","MAPPING1H":"4018"},{"SYMBOLID":"O*V*D-----*****","DESCRIPTION":"Drive-By Shooting","MAPPING1U":"4019","MAPPING1F":"4019","MAPPING1N":"4019","MAPPING1H":"4019"},{"SYMBOLID":"O*V*S-----*****","DESCRIPTION":"Sniping","MAPPING1U":"4020","MAPPING1F":"4020","MAPPING1N":"4020","MAPPING1H":"4020"},{"SYMBOLID":"O*V*P-----*****","DESCRIPTION":"Poisoning","MAPPING1U":"4021","MAPPING1F":"4021","MAPPING1N":"4021","MAPPING1H":"4021"},{"SYMBOLID":"O*V*E-----*****","DESCRIPTION":"Explosion","MAPPING1U":"4022","MAPPING1F":"4022","MAPPING1N":"4022","MAPPING1H":"4022","MAPPING2":"406","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"O*V*EI----*****","DESCRIPTION":"IED Explosion","MAPPING1U":"4023","MAPPING1F":"4023","MAPPING1N":"4023","MAPPING1H":"4023"},{"SYMBOLID":"O*V*EG----*****","DESCRIPTION":"Explosion, Grenade","MAPPING1U":"4508","MAPPING1F":"4508","MAPPING1N":"4508","MAPPING1H":"4508"},{"SYMBOLID":"O*V*EN----*****","DESCRIPTION":"Explosion, Incendiary","MAPPING1U":"4509","MAPPING1F":"4509","MAPPING1N":"4509","MAPPING1H":"4509"},{"SYMBOLID":"O*V*EM----*****","DESCRIPTION":"Explosion, Mine","MAPPING1U":"4510","MAPPING1F":"4510","MAPPING1N":"4510","MAPPING1H":"4510"},{"SYMBOLID":"O*V*EO----*****","DESCRIPTION":"Explosion, Mortar Fire","MAPPING1U":"4511","MAPPING1F":"4511","MAPPING1N":"4511","MAPPING1H":"4511"},{"SYMBOLID":"O*V*ER----*****","DESCRIPTION":"Explosion, Rocket","MAPPING1U":"4512","MAPPING1F":"4512","MAPPING1N":"4512","MAPPING1H":"4512"},{"SYMBOLID":"O*V*EV----*****","DESCRIPTION":"Explosion, Wheeled Vehicle","MAPPING1U":"4513","MAPPING1F":"4513","MAPPING1N":"4513","MAPPING1H":"4513"},{"SYMBOLID":"O*L*------*****","DESCRIPTION":"Locations"},{"SYMBOLID":"O*L*B-----*****","DESCRIPTION":"Black List Location","MAPPING1U":"4024","MAPPING1F":"4024","MAPPING1N":"4024","MAPPING1H":"4024"},{"SYMBOLID":"O*L*G-----*****","DESCRIPTION":"Gray List Location","MAPPING1U":"4025","MAPPING1F":"4025","MAPPING1N":"4025","MAPPING1H":"4025"},{"SYMBOLID":"O*L*W-----*****","DESCRIPTION":"White List Location","MAPPING1U":"4026","MAPPING1F":"4026","MAPPING1N":"4026","MAPPING1H":"4026"},{"SYMBOLID":"O*L*M-----*****","DESCRIPTION":"Mass Grave Location","MAPPING1U":"4027","MAPPING1F":"4027","MAPPING1N":"4027","MAPPING1H":"4027"},{"SYMBOLID":"O*L*E-----*****","DESCRIPTION":"Drug Lab","MAPPING1U":"4505","MAPPING1F":"4505","MAPPING1N":"4505","MAPPING1H":"4505"},{"SYMBOLID":"O*L*H-----*****","DESCRIPTION":"House/Residence","MAPPING1U":"4521","MAPPING1F":"4521","MAPPING1N":"4521","MAPPING1H":"4521"},{"SYMBOLID":"O*L*N-----*****","DESCRIPTION":"Cave Entrance","MAPPING1U":"4503","MAPPING1F":"4503","MAPPING1N":"4503","MAPPING1H":"4503"},{"SYMBOLID":"O*L*F-----*****","DESCRIPTION":"Polling Place","MAPPING1U":"4522","MAPPING1F":"4522","MAPPING1N":"4522","MAPPING1H":"4522"},{"SYMBOLID":"O*O*------*****","DESCRIPTION":"Operations"},{"SYMBOLID":"O*O*P-----*****","DESCRIPTION":"Patrolling","MAPPING1U":"4028","MAPPING1F":"4028","MAPPING1N":"4028","MAPPING1H":"4028"},{"SYMBOLID":"O*O*R-----*****","DESCRIPTION":"Recruitment"},{"SYMBOLID":"O*O*RW----*****","DESCRIPTION":"Recruitment (Willing)","MAPPING1U":"4029","MAPPING1F":"4029","MAPPING1N":"4029","MAPPING1H":"4029"},{"SYMBOLID":"O*O*RC----*****","DESCRIPTION":"Recruitment (Coerced/Impressed)","MAPPING1U":"4030","MAPPING1F":"4030","MAPPING1N":"4030","MAPPING1H":"4030"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Demonstration","MAPPING1U":"4031","MAPPING1F":"4031","MAPPING1N":"4031","MAPPING1H":"4031"},{"SYMBOLID":"O*O*M-----*****","DESCRIPTION":"Mine Laying","MAPPING1U":"4032","MAPPING1F":"4032","MAPPING1N":"4032","MAPPING1H":"4032"},{"SYMBOLID":"O*O*Y-----*****","DESCRIPTION":"Psychological Operations (Psyop)","MAPPING1U":"4033","MAPPING1F":"4033","MAPPING1N":"4033","MAPPING1H":"4033","MAPPING2":"4034","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YT----*****","DESCRIPTION":"Psyop (TV and Radio Propaganda)","MAPPING1U":"4035","MAPPING1F":"4036","MAPPING1N":"4037","MAPPING1H":"4038","MAPPING2":"4039","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YW----*****","DESCRIPTION":"Psyop (Written Propaganda)","MAPPING1U":"4043","MAPPING1F":"4043","MAPPING1N":"4043","MAPPING1H":"4043","MAPPING2":"4045","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YH----*****","DESCRIPTION":"House-to-House Propaganda","MAPPING1U":"4044","MAPPING1F":"4044","MAPPING1N":"4044","MAPPING1H":"4044","MAPPING2":"4045","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*F-----*****","DESCRIPTION":"Foraging/Searching","MAPPING1U":"4046","MAPPING1F":"4046","MAPPING1N":"4046","MAPPING1H":"4046"},{"SYMBOLID":"O*O*S-----*****","DESCRIPTION":"Spy","MAPPING1U":"4047","MAPPING1F":"4047","MAPPING1N":"4047","MAPPING1H":"4047"},{"SYMBOLID":"O*O*O-----*****","DESCRIPTION":"Food Distribution","MAPPING1U":"4048","MAPPING1F":"4049","MAPPING1N":"4050","MAPPING1H":"4051"},{"SYMBOLID":"O*O*E-----*****","DESCRIPTION":"Extortion","MAPPING1U":"4052","MAPPING1F":"4052","MAPPING1N":"4052","MAPPING1H":"4052"},{"SYMBOLID":"O*O*H-----*****","DESCRIPTION":"Hijacking"},{"SYMBOLID":"O*O*HT----*****","DESCRIPTION":"Hijacking (Vehicle)","MAPPING1U":"4053","MAPPING1F":"4053","MAPPING1N":"4053","MAPPING1H":"4053"},{"SYMBOLID":"O*O*HA----*****","DESCRIPTION":"Hijacking (Airplane)","MAPPING1U":"4054","MAPPING1F":"4054","MAPPING1N":"4054","MAPPING1H":"4054","MAPPING2":"4055","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*HV----*****","DESCRIPTION":"Hijacking (Boat)","MAPPING1U":"4056","MAPPING1F":"4056","MAPPING1N":"4056","MAPPING1H":"4056","MAPPING2":"4057","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*K-----*****","DESCRIPTION":"Kidnapping","MAPPING1U":"4058","MAPPING1F":"4058","MAPPING1N":"4058","MAPPING1H":"4058"},{"SYMBOLID":"O*O*KA----*****","DESCRIPTION":"Attempted Kidnapping","MAPPING1U":"4059","MAPPING1F":"4059","MAPPING1N":"4059","MAPPING1H":"4059"},{"SYMBOLID":"O*O*A-----*****","DESCRIPTION":"Arrest","MAPPING1U":"4060","MAPPING1F":"4060","MAPPING1N":"4060","MAPPING1H":"4060"},{"SYMBOLID":"O*O*U-----*****","DESCRIPTION":"Drug Operation","MAPPING1U":"4061","MAPPING1F":"4061","MAPPING1N":"4061","MAPPING1H":"4061"},{"SYMBOLID":"O*O*UT----*****","DESCRIPTION":"Drug Trafficking","MAPPING1U":"4506","MAPPING1F":"4506","MAPPING1N":"4506","MAPPING1H":"4506"},{"SYMBOLID":"O*O*N-----*****","DESCRIPTION":"Raid on a House","MAPPING1U":"4500","MAPPING1F":"4500","MAPPING1N":"4500","MAPPING1H":"4500"},{"SYMBOLID":"O*O*2-----*****","DESCRIPTION":"Burglary","MAPPING1U":"4502","MAPPING1F":"4502","MAPPING1N":"4502","MAPPING1H":"4502"},{"SYMBOLID":"O*O*V-----*****","DESCRIPTION":"Home Eviction","MAPPING1U":"4514","MAPPING1F":"4514","MAPPING1N":"4514","MAPPING1H":"4514"},{"SYMBOLID":"O*O*I-----*****","DESCRIPTION":"Black Marketing","MAPPING1U":"4516","MAPPING1F":"4516","MAPPING1N":"4516","MAPPING1H":"4516"},{"SYMBOLID":"O*O*J-----*****","DESCRIPTION":"Jail Break","MAPPING1U":"4518","MAPPING1F":"4518","MAPPING1N":"4518","MAPPING1H":"4518","MAPPING2":"4519","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*B-----*****","DESCRIPTION":"Robbery","MAPPING1U":"4524","MAPPING1F":"4524","MAPPING1N":"4524","MAPPING1H":"4524"},{"SYMBOLID":"O*O*G-----*****","DESCRIPTION":"Sabotage","MAPPING1U":"4526","MAPPING1F":"4526","MAPPING1N":"4526","MAPPING1H":"4526"},{"SYMBOLID":"O*O*X-----*****","DESCRIPTION":"Smuggling","MAPPING1U":"4527","MAPPING1F":"4527","MAPPING1N":"4527","MAPPING1H":"4527"},{"SYMBOLID":"O*O*W-----*****","DESCRIPTION":"Rock Throwing","MAPPING1U":"4525","MAPPING1F":"4525","MAPPING1N":"4525","MAPPING1H":"4525"},{"SYMBOLID":"O*O*Z-----*****","DESCRIPTION":"Suspicious Activity","MAPPING1U":"4529","MAPPING1F":"4529","MAPPING1N":"4529","MAPPING1H":"4529"},{"SYMBOLID":"O*O*T-----*****","DESCRIPTION":"Theft","MAPPING1U":"4531","MAPPING1F":"4531","MAPPING1N":"4531","MAPPING1H":"4531"},{"SYMBOLID":"O*O*TV----*****","DESCRIPTION":"Wheeled Vehicle Theft","MAPPING1U":"4533","MAPPING1F":"4533","MAPPING1N":"4533","MAPPING1H":"4533"},{"SYMBOLID":"O*O*Q-----*****","DESCRIPTION":"Warrant Served","MAPPING1U":"4532","MAPPING1F":"4532","MAPPING1N":"4532","MAPPING1H":"4532"},{"SYMBOLID":"O*I*------*****","DESCRIPTION":"Items"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Refugees","MAPPING1U":"4066","MAPPING1F":"4066","MAPPING1N":"4066","MAPPING1H":"4066"},{"SYMBOLID":"O*I*S-----*****","DESCRIPTION":"Safe House","MAPPING1U":"4067","MAPPING1F":"4067","MAPPING1N":"4067","MAPPING1H":"4067"},{"SYMBOLID":"O*I*G-----*****","DESCRIPTION":"Graffiti","MAPPING1U":"4068","MAPPING1F":"4068","MAPPING1N":"4068","MAPPING1H":"4068"},{"SYMBOLID":"O*I*V-----*****","DESCRIPTION":"Vandalism/Loot/Ransack/Plunder/Sack","MAPPING1U":"4069","MAPPING1F":"4069","MAPPING1N":"4069","MAPPING1H":"4069"},{"SYMBOLID":"O*I*I-----*****","DESCRIPTION":"Known Insurgent Vehicle","MAPPING1U":"4070","MAPPING1F":"4070","MAPPING1N":"4070","MAPPING1H":"4070"},{"SYMBOLID":"O*I*D-----*****","DESCRIPTION":"Drug Vehicle","MAPPING1U":"4071","MAPPING1F":"4071","MAPPING1N":"4071","MAPPING1H":"4071"},{"SYMBOLID":"O*I*F-----*****","DESCRIPTION":"Internal Security Force","MAPPING1U":"4072","MAPPING1F":"4072","MAPPING1N":"4072","MAPPING1H":"4072"},{"SYMBOLID":"O*I*M-----*****","DESCRIPTION":"Meeting","MAPPING1U":"4520","MAPPING1F":"4520","MAPPING1N":"4520","MAPPING1H":"4520"},{"SYMBOLID":"O*I*T-----*****","DESCRIPTION":"Tent","MAPPING1U":"4530","MAPPING1F":"4530","MAPPING1N":"4530","MAPPING1H":"4530"},{"SYMBOLID":"O*P*------*****","DESCRIPTION":"Individual","MAPPING1U":"4073","MAPPING1F":"4073","MAPPING1N":"4073","MAPPING1H":"4073"},{"SYMBOLID":"O*P*A-----*****","DESCRIPTION":"Leader","MAPPING1U":"4074","MAPPING1F":"4074","MAPPING1N":"4074","MAPPING1H":"4074"},{"SYMBOLID":"O*P*AR----*****","DESCRIPTION":"Religious Leader","MAPPING1U":"4523","MAPPING1F":"4523","MAPPING1N":"4523","MAPPING1H":"4523"},{"SYMBOLID":"O*P*B-----*****","DESCRIPTION":"Targeted Individual","MAPPING1U":"4075","MAPPING1F":"4075","MAPPING1N":"4075","MAPPING1H":"4075"},{"SYMBOLID":"O*P*C-----*****","DESCRIPTION":"Terrorist","MAPPING1U":"4076","MAPPING1F":"4076","MAPPING1N":"4076","MAPPING1H":"4076"},{"SYMBOLID":"O*P*F-----*****","DESCRIPTION":"IED Suicide Bomber","MAPPING1U":"4501","MAPPING1F":"4501","MAPPING1N":"4501","MAPPING1H":"4501"},{"SYMBOLID":"O*P*D-----*****","DESCRIPTION":"Dead Body","MAPPING1U":"4504","MAPPING1F":"4504","MAPPING1N":"4504","MAPPING1H":"4504"},{"SYMBOLID":"O*P*G-----*****","DESCRIPTION":"Exfiltrating Individual","MAPPING1U":"4507","MAPPING1F":"4507","MAPPING1N":"4507","MAPPING1H":"4507"},{"SYMBOLID":"O*P*H-----*****","DESCRIPTION":"Infiltrating Individual","MAPPING1U":"4517","MAPPING1F":"4517","MAPPING1N":"4517","MAPPING1H":"4517"},{"SYMBOLID":"O*P*E-----*****","DESCRIPTION":"Speaker","MAPPING1U":"4528","MAPPING1F":"4528","MAPPING1N":"4528","MAPPING1H":"4528"},{"SYMBOLID":"O*G*------*****","DESCRIPTION":"Non-Military Group or Organization","MAPPING1U":"4077","MAPPING1F":"4077","MAPPING1N":"4077","MAPPING1H":"4077"},{"SYMBOLID":"O*G*B-----*****","DESCRIPTION":"Non-Governmental Organizations (NGO)","MAPPING1U":"4079","MAPPING1F":"4079","MAPPING1N":"4079","MAPPING1H":"4079"},{"SYMBOLID":"O*G*C-----*****","DESCRIPTION":"Terrorist Organization","MAPPING1U":"4080","MAPPING1F":"4080","MAPPING1N":"4080","MAPPING1H":"4080"},{"SYMBOLID":"O*G*D-----*****","DESCRIPTION":"Religious Organization","MAPPING1U":"4081","MAPPING1F":"4081","MAPPING1N":"4081","MAPPING1H":"4081"},{"SYMBOLID":"O*G*E-----*****","DESCRIPTION":"Foreign Fighter","MAPPING1U":"4082","MAPPING1F":"4082","MAPPING1N":"4082","MAPPING1H":"4082"},{"SYMBOLID":"O*G*F-----*****","DESCRIPTION":"GANG","MAPPING1U":"4083","MAPPING1F":"4083","MAPPING1N":"4083","MAPPING1H":"4083"},{"SYMBOLID":"O*R*------*****","DESCRIPTION":"Rape","MAPPING1U":"4084","MAPPING1F":"4084","MAPPING1N":"4084","MAPPING1H":"4084"},{"SYMBOLID":"O*R*A-----*****","DESCRIPTION":"Attempted Rape","MAPPING1U":"4085","MAPPING1F":"4085","MAPPING1N":"4085","MAPPING1H":"4085"},{"SYMBOLID":"O*E*------*****","DESCRIPTION":"Events"},{"SYMBOLID":"O*E*A-----*****","DESCRIPTION":"Elections","MAPPING1U":"9004","MAPPING1F":"9004","MAPPING1N":"9004","MAPPING1H":"9004"},{"SYMBOLID":"O*E*B-----*****","DESCRIPTION":"Speech","MAPPING1U":"9005","MAPPING1F":"9005","MAPPING1N":"9005","MAPPING1H":"9005"},{"SYMBOLID":"O*E*C-----*****","DESCRIPTION":"Sermon","MAPPING1U":"9006","MAPPING1F":"9006","MAPPING1N":"9006","MAPPING1H":"9006"},{"SYMBOLID":"O*E*D-----*****","DESCRIPTION":"Meeting","MAPPING1U":"9007","MAPPING1F":"9007","MAPPING1N":"9007","MAPPING1H":"9007"},{"SYMBOLID":"O*E*E-----*****","DESCRIPTION":"Demonstration(Events)","MAPPING1U":"9008","MAPPING1F":"9008","MAPPING1N":"9008","MAPPING1H":"9008"},{"SYMBOLID":"O*E*F-----*****","DESCRIPTION":"Riot","MAPPING1U":"9009","MAPPING1F":"9009","MAPPING1N":"9009","MAPPING1H":"9009"},{"SYMBOLID":"O*E*G-----*****","DESCRIPTION":"Gang Activity","MAPPING1U":"9010","MAPPING1F":"9010","MAPPING1N":"9010","MAPPING1H":"9010"},{"SYMBOLID":"O*E*H-----*****","DESCRIPTION":"Jail Break/Escape Custody","MAPPING1U":"9011","MAPPING1F":"9011","MAPPING1N":"9011","MAPPING1H":"9011"},{"SYMBOLID":"O*E*I-----*****","DESCRIPTION":"Rock Throwing","MAPPING1U":"9012","MAPPING1F":"9012","MAPPING1N":"9012","MAPPING1H":"9012"},{"SYMBOLID":"O*E*J-----*****","DESCRIPTION":"Illegal Selling/Purchasing/Distributing/Black Market","MAPPING1U":"9013","MAPPING1F":"9013","MAPPING1N":"9013","MAPPING1H":"9013"},{"SYMBOLID":"O*E*K-----*****","DESCRIPTION":"Surveillance","MAPPING1U":"9014","MAPPING1F":"9014","MAPPING1N":"9014","MAPPING1H":"9014"},{"SYMBOLID":"O*E*L-----*****","DESCRIPTION":"Lights","MAPPING1U":"9015","MAPPING1F":"9015","MAPPING1N":"9015","MAPPING1H":"9015"},{"SYMBOLID":"O*E*M-----*****","DESCRIPTION":"Border Crossing","MAPPING1U":"9016","MAPPING1F":"9016","MAPPING1N":"9016","MAPPING1H":"9016"},{"SYMBOLID":"O*E*N-----*****","DESCRIPTION":"Border Activity","MAPPING1U":"9017","MAPPING1F":"9017","MAPPING1N":"9017","MAPPING1H":"9017"},{"SYMBOLID":"O*E*O-----*****","DESCRIPTION":"Smuggling","MAPPING1U":"9018","MAPPING1F":"9018","MAPPING1N":"9018","MAPPING1H":"9018"},{"SYMBOLID":"O*E*P-----*****","DESCRIPTION":"Exfiltration","MAPPING1U":"9019","MAPPING1F":"9019","MAPPING1N":"9019","MAPPING1H":"9019"},{"SYMBOLID":"O*E*Q-----*****","DESCRIPTION":"Infiltration","MAPPING1U":"9020","MAPPING1F":"9020","MAPPING1N":"9020","MAPPING1H":"9020"},{"SYMBOLID":"O*E*R-----*****","DESCRIPTION":"Auto Theft","MAPPING1U":"9021","MAPPING1F":"9021","MAPPING1N":"9021","MAPPING1H":"9021"},{"SYMBOLID":"O*E*S-----*****","DESCRIPTION":"Auto Accident","MAPPING1U":"9022","MAPPING1F":"9022","MAPPING1N":"9022","MAPPING1H":"9022"},{"SYMBOLID":"O*E*T-----*****","DESCRIPTION":"Looting","MAPPING1U":"9023","MAPPING1F":"9023","MAPPING1N":"9023","MAPPING1H":"9023"},{"SYMBOLID":"O*E*U-----*****","DESCRIPTION":"Theft","MAPPING1U":"9024","MAPPING1F":"9024","MAPPING1N":"9024","MAPPING1H":"9024"},{"SYMBOLID":"O*E*V-----*****","DESCRIPTION":"Robbery","MAPPING1U":"9025","MAPPING1F":"9025","MAPPING1N":"9025","MAPPING1H":"9025"},{"SYMBOLID":"O*E*X-----*****","DESCRIPTION":"Shooting (Non Deadly)","MAPPING1U":"9027","MAPPING1F":"9027","MAPPING1N":"9027","MAPPING1H":"9027"},{"SYMBOLID":"O*E*W-----*****","DESCRIPTION":"Home Eviction","MAPPING1U":"9026","MAPPING1F":"9026","MAPPING1N":"9026","MAPPING1H":"9026"},{"SYMBOLID":"O*E*Y-----*****","DESCRIPTION":"Raid","MAPPING1U":"9028","MAPPING1F":"9028","MAPPING1N":"9028","MAPPING1H":"9028"},{"SYMBOLID":"O*E*Z-----*****","DESCRIPTION":"Sabotage","MAPPING1U":"9029","MAPPING1F":"9029","MAPPING1N":"9029","MAPPING1H":"9029"},{"SYMBOLID":"O*E*AA----*****","DESCRIPTION":"Warrant Served","MAPPING1U":"9030","MAPPING1F":"9030","MAPPING1N":"9030","MAPPING1H":"9030"},{"SYMBOLID":"O*E*AB----*****","DESCRIPTION":"Rape","MAPPING1U":"9031","MAPPING1F":"9031","MAPPING1N":"9031","MAPPING1H":"9031"},{"SYMBOLID":"O*E*AC----*****","DESCRIPTION":"Attempted Rape","MAPPING1U":"9032","MAPPING1F":"9032","MAPPING1N":"9032","MAPPING1H":"9032"},{"SYMBOLID":"O*E*AD----*****","DESCRIPTION":"Attack(Events)"},{"SYMBOLID":"O*E*ADA---*****","DESCRIPTION":"Attack on NGO","MAPPING1U":"9033","MAPPING1F":"9033","MAPPING1N":"9033","MAPPING1H":"9033"},{"SYMBOLID":"O*E*ADB---*****","DESCRIPTION":"Terrorist Attack","MAPPING1U":"9034","MAPPING1F":"9034","MAPPING1N":"9034","MAPPING1H":"9034"},{"SYMBOLID":"O*E*ADC---*****","DESCRIPTION":"Grenade Attack","MAPPING1U":"9035","MAPPING1F":"9035","MAPPING1N":"9035","MAPPING1H":"9035"},{"SYMBOLID":"O*E*ADD---*****","DESCRIPTION":"Rocket Attack","MAPPING1U":"9036","MAPPING1F":"9036","MAPPING1N":"9036","MAPPING1H":"9036"},{"SYMBOLID":"O*E*AE----*****","DESCRIPTION":"Explosions"},{"SYMBOLID":"O*E*AEA---*****","DESCRIPTION":"Explosion (general)","MAPPING1U":"9037","MAPPING1F":"9037","MAPPING1N":"9037","MAPPING1H":"9037"},{"SYMBOLID":"O*E*AEB---*****","DESCRIPTION":"Explosion, Mine","MAPPING1U":"9038","MAPPING1F":"9038","MAPPING1N":"9038","MAPPING1H":"9038"},{"SYMBOLID":"O*E*AEC---*****","DESCRIPTION":"Explosion, Grenade","MAPPING1U":"9039","MAPPING1F":"9039","MAPPING1N":"9039","MAPPING1H":"9039"},{"SYMBOLID":"O*E*AED---*****","DESCRIPTION":"Explosion, Bomb","MAPPING1U":"9040","MAPPING1F":"9040","MAPPING1N":"9040","MAPPING1H":"9040"},{"SYMBOLID":"O*E*AEE---*****","DESCRIPTION":"Explosion, Mortar Fire","MAPPING1U":"9041","MAPPING1F":"9041","MAPPING1N":"9041","MAPPING1H":"9041"},{"SYMBOLID":"O*E*AEF---*****","DESCRIPTION":"Explosion, Incendiary","MAPPING1U":"9042","MAPPING1F":"9042","MAPPING1N":"9042","MAPPING1H":"9042"},{"SYMBOLID":"O*E*AEG---*****","DESCRIPTION":"Explosion, Rocket","MAPPING1U":"9043","MAPPING1F":"9043","MAPPING1N":"9043","MAPPING1H":"9043"},{"SYMBOLID":"O*E*AEH---*****","DESCRIPTION":"Explosion, Improvised Explosive Device (IED)","MAPPING1U":"9044","MAPPING1F":"9044","MAPPING1N":"9044","MAPPING1H":"9044"},{"SYMBOLID":"O*E*AEI---*****","DESCRIPTION":"Explosion, Car Bomb","MAPPING1U":"9045","MAPPING1F":"9045","MAPPING1N":"9045","MAPPING1H":"9045"},{"SYMBOLID":"O*E*AEJ---*****","DESCRIPTION":"Suicide Bombing","MAPPING1U":"9046","MAPPING1F":"9046","MAPPING1N":"9046","MAPPING1H":"9046"},{"SYMBOLID":"O*E*AF----*****","DESCRIPTION":"Fighting/Contact"},{"SYMBOLID":"O*E*AFA---*****","DESCRIPTION":"Fighting (General)","MAPPING1U":"9047","MAPPING1F":"9047","MAPPING1N":"9047","MAPPING1H":"9047"},{"SYMBOLID":"O*E*AFB---*****","DESCRIPTION":"Coalition vs. Enemy","MAPPING1U":"9048","MAPPING1F":"9048","MAPPING1N":"9048","MAPPING1H":"9048"},{"SYMBOLID":"O*E*AFC---*****","DESCRIPTION":"Coalition vs. Coalition","MAPPING1U":"9049","MAPPING1F":"9049","MAPPING1N":"9049","MAPPING1H":"9049"},{"SYMBOLID":"O*E*AG----*****","DESCRIPTION":"Drug Possession","MAPPING1U":"9050","MAPPING1F":"9050","MAPPING1N":"9050","MAPPING1H":"9050"},{"SYMBOLID":"O*E*AH----*****","DESCRIPTION":"Drug Trafficking","MAPPING1U":"9051","MAPPING1F":"9051","MAPPING1N":"9051","MAPPING1H":"9051"},{"SYMBOLID":"O*E*AI----*****","DESCRIPTION":"Suspicious Activity","MAPPING1U":"9052","MAPPING1F":"9052","MAPPING1N":"9052","MAPPING1H":"9052"},{"SYMBOLID":"O*E*AJ----*****","DESCRIPTION":"Activity","MAPPING1U":"9053","MAPPING1F":"9053","MAPPING1N":"9053","MAPPING1H":"9053"},{"SYMBOLID":"O*E*AK----*****","DESCRIPTION":"Threat","MAPPING1U":"9054","MAPPING1F":"9054","MAPPING1N":"9054","MAPPING1H":"9054"},{"SYMBOLID":"O*E*AL----*****","DESCRIPTION":"Crater","MAPPING1U":"9055","MAPPING1F":"9055","MAPPING1N":"9055","MAPPING1H":"9055"},{"SYMBOLID":"O*E*AM----*****","DESCRIPTION":"Pothole","MAPPING1U":"9056","MAPPING1F":"9057","MAPPING1N":"9058","MAPPING1H":"9059"},{"SYMBOLID":"O*E*AN----*****","DESCRIPTION":"Escalation of Force","MAPPING1U":"9060","MAPPING1F":"9061","MAPPING1N":"9062","MAPPING1H":"9063"},{"SYMBOLID":"O*E*AO----*****","DESCRIPTION":"Submunitions","MAPPING1U":"9064","MAPPING1F":"9064","MAPPING1N":"9064","MAPPING1H":"9064"},{"SYMBOLID":"O*E*AP----*****","DESCRIPTION":"Confiscation","MAPPING1U":"9065","MAPPING1F":"9066","MAPPING1N":"9067","MAPPING1H":"9068"},{"SYMBOLID":"O*E*AQ----*****","DESCRIPTION":"Counter Insurgency","MAPPING1U":"9069","MAPPING1F":"9070","MAPPING1N":"9071","MAPPING1H":"9072"},{"SYMBOLID":"O*E*AR----*****","DESCRIPTION":"Counter Terrorism","MAPPING1U":"9073","MAPPING1F":"9074","MAPPING1N":"9075","MAPPING1H":"9076"},{"SYMBOLID":"O*E*AS----*****","DESCRIPTION":"Humanitarian Assistance","MAPPING1U":"9077","MAPPING1F":"9078","MAPPING1N":"9079","MAPPING1H":"9080"},{"SYMBOLID":"O*E*AT----*****","DESCRIPTION":"Tests of Security","MAPPING1U":"9081","MAPPING1F":"9082","MAPPING1N":"9083","MAPPING1H":"9084"},{"SYMBOLID":"O*E*AU----*****","DESCRIPTION":"AWOL","MAPPING1U":"9085","MAPPING1F":"9085","MAPPING1N":"9085","MAPPING1H":"9085"},{"SYMBOLID":"O*E*AV----*****","DESCRIPTION":"Curfew","MAPPING1U":"9086","MAPPING1F":"9086","MAPPING1N":"9086","MAPPING1H":"9086"},{"SYMBOLID":"O*E*AW----*****","DESCRIPTION":"DUI","MAPPING1U":"9087","MAPPING1F":"9087","MAPPING1N":"9087","MAPPING1H":"9087"},{"SYMBOLID":"O*E*AX----*****","DESCRIPTION":"Prostitution","MAPPING1U":"9088","MAPPING1F":"9088","MAPPING1N":"9088","MAPPING1H":"9088"},{"SYMBOLID":"O*Y*------*****","DESCRIPTION":"Organization/Groups"},{"SYMBOLID":"O*Y*A-----*****","DESCRIPTION":"Organization (General)","MAPPING1U":"9089","MAPPING1F":"9089","MAPPING1N":"9089","MAPPING1H":"9089"},{"SYMBOLID":"O*Y*B-----*****","DESCRIPTION":"NGO Organization","MAPPING1U":"9090","MAPPING1F":"9090","MAPPING1N":"9090","MAPPING1H":"9090"},{"SYMBOLID":"O*Y*C-----*****","DESCRIPTION":"Displaced Persons, Refugees","MAPPING1U":"9091","MAPPING1F":"9091","MAPPING1N":"9091","MAPPING1H":"9091"},{"SYMBOLID":"O*Y*D-----*****","DESCRIPTION":"Terrorist Organization","MAPPING1U":"9092","MAPPING1F":"9092","MAPPING1N":"9092","MAPPING1H":"9092"},{"SYMBOLID":"O*Y*E-----*****","DESCRIPTION":"Religious Organization","MAPPING1U":"9093","MAPPING1F":"9093","MAPPING1N":"9093","MAPPING1H":"9093"},{"SYMBOLID":"O*Y*F-----*****","DESCRIPTION":"Group Tribe Cell","MAPPING1U":"9094","MAPPING1F":"9094","MAPPING1N":"9094","MAPPING1H":"9094"},{"SYMBOLID":"O*Y*G-----*****","DESCRIPTION":"Foreign Fighters","MAPPING1U":"9095","MAPPING1F":"9095","MAPPING1N":"9095","MAPPING1H":"9095"},{"SYMBOLID":"O*Y*R-----*****","DESCRIPTION":"Red Cross"},{"SYMBOLID":"O*Y*SP----*****","DESCRIPTION":"State Police"},{"SYMBOLID":"O*Y*LP----*****","DESCRIPTION":"Local Police"},{"SYMBOLID":"O*Y*SH----*****","DESCRIPTION":"Shelter"},{"SYMBOLID":"O*Y*FM----*****","DESCRIPTION":"FEMA"},{"SYMBOLID":"O*Y*SA----*****","DESCRIPTION":"Staging Area"},{"SYMBOLID":"O*Y*EP----*****","DESCRIPTION":"Evacuation Point"},{"SYMBOLID":"O*Y*PD----*****","DESCRIPTION":"Person in Distress"},{"SYMBOLID":"O*S*------*****","DESCRIPTION":"Structures"},{"SYMBOLID":"O*S*A-----*****","DESCRIPTION":"Compound/Post/Fort","MAPPING1U":"9103","MAPPING1F":"9103","MAPPING1N":"9103","MAPPING1H":"9103"},{"SYMBOLID":"O*S*B-----*****","DESCRIPTION":"House/Residence","MAPPING1U":"9104","MAPPING1F":"9104","MAPPING1N":"9104","MAPPING1H":"9104"},{"SYMBOLID":"O*S*C-----*****","DESCRIPTION":"Safe House(Structures)","MAPPING1U":"9105","MAPPING1F":"9105","MAPPING1N":"9105","MAPPING1H":"9105"},{"SYMBOLID":"O*S*D-----*****","DESCRIPTION":"Church","MAPPING1U":"9106","MAPPING1F":"9106","MAPPING1N":"9106","MAPPING1H":"9106"},{"SYMBOLID":"O*S*E-----*****","DESCRIPTION":"Mosque","MAPPING1U":"9107","MAPPING1F":"9107","MAPPING1N":"9107","MAPPING1H":"9107"},{"SYMBOLID":"O*S*F-----*****","DESCRIPTION":"Synagogue","MAPPING1U":"9108","MAPPING1F":"9108","MAPPING1N":"9108","MAPPING1H":"9108"},{"SYMBOLID":"O*S*G-----*****","DESCRIPTION":"Warehouse/Storage Facility","MAPPING1U":"9109","MAPPING1F":"9109","MAPPING1N":"9109","MAPPING1H":"9109"},{"SYMBOLID":"O*S*H-----*****","DESCRIPTION":"Bunker/Underground Facility","MAPPING1U":"9110","MAPPING1F":"9110","MAPPING1N":"9110","MAPPING1H":"9110"},{"SYMBOLID":"O*S*I-----*****","DESCRIPTION":"Tents","MAPPING1U":"9111","MAPPING1F":"9111","MAPPING1N":"9111","MAPPING1H":"9111"},{"SYMBOLID":"O*S*J-----*****","DESCRIPTION":"Cave","MAPPING1U":"9112","MAPPING1F":"9112","MAPPING1N":"9112","MAPPING1H":"9112"},{"SYMBOLID":"O*S*K-----*****","DESCRIPTION":"Camps"},{"SYMBOLID":"O*S*KA----*****","DESCRIPTION":"Camp (General)","MAPPING1U":"9114","MAPPING1F":"9114","MAPPING1N":"9114","MAPPING1H":"9114"},{"SYMBOLID":"O*S*KB----*****","DESCRIPTION":"Displaced Persons/Refugees Camp","MAPPING1U":"9115","MAPPING1F":"9115","MAPPING1N":"9115","MAPPING1H":"9115"},{"SYMBOLID":"O*S*KC----*****","DESCRIPTION":"Training Camp","MAPPING1U":"9116","MAPPING1F":"9116","MAPPING1N":"9116","MAPPING1H":"9116"},{"SYMBOLID":"O*S*L-----*****","DESCRIPTION":"Prison/Detention Facility","MAPPING1U":"9117","MAPPING1F":"9117","MAPPING1N":"9117","MAPPING1H":"9117"},{"SYMBOLID":"O*S*M-----*****","DESCRIPTION":"Police Station","MAPPING1U":"9118","MAPPING1F":"9118","MAPPING1N":"9118","MAPPING1H":"9118"},{"SYMBOLID":"O*S*N-----*****","DESCRIPTION":"Palace/Presidential Residence","MAPPING1U":"9119","MAPPING1F":"9119","MAPPING1N":"9119","MAPPING1H":"9119"},{"SYMBOLID":"O*Q*------*****","DESCRIPTION":"Equipment/Weapons"},{"SYMBOLID":"O*Q*A-----*****","DESCRIPTION":"Weapons Found","MAPPING1U":"9121","MAPPING1F":"9121","MAPPING1N":"9121","MAPPING1H":"9121"},{"SYMBOLID":"O*Q*B-----*****","DESCRIPTION":"Weapons Cache","MAPPING1U":"9122","MAPPING1F":"9122","MAPPING1N":"9122","MAPPING1H":"9122"},{"SYMBOLID":"O*Q*C-----*****","DESCRIPTION":"Weapons Confiscated","MAPPING1U":"9123","MAPPING1F":"9123","MAPPING1N":"9123","MAPPING1H":"9123"},{"SYMBOLID":"O*Q*D-----*****","DESCRIPTION":"Weapons Sale","MAPPING1U":"9124","MAPPING1F":"9124","MAPPING1N":"9124","MAPPING1H":"9124"},{"SYMBOLID":"O*Q*E-----*****","DESCRIPTION":"Weapons Market","MAPPING1U":"9125","MAPPING1F":"9125","MAPPING1N":"9125","MAPPING1H":"9125"},{"SYMBOLID":"O*Q*F-----*****","DESCRIPTION":"Chem/Bio Weapons Cache","MAPPING1U":"9126","MAPPING1F":"9126","MAPPING1N":"9126","MAPPING1H":"9126"},{"SYMBOLID":"O*Q*G-----*****","DESCRIPTION":"Improvised Explosive Device (IED)","MAPPING1U":"9127","MAPPING1F":"9127","MAPPING1N":"9127","MAPPING1H":"9127"},{"SYMBOLID":"O*Q*H-----*****","DESCRIPTION":"Unexploded Ordnance (UXO)","MAPPING1U":"9128","MAPPING1F":"9128","MAPPING1N":"9128","MAPPING1H":"9128"},{"SYMBOLID":"O*Q*I-----*****","DESCRIPTION":"Horses","MAPPING1U":"9129","MAPPING1F":"9129","MAPPING1N":"9129","MAPPING1H":"9129"},{"SYMBOLID":"O*Q*J-----*****","DESCRIPTION":"Camels","MAPPING1U":"9130","MAPPING1F":"9130","MAPPING1N":"9130","MAPPING1H":"9130"},{"SYMBOLID":"O*Q*K-----*****","DESCRIPTION":"Donkeys","MAPPING1U":"9131","MAPPING1F":"9131","MAPPING1N":"9131","MAPPING1H":"9131"},{"SYMBOLID":"E*-*------*****","DESCRIPTION":"Emergency Management Symbols"},{"SYMBOLID":"E*I*------*****","DESCRIPTION":"Incident"},{"SYMBOLID":"E*I*A-----*****","DESCRIPTION":"Civil Disturbance Incident","MAPPING1U":"5000","MAPPING1F":"5000","MAPPING1N":"5000","MAPPING1H":"5000"},{"SYMBOLID":"E*I*AC----*****","DESCRIPTION":"Civil Rioting","MAPPING1U":"5001","MAPPING1F":"5001","MAPPING1N":"5001","MAPPING1H":"5001"},{"SYMBOLID":"E*I*B-----*****","DESCRIPTION":"Criminal Activity Incident","MAPPING1U":"5002","MAPPING1F":"5002","MAPPING1N":"5002","MAPPING1H":"5002"},{"SYMBOLID":"E*I*BC----*****","DESCRIPTION":"Explosion (Bomb)","MAPPING1U":"5004","MAPPING1F":"5004","MAPPING1N":"5004","MAPPING1H":"5004"},{"SYMBOLID":"E*I*BD----*****","DESCRIPTION":"Looting","MAPPING1U":"5005","MAPPING1F":"5005","MAPPING1N":"5005","MAPPING1H":"5005"},{"SYMBOLID":"E*I*C-----*****","DESCRIPTION":"Fire Incident"},{"SYMBOLID":"E*I*D-----*****","DESCRIPTION":"Hazardous Materiel Incident"},{"SYMBOLID":"E*I*E-----*****","DESCRIPTION":"Air Incident"},{"SYMBOLID":"E*I*F-----*****","DESCRIPTION":"Marine Incident"},{"SYMBOLID":"E*I*G-----*****","DESCRIPTION":"Rail Incident"},{"SYMBOLID":"E*I*H-----*****","DESCRIPTION":"Vehicle Incident"},{"SYMBOLID":"E*I*HA----*****","DESCRIPTION":"Vehicle Accident","MAPPING1U":"5061","MAPPING1F":"5061","MAPPING1N":"5061","MAPPING1H":"5061"},{"SYMBOLID":"E*N*------*****","DESCRIPTION":"Natural Events"},{"SYMBOLID":"E*O*------*****","DESCRIPTION":"Operations"},{"SYMBOLID":"E*O*D-----*****","DESCRIPTION":"Law Enforcement Operation"},{"SYMBOLID":"E*O*DJ----*****","DESCRIPTION":"Police"},{"SYMBOLID":"E*O*DJC---*****","DESCRIPTION":"Police Installation","MAPPING1U":"5251","MAPPING1F":"5251","MAPPING1N":"5251","MAPPING1H":"5251"},{"SYMBOLID":"E*O*DK----*****","DESCRIPTION":"Prison","MAPPING1U":"5252","MAPPING1F":"5252","MAPPING1N":"5252","MAPPING1H":"5252","MAPPING2":"5253","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"E*F*------*****","DESCRIPTION":"Infrastructure"},{"SYMBOLID":"E*F*I-----*****","DESCRIPTION":"Public Venues Infrastructure"},{"SYMBOLID":"E*F*ID----*****","DESCRIPTION":"Religious Institution","MAPPING1U":"5349","MAPPING1F":"5349","MAPPING1N":"5349","MAPPING1H":"5349","MAPPING2":"5350","MAPPING2COLOR":"#FFFFFF"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitConstantsB={"UNITCONSTANTS":{"SYMBOL":[{"SYMBOLID":"S***------*****","DESCRIPTION":"Warfighting Symbology","DRAWCATEGORY":"0","HIERARCHY":"1.X","ALPHAHIERARCHY":"WAR"},{"SYMBOLID":"S*P*------*****","DESCRIPTION":"Space Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.1","ALPHAHIERARCHY":"WAR.SPC","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*P*S-----*****","DESCRIPTION":"Satellite","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.1","ALPHAHIERARCHY":"WAR.SPC.SAT","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*V-----*****","DESCRIPTION":"Crewed Space Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.2","ALPHAHIERARCHY":"WAR.SPC.CSV","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*T-----*****","DESCRIPTION":"Space Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.3","ALPHAHIERARCHY":"WAR.SPC.SST","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*L-----*****","DESCRIPTION":"Space Launch Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.4","ALPHAHIERARCHY":"WAR.SPC.SLV","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*A*------*****","DESCRIPTION":"Air Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.2","ALPHAHIERARCHY":"WAR.AIRTRK","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*A*M-----*****","DESCRIPTION":"Military","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*MF----*****","DESCRIPTION":"Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*MFB---*****","DESCRIPTION":"Fixed Wing Bomber","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.BMB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFF---*****","DESCRIPTION":"Fixed Wing Fighter","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.FTR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFFI--*****","DESCRIPTION":"Fixed Wing Interceptor","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.FTR.INCR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Fighter"},{"SYMBOLID":"S*A*MFT---*****","DESCRIPTION":"Fixed Wing Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNE","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFA---*****","DESCRIPTION":"Attack/Strike","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ATK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFL---*****","DESCRIPTION":"Fixed Wing VSTOL","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.VSTOL","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFK---*****","DESCRIPTION":"Fixed Wing Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFKB--*****","DESCRIPTION":"Fixed Wing Tanker Boom-Only","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK.BOOM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Tanker"},{"SYMBOLID":"S*A*MFKD--*****","DESCRIPTION":"Fixed Wing Tanker Drouge-Only","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK.DROG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Tanker"},{"SYMBOLID":"S*A*MFC---*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Transport)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFCL--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.LIT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFCM--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.MDM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFCH--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.HVY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFJ---*****","DESCRIPTION":"Fixed Wing ECM/Jammer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFO---*****","DESCRIPTION":"Fixed Wing MEDEVAC","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFR---*****","DESCRIPTION":"Fixed Wing Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFRW--*****","DESCRIPTION":"Fixed Wing Airborne Early Warning (AEW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.ABNEW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFRZ--*****","DESCRIPTION":"Fixed Wing Electronic Surveillance Measures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.ESM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFRX--*****","DESCRIPTION":"Fixed Wing Photographic","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.PHG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFP---*****","DESCRIPTION":"Fixed Wing Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFPN--*****","DESCRIPTION":"Patrol Antisurface Warfare (ASUW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT.ASUW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Patrol"},{"SYMBOLID":"S*A*MFPM--*****","DESCRIPTION":"Fixed Wing Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Patrol"},{"SYMBOLID":"S*A*MFU---*****","DESCRIPTION":"Fixed Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFUL--*****","DESCRIPTION":"Fixed Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.LIT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFUM--*****","DESCRIPTION":"Fixed Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.MDM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFUH--*****","DESCRIPTION":"Fixed Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.HVY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFY---*****","DESCRIPTION":"Fixed Wing Communications (C3I)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.COMM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFH---*****","DESCRIPTION":"Fixed Wing Combat Search and Rescue (CSAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFD---*****","DESCRIPTION":"Fixed Wing Airborne Command Post (C2)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.15","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFQ---*****","DESCRIPTION":"Drone (RPV/UAV) Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFQA--*****","DESCRIPTION":"Drone Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ATK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQB--*****","DESCRIPTION":"Drone Bomber","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.BMB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQC--*****","DESCRIPTION":"Drone Cargo","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.CGO","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQD--*****","DESCRIPTION":"Drone (RPV/UAV) Airborne Command Post","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQF--*****","DESCRIPTION":"Drone Fighter","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.FTR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQH--*****","DESCRIPTION":"Search & Rescue (CSAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQJ--*****","DESCRIPTION":"Drone Electronic Countermeasures (Jammer)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQK--*****","DESCRIPTION":"Drone Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.TNK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQL--*****","DESCRIPTION":"Drone Vstol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.VSTOL","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQM--*****","DESCRIPTION":"Drone Special Operations Forces (SOF)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.SOF","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQI--*****","DESCRIPTION":"Drone Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQN--*****","DESCRIPTION":"Drone Anti-Surface Warfare (ASUW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ASUW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQP--*****","DESCRIPTION":"Drone Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.PAT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQR--*****","DESCRIPTION":"Drone Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQRW-*****","DESCRIPTION":"Drone Airborne Early Warning (AEW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.ABNEW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQRZ-*****","DESCRIPTION":"Drone Electronic Surveillance Measures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.ESM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQRX-*****","DESCRIPTION":"Drone Photographic","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.PHG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQS--*****","DESCRIPTION":"Drone Anti-Submarine Warfare (ASW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.15","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ASBW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQT--*****","DESCRIPTION":"Drone Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.16","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.TNE","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQU--*****","DESCRIPTION":"Drone Utility Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.17","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.UTY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQY--*****","DESCRIPTION":"Drone Communications (C3I)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.18","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.COMM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQO--*****","DESCRIPTION":"Drone Medevac","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.19","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFS---*****","DESCRIPTION":"Antisubmarine Warfare (ASW) Carrier Based","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.17","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ASBWCB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFM---*****","DESCRIPTION":"Fixed Wing Special Operations Forces (SOF)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.18","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.SOF","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MH----*****","DESCRIPTION":"Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*MHA---*****","DESCRIPTION":"Rotary Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ATK","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHS---*****","DESCRIPTION":"Antisubmarine Warfare/MPA ROTARY WING","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ASBW","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHU---*****","DESCRIPTION":"Rotary Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHUL--*****","DESCRIPTION":"Rotary Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.LIT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHUM--*****","DESCRIPTION":"Rotary Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.MDM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHUH--*****","DESCRIPTION":"Rotary Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.HVY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHI---*****","DESCRIPTION":"Rotary Wing Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHH---*****","DESCRIPTION":"Rotary Wing Combat Search and Rescue(Military)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHR---*****","DESCRIPTION":"Rotary Wing Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.RECON","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHQ---*****","DESCRIPTION":"Drone (RPV/UAV) Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.DRN","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHC---*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Transport)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHCL--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.LIT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHCM--*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.MDM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHCH--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.HVY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHT---*****","DESCRIPTION":"Rotary Wing Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.TNE","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHO---*****","DESCRIPTION":"Rotary Wing MEDEVAC","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHM---*****","DESCRIPTION":"Rotary Wing Special Operations Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.SOF","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHD---*****","DESCRIPTION":"Rotary Wing Airborne Command Post","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHK---*****","DESCRIPTION":"Rotary Wing Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.TNK","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHJ---*****","DESCRIPTION":"Rotary Wing ECM/Jammer(TANKER)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ECM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*ML----*****","DESCRIPTION":"Military Aircraft Lighter Than Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.LTA","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*W-----*****","DESCRIPTION":"Air Track Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*WM----*****","DESCRIPTION":"Missile In Flight","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF","PATH":"Warfighting Symbology/Air Track/Air Track Weapon"},{"SYMBOLID":"S*A*WMS---*****","DESCRIPTION":"Surface Launched Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMSS--*****","DESCRIPTION":"Surface to Surface Missile (SSM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SSM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSA--*****","DESCRIPTION":"Surface To Air Missile (SAM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SAM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSU--*****","DESCRIPTION":"Surface to Subsurface Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SSUM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSB--*****","DESCRIPTION":"Anti-Ballistic Missile (ABM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.ABM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMA---*****","DESCRIPTION":"Air Launched Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMAS--*****","DESCRIPTION":"Air To Surface Missile (ASM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.ASM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMAA--*****","DESCRIPTION":"Air To Air Missile (AAM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.AAM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMAP--*****","DESCRIPTION":"Air to Space Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.ASPC","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMU---*****","DESCRIPTION":"Subsurface To Surface Missile (S/SSM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SBSM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMCM--*****","DESCRIPTION":"Cruise Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.CM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMB---*****","DESCRIPTION":"Ballistic Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.5","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.BLST","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WD----*****","DESCRIPTION":"Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.DCY","PATH":"Warfighting Symbology/Air Track/Weapon"},{"SYMBOLID":"S*A*WB----*****","DESCRIPTION":"Bomb","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.BM","PATH":"Warfighting Symbology/Air Track/Weapon"},{"SYMBOLID":"S*A*C-----*****","DESCRIPTION":"Civil Aircraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.CVL","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*CF----*****","DESCRIPTION":"Civil Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.1","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.FIXD","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*A*CH----*****","DESCRIPTION":"Civil Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.2","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.ROT","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*A*CL----*****","DESCRIPTION":"Civil Aircraft Lighter Than Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.3","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.LTA","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*G*------*****","DESCRIPTION":"Ground Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.3","ALPHAHIERARCHY":"WAR.GRDTRK","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*G*U-----*****","DESCRIPTION":"Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*UC----*****","DESCRIPTION":"Combat","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*UCD---*****","DESCRIPTION":"Air Defense","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCDS--*****","DESCRIPTION":"Short Range","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDSC-*****","DESCRIPTION":"Chaparral","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.CPL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDSS-*****","DESCRIPTION":"Stinger","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.STG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDSV-*****","DESCRIPTION":"Vulcan","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.VUL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDM--*****","DESCRIPTION":"Air Defense Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDML-*****","DESCRIPTION":"Air Defense Missile Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDMLA*****","DESCRIPTION":"Air Defense Missile Motorized (Avenger)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/Air Defense Missile Light"},{"SYMBOLID":"S*G*UCDMM-*****","DESCRIPTION":"Air Defense Missile Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDMH-*****","DESCRIPTION":"Air Defense Missile Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDH--*****","DESCRIPTION":"H/MAD","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDHH-*****","DESCRIPTION":"Hawk","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.HWK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/H and MAD"},{"SYMBOLID":"S*G*UCDHP-*****","DESCRIPTION":"Patriot","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.PATT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/H and MAD"},{"SYMBOLID":"S*G*UCDG--*****","DESCRIPTION":"Gun Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.GUNUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDC--*****","DESCRIPTION":"Air Defense Composite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.CMPS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDT--*****","DESCRIPTION":"Targeting Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.TGTGUT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDO--*****","DESCRIPTION":"Theater Missile Defense Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.TMDU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCA---*****","DESCRIPTION":"Armor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCAT--*****","DESCRIPTION":"Armor Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor"},{"SYMBOLID":"S*G*UCATA-*****","DESCRIPTION":"Armor Track Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATW-*****","DESCRIPTION":"Armor Track Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATWR*****","DESCRIPTION":"Armor Track Amphibious Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track/Armor Track Amphibious"},{"SYMBOLID":"S*G*UCATL-*****","DESCRIPTION":"Armor Track, Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATM-*****","DESCRIPTION":"Armor Track, Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATH-*****","DESCRIPTION":"Armor Track, Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATR-*****","DESCRIPTION":"Armor Track, Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCAW--*****","DESCRIPTION":"Armor, Wheeled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor"},{"SYMBOLID":"S*G*UCAWS-*****","DESCRIPTION":"Armor, Wheeled Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWA-*****","DESCRIPTION":"Armor, Wheeled Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWW-*****","DESCRIPTION":"Armor, Wheeled Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWWR*****","DESCRIPTION":"Armor, Wheeled Amphibious Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled/Armor, Wheeled Amphibious"},{"SYMBOLID":"S*G*UCAWL-*****","DESCRIPTION":"Armor, Wheeled Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWM-*****","DESCRIPTION":"Armor, Wheeled Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWH-*****","DESCRIPTION":"Armor, Wheeled Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWR-*****","DESCRIPTION":"Armor, Wheeled Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAA--*****","DESCRIPTION":"Anti Armor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCAAD-*****","DESCRIPTION":"Anti Armor Dismounted","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAL-*****","DESCRIPTION":"Anti Armor Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAM-*****","DESCRIPTION":"Anti Armor Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAS-*****","DESCRIPTION":"Anti Armor Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAU-*****","DESCRIPTION":"Anti Armor Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAC-*****","DESCRIPTION":"Anti Armor Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAA-*****","DESCRIPTION":"Anti Armor Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAAT*****","DESCRIPTION":"Anti Armor Armored Tracked","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.TKD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAAW*****","DESCRIPTION":"Anti Armor Armored Wheeled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.WHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAAS*****","DESCRIPTION":"Anti Armor Armored Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAO-*****","DESCRIPTION":"Anti Armor Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAOS*****","DESCRIPTION":"Anti Armor Motorized Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MOT.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Motorized"},{"SYMBOLID":"S*G*UCV---*****","DESCRIPTION":"Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCVF--*****","DESCRIPTION":"Aviation Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVFU-*****","DESCRIPTION":"Utility Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.UTY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVFA-*****","DESCRIPTION":"Fixed Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.ATK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVFR-*****","DESCRIPTION":"Recon Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVR--*****","DESCRIPTION":"Aviation Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVRA-*****","DESCRIPTION":"Attack Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.ATK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRS-*****","DESCRIPTION":"Scout Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.SCUT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRW-*****","DESCRIPTION":"Antisubmarine Warfare Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.ASBW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRU-*****","DESCRIPTION":"Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRUL*****","DESCRIPTION":"Light Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUM*****","DESCRIPTION":"Medium Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUH*****","DESCRIPTION":"Heavy Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUC*****","DESCRIPTION":"C2 Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.C2","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRUE*****","DESCRIPTION":"Medevac Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.MEDV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRM-*****","DESCRIPTION":"Mine Countermeasure Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.MNECM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVS--*****","DESCRIPTION":"Search and Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.SAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVC--*****","DESCRIPTION":"Aviation Composite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.CMPS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVV--*****","DESCRIPTION":"Vertical/Short Takeoff And Landing (V/Stol)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.VSTOL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVU--*****","DESCRIPTION":"Unmanned Aerial Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVUF-*****","DESCRIPTION":"Unmanned Aerial Vehicle Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV.FIXD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Unmanned Aerial Vehicle"},{"SYMBOLID":"S*G*UCVUR-*****","DESCRIPTION":"Unmanned Aerial Vehicle Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV.ROT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Unmanned Aerial Vehicle"},{"SYMBOLID":"S*G*UCI---*****","DESCRIPTION":"Infantry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCIL--*****","DESCRIPTION":"Infantry Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIM--*****","DESCRIPTION":"Infantry Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIO--*****","DESCRIPTION":"Infantry Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIA--*****","DESCRIPTION":"Infantry Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIS--*****","DESCRIPTION":"Infantry Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIZ--*****","DESCRIPTION":"Infantry Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIN--*****","DESCRIPTION":"Infantry Naval","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.NAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCII--*****","DESCRIPTION":"Infantry Fighting Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.INFFV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIC--*****","DESCRIPTION":"Infantry Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCE---*****","DESCRIPTION":"Engineer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCEC--*****","DESCRIPTION":"Engineer Combat","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer"},{"SYMBOLID":"S*G*UCECS-*****","DESCRIPTION":"Engineer Combat Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECA-*****","DESCRIPTION":"Engineer Combat Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECC-*****","DESCRIPTION":"Engineer Combat Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECL-*****","DESCRIPTION":"Engineer Combat Light (Sapper)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECM-*****","DESCRIPTION":"Engineer Combat Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECH-*****","DESCRIPTION":"Engineer Combat Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECT-*****","DESCRIPTION":"Engineer Combat Mechanized (Track)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECW-*****","DESCRIPTION":"Engineer Combat Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECO-*****","DESCRIPTION":"Engineer Combat Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECR-*****","DESCRIPTION":"Engineer Combat Recon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCEN--*****","DESCRIPTION":"Engineer Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CSN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer"},{"SYMBOLID":"S*G*UCENN-*****","DESCRIPTION":"Engineer Naval Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CSN.NAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Construction"},{"SYMBOLID":"S*G*UCF---*****","DESCRIPTION":"Field Artillery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCFH--*****","DESCRIPTION":"Howitzer/Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFHE-*****","DESCRIPTION":"Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.SPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHS-*****","DESCRIPTION":"Howitzer/Gun Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHA-*****","DESCRIPTION":"Howitzer/Gun Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHC-*****","DESCRIPTION":"Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHO-*****","DESCRIPTION":"Howitzer/Gun Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHL-*****","DESCRIPTION":"Howitzer/Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHM-*****","DESCRIPTION":"Howitzer/Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHH-*****","DESCRIPTION":"Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHX-*****","DESCRIPTION":"Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFR--*****","DESCRIPTION":"Rocket","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFRS-*****","DESCRIPTION":"Rocket Single Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket"},{"SYMBOLID":"S*G*UCFRSS*****","DESCRIPTION":"Single Rocket Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRSPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRSR*****","DESCRIPTION":"Single Rocket Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRST*****","DESCRIPTION":"Single Rocket Towed","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRM-*****","DESCRIPTION":"Multi Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket"},{"SYMBOLID":"S*G*UCFRMS*****","DESCRIPTION":"Multi Rocket Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRSPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFRMR*****","DESCRIPTION":"Multi Rocket Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFRMT*****","DESCRIPTION":"Multi Rocket Towed","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFT--*****","DESCRIPTION":"Target Acquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFTR-*****","DESCRIPTION":"Target Acquisition Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.RAD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTS-*****","DESCRIPTION":"Sound","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.SND","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTF-*****","DESCRIPTION":"Flash (Optical)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.FLH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTC-*****","DESCRIPTION":"Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTCD*****","DESCRIPTION":"Dismounted Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition/Colt and Fist"},{"SYMBOLID":"S*G*UCFTCM*****","DESCRIPTION":"Tracked Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.TKD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition/Colt and Fist"},{"SYMBOLID":"S*G*UCFTA-*****","DESCRIPTION":"Anglico","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.ANG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFM--*****","DESCRIPTION":"Field Artillery Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFMS-*****","DESCRIPTION":"Self-Propelled (SP) Tracked Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMW-*****","DESCRIPTION":"SP Wheeled Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDWHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMT-*****","DESCRIPTION":"Towed Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMTA*****","DESCRIPTION":"Towed Airborne Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTS*****","DESCRIPTION":"Towed Air Assault Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTC*****","DESCRIPTION":"Towed Arctic Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTO*****","DESCRIPTION":"Towed Mountain Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFML-*****","DESCRIPTION":"Amphibious Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFS--*****","DESCRIPTION":"Artillery Survey","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFSS-*****","DESCRIPTION":"Artillery Survey Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSA-*****","DESCRIPTION":"Artillery Survey Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSL-*****","DESCRIPTION":"Artillery Survey Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSO-*****","DESCRIPTION":"Artillery Survey Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFO--*****","DESCRIPTION":"Field Artillery Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFOS-*****","DESCRIPTION":"Air Assault Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorologicall"},{"SYMBOLID":"S*G*UCFOA-*****","DESCRIPTION":"Airborne Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCFOL-*****","DESCRIPTION":"Light Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCFOO-*****","DESCRIPTION":"Mountain Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCR---*****","DESCRIPTION":"Combat Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCRH--*****","DESCRIPTION":"Reconnaissance Horse","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.HRE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRV--*****","DESCRIPTION":"Reconnaissance Cavalry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRVA-*****","DESCRIPTION":"Reconnaissance Cavalry Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.ARMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVM-*****","DESCRIPTION":"Reconnaissance Cavalry Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVG-*****","DESCRIPTION":"Reconnaissance Cavalry Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.GRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVO-*****","DESCRIPTION":"Reconnaissance Cavalry Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.AIR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRC--*****","DESCRIPTION":"Reconnaissance Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRS--*****","DESCRIPTION":"Reconnaissance Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRA--*****","DESCRIPTION":"Reconnaissance Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRO--*****","DESCRIPTION":"Reconnaissance Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRL--*****","DESCRIPTION":"Reconnaissance Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRR--*****","DESCRIPTION":"Reconnaissance Marine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRRD-*****","DESCRIPTION":"Reconnaissance Marine Division","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.DIV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRRF-*****","DESCRIPTION":"Reconnaissance Marine Force","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.FOR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRRL-*****","DESCRIPTION":"Reconnaissance Marine Light Armored (LAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.LAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRX--*****","DESCRIPTION":"Reconnaissance Long Range Surveillance (LRS)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.LRS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCM---*****","DESCRIPTION":"Missile (Surf-Surf)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCMT--*****","DESCRIPTION":"Missile (Surf-Surf) Tactical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL.TAC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Missile (Surf-Surf)"},{"SYMBOLID":"S*G*UCMS--*****","DESCRIPTION":"Missile (Surf-Surf) Strategic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL.STGC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Missile (Surf-Surf)"},{"SYMBOLID":"S*G*UCS---*****","DESCRIPTION":"Internal Security Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCSW--*****","DESCRIPTION":"Internal Security Forces Riverine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.RIV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSG--*****","DESCRIPTION":"Internal Security Forces Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSGD-*****","DESCRIPTION":"Internal Security Forces Dismounted","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSGM-*****","DESCRIPTION":"Internal Security Forces Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSGA-*****","DESCRIPTION":"Internal Security Forces Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSM--*****","DESCRIPTION":"Internal Security Forces Wheeled Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.WHMECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSR--*****","DESCRIPTION":"Internal Security Forces Railroad","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.RALRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSA--*****","DESCRIPTION":"Internal Security Forces Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCL---*****","DESCRIPTION":"Surveillance Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.SVL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UU----*****","DESCRIPTION":"Combat Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*UUA---*****","DESCRIPTION":"Combat Support NBC","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUAC--*****","DESCRIPTION":"Combat Support Chemical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUACC-*****","DESCRIPTION":"Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACCK*****","DESCRIPTION":"Mechanized Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke and Decon"},{"SYMBOLID":"S*G*UUACCM*****","DESCRIPTION":"Motorized Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke and Decon"},{"SYMBOLID":"S*G*UUACS-*****","DESCRIPTION":"Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACSM*****","DESCRIPTION":"Motorized Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke"},{"SYMBOLID":"S*G*UUACSA*****","DESCRIPTION":"Armor Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK.ARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke"},{"SYMBOLID":"S*G*UUACR-*****","DESCRIPTION":"Chemical Recon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACRW*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WARMVH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Chemical Recon"},{"SYMBOLID":"S*G*UUACRS*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle Reconnaissance Surveillance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WAVS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Chemical Recon"},{"SYMBOLID":"S*G*UUAN--*****","DESCRIPTION":"Combat Support NBC Nuclear","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.NUC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUAB--*****","DESCRIPTION":"Combat Support NBC Biological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.BIO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUABR-*****","DESCRIPTION":"Recon Equipped","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.BIO.RECEQP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support NBC Biological"},{"SYMBOLID":"S*G*UUAD--*****","DESCRIPTION":"NBC Decontamination","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.DECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUM---*****","DESCRIPTION":"Military Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUMA--*****","DESCRIPTION":"Aerial Exploitation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.AEREXP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMS--*****","DESCRIPTION":"Signal Intelligence (SIGINT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMSE-*****","DESCRIPTION":"Electronic Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)"},{"SYMBOLID":"S*G*UUMSEA*****","DESCRIPTION":"Armored Wheeled Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.ARMWVH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSED*****","DESCRIPTION":"Direction Finding","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.DFN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEI*****","DESCRIPTION":"Intercept","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.INC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEJ*****","DESCRIPTION":"Jamming","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.JMG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSET*****","DESCRIPTION":"Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEC*****","DESCRIPTION":"Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMC--*****","DESCRIPTION":"Counter Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.CINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMR--*****","DESCRIPTION":"Counter Intelligence Surveillance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMRG-*****","DESCRIPTION":"Ground Surveillance Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMRS-*****","DESCRIPTION":"Surveillance Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMRSS*****","DESCRIPTION":"Sensor SCM","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS.SCM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance/Surveillance Sensor"},{"SYMBOLID":"S*G*UUMRX-*****","DESCRIPTION":"Ground Station Module","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMMO-*****","DESCRIPTION":"Surveillance Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.METO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMO--*****","DESCRIPTION":"Military Intelligence Operations","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.OPN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMT--*****","DESCRIPTION":"Tactical Exploit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.TACEXP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMQ--*****","DESCRIPTION":"Interrogation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.INTGN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMJ--*****","DESCRIPTION":"Joint Intelligence Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.JINTCT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUL---*****","DESCRIPTION":"Law Enforcement Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UULS--*****","DESCRIPTION":"Shore Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.SHRPAT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULM--*****","DESCRIPTION":"Military Police","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.MILP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULC--*****","DESCRIPTION":"Civilian Law Enforcement","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.CLE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULF--*****","DESCRIPTION":"Security Police (Air)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.SECPOL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULD--*****","DESCRIPTION":"Central Intelligence Division (CID)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.CID","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UUS---*****","DESCRIPTION":"Signal Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUSA--*****","DESCRIPTION":"Area","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.ARA","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSC--*****","DESCRIPTION":"Communication Configured Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.COMCP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSCL-*****","DESCRIPTION":"Large Communication Configured Package (LCCP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.COMCP.LCCP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Communication Configured Package"},{"SYMBOLID":"S*G*UUSO--*****","DESCRIPTION":"Command Operations","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.CMDOPN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSF--*****","DESCRIPTION":"Forward Communications","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.FWDCOM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSM--*****","DESCRIPTION":"Multiple Subscriber Element","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSMS-*****","DESCRIPTION":"Small Extension Node","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.SEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSML-*****","DESCRIPTION":"Large Extension Node","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.LEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSMN-*****","DESCRIPTION":"Node Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.NODCTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSR--*****","DESCRIPTION":"Radio Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSRS-*****","DESCRIPTION":"Tactical Satellite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TACSAT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSRT-*****","DESCRIPTION":"Teletype Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TTYCTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSRW-*****","DESCRIPTION":"Relay","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.RLY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSS--*****","DESCRIPTION":"Signal Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.SIGSUP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSW--*****","DESCRIPTION":"Telephone Switch","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.PHOSWT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSX--*****","DESCRIPTION":"Electronic Ranging","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.ECRG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUI---*****","DESCRIPTION":"Information Warfare Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.IWU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUP---*****","DESCRIPTION":"Landing Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LNDSUP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUE---*****","DESCRIPTION":"Explosive Ordnance Disposal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.EOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*US----*****","DESCRIPTION":"Combat Service Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*USA---*****","DESCRIPTION":"Administrative (ADMIN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USAT--*****","DESCRIPTION":"Admin Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAC--*****","DESCRIPTION":"Admin Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAJ--*****","DESCRIPTION":"Judge Advocate General (JAG)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAJT-*****","DESCRIPTION":"JAG Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Judge Advocate General (JAG)"},{"SYMBOLID":"S*G*USAJC-*****","DESCRIPTION":"JAG Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Judge Advocate General (JAG)"},{"SYMBOLID":"S*G*USAO--*****","DESCRIPTION":"Postal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAOT-*****","DESCRIPTION":"Postal Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Postal"},{"SYMBOLID":"S*G*USAOC-*****","DESCRIPTION":"Postal Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Postal"},{"SYMBOLID":"S*G*USAF--*****","DESCRIPTION":"Finance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAFT-*****","DESCRIPTION":"Finance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Finance"},{"SYMBOLID":"S*G*USAFC-*****","DESCRIPTION":"Finance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Finance"},{"SYMBOLID":"S*G*USAS--*****","DESCRIPTION":"Personnel Services","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAST-*****","DESCRIPTION":"Personnel Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Personnel Services"},{"SYMBOLID":"S*G*USASC-*****","DESCRIPTION":"Personnel Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Personnel Services"},{"SYMBOLID":"S*G*USAM--*****","DESCRIPTION":"Mortuary/Graves Registry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAMT-*****","DESCRIPTION":"Mortuary/Graves Registry Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Mortuary and Graves Registry"},{"SYMBOLID":"S*G*USAMC-*****","DESCRIPTION":"Mortuary/Graves Registry Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Mortuary and Graves Registry"},{"SYMBOLID":"S*G*USAR--*****","DESCRIPTION":"Religious/Chaplain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USART-*****","DESCRIPTION":"Religious/Chaplain Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Religious and Chaplain"},{"SYMBOLID":"S*G*USARC-*****","DESCRIPTION":"Religious/Chaplain Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Religious and Chaplain"},{"SYMBOLID":"S*G*USAP--*****","DESCRIPTION":"Public Affairs","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAPT-*****","DESCRIPTION":"Public Affairs Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPC-*****","DESCRIPTION":"Public Affairs Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPB-*****","DESCRIPTION":"Public Affairs Broadcast","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPBT*****","DESCRIPTION":"Public Affairs Broadcast Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Broadcast"},{"SYMBOLID":"S*G*USAPBC*****","DESCRIPTION":"Public Affairs Broadcast Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Broadcast"},{"SYMBOLID":"S*G*USAPM-*****","DESCRIPTION":"Public Affairs Joint Information Bureau (JIB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPMT*****","DESCRIPTION":"Public Affairs JIB Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Joint Information Bureau (JIB)"},{"SYMBOLID":"S*G*USAPMC*****","DESCRIPTION":"Public Affairs JIB Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Joint Information Bureau (JIB)"},{"SYMBOLID":"S*G*USAX--*****","DESCRIPTION":"Replacement Holding Unit (RHU)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAXT-*****","DESCRIPTION":"RHU Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Replacement Holding Unit (RHU)"},{"SYMBOLID":"S*G*USAXC-*****","DESCRIPTION":"RHU Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Replacement Holding Unit (RHU)"},{"SYMBOLID":"S*G*USAL--*****","DESCRIPTION":"Labor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USALT-*****","DESCRIPTION":"Labor Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Labor"},{"SYMBOLID":"S*G*USALC-*****","DESCRIPTION":"Labor Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Labor"},{"SYMBOLID":"S*G*USAW--*****","DESCRIPTION":"Morale, Welfare, Recreation (MWR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAWT-*****","DESCRIPTION":"MWR Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Morale, Welfare, Recreation (MWR)"},{"SYMBOLID":"S*G*USAWC-*****","DESCRIPTION":"MWR Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Morale, Welfare, Recreation (MWR)"},{"SYMBOLID":"S*G*USAQ--*****","DESCRIPTION":"Quartermaster (Supply)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAQT-*****","DESCRIPTION":"Quartermaster (Supply) Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Quartermaster (Supply)"},{"SYMBOLID":"S*G*USAQC-*****","DESCRIPTION":"Quartermaster (Supply) Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Quartermaster (Supply)"},{"SYMBOLID":"S*G*USM---*****","DESCRIPTION":"Medical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USMT--*****","DESCRIPTION":"Medical Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMC--*****","DESCRIPTION":"Medical Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMM--*****","DESCRIPTION":"Medical Treatment Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMMT-*****","DESCRIPTION":"Medical Treatment Facility Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Treatment Facility"},{"SYMBOLID":"S*G*USMMC-*****","DESCRIPTION":"Medical Treatment Facility Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Treatment Facility"},{"SYMBOLID":"S*G*USMV--*****","DESCRIPTION":"Medical Veterinary","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMVT-*****","DESCRIPTION":"Medical Veterinary Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Veterinary"},{"SYMBOLID":"S*G*USMVC-*****","DESCRIPTION":"Medical Veterinary Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Veterinary"},{"SYMBOLID":"S*G*USMD--*****","DESCRIPTION":"Medical Dental","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMDT-*****","DESCRIPTION":"Medical Dental Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Dental"},{"SYMBOLID":"S*G*USMDC-*****","DESCRIPTION":"Medical Dental Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Dental"},{"SYMBOLID":"S*G*USMP--*****","DESCRIPTION":"Medical Psychological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMPT-*****","DESCRIPTION":"Medical Psychological Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Psychological"},{"SYMBOLID":"S*G*USMPC-*****","DESCRIPTION":"Medical Psychological Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Psychological"},{"SYMBOLID":"S*G*USS---*****","DESCRIPTION":"Supply","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USST--*****","DESCRIPTION":"Supply Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSC--*****","DESCRIPTION":"Supply Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS1--*****","DESCRIPTION":"Supply Class I","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS1T-*****","DESCRIPTION":"Supply Class I Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class I"},{"SYMBOLID":"S*G*USS1C-*****","DESCRIPTION":"Supply Class I Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class I"},{"SYMBOLID":"S*G*USS2--*****","DESCRIPTION":"Supply Class II","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS2T-*****","DESCRIPTION":"Supply Class II Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class II"},{"SYMBOLID":"S*G*USS2C-*****","DESCRIPTION":"Supply Class II Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class II"},{"SYMBOLID":"S*G*USS3--*****","DESCRIPTION":"Supply Class III","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS3T-*****","DESCRIPTION":"Supply Class III Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3C-*****","DESCRIPTION":"Supply Class III Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3A-*****","DESCRIPTION":"Supply Class III Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3AT*****","DESCRIPTION":"Supply Class III Aviation Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III/Supply Class III Aviation"},{"SYMBOLID":"S*G*USS3AC*****","DESCRIPTION":"Supply Class III Aviation Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III/Supply Class III Aviation"},{"SYMBOLID":"S*G*USS4--*****","DESCRIPTION":"Supply Class IV","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS4T-*****","DESCRIPTION":"Supply Class IV Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IV"},{"SYMBOLID":"S*G*USS4C-*****","DESCRIPTION":"Supply Class IV Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IV"},{"SYMBOLID":"S*G*USS5--*****","DESCRIPTION":"Supply Class V","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS5T-*****","DESCRIPTION":"Supply Class V Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class V"},{"SYMBOLID":"S*G*USS5C-*****","DESCRIPTION":"Supply Class V Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class V"},{"SYMBOLID":"S*G*USS6--*****","DESCRIPTION":"Supply Class VI","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS6T-*****","DESCRIPTION":"Supply Class VI Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VI"},{"SYMBOLID":"S*G*USS6C-*****","DESCRIPTION":"Supply Class VI Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VI"},{"SYMBOLID":"S*G*USS7--*****","DESCRIPTION":"Supply Class VII","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS7T-*****","DESCRIPTION":"Supply Class VII Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VII"},{"SYMBOLID":"S*G*USS7C-*****","DESCRIPTION":"Supply Class VII Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VII"},{"SYMBOLID":"S*G*USS8--*****","DESCRIPTION":"Supply Class VIII","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS8T-*****","DESCRIPTION":"Supply Class VIII Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VIII"},{"SYMBOLID":"S*G*USS8C-*****","DESCRIPTION":"Supply Class VIII Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VIII"},{"SYMBOLID":"S*G*USS9--*****","DESCRIPTION":"Supply Class IX","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS9T-*****","DESCRIPTION":"Supply Class IX Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IX"},{"SYMBOLID":"S*G*USS9C-*****","DESCRIPTION":"Supply Class IX Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IX"},{"SYMBOLID":"S*G*USSX--*****","DESCRIPTION":"Supply Class X","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSXT-*****","DESCRIPTION":"Supply Class X Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class X"},{"SYMBOLID":"S*G*USSXC-*****","DESCRIPTION":"Supply Class X Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class X"},{"SYMBOLID":"S*G*USSL--*****","DESCRIPTION":"Supply Laundry/Bath","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSLT-*****","DESCRIPTION":"Supply Laundry/Bath Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Laundry and Bath"},{"SYMBOLID":"S*G*USSLC-*****","DESCRIPTION":"Supply Laundry/Bath Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Laundry and Bath"},{"SYMBOLID":"S*G*USSW--*****","DESCRIPTION":"Supply Water","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSWT-*****","DESCRIPTION":"Supply Water Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWC-*****","DESCRIPTION":"Supply Water Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWP-*****","DESCRIPTION":"Supply Water Purification","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWPT*****","DESCRIPTION":"Supply Water Purification Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water/Supply Water Purification"},{"SYMBOLID":"S*G*USSWPC*****","DESCRIPTION":"Supply Water Purification Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water/Supply Water Purification"},{"SYMBOLID":"S*G*UST---*****","DESCRIPTION":"Transportation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USTT--*****","DESCRIPTION":"Transportation Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTC--*****","DESCRIPTION":"Transportation Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTM--*****","DESCRIPTION":"Movement Control Center (MCC)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTMT-*****","DESCRIPTION":"MCC Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Movement Control Center (MCC)"},{"SYMBOLID":"S*G*USTMC-*****","DESCRIPTION":"MCC Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Movement Control Center (MCC)"},{"SYMBOLID":"S*G*USTR--*****","DESCRIPTION":"Railhead","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTRT-*****","DESCRIPTION":"Railhead Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Railhead"},{"SYMBOLID":"S*G*USTRC-*****","DESCRIPTION":"Railhead Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Railhead"},{"SYMBOLID":"S*G*USTS--*****","DESCRIPTION":"SPOD/SPOE","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTST-*****","DESCRIPTION":"SPOD/SPOE Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/SPOD and SPOE"},{"SYMBOLID":"S*G*USTSC-*****","DESCRIPTION":"SPOD/SPOE Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/SPOD and SPOE"},{"SYMBOLID":"S*G*USTA--*****","DESCRIPTION":"APOD/APOE","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTAT-*****","DESCRIPTION":"APOD/APOE Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/APOD and APOE"},{"SYMBOLID":"S*G*USTAC-*****","DESCRIPTION":"APOD/APOE Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/APOD and APOE"},{"SYMBOLID":"S*G*USTI--*****","DESCRIPTION":"Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTIT-*****","DESCRIPTION":"Missile Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Missile"},{"SYMBOLID":"S*G*USTIC-*****","DESCRIPTION":"Missile Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Missile"},{"SYMBOLID":"S*G*USX---*****","DESCRIPTION":"Maintenance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USXT--*****","DESCRIPTION":"Maintenance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXC--*****","DESCRIPTION":"Maintenance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXH--*****","DESCRIPTION":"Maintenance Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXHT-*****","DESCRIPTION":"Maintenance Heavy Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Heavy"},{"SYMBOLID":"S*G*USXHC-*****","DESCRIPTION":"Maintenance Heavy Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Heavy"},{"SYMBOLID":"S*G*USXR--*****","DESCRIPTION":"Maintenance Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXRT-*****","DESCRIPTION":"Maintenance Recovery Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Recovery"},{"SYMBOLID":"S*G*USXRC-*****","DESCRIPTION":"Maintenance Recovery Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Recovery"},{"SYMBOLID":"S*G*USXO--*****","DESCRIPTION":"Ordnance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXOT-*****","DESCRIPTION":"Ordnance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOC-*****","DESCRIPTION":"Ordnance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOM-*****","DESCRIPTION":"Ordnance Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOMT*****","DESCRIPTION":"Ordnance Missile Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance/Ordnance Missile"},{"SYMBOLID":"S*G*USXOMC*****","DESCRIPTION":"Ordnance Missile Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance/Ordnance Missile"},{"SYMBOLID":"S*G*USXE--*****","DESCRIPTION":"Electro-Optical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXET-*****","DESCRIPTION":"Electro-Optical Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Electro-Optical"},{"SYMBOLID":"S*G*USXEC-*****","DESCRIPTION":"Electro-Optical Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Electro-Optical"},{"SYMBOLID":"S*G*UH----*****","DESCRIPTION":"Special C2 Headquarters Component","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.C2HQ","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*E-----*****","DESCRIPTION":"Ground Track Equipment","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*EW----*****","DESCRIPTION":"Weapon","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EWM---*****","DESCRIPTION":"Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWMA--*****","DESCRIPTION":"Air Defense (AD) Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMAS-*****","DESCRIPTION":"Short Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMASR*****","DESCRIPTION":"Short Range Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/ShortRange"},{"SYMBOLID":"S*G*EWMASE*****","DESCRIPTION":"Short Range Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/ShortRange"},{"SYMBOLID":"S*G*EWMAI-*****","DESCRIPTION":"Intermediate Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMAIR*****","DESCRIPTION":"Intermediate Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Intermediate Range"},{"SYMBOLID":"S*G*EWMAIE*****","DESCRIPTION":"Intermediate Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Intermediate Range"},{"SYMBOLID":"S*G*EWMAL-*****","DESCRIPTION":"Long Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMALR*****","DESCRIPTION":"Long Range Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Long Range"},{"SYMBOLID":"S*G*EWMALE*****","DESCRIPTION":"Long Range Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Long Range"},{"SYMBOLID":"S*G*EWMAT-*****","DESCRIPTION":"AD Missile Launcher Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMATR*****","DESCRIPTION":"Theater Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Theater"},{"SYMBOLID":"S*G*EWMATE*****","DESCRIPTION":"Theater Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Theater"},{"SYMBOLID":"S*G*EWMS--*****","DESCRIPTION":"Surf-Surf (SS) Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMSS-*****","DESCRIPTION":"Short Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.SHTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMSI-*****","DESCRIPTION":"Intermediate Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.INTMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMSL-*****","DESCRIPTION":"Long Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.LNGR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMT--*****","DESCRIPTION":"Missile Launcher Antitank (AT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMTL-*****","DESCRIPTION":"Missile Launcher AT Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWMTM-*****","DESCRIPTION":"Missile Launcher AT Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWMTH-*****","DESCRIPTION":"Missile Launcher AT Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWS---*****","DESCRIPTION":"Weapon Single Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWSL--*****","DESCRIPTION":"Single Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWSM--*****","DESCRIPTION":"Single Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWSH--*****","DESCRIPTION":"Single Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWX---*****","DESCRIPTION":"Multiple Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWXL--*****","DESCRIPTION":"Multiple Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWXM--*****","DESCRIPTION":"Multiple Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWXH--*****","DESCRIPTION":"Multiple Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWT---*****","DESCRIPTION":"Anti-Tank Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWTL--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.1","ALPHAHIERARCHY":"211SYMBOL UNKNOWN FRIEND NEUTRAL HOSTILEWAR.GRDTRK.EQT.WPN.MRL.HVYWARFIGHTING SYMBOLSGROUND TRACKEQUIPMENTWEAPONMULTIPLE ROCKET LAUNCHERHEAVYHierarchy: 1.X.3.2.1.3.3Framed: FOSUGPEWXH--*****SFGPEWXH--*****SNGPEWXH--*****SHGPEWXH--*****SUGPEWXH--*****SFGPEWXH--*****SNGPEWXH--*****SHGPEWXH--*****WAR.GRDTRK.EQT.WPN.ATRLWARFIGHTING SYMBOLSGROUND TRACKEQUIPMENTWEAPONANTITANK ROCKET LAUNCHERHierarchy: 1.X.3.2.1.4Framed: FOSUGPEWT---*****SFGPEWT---*****SNGPEWT---*****SHGPEWT---*****SUGPEWT---*****SFGPEWT---*****SNGPEWT---*****SHGPEWT---*****WAR.GRDTRK.EQT.WPN.ATRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWTM--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWTH--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWR---*****","DESCRIPTION":"Rifle/Automatic Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Rifle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Cache","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.CACHE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Confiscated","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.CONF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Found","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.FND","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Market","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.MKT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Sale","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.SALE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRL--*****","DESCRIPTION":"Light Machine Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.LMG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWRH--*****","DESCRIPTION":"Heavy Machine Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.HMG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWZ---*****","DESCRIPTION":"Grenade Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWZL--*****","DESCRIPTION":"Grenade Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWZM--*****","DESCRIPTION":"Grenade Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWZH--*****","DESCRIPTION":"Grenade Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWO---*****","DESCRIPTION":"Weapon Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWOL--*****","DESCRIPTION":"Mortar Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWOM--*****","DESCRIPTION":"Mortar Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWOH--*****","DESCRIPTION":"Mortar Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWH---*****","DESCRIPTION":"Howitzer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWHL--*****","DESCRIPTION":"Howitzer Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHLS-*****","DESCRIPTION":"Howitzer Light Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.LIT.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Light"},{"SYMBOLID":"S*G*EWHM--*****","DESCRIPTION":"Howitzer Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHMS-*****","DESCRIPTION":"Howitzer Medium Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.MDM.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Medium"},{"SYMBOLID":"S*G*EWHH--*****","DESCRIPTION":"Howitzer Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHHS-*****","DESCRIPTION":"Howitzer Heavy Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.HVY.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Heavy"},{"SYMBOLID":"S*G*EWG---*****","DESCRIPTION":"Anti-Tank Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWGL--*****","DESCRIPTION":"Anti-Tank Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGM--*****","DESCRIPTION":"Anti-Tank Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGH--*****","DESCRIPTION":"Anti-Tank Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGR--*****","DESCRIPTION":"Anti-Tank Gun Recoilless","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.RECL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWD---*****","DESCRIPTION":"Direct Fire Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWDL--*****","DESCRIPTION":"Direct Fire Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDLS-*****","DESCRIPTION":"Direct Fire Gun Light Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.LIT.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Light"},{"SYMBOLID":"S*G*EWDM--*****","DESCRIPTION":"Direct Fire Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDMS-*****","DESCRIPTION":"Direct Fire Gun Medium Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.MDM.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Medium"},{"SYMBOLID":"S*G*EWDH--*****","DESCRIPTION":"Direct Fire Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDHS-*****","DESCRIPTION":"Direct Fire Gun Heavy Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.HVY.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Heavy"},{"SYMBOLID":"S*G*EWA---*****","DESCRIPTION":"Air Defense Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWAL--*****","DESCRIPTION":"Air Defense Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EWAM--*****","DESCRIPTION":"Air Defense Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EWAH--*****","DESCRIPTION":"Air Defense Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EV----*****","DESCRIPTION":"Ground Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EVA---*****","DESCRIPTION":"Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVAT--*****","DESCRIPTION":"Tank","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVATL-*****","DESCRIPTION":"Tank Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATLR*****","DESCRIPTION":"Tank Light Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Light"},{"SYMBOLID":"S*G*EVATM-*****","DESCRIPTION":"Tank Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATMR*****","DESCRIPTION":"Tank Medium Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Medium"},{"SYMBOLID":"S*G*EVATH-*****","DESCRIPTION":"Tank Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATHR*****","DESCRIPTION":"Tank Heavy Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Heavy"},{"SYMBOLID":"S*G*EVAA--*****","DESCRIPTION":"Armored Personnel Carrier","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAAR-*****","DESCRIPTION":"Armored Personnel Carrier Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Armored Personnel Carrier"},{"SYMBOLID":"S*G*EVAI--*****","DESCRIPTION":"Armored Infantry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMINF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAC--*****","DESCRIPTION":"C2V/ACV","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.C2V","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAS--*****","DESCRIPTION":"Combat Service Support Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.CSSVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAL--*****","DESCRIPTION":"Light Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.LARMVH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVU---*****","DESCRIPTION":"Utility Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVUB--*****","DESCRIPTION":"Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.BUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUS--*****","DESCRIPTION":"Semi","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUSL-*****","DESCRIPTION":"Semi Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUSM-*****","DESCRIPTION":"Semi Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUSH-*****","DESCRIPTION":"Semi Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUL--*****","DESCRIPTION":"Limited Cross-Country Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.LCCTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUX--*****","DESCRIPTION":"Cross-Country Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.CCTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUR--*****","DESCRIPTION":"Water Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.H2OCRT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUT--*****","DESCRIPTION":"Tow Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUTL-*****","DESCRIPTION":"Tow Truck Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Tow Truck"},{"SYMBOLID":"S*G*EVUTH-*****","DESCRIPTION":"Tow Truck Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Tow Truck"},{"SYMBOLID":"S*G*EVUA--*****","DESCRIPTION":"Ambulance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUAA-*****","DESCRIPTION":"Ambulance Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Ambulance"},{"SYMBOLID":"S*G*EVE---*****","DESCRIPTION":"Engineer Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVEB--*****","DESCRIPTION":"Engineer Vehicle Bridge","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEE--*****","DESCRIPTION":"Earthmover","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ERHMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEC--*****","DESCRIPTION":"Construction Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.CSNVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEM--*****","DESCRIPTION":"Mine Laying Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEMV-*****","DESCRIPTION":"Armored Carrier with Volcano","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.ARMCV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Laying Vehicle"},{"SYMBOLID":"S*G*EVEML-*****","DESCRIPTION":"Truck Mounted with Volcano","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.TRKMV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Laying Vehicle"},{"SYMBOLID":"S*G*EVEA--*****","DESCRIPTION":"Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEAA-*****","DESCRIPTION":"Armored Mounted Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.ARMVM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Clearing Vehicle"},{"SYMBOLID":"S*G*EVEAT-*****","DESCRIPTION":"Trailer Mounted Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.TM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Clearing Vehicle"},{"SYMBOLID":"S*G*EVED--*****","DESCRIPTION":"Dozer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEDA-*****","DESCRIPTION":"Armored Dozer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVES--*****","DESCRIPTION":"Armored Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.AST","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVER--*****","DESCRIPTION":"Armored Engineer Recon Vehicle (AERV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ARMERV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEH--*****","DESCRIPTION":"Backhoe","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEF--*****","DESCRIPTION":"Ferry Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.FRYTSP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVT---*****","DESCRIPTION":"Train Locomotive","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.TRNLCO","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVC---*****","DESCRIPTION":"Civilian Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVCA--*****","DESCRIPTION":"Civilian Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCAL-*****","DESCRIPTION":"Civilian Compact Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.CPCT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCAM-*****","DESCRIPTION":"Civilian Midsize Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.MDSZ","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCAH-*****","DESCRIPTION":"Civilian Automobile Sedan","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.SDN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCO--*****","DESCRIPTION":"Civilian Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCOL-*****","DESCRIPTION":"Civilian Pickup Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.PU","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCOM-*****","DESCRIPTION":"Civilian Small Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCOH-*****","DESCRIPTION":"Civilian Large Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCM--*****","DESCRIPTION":"Civilian Multi-Passenger Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCML-*****","DESCRIPTION":"Civilian Multi-Passenger Van","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.VAN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCMM-*****","DESCRIPTION":"Civilian Small Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.SBUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCMH-*****","DESCRIPTION":"Civilian Large Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.LBUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCU--*****","DESCRIPTION":"Civilian Utility Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCUL-*****","DESCRIPTION":"Civilian Sport Utility Vehicle (SUV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SUV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCUM-*****","DESCRIPTION":"Civilian Utility Small Box Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SBOX","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCUH-*****","DESCRIPTION":"Civilian Utility Large Box Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.LBOX","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCJ--*****","DESCRIPTION":"Civilian Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCJL-*****","DESCRIPTION":"Civilian Small/Light Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCJM-*****","DESCRIPTION":"Civilian Medium Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCJH-*****","DESCRIPTION":"Civilian Large/Heavy Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCT--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCTL-*****","DESCRIPTION":"Civilian Small/Light Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCTM-*****","DESCRIPTION":"Civilian Medium Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCTH-*****","DESCRIPTION":"Civilian Large/Heavy Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCF--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCFL-*****","DESCRIPTION":"Civilian Small/Light Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVCFM-*****","DESCRIPTION":"Civilian Medium Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVCFH-*****","DESCRIPTION":"Civilian Large/Heavy Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVS---*****","DESCRIPTION":"Missile Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVST--*****","DESCRIPTION":"Transloader","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TLDR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSR--*****","DESCRIPTION":"Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TPTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSC--*****","DESCRIPTION":"Crane/Loading Device","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.CRN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSP--*****","DESCRIPTION":"Propellant Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.PLNT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSW--*****","DESCRIPTION":"Warhead Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.WH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVM---*****","DESCRIPTION":"Pack Animal(s)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.PKAN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*ES----*****","DESCRIPTION":"Equipment Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*ESR---*****","DESCRIPTION":"Sensor Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS.RAD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Sensor"},{"SYMBOLID":"S*G*ESE---*****","DESCRIPTION":"Emplaced Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS.EMP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Sensor"},{"SYMBOLID":"S*G*EX----*****","DESCRIPTION":"Special","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.2.4","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EXL---*****","DESCRIPTION":"Laser","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LSR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXN---*****","DESCRIPTION":"NBC Equipment","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.NBCEQ","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXF---*****","DESCRIPTION":"Flame Thrower","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.FLMTHR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXM---*****","DESCRIPTION":"Land Mines","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXMC--*****","DESCRIPTION":"Claymore","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE.CLM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Land Mines"},{"SYMBOLID":"S*G*EXML--*****","DESCRIPTION":"Less Than Lethal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE.LTL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Land Mines"},{"SYMBOLID":"S*G*EXI---*****","DESCRIPTION":"IED","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.5","ALPHAHIERARCHY":"WAR.GRNTRK.EQT.SPL.IED","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXI---MO***","DESCRIPTION":"VBIED","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.5.1","ALPHAHIERARCHY":"WAR.GRNTRK.EQT.SPL.IED.VBIED","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Improvised Explosive Device (IED)"},{"SYMBOLID":"S*G*I-----H****","DESCRIPTION":"Installation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*IR----H****","DESCRIPTION":"Raw Material Production/Storage","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IRM---H****","DESCRIPTION":"Raw Material Production/Storage Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.MNE","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRP---H****","DESCRIPTION":"Petroleum/Gas/Oil","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.PGO","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRN---H****","DESCRIPTION":"NBC","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRNB--H****","DESCRIPTION":"Production/Storage NBC Biological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.BIO","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IRNC--H****","DESCRIPTION":"Production/Storage NBC Chemical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.CML","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IRNN--H****","DESCRIPTION":"Production/Storage NBC Nuclear","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.NUC","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IP----H****","DESCRIPTION":"Processing Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.PF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IPD---H****","DESCRIPTION":"Processing Facility Decontamination","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.PF.DECON","PATH":"Warfighting Symbology/Ground Track/Installation/Processing Facility"},{"SYMBOLID":"S*G*IE----H****","DESCRIPTION":"Equipment Manufacture","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.EQTMNF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IU----H****","DESCRIPTION":"Service, Reasearch, Utility Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IUR---H****","DESCRIPTION":"Technological Research Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.TRF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUT---H****","DESCRIPTION":"Telecommunications Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.TCF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUE---H****","DESCRIPTION":"Electric Power Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUEN--H****","DESCRIPTION":"Nuclear Plant","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.NPT","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUED--H****","DESCRIPTION":"Dam","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.DAM","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUEF--H****","DESCRIPTION":"Fossil Fuel","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.FOSF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUP---H****","DESCRIPTION":"Public Water Services","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.PWS","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IM----H****","DESCRIPTION":"Military Materiel Facility","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.3.5","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IMF---H****","DESCRIPTION":"Nuclear Energy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMFA--H****","DESCRIPTION":"Atomic Energy Reactor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.ATMER","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMFP--H****","DESCRIPTION":"Nuclear Material Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMFPW-H****","DESCRIPTION":"Weapons Grade","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMP.WPNGR","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy/Nuclear Material Production"},{"SYMBOLID":"S*G*IMFS--H****","DESCRIPTION":"Nuclear Material Storage","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMS","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMA---H****","DESCRIPTION":"Aircraft Production & Assembly","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.APA","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IME---H****","DESCRIPTION":"Ammunition And Explosives Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.AMEP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMG---H****","DESCRIPTION":"Armament Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.AMTP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMV---H****","DESCRIPTION":"Military Vehicle Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.MILVP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMN---H****","DESCRIPTION":"Engineering Equipment Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.ENGEP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMNB--H****","DESCRIPTION":"Engineering Equipment Production Bridge","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.ENGEP.BRG","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Engineering Equipment Production"},{"SYMBOLID":"S*G*IMC---H****","DESCRIPTION":"Chemical & Biological Warfare Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.CBWP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMS---H****","DESCRIPTION":"Ship Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.8","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.SHPCSN","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMM---H****","DESCRIPTION":"Missile & Space System Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.9","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.MSSP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IG----H****","DESCRIPTION":"Government Leadership","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.INS.GOVLDR","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IB----H****","DESCRIPTION":"Military Base/Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IBA---H****","DESCRIPTION":"Airport/Airbase","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF.AB","PATH":"Warfighting Symbology/Ground Track/Installation/Military Base and Facility"},{"SYMBOLID":"S*G*IBN---H****","DESCRIPTION":"Seaport/Naval Base","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF.SP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Base and Facility"},{"SYMBOLID":"S*G*IT----H****","DESCRIPTION":"Transport Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TSPF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IX----H****","DESCRIPTION":"Medical Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MEDF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IXH---H****","DESCRIPTION":"Hospital","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MEDF.HSP","PATH":"Warfighting Symbology/Ground Track/Installation/Medical Facility"},{"SYMBOLID":"S*G*IC----H****","DESCRIPTION":"Tented Camp","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TNTCMP","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION"},{"SYMBOLID":"S*G*ICD---H****","DESCRIPTION":"Tented Camp, Displaced Persons/Refugees","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TNTCMP.DPRE","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION/Tented Camp"},{"SYMBOLID":"S*G*ICT---H****","DESCRIPTION":"Tented Training Camp","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.INK.INS.TNTCMP.TNG","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION/TENTED CAMP"},{"SYMBOLID":"S*G*IW----H****","DESCRIPTION":"Warehouse/Storage Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.11","ALPHAHIERARCHY":"WAR.GRDTRK.INS.WAREHS","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION"},{"SYMBOLID":"S*S*------*****","DESCRIPTION":"Sea Surface Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.4","ALPHAHIERARCHY":"WAR.SSUF","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*S*C-----*****","DESCRIPTION":"Sea Surface Track Combatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*CL----*****","DESCRIPTION":"Line","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CLCV--*****","DESCRIPTION":"Carrier","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.1","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLBB--*****","DESCRIPTION":"Battleship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.BBS","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLCC--*****","DESCRIPTION":"Cruiser","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.CRU","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLDD--*****","DESCRIPTION":"Destroyer","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.DD","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLFF--*****","DESCRIPTION":"Frigate/Corvette","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.5","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.FFR","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLLL--*****","DESCRIPTION":"Littoral Combatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLLLAS*****","DESCRIPTION":"Antisubmarine Warfare Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CLLLMI*****","DESCRIPTION":"Mine Warfare Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.MNEW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CLLLSU*****","DESCRIPTION":"Surface Warfare (SUW) Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.SUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CA----*****","DESCRIPTION":"Amphibious Warfare Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CALA--*****","DESCRIPTION":"Assault Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.ASTVES","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CALS--*****","DESCRIPTION":"Landing Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CALSM-*****","DESCRIPTION":"Landing Ship Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP.MDM","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship/Landing Ship"},{"SYMBOLID":"S*S*CALST-*****","DESCRIPTION":"Landing Ship Tank","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP.TANK","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship/Landing Ship"},{"SYMBOLID":"S*S*CALC--*****","DESCRIPTION":"Landing Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDCRT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CM----*****","DESCRIPTION":"Mine Warfare Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CMML--*****","DESCRIPTION":"Minelayer","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNELYR","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMS--*****","DESCRIPTION":"Minesweeper","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNESWE","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMH--*****","DESCRIPTION":"Minehunter","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNEHNT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMA--*****","DESCRIPTION":"MCM Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MCMSUP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CP----*****","DESCRIPTION":"Sea Surface Combatant Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CPSB--*****","DESCRIPTION":"Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Sea Surface Combatant Patrol"},{"SYMBOLID":"S*S*CPSU--*****","DESCRIPTION":"Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Sea Surface Combatant Patrol"},{"SYMBOLID":"S*S*CPSUM-*****","DESCRIPTION":"Anti-Ship Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.ASMSL","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CPSUT-*****","DESCRIPTION":"Torpedo(Antisurface Warfare)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.TPD","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CPSUG-*****","DESCRIPTION":"Antisurface Warfare Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.GUN","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CH----*****","DESCRIPTION":"Combatant Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.5","ALPHAHIERARCHY":"WAR.SSUF.CBTT.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*S-----*****","DESCRIPTION":"Sea Surface Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*SP----*****","DESCRIPTION":"Picket","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN.PKT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Station"},{"SYMBOLID":"S*S*SA----*****","DESCRIPTION":"ASW Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN.ASWSHP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Station"},{"SYMBOLID":"S*S*G-----*****","DESCRIPTION":"Navy Group","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*GT----*****","DESCRIPTION":"Navy Task Force","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTF","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GG----*****","DESCRIPTION":"Navy Task Group","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTG","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GU----*****","DESCRIPTION":"Navy Task Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTU","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GC----*****","DESCRIPTION":"Convoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.CNY","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*CD----*****","DESCRIPTION":"Surface Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.8","ALPHAHIERARCHY":"WAR.SSUF.CBTT.SUFDCY","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CU----*****","DESCRIPTION":"Unmanned Surface Vehicle (USV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/"},{"SYMBOLID":"S*S*CUM---*****","DESCRIPTION":"USV Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.MNECM","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUS---*****","DESCRIPTION":"USV Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUN---*****","DESCRIPTION":"USV Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.ASUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUR---*****","DESCRIPTION":"USV Remote Multimission Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.RMV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*N-----*****","DESCRIPTION":"Noncombatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2","ALPHAHIERARCHY":"WAR.SSUF.NCBTT","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*NR----*****","DESCRIPTION":"Underway Replenishment","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.1","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.UWRPM","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NF----*****","DESCRIPTION":"Fleet Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.2","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.FLTSUP","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NI----*****","DESCRIPTION":"Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.3","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.INT","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NS----*****","DESCRIPTION":"Service & Support Harbor","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.4","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.SSH","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NM----*****","DESCRIPTION":"Hospital Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.5","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.HSPSHP","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NH----*****","DESCRIPTION":"Noncombatant Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.6","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NN----*****","DESCRIPTION":"Noncombatant Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.7","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.STN","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NNR---*****","DESCRIPTION":"Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.7.1","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.STN.RSC","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant/Station"},{"SYMBOLID":"S*S*X-----*****","DESCRIPTION":"Non-Military","DRAWCATEGORY":"0","HIERARCHY":"1.X.4.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*XM----*****","DESCRIPTION":"Merchant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XMC---*****","DESCRIPTION":"Subsurface Non-military Cargo","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.CGO","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMR---*****","DESCRIPTION":"Roll On/Roll Off","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.RORO","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMO---*****","DESCRIPTION":"Oiler/Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.OLR","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMTU--*****","DESCRIPTION":"Tug","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.4","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.TUG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMF---*****","DESCRIPTION":"Ferry","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.5","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.FRY","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMP---*****","DESCRIPTION":"Passenger","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.6","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.PSG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMH---*****","DESCRIPTION":"Hazardous Materials (HAZMAT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.7","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.HAZMAT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMTO--*****","DESCRIPTION":"Towing Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.8","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.TOWVES","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XF----*****","DESCRIPTION":"Fishing","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XFDF--*****","DESCRIPTION":"Drifter","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.DRFT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XFDR--*****","DESCRIPTION":"Dredge","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.DRG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XFTR--*****","DESCRIPTION":"Trawler","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.TRW","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XR----*****","DESCRIPTION":"Leisure Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.LESCRT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XL----*****","DESCRIPTION":"Law Enforcement Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.4","ALPHAHIERARCHY":"WAR.SSUF.NMIL.LAWENV","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XH----*****","DESCRIPTION":"Non-military Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.5","ALPHAHIERARCHY":"WAR.SSUF.NMIL.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*O-----*****","DESCRIPTION":"Own Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.4","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*U*------*****","DESCRIPTION":"Subsurface Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.5","ALPHAHIERARCHY":"WAR.SBSUF","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*U*S-----*****","DESCRIPTION":"Submarine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*SN----*****","DESCRIPTION":"Nuclear Propulsion","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SNF---*****","DESCRIPTION":"Submarine Nuclear Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNA---*****","DESCRIPTION":"Submarine Nuclear Attack (SSN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.ATK","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNM---*****","DESCRIPTION":"Submarine Nuclear Missile Type Unknown","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.MSL","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNG---*****","DESCRIPTION":"Submarine Nuclear Guided Missile (SSGN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.4","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.GDD","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNB---*****","DESCRIPTION":"Ballistic Missile Submarine (SSB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.BLST","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SC----*****","DESCRIPTION":"Conventional Propulsion","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SCF---*****","DESCRIPTION":"Conventional Propulsion Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCA---*****","DESCRIPTION":"Attack Submarine (SS)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.ATK","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCM---*****","DESCRIPTION":"Conventional Propulsion Missile Submarine (TYPE UNKNOWN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.MSL","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCG---*****","DESCRIPTION":"Guided Missile Submarine (SSG)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.4","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.GDD","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCB---*****","DESCRIPTION":"Conventional Propulsion Ballistic Missile (SSB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.BLST","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SO----*****","DESCRIPTION":"Other Submersible","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.OTH","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SOF---*****","DESCRIPTION":"Other Submersible Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.0","ALPHAHIERARCHY":"WAR.SBSUF.SUB.OTH.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible"},{"SYMBOLID":"S*U*SU----*****","DESCRIPTION":"Unmanned Underwater Vehicle (UUV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible"},{"SYMBOLID":"S*U*SUM---*****","DESCRIPTION":"UUV Mine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.MNEW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SUS---*****","DESCRIPTION":"UUV Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.ASBW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SUN---*****","DESCRIPTION":"UUV Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.ASUW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SS----*****","DESCRIPTION":"Submarine Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.4","ALPHAHIERARCHY":"WAR.SBSUF.SUB.STN","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SSA---*****","DESCRIPTION":"ASW Submarine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.4.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.STN.ASWSUB","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Submarine Station"},{"SYMBOLID":"S*U*SF----*****","DESCRIPTION":"Submarine Station Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*W-----*****","DESCRIPTION":"Underwater Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*WT----*****","DESCRIPTION":"Torpedo","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.TPD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon"},{"SYMBOLID":"S*U*WM----*****","DESCRIPTION":"Sea Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon"},{"SYMBOLID":"S*U*WMD---*****","DESCRIPTION":"Sea Mine Dealt","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMG---*****","DESCRIPTION":"Sea Mine (Ground)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMGD--*****","DESCRIPTION":"Sea Mine (Ground) Dealt","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMM---*****","DESCRIPTION":"Sea Mine (Moored)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMMD--*****","DESCRIPTION":"Sea Mine (Moored) Dealt","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMF---*****","DESCRIPTION":"Sea Mine (Floating)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMFD--*****","DESCRIPTION":"Sea Mine (Floating) Dealt","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMO---*****","DESCRIPTION":"Sea Mine (Other Position)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.5","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMOP","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMOD--*****","DESCRIPTION":"Sea Mine (Other Position) Dealt","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.5.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMOP.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (In Other Position)"},{"SYMBOLID":"S*U*WD----*****","DESCRIPTION":"Underwater Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*WDM---*****","DESCRIPTION":"Sea Mine Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY.SMDCY","PATH":"Warfighting Symbology/Subsurface Track/Underwater Decoy"},{"SYMBOLID":"S*U*N-----*****","DESCRIPTION":"Non-Submarine","DRAWCATEGORY":"0","HIERARCHY":"1.X.5.4","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*ND----*****","DESCRIPTION":"Diver","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.4.1","ALPHAHIERARCHY":"WAR.SBSUF.NSUB.DVR","PATH":"Warfighting Symbology/Subsurface Track/Non-Submarine"},{"SYMBOLID":"S*U*X-----*****","DESCRIPTION":"Unexploded Ordnance Area (Subsurface)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.8","ALPHAHIERARCHY":"WAR.SBSUF.UXO","PATH":"WARFIGHTING SYMBOLS/SUBSURFACE TRACK"},{"SYMBOLID":"S*F*------*****","DESCRIPTION":"Special Operations Forces (SOF) Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.6","ALPHAHIERARCHY":"WAR.SOFUNT","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*F*A-----*****","DESCRIPTION":"SOF Unit Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*AF----*****","DESCRIPTION":"SOF Unit Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AFA---*****","DESCRIPTION":"SOF Unit Fixed Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.ATK","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFK---*****","DESCRIPTION":"SOF Unit Refuel","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.RFE","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFU---*****","DESCRIPTION":"SOF Unit Fixed Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFUL--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.LIT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AFUM--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.MDM","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AFUH--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.HVY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AV----*****","DESCRIPTION":"SOF Unit V/STOL","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.VSTOL","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AH----*****","DESCRIPTION":"SOF Unit Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AHH---*****","DESCRIPTION":"SOF Unit Rotary Wing Combat Search & Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.CSAR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHA---*****","DESCRIPTION":"SOF Unit Rotary Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.ATK","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHU---*****","DESCRIPTION":"SOF Unit Rotary Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHUL--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.LIT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*AHUM--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.MDM","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*AHUH--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.HVY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*N-----*****","DESCRIPTION":"SOF Unit SOF Unit Naval","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2","ALPHAHIERARCHY":"WAR.SOFUNT.NAV","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*NS----*****","DESCRIPTION":"SOF Unit Seal","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.1","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SEAL","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NU----*****","DESCRIPTION":"SOF Unit Underwater Demolition Team","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.2","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.UH2DML","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NB----*****","DESCRIPTION":"SOF Unit Special Boat","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.3","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SBT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NN----*****","DESCRIPTION":"SOF Unit Special SSNR","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.4","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SSSNR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*G-----*****","DESCRIPTION":"SOF Unit Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3","ALPHAHIERARCHY":"WAR.SOFUNT.GRD","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*GS----*****","DESCRIPTION":"SOF Unit Special Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.SOF","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GR----*****","DESCRIPTION":"SOF Unit Ranger","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.RGR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GP----*****","DESCRIPTION":"SOF Unit Psychological Operations (PSYOP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.PSYOP","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GPA---*****","DESCRIPTION":"SOF Unit Fixed Wing Aviation (PSYOP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.PSYOP.FIXAVN","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground/SOF Unit Psychological Operations (PSYOP)"},{"SYMBOLID":"S*F*GC----*****","DESCRIPTION":"SOF Unit Civil Affairs","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.4","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.CVLAFF","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*B-----*****","DESCRIPTION":"SOF Unit Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.4","ALPHAHIERARCHY":"WAR.SOFUNT.SUP","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*Z*------*****","DESCRIPTION":"Unknown Battle Dimension","DRAWCATEGORY":"8","HIERARCHY":"1.X.7","ALPHAHIERARCHY":"UNK","PATH":"Warfighting Symbology"},{"SYMBOLID":"I*-*--------***","DESCRIPTION":"Signals Intelligence","DRAWCATEGORY":"0","HIERARCHY":"4.X"},{"SYMBOLID":"I*P*--------***","DESCRIPTION":"Space Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.1","PATH":"Signals Intelligence"},{"SYMBOLID":"I*P*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1","PATH":"Signals Intelligence/Space Track"},{"SYMBOLID":"I*P*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1.1","PATH":"Signals Intelligence/Space Track/Signal Intercept"},{"SYMBOLID":"I*P*SCD-----***","DESCRIPTION":"Satellite Down-Link","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.1.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.COMM.SATDL","PATH":"Signals Intelligence/Space Track/Signal Intercept/Communications"},{"SYMBOLID":"I*P*SR------***","DESCRIPTION":"Radar(Signal Intercept)","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1.2","PATH":"Signals Intelligence/Space Track/Signal Intercept"},{"SYMBOLID":"I*P*SRD-----***","DESCRIPTION":"Data Transmission(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRE-----***","DESCRIPTION":"Earth Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.2","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.ERHSVL","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRI-----***","DESCRIPTION":"IFF (Transponder)(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.3","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.IFF","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRM-----***","DESCRIPTION":"Multi-function(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.4","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRT-----***","DESCRIPTION":"Target Acquisition(Space Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.5","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRS-----***","DESCRIPTION":"Space","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.6","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.SPC","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRU-----***","DESCRIPTION":"Unknown(Space Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.7","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*--------***","DESCRIPTION":"Air Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.2","PATH":"Signals Intelligence"},{"SYMBOLID":"I*A*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1","PATH":"Signals Intelligence/Air Track"},{"SYMBOLID":"I*A*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1.1","PATH":"Signals Intelligence/Air Track/Signal Intercept"},{"SYMBOLID":"I*A*SCC-----***","DESCRIPTION":"Cellular/Mobile(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.2","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.3","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCS-----***","DESCRIPTION":"Satellite Up-Link(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.4","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SR------***","DESCRIPTION":"Radar","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1.2","PATH":"Signals Intelligence/Air Track/Signal Intercept"},{"SYMBOLID":"I*A*SRAI----***","DESCRIPTION":"Airborne Intercept","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.ABNINC","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRAS----***","DESCRIPTION":"Airborne Search and Bombing","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.2","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.ABNSB","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRC-----***","DESCRIPTION":"Controlled Intercept(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.3","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.CTDINC","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRD-----***","DESCRIPTION":"Data Transmission(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.4","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRE-----***","DESCRIPTION":"Early Warning(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.5","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.EW","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRF-----***","DESCRIPTION":"Fire Control(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.6","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRI-----***","DESCRIPTION":"IFF (Transponder)(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.7","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.IFF","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMA----***","DESCRIPTION":"Missile Acquisition(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.8","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMD----***","DESCRIPTION":"Missile Downlink","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.9","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLDL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMG----***","DESCRIPTION":"Missile Guidance(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.10","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMT----***","DESCRIPTION":"Missile Tracking(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.11","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMF----***","DESCRIPTION":"Multi-Function(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.12","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTI----***","DESCRIPTION":"Target Illuminator(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.13","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTA----***","DESCRIPTION":"Target Acquisition(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.14","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTT----***","DESCRIPTION":"Target Tracking(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.15","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRU-----***","DESCRIPTION":"Unknown(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.16","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*--------***","DESCRIPTION":"Ground Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.3","PATH":"Signals Intelligence"},{"SYMBOLID":"I*G*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1","PATH":"Signals Intelligence/Ground Track"},{"SYMBOLID":"I*G*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1.1","PATH":"Signals Intelligence/Ground Track/Signal Intercept"},{"SYMBOLID":"I*G*SCC-----***","DESCRIPTION":"Cellular/Mobile(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.2","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.3","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCS-----***","DESCRIPTION":"Satellite Up-Link(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.4","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCT-----***","DESCRIPTION":"Tropospheric Scatter","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.5","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.TPSSCT","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SR------***","DESCRIPTION":"Radar(Signals Intelligence)","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1.2","PATH":"Signals Intelligence/Ground Track/Signal Intercept"},{"SYMBOLID":"I*G*SRAT----***","DESCRIPTION":"Air Traffic Control(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.ATCTL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRAA----***","DESCRIPTION":"Anti-Aircraft(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.2","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.AAC","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRB-----***","DESCRIPTION":"Battlefield Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.3","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.BTFSVL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRCS----***","DESCRIPTION":"Coastal Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.4","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.CSTSVL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRCA----***","DESCRIPTION":"Controlled Approach(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.5","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.CTDAPP","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRD-----***","DESCRIPTION":"Data Transmission(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.6","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRE-----***","DESCRIPTION":"Early Warning(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.7","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.EW","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRF-----***","DESCRIPTION":"Fire Control(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.8","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRH-----***","DESCRIPTION":"Height Finding(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.9","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.HGTFDG","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRI-----***","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.10","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.IDFF","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMM----***","DESCRIPTION":"Meteorological (Military)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.11","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.METO","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMA----***","DESCRIPTION":"Missile Acquisition(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.12","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMG----***","DESCRIPTION":"Missile Guidance(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.13","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMT----***","DESCRIPTION":"Missile Tracking(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.14","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMF----***","DESCRIPTION":"Multi-Function(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.15","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRS-----***","DESCRIPTION":"Shell Tracking","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.16","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.SHETKG","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTA----***","DESCRIPTION":"Target Acquisition(Radar)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.17","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTI----***","DESCRIPTION":"Target Illuminator(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.18","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTT----***","DESCRIPTION":"Target Tracking(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.19","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRU-----***","DESCRIPTION":"Unknown(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.20","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*--------***","DESCRIPTION":"Sea Surface Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.4","PATH":"Signals Intelligence"},{"SYMBOLID":"I*S*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1","PATH":"Signals Intelligence/Sea Surface Track"},{"SYMBOLID":"I*S*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1.1","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept"},{"SYMBOLID":"I*S*SCC-----***","DESCRIPTION":"Cellular/Mobile(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.2","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.3","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCS-----***","DESCRIPTION":"Satellite Up-Link(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.4","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SR------***","DESCRIPTION":"Radar(Sea Surface Track)","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1.2","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept"},{"SYMBOLID":"I*S*SRAT----***","DESCRIPTION":"Air Traffic Control(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.ATCTL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRAA----***","DESCRIPTION":"Anti-Aircraft(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.2","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.AAC","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRCA----***","DESCRIPTION":"Controlled Approach(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.3","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.CTDAPP","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRCI----***","DESCRIPTION":"Controlled Intercept(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.4","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.CTDINC","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRD-----***","DESCRIPTION":"Data Transmission(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.5","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRE-----***","DESCRIPTION":"Early Warning(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.6","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.EW","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRF-----***","DESCRIPTION":"Fire Control(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.7","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRH-----***","DESCRIPTION":"Height Finding(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.8","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.HGTFDG","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRI-----***","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.9","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.IDFF","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMM----***","DESCRIPTION":"Meteorological (Military)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.10","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.METO","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMA----***","DESCRIPTION":"Missile Acquisition(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.11","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMG----***","DESCRIPTION":"Missile Guidance(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.12","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMT----***","DESCRIPTION":"Missile Tracking(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.13","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMF----***","DESCRIPTION":"Multi-Function(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.14","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRS-----***","DESCRIPTION":"Surface Search(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.15","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.SUFSRH","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTA----***","DESCRIPTION":"Target Acquisition(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.16","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTI----***","DESCRIPTION":"Target Illuminator(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.17","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTT----***","DESCRIPTION":"Target Tracking(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.18","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRU-----***","DESCRIPTION":"Unknown(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.19","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*--------***","DESCRIPTION":"Subsurface Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.5","PATH":"Signals Intelligence"},{"SYMBOLID":"I*U*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1","PATH":"Signals Intelligence/Subsurface Track"},{"SYMBOLID":"I*U*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1.1","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept"},{"SYMBOLID":"I*U*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.2","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SCS-----***","DESCRIPTION":"Satellite Up-Link(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.3","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SR------***","DESCRIPTION":"Radar(Subsurface Track)","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1.2","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept"},{"SYMBOLID":"I*U*SRD-----***","DESCRIPTION":"Data Transmission(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRE-----***","DESCRIPTION":"Early Warning(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.2","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.EW","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRM-----***","DESCRIPTION":"Multi-Function(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.3","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRS-----***","DESCRIPTION":"Surface Search(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.4","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.SUFSRH","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRT-----***","DESCRIPTION":"Target Acquisition(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.5","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRU-----***","DESCRIPTION":"Unknown(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.6","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"O*-*------*****","DESCRIPTION":"Stability Operations","DRAWCATEGORY":"0","HIERARCHY":"5.X","ALPHAHIERARCHY":"STBOPS"},{"SYMBOLID":"O*V*------*****","DESCRIPTION":"Violent Activities","DRAWCATEGORY":"0","HIERARCHY":"5.X.1","ALPHAHIERARCHY":"STBOPS.VIOATY","PATH":"Stability Operations"},{"SYMBOLID":"O*V*A-----*****","DESCRIPTION":"Arson/Fire","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.1","ALPHAHIERARCHY":"STBOPS.VIOATY.ASN","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*M-----*****","DESCRIPTION":"Killing (General)","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*MA----*****","DESCRIPTION":"Murder","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.1","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.MDR","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*MB----*****","DESCRIPTION":"Execution","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.2","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.EX","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*MC----*****","DESCRIPTION":"Assassination","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.3","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.ASS","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*B-----*****","DESCRIPTION":"Bomb/Bombing","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.3","ALPHAHIERARCHY":"STBOPS.VIOATY.BM","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*Y-----*****","DESCRIPTION":"Booby Trap","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.4","ALPHAHIERARCHY":"STBOPS.VIOATY.BBY","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*D-----*****","DESCRIPTION":"Drive-By Shooting","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.5","ALPHAHIERARCHY":"STBOPS.VIOATY.DBS","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*S-----*****","DESCRIPTION":"Sniping","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.6","ALPHAHIERARCHY":"STBOPS.VIOATY.SPG","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*P-----*****","DESCRIPTION":"Poisoning","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.7","ALPHAHIERARCHY":"STBOPS.VIOATY.PSNG","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*E-----*****","DESCRIPTION":"Explosion","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*EI----*****","DESCRIPTION":"IED Explosion","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.1","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EG----*****","DESCRIPTION":"Explosion, Grenade","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.2","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EN----*****","DESCRIPTION":"Explosion, Incendiary","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.3","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EM----*****","DESCRIPTION":"Explosion, Mine","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.4","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EO----*****","DESCRIPTION":"Explosion, Mortar Fire","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.5","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*ER----*****","DESCRIPTION":"Explosion, Rocket","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.6","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EV----*****","DESCRIPTION":"Explosion, Wheeled Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.7","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN.VEH","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*L*------*****","DESCRIPTION":"Locations","DRAWCATEGORY":"0","HIERARCHY":"5.X.2","ALPHAHIERARCHY":"STBOPS.LOCAT","PATH":"Stability Operations"},{"SYMBOLID":"O*L*B-----*****","DESCRIPTION":"Black List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.1","ALPHAHIERARCHY":"STBOPS.LOCAT.BLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*G-----*****","DESCRIPTION":"Gray List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.2","ALPHAHIERARCHY":"STBOPS.LOCAT.GLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*W-----*****","DESCRIPTION":"White List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.3","ALPHAHIERARCHY":"STBOPS.LOCAT.WLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*M-----*****","DESCRIPTION":"Mass Grave Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.4","ALPHAHIERARCHY":"STBOPS.LOCAT.MASS","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*E-----H****","DESCRIPTION":"Drug Lab","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.6","ALPHAHIERARCHY":"STBOPS.LOCAT.DGLAB","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*H-----H****","DESCRIPTION":"House/Residence","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.7","ALPHAHIERARCHY":"STBOPS.LOCAT.HOUSE","PATH":"Stability Operations/LOCATIONS"},{"SYMBOLID":"O*L*N-----H****","DESCRIPTION":"Cave Entrance","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.8","ALPHAHIERARCHY":"STBOPS.LOCAT.CAVENT","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*H-----H****","DESCRIPTION":"Palace/Presidential Residence","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.9","ALPHAHIERARCHY":"STBOPS.LOCAT.HOUSE","PATH":"Stability Operations/lOCATIONS"},{"SYMBOLID":"O*L*F-----H****","DESCRIPTION":"Polling Place","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.10","ALPHAHIERARCHY":"STBOPS.LOCAT.POLLPL","PATH":"Stability Operations/LOCATIONS"},{"SYMBOLID":"O*O*------*****","DESCRIPTION":"Operations","DRAWCATEGORY":"0","HIERARCHY":"5.X.3","ALPHAHIERARCHY":"STBOPS.OPN","PATH":"Stability Operations"},{"SYMBOLID":"O*O*P-----*****","DESCRIPTION":"Patrolling","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.1","ALPHAHIERARCHY":"STBOPS.OPN.PATG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*R-----*****","DESCRIPTION":"Recruitment","DRAWCATEGORY":"0","HIERARCHY":"5.X.3.2","ALPHAHIERARCHY":"STBOPS.OPN.RCMT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*RW----*****","DESCRIPTION":"Recruitment (Willing)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.2.1","ALPHAHIERARCHY":"STBOPS.OPN.RCMT.WLG","PATH":"Stability Operations/Operations/Recruitment"},{"SYMBOLID":"O*O*RC----*****","DESCRIPTION":"Recruitment (Coerced/Impressed)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.2.2","ALPHAHIERARCHY":"STBOPS.OPN.RCMT.CRCD","PATH":"Stability Operations/Operations/Recruitment"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Demonstration","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.3","ALPHAHIERARCHY":"STBOPS.OPN.DEMO","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*M-----*****","DESCRIPTION":"Mine Laying","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.4","ALPHAHIERARCHY":"STBOPS.OPN.ML","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*Y-----*****","DESCRIPTION":"Psychological Operations (Psyop)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*YT----*****","DESCRIPTION":"Psyop (TV and Radio Propaganda)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.1","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.TARP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*YW----*****","DESCRIPTION":"Psyop (Written Propaganda)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.2","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.WP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*YH----*****","DESCRIPTION":"House-to-House Propaganda","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.3","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.HTHP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*F-----*****","DESCRIPTION":"Foraging/Searching","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.6","ALPHAHIERARCHY":"STBOPS.OPN.FRGSRH","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*S-----*****","DESCRIPTION":"Spy","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.7","ALPHAHIERARCHY":"STBOPS.OPN.SPY","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*O-----*****","DESCRIPTION":"Food Distribution","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.8","ALPHAHIERARCHY":"STBOPS.OPN.FDDIST","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*E-----*****","DESCRIPTION":"Extortion","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.9","ALPHAHIERARCHY":"STBOPS.OPN.EXTN","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*H-----*****","DESCRIPTION":"Hijacking","DRAWCATEGORY":"0","HIERARCHY":"5.X.3.10","ALPHAHIERARCHY":"STBOPS.OPN.HJKG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*HT----*****","DESCRIPTION":"Hijacking (Vehicle)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.1","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.VEH","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*HA----*****","DESCRIPTION":"Hijacking (Airplane)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.2","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.APL","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*HV----*****","DESCRIPTION":"Hijacking (Boat)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.3","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.BOAT","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*K-----*****","DESCRIPTION":"Kidnapping","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.11","ALPHAHIERARCHY":"STBOPS.OPN.KDNG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*KA----*****","DESCRIPTION":"Attempted Kidnapping","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.11.1","ALPHAHIERARCHY":"STBOPS.OPN.KDNG.ATEMPT","PATH":"Stability Operations/Operations/Kidnapping"},{"SYMBOLID":"O*O*A-----*****","DESCRIPTION":"Arrest","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.12","ALPHAHIERARCHY":"STBOPS.OPN.ARR","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*U-----*****","DESCRIPTION":"Drug Operation","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.13","ALPHAHIERARCHY":"STBOPS.OPN.DGOPN","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*UT----*****","DESCRIPTION":"Drug Trafficking","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.13.1","ALPHAHIERARCHY":"STBOPS.OPN.DGOPN.DGTRFC","PATH":"Stability Operations/OPERATIONS/DRUG OPERATION"},{"SYMBOLID":"O*O*N-----*****","DESCRIPTION":"Raid on a House","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.14","ALPHAHIERARCHY":"STBOPS.OPN.HSRAID","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*2-----*****","DESCRIPTION":"Burglary","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.15","ALPHAHIERARCHY":"STBOPS.OPN.BRGLRY","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*V-----*****","DESCRIPTION":"Home Eviction","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.16","ALPHAHIERARCHY":"STBOPS.OPN.HSEVCT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*I-----*****","DESCRIPTION":"Black Marketing","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.17","ALPHAHIERARCHY":"STBOPS.OPM.BLKMKT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*J-----*****","DESCRIPTION":"Jail Break","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.18","ALPHAHIERARCHY":"STBOPS.OPN.JAILBREAK","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*B-----*****","DESCRIPTION":"Robbery","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.19","ALPHAHIERARCHY":"STBOPS.OPN.ROB","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*G-----*****","DESCRIPTION":"Sabotage","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.21","ALPHAHIERARCHY":"STBOPS.OPN.SABOTG","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*X-----*****","DESCRIPTION":"Smuggling","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.22","ALPHAHIERARCHY":"STBOPS.OPN.SMGLNG","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*W-----*****","DESCRIPTION":"Rock Throwing","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.23","ALPHAHIERARCHY":"STBOPS.OPN.RCKTHR","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*Z-----*****","DESCRIPTION":"Suspicious Activity","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.24","ALPHAHIERARCHY":"STBOPS.OPN.SUSACT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*T-----*****","DESCRIPTION":"Theft","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.25","ALPHAHIERARCHY":"STBOPS.OPN.THEFT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*TV----*****","DESCRIPTION":"Wheeled Vehicle Theft","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.25.1","ALPHAHIERARCHY":"STBOPS.OPN.THEFT.VEH","PATH":"Stability Operations/OPERATIONS/THEFT"},{"SYMBOLID":"O*O*Q-----*****","DESCRIPTION":"Warrant Served","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.26","ALPHAHIERARCHY":"STBOPS.OPN.WARRENT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*I*------*****","DESCRIPTION":"Items","DRAWCATEGORY":"0","HIERARCHY":"5.X.4","ALPHAHIERARCHY":"STBOPS.ITM","PATH":"Stability Operations"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Refugees","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.1","ALPHAHIERARCHY":"STBOPS.ITM.RFG","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*S-----*****","DESCRIPTION":"Safe House","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.2","ALPHAHIERARCHY":"STBOPS.ITM.SAFHSE","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*G-----*****","DESCRIPTION":"Graffiti","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.3","ALPHAHIERARCHY":"STBOPS.ITM.GRF","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*V-----*****","DESCRIPTION":"Vandalism/Rape/Loot/Ransack/Plunder/Sack","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.4","ALPHAHIERARCHY":"STBOPS.ITM.VRLRPS","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*I-----*****","DESCRIPTION":"Known Insurgent Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.5","ALPHAHIERARCHY":"STBOPS.ITM.KNIVEH","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*D-----*****","DESCRIPTION":"Drug Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.6","ALPHAHIERARCHY":"STBOPS.ITM.DGVEH","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*F-----*****","DESCRIPTION":"Internal Security Force","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.7","ALPHAHIERARCHY":"STBOPS.ITM.ISF","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*M-----*****","DESCRIPTION":"Meeting","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.8","ALPHAHIERARCHY":"STBOPS.ITM.MEETING","PATH":"Stability Operations/ITEMS"},{"SYMBOLID":"O*I*T-----*****","DESCRIPTION":"Tent","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.9","ALPHAHIERARCHY":"STBOPS.ITM.TENT","PATH":"Stability Operations/ITEMS"},{"SYMBOLID":"O*P*------*****","DESCRIPTION":"Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5","ALPHAHIERARCHY":"STBOPS.INDIV","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*A-----*****","DESCRIPTION":"Leader","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.1","ALPHAHIERARCHY":"STBOPS.INDIV.LEADER","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*AR----*****","DESCRIPTION":"Religious Leader","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.1.1","ALPHAHIERARCHY":"STBOPS.INDIV.LEADER.RELIGS","PATH":"Stability Operations/INDIVIDUAL/LEADER"},{"SYMBOLID":"O*P*B-----*****","DESCRIPTION":"Targeted Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.2","ALPHAHIERARCHY":"STBOPS.INDIV.TRGTD","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*C-----*****","DESCRIPTION":"Terrorist","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.3","ALPHAHIERARCHY":"STBOPS.INDIV.TERRST","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*P*F-----*****","DESCRIPTION":"IED Suicide Bomber","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.6","ALPHAHIERARCHY":"STBOPS.INDIV.SUICBM","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*P*D-----*****","DESCRIPTION":"Dead Body","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.4","ALPHAHIERARCHY":"STBOPS.INDIV.DDBODY","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*G-----*****","DESCRIPTION":"Exfiltrating Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.7","ALPHAHIERARCHY":"STBOPS.INDIV.EXFLT","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*H-----*****","DESCRIPTION":"Infiltrating Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.8","ALPHAHIERARCHY":"STBOPS.INDIV.INFLT","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*E-----*****","DESCRIPTION":"Speaker","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.5","ALPHAHIERARCHY":"STBOPS.INDIV.SPKR","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*G*------*****","DESCRIPTION":"Non-Military Group or Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6","ALPHAHIERARCHY":"STBOPS.GRPORG","PATH":"Stability Operations"},{"SYMBOLID":"O*G*B-----*****","DESCRIPTION":"Non-Governmental Organizations (NGO)","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.2","ALPHAHIERARCHY":"STBOPS.GRPORG.NGO","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*C-----*****","DESCRIPTION":"Terrorist Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.3","ALPHAHIERARCHY":"STBOPS.GRPORG.TERRST","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*D-----*****","DESCRIPTION":"Religious Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.4","ALPHAHIERARCHY":"STBOPS.GRPORG.RELIGS","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*E-----*****","DESCRIPTION":"Foreign Fighter","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.5","ALPHAHIERARCHY":"STBOPS.GRPORG.FNFGHT","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*F-----*****","DESCRIPTION":"Gang","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.6","ALPHAHIERARCHY":"STBOPS.GRPORG.GANG","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*R*------*****","DESCRIPTION":"Rape","DRAWCATEGORY":"8","HIERARCHY":"5.X.7","ALPHAHIERARCHY":"STBOPS.RAPE","PATH":"Stability Operations/RAPE"},{"SYMBOLID":"O*R*A-----*****","DESCRIPTION":"Attempted Rape","DRAWCATEGORY":"8","HIERARCHY":"5.X.7.1","ALPHAHIERARCHY":"STBOPS.RAPE.ATEMPT","PATH":"Stability Operations/Rape"},{"SYMBOLID":"O*E*------*****","DESCRIPTION":"Events SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10","PATH":"Stability Operations"},{"SYMBOLID":"O*E*A-----*****","DESCRIPTION":"Elections SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.1","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*B-----*****","DESCRIPTION":"Speech SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.2","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*C-----*****","DESCRIPTION":"Sermon SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.3","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*D-----*****","DESCRIPTION":"Meeting SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.4","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*E-----*****","DESCRIPTION":"Demonstration(Events) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.5","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*F-----*****","DESCRIPTION":"Riot SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.6","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*G-----*****","DESCRIPTION":"Gang Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.7","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*H-----*****","DESCRIPTION":"Jail Break/Escape Custody SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.8","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*I-----*****","DESCRIPTION":"Rock Throwing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.9","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*J-----*****","DESCRIPTION":"Illegal Selling/Purchasing/Distributing/Black Market SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.10","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*K-----*****","DESCRIPTION":"Surveillance SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.11","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*L-----*****","DESCRIPTION":"Lights SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.12","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*M-----*****","DESCRIPTION":"Border Crossing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.13","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*N-----*****","DESCRIPTION":"Border Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.14","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*O-----*****","DESCRIPTION":"Smuggling SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.15","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*P-----*****","DESCRIPTION":"Exfiltration SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.16","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Q-----*****","DESCRIPTION":"Infiltration SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.17","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*R-----*****","DESCRIPTION":"Auto Theft SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.18","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*S-----*****","DESCRIPTION":"Auto Accident SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.19","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*T-----*****","DESCRIPTION":"Looting SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.20","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*U-----*****","DESCRIPTION":"Theft SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.21","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*V-----*****","DESCRIPTION":"Robbery SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.22","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*X-----*****","DESCRIPTION":"Shooting (Non Deadly) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.24","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*W-----*****","DESCRIPTION":"Home Eviction SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.23","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Y-----*****","DESCRIPTION":"Raid SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.25","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Z-----*****","DESCRIPTION":"Sabotage SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.26","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AA----*****","DESCRIPTION":"Warrant Served SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.27","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AB----*****","DESCRIPTION":"Rape SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.28","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AC----*****","DESCRIPTION":"Attempted Rape SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.29","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AD----*****","DESCRIPTION":"Attack(Events) SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.30","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*ADA---*****","DESCRIPTION":"Attack on NGO SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.1","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADB---*****","DESCRIPTION":"Terrorist Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.2","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADC---*****","DESCRIPTION":"Grenade Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.3","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADD---*****","DESCRIPTION":"Rocket Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.4","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*AE----*****","DESCRIPTION":"Explosions SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.31","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AEA---*****","DESCRIPTION":"Explosion (general) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.1","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEB---*****","DESCRIPTION":"Explosion, Mine SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.2","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEC---*****","DESCRIPTION":"Explosion, Grenade SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.3","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AED---*****","DESCRIPTION":"Explosion, Bomb SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.4","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEE---*****","DESCRIPTION":"Explosion, Mortar Fire SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.5","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEF---*****","DESCRIPTION":"Explosion, Incendiary SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.6","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEG---*****","DESCRIPTION":"Explosion, Rocket SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.7","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEH---*****","DESCRIPTION":"Explosion, Improvised Explosive Device (IED) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.8","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEI---*****","DESCRIPTION":"Explosion, Car Bomb SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.9","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEJ---*****","DESCRIPTION":"Suicide Bombing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.10","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AF----*****","DESCRIPTION":"Fighting/Contact SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.32","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AFA---*****","DESCRIPTION":"Fighting (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.1","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AFB---*****","DESCRIPTION":"Coalition vs. Enemy SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.2","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AFC---*****","DESCRIPTION":"Coalition vs. Coalition SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.3","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AG----*****","DESCRIPTION":"Drug Possession SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.33","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AH----*****","DESCRIPTION":"Drug Trafficking SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.34","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AI----*****","DESCRIPTION":"Suspicious Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.35","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AJ----*****","DESCRIPTION":"Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.36","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AK----*****","DESCRIPTION":"Threat SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.37","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AL----*****","DESCRIPTION":"Crater SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.38","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AM----*****","DESCRIPTION":"Pothole SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.39","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AN----*****","DESCRIPTION":"Escalation of Force SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.40","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AO----*****","DESCRIPTION":"Submunitions SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.41","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AP----*****","DESCRIPTION":"Confiscation SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.42","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AQ----*****","DESCRIPTION":"Counter Insurgency SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.43","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AR----*****","DESCRIPTION":"Counter Terrorism SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.44","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AS----*****","DESCRIPTION":"Humanitarian Assistance SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.45","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AT----*****","DESCRIPTION":"Tests of Security SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.46","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AU----*****","DESCRIPTION":"AWOL SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.47","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AV----*****","DESCRIPTION":"Curfew SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.48","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AW----*****","DESCRIPTION":"DUI SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.49","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AX----*****","DESCRIPTION":"Prostitution SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.50","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*Y*------*****","DESCRIPTION":"Organization/Groups SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.11","PATH":"Stability Operations"},{"SYMBOLID":"O*Y*A-----*****","DESCRIPTION":"Organization (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.1","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*B-----*****","DESCRIPTION":"NGO Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.2","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*C-----*****","DESCRIPTION":"Displaced Persons, Refugees SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.3","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*D-----*****","DESCRIPTION":"Terrorist Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.4","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*E-----*****","DESCRIPTION":"Religious Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.5","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*F-----*****","DESCRIPTION":"Group Tribe Cell SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.6","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*G-----*****","DESCRIPTION":"Foreign Fighters SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.7","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*R-----*****","DESCRIPTION":"Red Cross SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.8","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SP----*****","DESCRIPTION":"State Police SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.9","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*LP----*****","DESCRIPTION":"Local Police SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.10","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SH----*****","DESCRIPTION":"Shelter SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.11","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*FM----*****","DESCRIPTION":"FEMA SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.12","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SA----*****","DESCRIPTION":"Staging Area SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.13","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*EP----*****","DESCRIPTION":"Evacuation Point SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.14","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*PD----*****","DESCRIPTION":"Person in Distress SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.15","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*S*------*****","DESCRIPTION":"Structures SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.13","PATH":"Stability Operations"},{"SYMBOLID":"O*S*A-----*****","DESCRIPTION":"Compound/Post/Fort SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.1","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*B-----*****","DESCRIPTION":"House/Residence SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.2","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*C-----*****","DESCRIPTION":"Safe House(Structures) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.3","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*D-----*****","DESCRIPTION":"Church SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.4","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*E-----*****","DESCRIPTION":"Mosque SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.5","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*F-----*****","DESCRIPTION":"Synagogue SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.6","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*G-----*****","DESCRIPTION":"Warehouse/Storage Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.7","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*H-----*****","DESCRIPTION":"Bunker/Underground Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.8","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*I-----*****","DESCRIPTION":"Tents SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.9","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*J-----*****","DESCRIPTION":"Cave SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.10","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*K-----*****","DESCRIPTION":"Camps SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.13.11","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*KA----*****","DESCRIPTION":"Camp (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.1","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*KB----*****","DESCRIPTION":"Displaced Persons/Refugees Camp SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.2","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*KC----*****","DESCRIPTION":"Training Camp SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.3","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*L-----*****","DESCRIPTION":"Prison/Detention Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.12","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*M-----*****","DESCRIPTION":"Police Station SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.13","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*N-----*****","DESCRIPTION":"Palace/Presidential Residence SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.14","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*Q*------*****","DESCRIPTION":"Equipment/Weapons SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.14","PATH":"Stability Operations"},{"SYMBOLID":"O*Q*A-----*****","DESCRIPTION":"Weapons Found SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.1","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*B-----*****","DESCRIPTION":"Weapons Cache SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.2","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*C-----*****","DESCRIPTION":"Weapons Confiscated SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.3","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*D-----*****","DESCRIPTION":"Weapons Sale SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.4","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*E-----*****","DESCRIPTION":"Weapons Market SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.5","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*F-----*****","DESCRIPTION":"Chem/Bio Weapons Cache SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.6","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*G-----*****","DESCRIPTION":"Improvised Explosive Device (IED) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.7","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*H-----*****","DESCRIPTION":"Unexploded Ordnance (UXO) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.8","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*I-----*****","DESCRIPTION":"Horses SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.9","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*J-----*****","DESCRIPTION":"Camels SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.10","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*K-----*****","DESCRIPTION":"Donkeys SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.11","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"E*-*------*****","DESCRIPTION":"Emergency Management Symbols","DRAWCATEGORY":"0","HIERARCHY":"6.X","ALPHAHIERARCHY":"EMS"},{"SYMBOLID":"E*I*------*****","DESCRIPTION":"Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1","ALPHAHIERARCHY":"EMS.INCDNT","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*I*A-----*****","DESCRIPTION":"Civil Disturbance Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.1","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Civil Demonstration","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.1.1","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.CVRIOT","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Civil Displaced Population","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.1.2","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.CVRIOT","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"E*I*AC----*****","DESCRIPTION":"Civil Rioting","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.1.3","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.CVRIOT","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"E*I*B-----*****","DESCRIPTION":"Criminal Activity Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*BC----*****","DESCRIPTION":"Explosion (Bomb)","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.3","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.EXPLN","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"E*I*BD----*****","DESCRIPTION":"Looting","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.4","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.LOOT","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"E*I*C-----*****","DESCRIPTION":"Fire Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.3","ALPHAHIERARCHY":"EMS.INCDNT.FIRE","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*D-----*****","DESCRIPTION":"Hazardous Materiel Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.4","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*E-----*****","DESCRIPTION":"Air Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.5","ALPHAHIERARCHY":"EMS.INCDNT.AIR","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*F-----*****","DESCRIPTION":"Marine Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.6","ALPHAHIERARCHY":"EMS.INCDNT.MRN","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*G-----*****","DESCRIPTION":"Rail Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.7","ALPHAHIERARCHY":"EMS.INCDNT.RAIL","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*H-----*****","DESCRIPTION":"Vehicle Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.8","ALPHAHIERARCHY":"EMS.INCDNT.VEH","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*HA----*****","DESCRIPTION":"Vehicle Accident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.8.1","ALPHAHIERARCHY":"EMS.INCDNT.VEH.ACDNT","PATH":"EEmergency Management Symbols/Incident/Vehicle Incident"},{"SYMBOLID":"E*N*------*****","DESCRIPTION":"Natural Events","DRAWCATEGORY":"0","HIERARCHY":"6.X.2","ALPHAHIERARCHY":"EMS.NATEVT","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*O*------*****","DESCRIPTION":"Operations","DRAWCATEGORY":"0","HIERARCHY":"6.X.3","ALPHAHIERARCHY":"EMS.OPN","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*O*D-----*****","DESCRIPTION":"Law Enforcement Operation","DRAWCATEGORY":"0","HIERARCHY":"6.X.3.4","ALPHAHIERARCHY":"EMS.OPN.LAWENF","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*DJ----*****","DESCRIPTION":"Police","DRAWCATEGORY":"0","HIERARCHY":"6.X.3.4.7","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DJC---H****","DESCRIPTION":"Police Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.7.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL.POLINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Police"},{"SYMBOLID":"E*O*DK----H****","DESCRIPTION":"Prison","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.8","ALPHAHIERARCHY":"EMS.OPN.LAWENF.PRSN","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*F*------H****","DESCRIPTION":"Infrastructure","DRAWCATEGORY":"0","HIERARCHY":"6.X.4","ALPHAHIERARCHY":"EMS.INFSTR","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*F*I-----H****","DESCRIPTION":"Public Venues Infrastructure","DRAWCATEGORY":"0","HIERARCHY":"6.X.4.8","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN","PATH":"Emergency Management Symbols/BLANK"},{"SYMBOLID":"E*F*ID----H****","DESCRIPTION":"Religious Institution","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.8.4","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN.RELIG","PATH":"Emergency Management Symbols/Infrastructure/Public Venues Infrastructure"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SinglePointMappingsC={"SINGLEPOINTMAPPINGS":{"SYMBOL":[{"SYMBOLID":"NBCNUCFILL****X","MAPPINGP":"1900","MAPPINGA":"1900","DESCRIPTION":"Nuclear Symbol Fill","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"NBCBIOFILL****X","MAPPINGP":"1901","MAPPINGA":"1901","DESCRIPTION":"Bio Symbol Fill","WIDTH":"28","HEIGHT":"39"},{"SYMBOLID":"NBCCMLFILL****X","MAPPINGP":"1902","MAPPINGA":"1902","DESCRIPTION":"Chem Symbol Fill","WIDTH":"22","HEIGHT":"39"},{"SYMBOLID":"SONOBYFILL****X","MAPPINGP":"1904","MAPPINGA":"1904","DESCRIPTION":"Sonobuoy Fill","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"CPOINTFILL****X","MAPPINGP":"1903","MAPPINGA":"1903","DESCRIPTION":"Small circle point fill","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"CHKPNTFILL****X","MAPPINGP":"1905","MAPPINGA":"1905","DESCRIPTION":"Action Points Fill","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"REFPNTFILL****X","MAPPINGP":"1908","MAPPINGA":"1908","DESCRIPTION":"Reference Points Fill","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"DECPNTFILL****X","MAPPINGP":"1909","MAPPINGA":"1909","DESCRIPTION":"Decision Point Fill","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*F*PTS---****X","MAPPINGP":"2162","MAPPINGA":"3162","DESCRIPTION":"Point Single Target","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*T*G-----****X","MAPPINGP":"1999","MAPPINGA":"1999","DESCRIPTION":"Suppress","WIDTH":"62","HEIGHT":"35"},{"SYMBOLID":"G*G*GPPN--****X","MAPPINGP":"2196","MAPPINGA":"3196","DESCRIPTION":"Entry Control Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PTN---****X","MAPPINGP":"2163","MAPPINGA":"3163","DESCRIPTION":"Nuclear Target","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*F*PTC---****X","MAPPINGP":"34","MAPPINGA":"34","DESCRIPTION":"Circular Target","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"G*F*PTR---****X","MAPPINGP":"35","MAPPINGA":"35","DESCRIPTION":"Rectangular Target","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"G*F*PCF---****X","MAPPINGP":"2164","MAPPINGA":"3164","DESCRIPTION":"Fire Support Station","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*F*PCS---****X","MAPPINGP":"2165","MAPPINGA":"3165","DESCRIPTION":"Survey Control Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCB---****X","MAPPINGP":"2166","MAPPINGA":"3166","DESCRIPTION":"Firing Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCR---****X","MAPPINGP":"2167","MAPPINGA":"3167","DESCRIPTION":"Reload Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCH---****X","MAPPINGP":"2168","MAPPINGA":"3168","DESCRIPTION":"Hide Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*F*PCL---****X","MAPPINGP":"2169","MAPPINGA":"3169","DESCRIPTION":"Launch Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PX----****X","MAPPINGP":"2170","MAPPINGA":"3170","DESCRIPTION":"Ambulance Exchange Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PC----****X","MAPPINGP":"2171","MAPPINGA":"3171","DESCRIPTION":"Cannibalization Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PY----****X","MAPPINGP":"2172","MAPPINGA":"3172","DESCRIPTION":"Casualty Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PT----****X","MAPPINGP":"2173","MAPPINGA":"3173","DESCRIPTION":"Civilian Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PD----****X","MAPPINGP":"2174","MAPPINGA":"3174","DESCRIPTION":"Detainee Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PE----****X","MAPPINGP":"2175","MAPPINGA":"3175","DESCRIPTION":"Enemy Prisoner of War (EPW) Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PL----****X","MAPPINGP":"2176","MAPPINGA":"3176","DESCRIPTION":"Logistics Release Point (LRP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PM----****X","MAPPINGP":"2177","MAPPINGA":"3177","DESCRIPTION":"Maintenance Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PR----****X","MAPPINGP":"2178","MAPPINGA":"3178","DESCRIPTION":"Refuel and Resupply Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PU----****X","MAPPINGP":"2179","MAPPINGA":"3179","DESCRIPTION":"Refuel on the Move (ROM) Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PO----****X","MAPPINGP":"2180","MAPPINGA":"3180","DESCRIPTION":"Traffic Control Post (TCP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PI----****X","MAPPINGP":"2181","MAPPINGA":"3181","DESCRIPTION":"Trailer Transfer Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PN----****X","MAPPINGP":"2182","MAPPINGA":"3182","DESCRIPTION":"Unit Maintenance Collection Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSZ---****X","MAPPINGP":"2183","MAPPINGA":"3183","DESCRIPTION":"Supply Points_General","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSA---****X","MAPPINGP":"2184","MAPPINGA":"3184","DESCRIPTION":"Supply Points_Class I","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSB---****X","MAPPINGP":"2185","MAPPINGA":"3185","DESCRIPTION":"Supply Points_Class II","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSC---****X","MAPPINGP":"2186","MAPPINGA":"3186","DESCRIPTION":"Supply Points_Class III","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSD---****X","MAPPINGP":"2187","MAPPINGA":"3187","DESCRIPTION":"Supply Points_Class IV","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSE---****X","MAPPINGP":"2188","MAPPINGA":"3188","DESCRIPTION":"Supply Points_Class V","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSF---****X","MAPPINGP":"2189","MAPPINGA":"3189","DESCRIPTION":"Supply Points_Class VI","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSG---****X","MAPPINGP":"2190","MAPPINGA":"3190","DESCRIPTION":"Supply Points_Class VII","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSH---****X","MAPPINGP":"2191","MAPPINGA":"3191","DESCRIPTION":"Supply Points_Class VIII","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSI---****X","MAPPINGP":"2192","MAPPINGA":"3192","DESCRIPTION":"Supply Points_Class IX","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PSJ---****X","MAPPINGP":"2193","MAPPINGA":"3191","DESCRIPTION":"Supply Points_Class X","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PAS---****X","MAPPINGP":"2194","MAPPINGA":"3194","DESCRIPTION":"Ammunition Supply Point (ASP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PAT---****X","MAPPINGP":"2195","MAPPINGA":"3195","DESCRIPTION":"Ammunition Transfer Point (ATP)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*S*PP----****X","MAPPINGP":"2214","MAPPINGA":"3214","DESCRIPTION":"Medevac Pick-Up Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*DPO---****X","MAPPINGP":"2122","MAPPINGA":"3122","DESCRIPTION":"Observation Post/Outpost","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*G*GPPK--****X","MAPPINGP":"2081","MAPPINGA":"3081","DESCRIPTION":"Checkpoint","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPC--****X","MAPPINGP":"2082","MAPPINGA":"3082","DESCRIPTION":"Contact Point","WIDTH":"22","HEIGHT":"31"},{"SYMBOLID":"G*G*GPPO--****X","MAPPINGP":"2083","MAPPINGA":"3083","DESCRIPTION":"Coordination Point","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPL--****X","MAPPINGP":"2085","MAPPINGA":"3085","DESCRIPTION":"Link-Up Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*OAOF--****X","MAPPINGP":"2129","MAPPINGA":"2129","DESCRIPTION":"Fixed and Prefabricated Obstacles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*OAOM--****X","MAPPINGP":"2130","MAPPINGA":"3130","DESCRIPTION":"Moveable Obstacles","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*M*OAOP--****X","MAPPINGP":"2131","MAPPINGA":"3131","DESCRIPTION":"Moveable and Prefabricated Obstacles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APP---****X","MAPPINGP":"2116","MAPPINGA":"3116","DESCRIPTION":"Air Control Point (ACP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APC---****X","MAPPINGP":"2117","MAPPINGA":"3117","DESCRIPTION":"Communications Checkpoint (CCP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPP--****X","MAPPINGP":"2086","MAPPINGA":"3086","DESCRIPTION":"Passage Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPE--****X","MAPPINGP":"2088","MAPPINGA":"3088","DESCRIPTION":"Release Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPS--****X","MAPPINGP":"2089","MAPPINGA":"3089","DESCRIPTION":"Start Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*OPP---****X","MAPPINGP":"2128","MAPPINGA":"3128","DESCRIPTION":"Point of Departure","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*APU---****X","MAPPINGP":"2118","MAPPINGA":"3118","DESCRIPTION":"Pull-Up Point (PUP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*APD---****X","MAPPINGP":"2119","MAPPINGA":"3119","DESCRIPTION":"Downed Aircrew Pickup-Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPP---****X","MAPPINGP":"2080","MAPPINGA":"3080","DESCRIPTION":"Action Points (General)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPD--****X","MAPPINGP":"2084","MAPPINGA":"3084","DESCRIPTION":"Decision Point","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*G*GPPR--****X","MAPPINGP":"2087","MAPPINGA":"3087","DESCRIPTION":"Rally Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*G*GPPW--****X","MAPPINGP":"2090","MAPPINGA":"3090","DESCRIPTION":"Waypoint","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*NEB---****X","MAPPINGP":"2149","MAPPINGA":"3149","DESCRIPTION":"Biological","WIDTH":"28","HEIGHT":"39"},{"SYMBOLID":"G*M*NEC---****X","MAPPINGP":"2150","MAPPINGA":"3150","DESCRIPTION":"Chemical","WIDTH":"22","HEIGHT":"39"},{"SYMBOLID":"G*M*NDP---****X","MAPPINGP":"2151","MAPPINGA":"3151","DESCRIPTION":"DECON Site/Point (Unspecified)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDT---****X","MAPPINGP":"2153","MAPPINGA":"3153","DESCRIPTION":"DECON Site/Point (Troops)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDE---****X","MAPPINGP":"2154","MAPPINGA":"3154","DESCRIPTION":"DECON Site/Point (Equipment)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDB---****X","MAPPINGP":"2155","MAPPINGA":"3155","DESCRIPTION":"DECON Site/Point (Equipment and Troops)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDD---****X","MAPPINGP":"2157","MAPPINGA":"3157","DESCRIPTION":"DECON Site/Point (Thorough Decontamination)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDA---****X","MAPPINGP":"2152","MAPPINGA":"3152","DESCRIPTION":"Alternate DECON Site/Point (Unspecified)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*NDO---****X","MAPPINGP":"2156","MAPPINGA":"3156","DESCRIPTION":"DECON Site/Point (Operational Decontamination)","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*T*D-----****X","MAPPINGP":"2000","MAPPINGA":"2000","DESCRIPTION":"Destroy","WIDTH":"62","HEIGHT":"36"},{"SYMBOLID":"G*T*I-----****X","MAPPINGP":"2001","MAPPINGA":"3001","DESCRIPTION":"Interdict","WIDTH":"60","HEIGHT":"38"},{"SYMBOLID":"G*T*N-----****X","MAPPINGP":"2002","MAPPINGA":"3002","DESCRIPTION":"Neutralize","WIDTH":"62","HEIGHT":"36"},{"SYMBOLID":"G*G*PN----****X","MAPPINGP":"2120","MAPPINGA":"3120","DESCRIPTION":"Dummy Minefield - Static","WIDTH":"48","HEIGHT":"41"},{"SYMBOLID":"G*G*DPT---****X","MAPPINGP":"2121","MAPPINGA":"3121","DESCRIPTION":"Target Reference","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*DPOC--****X","MAPPINGP":"2123","MAPPINGA":"3123","DESCRIPTION":"Combat Outpost","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"G*G*DPOR--****X","MAPPINGP":"2124","MAPPINGA":"3124","DESCRIPTION":"Observation Post Occupied by Dismounted Scouts or Reconnaissance","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPOF--****X","MAPPINGP":"2125","MAPPINGA":"3125","DESCRIPTION":"Forward Observation Position","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPOS--****X","MAPPINGP":"2126","MAPPINGA":"3126","DESCRIPTION":"Sensor Outpost/Listening Post (OP/LP)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*G*DPON--****X","MAPPINGP":"2127","MAPPINGA":"3127","DESCRIPTION":"NBC Observation Post (Dismounted)","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"G*M*OB----****X","MAPPINGP":"2132","MAPPINGA":"3132","DESCRIPTION":"Booby Trap","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"G*M*OMU---****X","MAPPINGP":"2133","MAPPINGA":"2133","DESCRIPTION":"Unspecified Mine","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*M*OMT---****X","MAPPINGP":"2134","MAPPINGA":"2134","DESCRIPTION":"Antitank Mine (AT)","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*M*OMD---****X","MAPPINGP":"2135","MAPPINGA":"2135","DESCRIPTION":"Antitank Mine with Antihandling Device","WIDTH":"24","HEIGHT":"44"},{"SYMBOLID":"G*M*OME---****X","MAPPINGP":"2136","MAPPINGA":"2136","DESCRIPTION":"Antitank Mine (Directional)","WIDTH":"24","HEIGHT":"53"},{"SYMBOLID":"G*M*OMP---****X","MAPPINGP":"2137","MAPPINGA":"2137","DESCRIPTION":"Antipersonnel (AP) Mines","WIDTH":"34","HEIGHT":"30"},{"SYMBOLID":"G*M*OMW---****X","MAPPINGP":"2138","MAPPINGA":"2138","DESCRIPTION":"Wide Area Mines","WIDTH":"40","HEIGHT":"33"},{"SYMBOLID":"G*M*OFS---****X","MAPPINGP":"2139","MAPPINGA":"3139","DESCRIPTION":"Static Depiction","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"G*M*OHTL--****X","MAPPINGP":"2140","MAPPINGA":"2140","DESCRIPTION":"Aviation Tower Low","WIDTH":"26","HEIGHT":"33"},{"SYMBOLID":"G*M*OHTH--****X","MAPPINGP":"2141","MAPPINGA":"2141","DESCRIPTION":"Aviation Tower High","WIDTH":"26","HEIGHT":"32"},{"SYMBOLID":"G*M*BCP---****X","MAPPINGP":"2142","MAPPINGA":"3142","DESCRIPTION":"Engineer Regulating Point","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*M*SE----****X","MAPPINGP":"2143","MAPPINGA":"2143","DESCRIPTION":"Small Trench or Fortification","WIDTH":"31","HEIGHT":"30"},{"SYMBOLID":"G*M*SF----****X","MAPPINGP":"2144","MAPPINGA":"3144","DESCRIPTION":"Fort","WIDTH":"44","HEIGHT":"48"},{"SYMBOLID":"G*M*SS----****X","MAPPINGP":"2145","MAPPINGA":"2145","DESCRIPTION":"Surface Shelter","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"G*M*SU----****X","MAPPINGP":"2146","MAPPINGA":"2146","DESCRIPTION":"Underground Shelter","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"G*M*NZ----****X","MAPPINGP":"2147","MAPPINGA":"3147","DESCRIPTION":"Nuclear Detonations Ground Zero","WIDTH":"31","HEIGHT":"39"},{"SYMBOLID":"G*M*NF----****X","MAPPINGP":"2148","MAPPINGA":"3148","DESCRIPTION":"Fallout Producing","WIDTH":"30","HEIGHT":"39"},{"SYMBOLID":"G*G*GPWI--****X","MAPPINGP":"2038","MAPPINGA":"2038","DESCRIPTION":"Impact Point","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-PL----P----","MAPPINGP":"5000","DESCRIPTION":"Low Pressure Center","WIDTH":"24","HEIGHT":"33"},{"SYMBOLID":"WAS-PH----P----","MAPPINGP":"5003","DESCRIPTION":"High Pressure Center","WIDTH":"26","HEIGHT":"34"},{"SYMBOLID":"WAS-TL----P----","MAPPINGP":"5006","DESCRIPTION":"Light Turbulence","WIDTH":"38","HEIGHT":"22"},{"SYMBOLID":"WAS-TM----P----","MAPPINGP":"5007","DESCRIPTION":"Moderate Turbulence","WIDTH":"46","HEIGHT":"22"},{"SYMBOLID":"WAS-TS----P----","MAPPINGP":"5008","DESCRIPTION":"Severe Turbulence","WIDTH":"46","HEIGHT":"28"},{"SYMBOLID":"WAS-TE----P----","MAPPINGP":"5009","DESCRIPTION":"Extreme Turbulence","WIDTH":"46","HEIGHT":"34"},{"SYMBOLID":"WAS-ICL---P----","MAPPINGP":"5011","DESCRIPTION":"Light Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-ICM---P----","MAPPINGP":"5012","DESCRIPTION":"Moderate Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-ICS---P----","MAPPINGP":"5013","DESCRIPTION":"Severe Clear Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRL---P----","MAPPINGP":"5014","DESCRIPTION":"Light Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRM---P----","MAPPINGP":"5015","DESCRIPTION":"Moderate Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IRS---P----","MAPPINGP":"5016","DESCRIPTION":"Severe Rime Icing","WIDTH":"48","HEIGHT":"30"},{"SYMBOLID":"WAS-IML---P----","MAPPINGP":"5017","DESCRIPTION":"Light Mixed Icing","WIDTH":"48","HEIGHT":"54"},{"SYMBOLID":"WAS-IMM---P----","MAPPINGP":"5018","DESCRIPTION":"Moderate Mixed Icing","WIDTH":"60","HEIGHT":"35"},{"SYMBOLID":"WAS-IMS---P----","MAPPINGP":"5019","DESCRIPTION":"Severe Mixed Icing","WIDTH":"60","HEIGHT":"34"},{"SYMBOLID":"WA--W----------","MAPPINGP":"10136","MAPPINGA":"10136","DESCRIPTION":"Wind Barb","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WC----P----","MAPPINGP":"5020","DESCRIPTION":"Calm Winds","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WA--FI---------","MAPPINGP":"10138","MAPPINGA":"10138","DESCRIPTION":"Instrument Ceiling","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-CCCSCSP----","MAPPINGP":"5021","DESCRIPTION":"Clear Sky (SKC)","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSBCP----","MAPPINGP":"5024","DESCRIPTION":"Broken Coverage (BKN)","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WAS-WST-FCP----","MAPPINGP":"5072","DESCRIPTION":"Funnel Cloud (FC) Tornado / Waterspout","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-GSI---P----","MAPPINGP":"5107","DESCRIPTION":"Predominately Ice Covered","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"WAS-WSDD--P----","MAPPINGP":"5087","DESCRIPTION":"Dust Devil","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSFU--P----","MAPPINGP":"5083","DESCRIPTION":"Smoke","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSDB--P----","MAPPINGP":"5088","DESCRIPTION":"Blowing Dust or Sand","WIDTH":"28","HEIGHT":"48"},{"SYMBOLID":"WA-DBAFG----A--","MAPPINGP":"170","MAPPINGA":"170","DESCRIPTION":"Fog","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"G*O*SS----****X","MAPPINGP":"2210","MAPPINGA":"2210","DESCRIPTION":"Sea Anomaly [Wake, Current, Knuckle]","WIDTH":"39","HEIGHT":"31"},{"SYMBOLID":"G*O*SM----****X","MAPPINGP":"2209","MAPPINGA":"2209","DESCRIPTION":"Marine Life","WIDTH":"35","HEIGHT":"12"},{"SYMBOLID":"G*O*SBW---****X","MAPPINGP":"2207","MAPPINGA":"2207","DESCRIPTION":"Wreck, Non-Dangerous","WIDTH":"44","HEIGHT":"24"},{"SYMBOLID":"G*O*SBX---****X","MAPPINGP":"2208","MAPPINGA":"2208","DESCRIPTION":"Wreck, Dangerous","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"G*O*SBN---****X","MAPPINGP":"2206","MAPPINGA":"2206","DESCRIPTION":"Seabed Rock/Stone, Obstacle, Other","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*SBM---****X","MAPPINGP":"2205","MAPPINGA":"2205","DESCRIPTION":"Installation/Manmade","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*SB----****X","MAPPINGP":"2204","MAPPINGA":"2204","DESCRIPTION":"Bottom Return/Nombo","WIDTH":"30","HEIGHT":"22"},{"SYMBOLID":"G*O*HM----****X","MAPPINGP":"2201","MAPPINGA":"2201","DESCRIPTION":"Sea Mine-Like","WIDTH":"22","HEIGHT":"22"},{"SYMBOLID":"G*O*HO----****X","MAPPINGP":"2203","MAPPINGA":"2203","DESCRIPTION":"Oil Rig","WIDTH":"30","HEIGHT":"18"},{"SYMBOLID":"G*O*HI----****X","MAPPINGP":"2202","MAPPINGA":"2202","DESCRIPTION":"Iceberg","WIDTH":"36","HEIGHT":"27"},{"SYMBOLID":"G*O*FO----****X","MAPPINGP":"2213","MAPPINGA":"2213","DESCRIPTION":"Electro-Optical","WIDTH":"30","HEIGHT":"29"},{"SYMBOLID":"G*O*FE----****X","MAPPINGP":"2212","MAPPINGA":"2212","DESCRIPTION":"Electro-Magnetic","WIDTH":"31","HEIGHT":"29"},{"SYMBOLID":"G*O*FA----****X","MAPPINGP":"2211","MAPPINGA":"2211","DESCRIPTION":"Acoustic","WIDTH":"28","HEIGHT":"29"},{"SYMBOLID":"G*O*EP----****X","MAPPINGP":"2199","MAPPINGA":"2199","DESCRIPTION":"Person In Water","WIDTH":"32","HEIGHT":"20"},{"SYMBOLID":"G*O*ED----****X","MAPPINGP":"2198","MAPPINGA":"2198","DESCRIPTION":"Ditched Aircraft","WIDTH":"44","HEIGHT":"35"},{"SYMBOLID":"G*O*ES----****X","MAPPINGP":"2197","MAPPINGA":"3197","DESCRIPTION":"Emergency Distress Call","WIDTH":"24","HEIGHT":"45"},{"SYMBOLID":"G*O*EV----****X","MAPPINGP":"2200","MAPPINGA":"2200","DESCRIPTION":"Distressed Vessel","WIDTH":"52","HEIGHT":"37"},{"SYMBOLID":"G*G*GPWP--****X","MAPPINGP":"2039","MAPPINGA":"2039","DESCRIPTION":"Predicted Impact Point","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"G*G*GPWM--****X","MAPPINGP":"2037","MAPPINGA":"3037","DESCRIPTION":"MSL Detect Point","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"G*G*GPWG--****X","MAPPINGP":"2036","MAPPINGA":"2036","DESCRIPTION":"Ground Zero","WIDTH":"34","HEIGHT":"43"},{"SYMBOLID":"G*G*GPWE--****X","MAPPINGP":"2035","MAPPINGA":"3035","DESCRIPTION":"Entry Point","WIDTH":"62","HEIGHT":"34"},{"SYMBOLID":"G*G*GPWD--****X","MAPPINGP":"2034","MAPPINGA":"3034","DESCRIPTION":"Drop Point","WIDTH":"44","HEIGHT":"38"},{"SYMBOLID":"G*G*GPWA--****X","MAPPINGP":"2033","MAPPINGA":"3033","DESCRIPTION":"Aim Point","WIDTH":"47","HEIGHT":"47"},{"SYMBOLID":"G*G*GPUUS-****X","MAPPINGP":"2006","MAPPINGA":"2006","DESCRIPTION":"Sinker","WIDTH":"30","HEIGHT":"31"},{"SYMBOLID":"G*G*GPUUL-****X","MAPPINGP":"2005","MAPPINGA":"2005","DESCRIPTION":"Lost Contact","WIDTH":"24","HEIGHT":"30"},{"SYMBOLID":"G*G*GPUUD-****X","MAPPINGP":"2003","MAPPINGA":"2003","DESCRIPTION":"Datum","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"G*G*GPUUB-****X","MAPPINGP":"2004","MAPPINGA":"2004","DESCRIPTION":"Brief Contact","WIDTH":"24","HEIGHT":"30"},{"SYMBOLID":"G*G*GPUYV-****X","MAPPINGP":"2015","MAPPINGA":"3015","DESCRIPTION":"Vertical Line Array DIFAR (VLAD)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYR-****X","MAPPINGP":"2017","MAPPINGA":"3017","DESCRIPTION":"Range Only [RO]","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYP-****X","MAPPINGP":"2008","MAPPINGA":"3008","DESCRIPTION":"Pattern Center","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYL-****X","MAPPINGP":"2010","MAPPINGA":"3010","DESCRIPTION":"Low Frequency Analyzing and Recording (LOFAR)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYC-****X","MAPPINGP":"2011","MAPPINGA":"3011","DESCRIPTION":"Command Active Sonobouy System (CASS)","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYK-****X","MAPPINGP":"2018","MAPPINGA":"3018","DESCRIPTION":"Kingpin","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYX-****X","MAPPINGP":"2019","MAPPINGA":"3019","DESCRIPTION":"Expired","WIDTH":"50","HEIGHT":"51"},{"SYMBOLID":"G*G*GPUYD-****X","MAPPINGP":"2009","MAPPINGA":"3009","DESCRIPTION":"Directional Frequency Analyzing and Recording [DIFAR]","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYS-****X","MAPPINGP":"2012","MAPPINGA":"3012","DESCRIPTION":"Directional Command Active Sonobuoy System [DICASS]","WIDTH":"25","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYB-****X","MAPPINGP":"2013","MAPPINGA":"3013","DESCRIPTION":"Bathythermograph Transmitting [BT]","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYT-****X","MAPPINGP":"2016","MAPPINGA":"3016","DESCRIPTION":"ATAC","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUYA-****X","MAPPINGP":"2014","MAPPINGA":"3014","DESCRIPTION":"ANM","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUSC-****X","MAPPINGP":"2023","MAPPINGA":"2023","DESCRIPTION":"Search Center","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*GPUSA-****X","MAPPINGP":"2021","MAPPINGA":"2021","DESCRIPTION":"Search Area","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPUSD-****X","MAPPINGP":"2022","MAPPINGA":"2022","DESCRIPTION":"Dip Position","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPOW--****X","MAPPINGP":"2049","MAPPINGA":"3049","DESCRIPTION":"Waypoint","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPOZ--****X","MAPPINGP":"2047","MAPPINGA":"3047","DESCRIPTION":"Rendezvous","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"G*G*GPOR--****X","MAPPINGP":"2051","MAPPINGA":"3051","DESCRIPTION":"Point R","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPOP--****X","MAPPINGP":"2050","MAPPINGA":"3050","DESCRIPTION":"PIM","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"G*G*GPOD--****X","MAPPINGP":"2048","MAPPINGA":"3048","DESCRIPTION":"Diversions","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"G*G*GPRS--****X","MAPPINGP":"2025","MAPPINGA":"3025","DESCRIPTION":"Special Point","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRI--****X","MAPPINGP":"2032","MAPPINGA":"2032","DESCRIPTION":"Point of Interest","WIDTH":"24","HEIGHT":"43"},{"SYMBOLID":"G*G*GPR---****X","MAPPINGP":"2024","MAPPINGA":"2024","DESCRIPTION":"Reference Point","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRN--****X","MAPPINGP":"2026","MAPPINGA":"3026","DESCRIPTION":"Nav Reference","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRD--****X","MAPPINGP":"2027","MAPPINGA":"3027","DESCRIPTION":"DLRP","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRP--****X","MAPPINGP":"2028","MAPPINGA":"3028","DESCRIPTION":"PIM","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRM--****X","MAPPINGP":"2029","MAPPINGA":"3029","DESCRIPTION":"Marshall Point","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRW--****X","MAPPINGP":"2030","MAPPINGA":"3030","DESCRIPTION":"Waypoint","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPRC--****X","MAPPINGP":"2031","MAPPINGA":"3031","DESCRIPTION":"Corridor Tab","WIDTH":"32","HEIGHT":"31"},{"SYMBOLID":"G*G*GPHY--****X","MAPPINGP":"2044","MAPPINGA":"3044","DESCRIPTION":"Point Y","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHX--****X","MAPPINGP":"2045","MAPPINGA":"3045","DESCRIPTION":"Point X","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHQ--****X","MAPPINGP":"2042","MAPPINGA":"3042","DESCRIPTION":"Point Q","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPHA--****X","MAPPINGP":"2043","MAPPINGA":"3043","DESCRIPTION":"Point A","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPAO--****X","MAPPINGP":"2059","MAPPINGA":"3059","DESCRIPTION":"Tomcat","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAK--****X","MAPPINGP":"2056","MAPPINGA":"3056","DESCRIPTION":"Tanking","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAT--****X","MAPPINGP":"2055","MAPPINGA":"3055","DESCRIPTION":"TACAN","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAS--****X","MAPPINGP":"2063","MAPPINGA":"3063","DESCRIPTION":"Strike IP","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAB--****X","MAPPINGP":"2065","MAPPINGA":"3065","DESCRIPTION":"SUCAP-fixed wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAC--****X","MAPPINGP":"2066","MAPPINGA":"3066","DESCRIPTION":"SUCAP-rotary wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAD--****X","MAPPINGP":"2067","MAPPINGA":"3067","DESCRIPTION":"MIW-fixed wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAE--****X","MAPPINGP":"2068","MAPPINGA":"3068","DESCRIPTION":"MIW-rotary wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAF--****X","MAPPINGP":"2069","MAPPINGA":"3069","DESCRIPTION":"(UAS/UA)","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAG--****X","MAPPINGP":"2070","MAPPINGA":"3070","DESCRIPTION":"VTUA","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAI--****X","MAPPINGP":"2071","MAPPINGA":"3071","DESCRIPTION":"Orbit","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAJ--****X","MAPPINGP":"2072","MAPPINGA":"3072","DESCRIPTION":"Orbit - F8","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAM--****X","MAPPINGP":"2073","MAPPINGA":"3073","DESCRIPTION":"Orbit - RT","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAN--****X","MAPPINGP":"2074","MAPPINGA":"3074","DESCRIPTION":"Orbit - RC","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAR--****X","MAPPINGP":"2060","MAPPINGA":"3060","DESCRIPTION":"Rescue","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAL--****X","MAPPINGP":"2061","MAPPINGA":"3061","DESCRIPTION":"Replenish","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPA---****X","MAPPINGP":"2052","MAPPINGA":"3052","DESCRIPTION":"Air Control","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAP--****X","MAPPINGP":"2053","MAPPINGA":"3053","DESCRIPTION":"Combat Air Patrol (CAP)","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAH--****X","MAPPINGP":"2058","MAPPINGA":"3058","DESCRIPTION":"Antisubmarine Warfare, Rotary Wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAA--****X","MAPPINGP":"2057","MAPPINGA":"3057","DESCRIPTION":"Antisubmarine Warfare, Fixed Wing","WIDTH":"29","HEIGHT":"42"},{"SYMBOLID":"G*G*GPAW--****X","MAPPINGP":"2054","MAPPINGA":"3054","DESCRIPTION":"Airborne Early Warning (AEW)","WIDTH":"30","HEIGHT":"42"},{"SYMBOLID":"WAS-PC----P----","MAPPINGP":"5001","DESCRIPTION":"Cyclone Center","WIDTH":"26","HEIGHT":"33"},{"SYMBOLID":"WAS-PLT---P----","MAPPINGP":"5002","DESCRIPTION":"Tropopause Low","WIDTH":"28","HEIGHT":"26"},{"SYMBOLID":"WAS-PA----P----","MAPPINGP":"5004","DESCRIPTION":"Anticyclone Center","WIDTH":"26","HEIGHT":"33"},{"SYMBOLID":"WAS-PHT---P----","MAPPINGP":"5005","DESCRIPTION":"Tropopause High","WIDTH":"28","HEIGHT":"26"},{"SYMBOLID":"WAS-T-MW--P----","MAPPINGP":"5010","DESCRIPTION":"Mountain Waves","WIDTH":"24","HEIGHT":"12"},{"SYMBOLID":"WAS-CCCSFCP----","MAPPINGP":"5022","DESCRIPTION":"Few Coverage","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSSCP----","MAPPINGP":"5023","DESCRIPTION":"Scattered Coverage","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WAS-CCCSOCP----","MAPPINGP":"5025","DESCRIPTION":"Overcast Coverage","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-CCCSOBP----","MAPPINGP":"5026","DESCRIPTION":"Sky Totally or Partially Obscured","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"WAS-WSR-LIP----","MAPPINGP":"5027","DESCRIPTION":"Intermittent Light Rain","WIDTH":"10","HEIGHT":"10"},{"SYMBOLID":"WAS-WSR-LCP----","MAPPINGP":"5028","DESCRIPTION":"Continuous Light Rain","WIDTH":"36","HEIGHT":"10"},{"SYMBOLID":"WAS-WSR-MIP----","MAPPINGP":"5029","DESCRIPTION":"Intermittent Moderate Rain","WIDTH":"10","HEIGHT":"27"},{"SYMBOLID":"WAS-WSR-MCP----","MAPPINGP":"5030","DESCRIPTION":"Continuous Moderate Rain","WIDTH":"26","HEIGHT":"22"},{"SYMBOLID":"WAS-WSR-HIP----","MAPPINGP":"5031","DESCRIPTION":"Intermittent Heavy Rain","WIDTH":"10","HEIGHT":"30"},{"SYMBOLID":"WAS-WSR-HCP----","MAPPINGP":"5032","DESCRIPTION":"Continuous Heavy Rain","WIDTH":"34","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRFL-P----","MAPPINGP":"5033","DESCRIPTION":"Light Freezing Rain","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSRFMHP----","MAPPINGP":"5034","DESCRIPTION":"Moderate/Heavy Freezing Rain","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSRSL-P----","MAPPINGP":"5035","DESCRIPTION":"Light Rain Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRSMHP----","MAPPINGP":"5036","DESCRIPTION":"Moderate/Heavy Rain Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSRST-P----","MAPPINGP":"5037","DESCRIPTION":"Torrential Rain Showers","WIDTH":"12","HEIGHT":"37"},{"SYMBOLID":"WAS-WSD-LIP----","MAPPINGP":"5038","DESCRIPTION":"Intermittent Light Drizzle","WIDTH":"8","HEIGHT":"14"},{"SYMBOLID":"WAS-WSD-LCP----","MAPPINGP":"5039","DESCRIPTION":"Continuous Light Drizzle","WIDTH":"21","HEIGHT":"14"},{"SYMBOLID":"WAS-WSD-MIP----","MAPPINGP":"5040","DESCRIPTION":"Intermittent Moderate Drizzle","WIDTH":"8","HEIGHT":"32"},{"SYMBOLID":"WAS-WSD-MCP----","MAPPINGP":"5041","DESCRIPTION":"Continuous Moderate Drizzle","WIDTH":"21","HEIGHT":"29"},{"SYMBOLID":"WAS-WSD-HIP----","MAPPINGP":"5042","DESCRIPTION":"Intermittent Heavy Drizzle","WIDTH":"8","HEIGHT":"44"},{"SYMBOLID":"WAS-WSD-HCP----","MAPPINGP":"5043","DESCRIPTION":"Continuous Heavy Drizzle","WIDTH":"27","HEIGHT":"34"},{"SYMBOLID":"WAS-WSDFL-P----","MAPPINGP":"5044","DESCRIPTION":"Light Freezing Drizzle","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSDFMHP----","MAPPINGP":"5045","DESCRIPTION":"Moderate/Heavy Freezing Drizzle","WIDTH":"48","HEIGHT":"26"},{"SYMBOLID":"WAS-WSM-L-P----","MAPPINGP":"5046","DESCRIPTION":"Light Rain or Drizzle and Snow","WIDTH":"16","HEIGHT":"33"},{"SYMBOLID":"WAS-WSM-MHP----","MAPPINGP":"5047","DESCRIPTION":"Moderate Heavy Rain or Drizzle and Snow","WIDTH":"16","HEIGHT":"52"},{"SYMBOLID":"WAS-WSMSL-P----","MAPPINGP":"5048","DESCRIPTION":"Light Rain and Snow Showers","WIDTH":"16","HEIGHT":"53"},{"SYMBOLID":"WAS-WSMSMHP----","MAPPINGP":"5049","DESCRIPTION":"Moderate/Heavy Rain and Snow Showers","WIDTH":"16","HEIGHT":"52"},{"SYMBOLID":"WAS-WSS-LIP----","MAPPINGP":"5050","DESCRIPTION":"Intermittent Light Snow","WIDTH":"16","HEIGHT":"18"},{"SYMBOLID":"WAS-WSS-LCP----","MAPPINGP":"5051","DESCRIPTION":"Continuous Light Snow","WIDTH":"35","HEIGHT":"18"},{"SYMBOLID":"WAS-WSS-MIP----","MAPPINGP":"5052","DESCRIPTION":"Intermittent Moderate Snow","WIDTH":"16","HEIGHT":"39"},{"SYMBOLID":"WAS-WSS-MCP----","MAPPINGP":"5053","DESCRIPTION":"Continuous Moderate Snow","WIDTH":"35","HEIGHT":"40"},{"SYMBOLID":"WAS-WSS-HIP----","MAPPINGP":"5054","DESCRIPTION":"Intermittent Heavy Snow","WIDTH":"16","HEIGHT":"60"},{"SYMBOLID":"WAS-WSS-HCP----","MAPPINGP":"5055","DESCRIPTION":"Continuous Heavy Snow","WIDTH":"35","HEIGHT":"60"},{"SYMBOLID":"WAS-WSSBLMP----","MAPPINGP":"5056","DESCRIPTION":"Light/Moderate Blowing Snow","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"WAS-WSSBH-P----","MAPPINGP":"5057","DESCRIPTION":"Heavy Blowing Snow","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"WAS-WSSG--P----","MAPPINGP":"5058","DESCRIPTION":"Snow Grains (SG)","WIDTH":"42","HEIGHT":"19"},{"SYMBOLID":"WAS-WSSSL-P----","MAPPINGP":"5059","DESCRIPTION":"Light Snow Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSSSMHP----","MAPPINGP":"5060","DESCRIPTION":"Moderate/Heavy Snow Showers","WIDTH":"12","HEIGHT":"27"},{"SYMBOLID":"WAS-WSGRL-P----","MAPPINGP":"5061","DESCRIPTION":"Hail - Light not Associated With Thunder","WIDTH":"12","HEIGHT":"28"},{"SYMBOLID":"WAS-WSGRMHP----","MAPPINGP":"5062","DESCRIPTION":"Hail - Moderate/Heavy not Associated With Thunder","WIDTH":"12","HEIGHT":"28"},{"SYMBOLID":"WAS-WSIC--P----","MAPPINGP":"5063","DESCRIPTION":"Ice Crystals (DD)","WIDTH":"50","HEIGHT":"14"},{"SYMBOLID":"WAS-WSPLL-P----","MAPPINGP":"5064","DESCRIPTION":"Light Ice Pellets","WIDTH":"24","HEIGHT":"19"},{"SYMBOLID":"WAS-WSPLM-P----","MAPPINGP":"5065","DESCRIPTION":"Moderate Ice Pellets","WIDTH":"33","HEIGHT":"30"},{"SYMBOLID":"WAS-WSPLH-P----","MAPPINGP":"5066","DESCRIPTION":"Heavy Ice Pellets","WIDTH":"34","HEIGHT":"41"},{"SYMBOLID":"WAS-WST-NPP----","MAPPINGP":"5067","DESCRIPTION":"Thunderstorm - No Precipitation","WIDTH":"49","HEIGHT":"42"},{"SYMBOLID":"WAS-WSTMR-P----","MAPPINGP":"5068","DESCRIPTION":"Thunderstorm Light to Moderate With Rain/Snow - No Hail","WIDTH":"26","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTHR-P----","MAPPINGP":"5069","DESCRIPTION":"Thunderstorm Heavy With Rain/Snow - No Hail","WIDTH":"28","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTMH-P----","MAPPINGP":"5070","DESCRIPTION":"Thunderstorm Light to Moderate - With Hail","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"WAS-WSTHH-P----","MAPPINGP":"5071","DESCRIPTION":"Thunderstorm Heavy - With Hail","WIDTH":"25","HEIGHT":"48"},{"SYMBOLID":"WAS-WST-SQP----","MAPPINGP":"5073","DESCRIPTION":"Squall","WIDTH":"24","HEIGHT":"28"},{"SYMBOLID":"WAS-WST-LGP----","MAPPINGP":"5074","DESCRIPTION":"Lightning","WIDTH":"32","HEIGHT":"42"},{"SYMBOLID":"WAS-WSFGPSP----","MAPPINGP":"5075","DESCRIPTION":"Fog - Shallow Patches","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGCSP----","MAPPINGP":"5076","MAPPINGA":"7","DESCRIPTION":"Fog - Shallow Continuous","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGP-P----","MAPPINGP":"5077","DESCRIPTION":"Fog - Patchy","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGSVP----","MAPPINGP":"5078","DESCRIPTION":"Fog - Sky Visible","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGSOP----","MAPPINGP":"5079","DESCRIPTION":"Fog - Sky Obscured","WIDTH":"28","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGFVP----","MAPPINGP":"5080","DESCRIPTION":"Fog - Freezing, Sky Visible","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WAS-WSFGFOP----","MAPPINGP":"5081","DESCRIPTION":"Fog - Freezing, Sky Not Visible","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WAS-WSBR--P----","MAPPINGP":"5082","DESCRIPTION":"Mist","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WSHZ--P----","MAPPINGP":"5084","DESCRIPTION":"Haze","WIDTH":"48","HEIGHT":"22"},{"SYMBOLID":"WAS-WSDSLMP----","MAPPINGP":"5085","DESCRIPTION":"Light to Moderate Dust/Sand Storm","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-WSDSS-P----","MAPPINGP":"5086","DESCRIPTION":"Severe Dust/Sand Storm","WIDTH":"42","HEIGHT":"42"},{"SYMBOLID":"WAS-WSBD--P----","MAPPINGP":"349","MAPPINGA":"349","DESCRIPTION":"Blowing Dust or Sand","WIDTH":"26","HEIGHT":"43"},{"SYMBOLID":"WAS-WSTSD-P----","MAPPINGP":"5089","DESCRIPTION":"Tropical Depression","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"WAS-WSTSS-P----","MAPPINGP":"5090","DESCRIPTION":"Tropical Storm","WIDTH":"32","HEIGHT":"52"},{"SYMBOLID":"WAS-WSTSH-P----","MAPPINGP":"5091","DESCRIPTION":"Hurricane/Typhoon","WIDTH":"32","HEIGHT":"52"},{"SYMBOLID":"WAS-WSVE--P----","MAPPINGP":"5092","DESCRIPTION":"Volcanic Eruption","WIDTH":"31","HEIGHT":"37"},{"SYMBOLID":"WAS-WSVA--P----","MAPPINGP":"5093","DESCRIPTION":"Volcanic Ash","WIDTH":"26","HEIGHT":"27"},{"SYMBOLID":"WAS-WST-LVP----","MAPPINGP":"5094","DESCRIPTION":"Tropopause Level","WIDTH":"50","HEIGHT":"28"},{"SYMBOLID":"WAS-WSF-LVP----","MAPPINGP":"5095","DESCRIPTION":"Freezing Level","WIDTH":"50","HEIGHT":"28"},{"SYMBOLID":"WAS-WSUKP-P----","MAPPINGP":"5096","DESCRIPTION":"Precipitation of Unknown Type and Intensity","WIDTH":"48","HEIGHT":"25"},{"SYMBOLID":"WAS-GND-NCP----","MAPPINGP":"5097","DESCRIPTION":"Loose Sand","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNM---P----","MAPPINGP":"5098","DESCRIPTION":"Surface Moist","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNW-SWP----","MAPPINGP":"5099","DESCRIPTION":"Surface Wet, Standing Water in Small or Large Pools","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNFL--P----","MAPPINGP":"5100","DESCRIPTION":"Surface Flooded","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNFZ--P----","MAPPINGP":"5101","DESCRIPTION":"Surface Frozen","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNG-TIP----","MAPPINGP":"5102","DESCRIPTION":"Glaze (Thin Ice) on Ground","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNLDN-P----","MAPPINGP":"5103","DESCRIPTION":"Loose Dry Dust or Sand not Covering Ground Completely","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GNLDTCP----","MAPPINGP":"5104","DESCRIPTION":"Thin Loose Dry Dust or Sand Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNLDMCP----","MAPPINGP":"5105","DESCRIPTION":"Moderae/Thick Loose Dry Dust or Sand Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GNDEWCP----","MAPPINGP":"5106","DESCRIPTION":"Extremely Dry With Cracks","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSCL-P----","MAPPINGP":"5108","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering Less than One-Half of Ground","WIDTH":"33","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSCH-P----","MAPPINGP":"5109","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering At Least One-Half Ground, but Ground not Completely Covered","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSCCEP----","MAPPINGP":"5110","DESCRIPTION":"Even Layer of Compact or Wet Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSCCUP----","MAPPINGP":"5111","DESCRIPTION":"Uneven Layer of Compact or Wet Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSLL-P----","MAPPINGP":"5112","DESCRIPTION":"Loose Dry Snow Covering Less than One-Half of Ground","WIDTH":"33","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSLH-P----","MAPPINGP":"5113","DESCRIPTION":"Loose Dry Snow Covering at Least One-Half Ground, but Ground not Completely Covered","WIDTH":"36","HEIGHT":"38"},{"SYMBOLID":"WAS-GSSLCEP----","MAPPINGP":"5114","DESCRIPTION":"Even Layer of Loose Dry Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSLCUP----","MAPPINGP":"5115","DESCRIPTION":"Uneven Layer of Loose Dry Snow Covering Ground Completely","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WAS-GSSDC-P----","MAPPINGP":"5116","DESCRIPTION":"Snow Covering Ground Completely; Deep Drifts","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WOS-IB----P----","MAPPINGP":"5117","DESCRIPTION":"Icebergs","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBM---P----","MAPPINGP":"5118","DESCRIPTION":"Many Icebergs","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-IBBS--P----","MAPPINGP":"5119","DESCRIPTION":"Belts and Strips","WIDTH":"36","HEIGHT":"10"},{"SYMBOLID":"WOS-IBG---P----","MAPPINGP":"5120","DESCRIPTION":"Iceberg - General","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBMG--P----","MAPPINGP":"5121","DESCRIPTION":"Many Icebergs - General","WIDTH":"36","HEIGHT":"29"},{"SYMBOLID":"WOS-IBBB--P----","MAPPINGP":"5122","DESCRIPTION":"Bergy Bit","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-IBBBM-P----","MAPPINGP":"5123","DESCRIPTION":"Many Bergy Bits","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-IBGL--P----","MAPPINGP":"5124","DESCRIPTION":"Growler","WIDTH":"30","HEIGHT":"24"},{"SYMBOLID":"WOS-IBGLM-P----","MAPPINGP":"5125","DESCRIPTION":"Many Growlers","WIDTH":"30","HEIGHT":"24"},{"SYMBOLID":"WOS-IBF---P----","MAPPINGP":"5126","DESCRIPTION":"Floeberg","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-IBII--P----","MAPPINGP":"5127","DESCRIPTION":"Ice Island","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-ICWB--P----","MAPPINGP":"5128","DESCRIPTION":"Bergy Water","WIDTH":"48","HEIGHT":"17"},{"SYMBOLID":"WOS-ICWR--P----","MAPPINGP":"5129","DESCRIPTION":"Water With Radar Targets","WIDTH":"48","HEIGHT":"16"},{"SYMBOLID":"WOS-ICIF--P----","MAPPINGP":"5130","DESCRIPTION":"Ice Free","WIDTH":"36","HEIGHT":"14"},{"SYMBOLID":"WOS-IDC---P----","MAPPINGP":"5131","DESCRIPTION":"Convergence","WIDTH":"42","HEIGHT":"8"},{"SYMBOLID":"WOS-IDD---P----","MAPPINGP":"5132","DESCRIPTION":"Divergence","WIDTH":"42","HEIGHT":"8"},{"SYMBOLID":"WOS-IDS---P----","MAPPINGP":"5133","DESCRIPTION":"Shearing or Shear Zone","WIDTH":"20","HEIGHT":"18"},{"SYMBOLID":"WO-DIDID---L---","MAPPINGP":"5134","DESCRIPTION":"Ice Drift (Direction)","WIDTH":"20","HEIGHT":"8"},{"SYMBOLID":"WOS-II----P----","MAPPINGP":"5135","DESCRIPTION":"Sea Ice","WIDTH":"25","HEIGHT":"24"},{"SYMBOLID":"WOS-IITM--P----","MAPPINGP":"5136","DESCRIPTION":"Ice Thickness (Observed)","WIDTH":"46","HEIGHT":"40"},{"SYMBOLID":"WOS-IITE--P----","MAPPINGP":"5137","DESCRIPTION":"Ice Thickness (Estimated)","WIDTH":"45","HEIGHT":"40"},{"SYMBOLID":"WOS-IIP---P----","MAPPINGP":"5138","DESCRIPTION":"Melt Puddles or Flooded Ice","WIDTH":"39","HEIGHT":"14"},{"SYMBOLID":"WOS-ISC---P----","MAPPINGP":"5139","DESCRIPTION":"Snow Cover","WIDTH":"17","HEIGHT":"29"},{"SYMBOLID":"WOS-ISS---P----","MAPPINGP":"5140","DESCRIPTION":"Sastrugi (With Orientation)","WIDTH":"29","HEIGHT":"44"},{"SYMBOLID":"WOS-ITRH--P----","MAPPINGP":"5141","DESCRIPTION":"Ridges or Hummocks","WIDTH":"36","HEIGHT":"18"},{"SYMBOLID":"WOS-ITR---P----","MAPPINGP":"5142","DESCRIPTION":"Rafting","WIDTH":"36","HEIGHT":"26"},{"SYMBOLID":"WOS-ITBB--P----","MAPPINGP":"5143","DESCRIPTION":"Jammed Brash Barrier","WIDTH":"36","HEIGHT":"18"},{"SYMBOLID":"WOS-HDS---P----","MAPPINGP":"5144","MAPPINGA":"404","DESCRIPTION":"Soundings","WIDTH":"30","HEIGHT":"32"},{"SYMBOLID":"WOS-HPB-O-P----","MAPPINGP":"5145","DESCRIPTION":"Berths (Onshore)","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WOS-HPB-A-P----","MAPPINGP":"5146","DESCRIPTION":"Berths (Anchor)","WIDTH":"46","HEIGHT":"44"},{"SYMBOLID":"WOS-HPBA--P----","MAPPINGP":"5147","DESCRIPTION":"Anchorage","WIDTH":"46","HEIGHT":"44"},{"SYMBOLID":"WOS-HPCP--P----","MAPPINGP":"5148","DESCRIPTION":"Call in Point","WIDTH":"19","HEIGHT":"36"},{"SYMBOLID":"WOS-HPFH--P----","MAPPINGP":"5149","DESCRIPTION":"Fishing Harbor","WIDTH":"36","HEIGHT":"34"},{"SYMBOLID":"WOS-HPFS--P----","MAPPINGP":"5150","DESCRIPTION":"Fish Stakes/Traps/Weirs","WIDTH":"34","HEIGHT":"32"},{"SYMBOLID":"WOS-HPFS---L---","MAPPINGP":"5151","DESCRIPTION":"Fish Stakes","WIDTH":"36","HEIGHT":"31"},{"SYMBOLID":"WOS-HPML--P----","MAPPINGP":"5152","DESCRIPTION":"Landing Place","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"WO-DHPMO--P----","MAPPINGP":"5153","DESCRIPTION":"Offshore Loading Facility 1","WIDTH":"35","HEIGHT":"33"},{"SYMBOLID":"WO-DHPMO---L---","MAPPINGP":"5154","DESCRIPTION":"Offshore Loading Facility 2","WIDTH":"36","HEIGHT":"4"},{"SYMBOLID":"WOS-HPM-R-P----","MAPPINGP":"5155","MAPPINGA":"5156","DESCRIPTION":"Landing Ring","WIDTH":"36","HEIGHT":"20"},{"SYMBOLID":"WOS-HPM-FC-L---","MAPPINGP":"5157","DESCRIPTION":"Ferry Crossing","WIDTH":"38","HEIGHT":"10"},{"SYMBOLID":"WOS-HPM-CC-L---","MAPPINGP":"5158","DESCRIPTION":"Cable Ferry Crossing","WIDTH":"38","HEIGHT":"10"},{"SYMBOLID":"WOS-HPD---P----","MAPPINGP":"5159","MAPPINGA":"5160","DESCRIPTION":"Dolphin","WIDTH":"36","HEIGHT":"20"},{"SYMBOLID":"WOS-HABA--P----","MAPPINGP":"5161","DESCRIPTION":"Beacon","WIDTH":"36","HEIGHT":"39"},{"SYMBOLID":"WOS-HABB--P----","MAPPINGP":"5162","MAPPINGA":"5163","DESCRIPTION":"Buoy Default","WIDTH":"52","HEIGHT":"34"},{"SYMBOLID":"WOS-HABM--P----","MAPPINGP":"5164","DESCRIPTION":"Marker","WIDTH":"24","HEIGHT":"32"},{"SYMBOLID":"WOS-HABP--P----","MAPPINGP":"5165","DESCRIPTION":"Perches/Stakes","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"WOS-HAL---P----","MAPPINGP":"5166","DESCRIPTION":"Light","WIDTH":"40","HEIGHT":"36"},{"SYMBOLID":"WOS-HALV--P----","MAPPINGP":"5167","DESCRIPTION":"Light Vessel/Lightship","WIDTH":"36","HEIGHT":"32"},{"SYMBOLID":"WOS-HALH--P----","MAPPINGP":"5168","DESCRIPTION":"Lighthouse","WIDTH":"28","HEIGHT":"36"},{"SYMBOLID":"WOS-HHRS--P----","MAPPINGP":"5169","MAPPINGA":"5170","DESCRIPTION":"Rock Submerged","WIDTH":"26","HEIGHT":"26"},{"SYMBOLID":"WOS-HHRA--P----","MAPPINGP":"5171","DESCRIPTION":"Rock Awashed","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDF--P----","MAPPINGP":"5172","DESCRIPTION":"Foul Ground","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WO-DHHDK--P----","MAPPINGP":"5173","DESCRIPTION":"Kelp/Seaweed","WIDTH":"38","HEIGHT":"13"},{"SYMBOLID":"WOS-HHDMDBP----","MAPPINGP":"5174","DESCRIPTION":"Mine-Naval (Doubtful)","WIDTH":"24","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDMDFP----","MAPPINGP":"5175","DESCRIPTION":"Mine-Naval (Definite)","WIDTH":"24","HEIGHT":"36"},{"SYMBOLID":"WOS-HHDS--P----","MAPPINGP":"5176","MAPPINGA":"5177","DESCRIPTION":"Snags/Stumps","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-HHDWA-P----","MAPPINGP":"5178","DESCRIPTION":"Wreck (Uncovers)","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"WOS-HHDWB-P----","MAPPINGP":"5179","MAPPINGA":"5180","DESCRIPTION":"Wreck (Submerged)","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"WOS-HHDE--P----","MAPPINGP":"5181","DESCRIPTION":"Eddies/Overfalls/Tide Rips","WIDTH":"59","HEIGHT":"20"},{"SYMBOLID":"WOS-BFC-S-P----","MAPPINGP":"5182","DESCRIPTION":"Sand","WIDTH":"28","HEIGHT":"37"},{"SYMBOLID":"WOS-BFC-M-P----","MAPPINGP":"5183","DESCRIPTION":"Mud","WIDTH":"38","HEIGHT":"26"},{"SYMBOLID":"WOS-BFC-CLP----","MAPPINGP":"5184","DESCRIPTION":"Clay","WIDTH":"36","HEIGHT":"30"},{"SYMBOLID":"WOS-BFC-SIP----","MAPPINGP":"5185","DESCRIPTION":"Silt","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"WOS-BFC-STP----","MAPPINGP":"5186","DESCRIPTION":"Stones","WIDTH":"36","HEIGHT":"33"},{"SYMBOLID":"WOS-BFC-G-P----","MAPPINGP":"5187","DESCRIPTION":"Gravel","WIDTH":"40","HEIGHT":"42"},{"SYMBOLID":"WOS-BFC-P-P----","MAPPINGP":"5188","DESCRIPTION":"Pebbles","WIDTH":"30","HEIGHT":"30"},{"SYMBOLID":"WOS-BFC-CBP----","MAPPINGP":"5189","DESCRIPTION":"Cobbles","WIDTH":"36","HEIGHT":"26"},{"SYMBOLID":"WOS-BFC-R-P----","MAPPINGP":"5190","DESCRIPTION":"Rock","WIDTH":"30","HEIGHT":"34"},{"SYMBOLID":"WOS-BFC-COP----","MAPPINGP":"5191","DESCRIPTION":"Coral","WIDTH":"36","HEIGHT":"25"},{"SYMBOLID":"WOS-BFC-SHP----","MAPPINGP":"5192","DESCRIPTION":"Shell","WIDTH":"36","HEIGHT":"28"},{"SYMBOLID":"WOS-BFQ-F-P----","MAPPINGP":"5193","DESCRIPTION":"Fine","WIDTH":"26","HEIGHT":"36"},{"SYMBOLID":"WOS-BFQ-M-P----","MAPPINGP":"5194","DESCRIPTION":"Medium","WIDTH":"36","HEIGHT":"25"},{"SYMBOLID":"WOS-BFQ-C-P----","MAPPINGP":"5195","DESCRIPTION":"Coarse","WIDTH":"32","HEIGHT":"36"},{"SYMBOLID":"WOS-TCCW--P----","MAPPINGP":"5196","DESCRIPTION":"Water Turbulence","WIDTH":"60","HEIGHT":"21"},{"SYMBOLID":"WOS-TCCTD-P----","MAPPINGP":"5197","DESCRIPTION":"Tide Data Point","WIDTH":"30","HEIGHT":"36"},{"SYMBOLID":"WOS-TCCTG-P----","MAPPINGP":"5198","MAPPINGA":"5199","DESCRIPTION":"Tide Gauge","WIDTH":"33","HEIGHT":"20"},{"SYMBOLID":"WOS-MF----P----","MAPPINGP":"5200","DESCRIPTION":"Ford","WIDTH":"12","HEIGHT":"34"},{"SYMBOLID":"WOS-ML----P----","MAPPINGP":"5201","DESCRIPTION":"Lock","WIDTH":"22","HEIGHT":"26"},{"SYMBOLID":"WOS-MOA---P----","MAPPINGP":"5202","DESCRIPTION":"Oil/Gas Rig","WIDTH":"31","HEIGHT":"42"},{"SYMBOLID":"WOS-MPA---P----","MAPPINGP":"5203","DESCRIPTION":"Pile/Piling/Post","WIDTH":"24","HEIGHT":"24"},{"SYMBOLID":"G*G*GPUY--****X","MAPPINGP":"2007","MAPPINGA":"3007","DESCRIPTION":"Sonobuoy","WIDTH":"24","HEIGHT":"48"},{"SYMBOLID":"G*G*GPUS--****X","MAPPINGP":"2020","MAPPINGA":"2020","DESCRIPTION":"Search","WIDTH":"39","HEIGHT":"35"},{"SYMBOLID":"G*G*GPF---****X","MAPPINGP":"2040","MAPPINGA":"3040","DESCRIPTION":"Formation","WIDTH":"36","HEIGHT":"36"},{"SYMBOLID":"G*G*GPH---****X","MAPPINGP":"2041","MAPPINGA":"3041","DESCRIPTION":"Harbor (General)","WIDTH":"32","HEIGHT":"23"},{"SYMBOLID":"G*G*GPO---****X","MAPPINGP":"2046","MAPPINGA":"3046","DESCRIPTION":"Route","WIDTH":"36","HEIGHT":"24"},{"SYMBOLID":"G*G*GPPA--****X","MAPPINGP":"2091","MAPPINGA":"3091","DESCRIPTION":"Amnesty Point","WIDTH":"25","HEIGHT":"45"},{"SYMBOLID":"G*G*GPC---****X","MAPPINGP":"2092","MAPPINGA":"3092","DESCRIPTION":"Sea Surface Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCU--****X","MAPPINGP":"2093","MAPPINGA":"3093","DESCRIPTION":"USV Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCUR-****X","MAPPINGP":"2094","MAPPINGA":"3094","DESCRIPTION":"RMV USV Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCUA-****X","MAPPINGP":"2095","MAPPINGA":"3095","DESCRIPTION":"USV ASW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCUS-****X","MAPPINGP":"2096","MAPPINGA":"3096","DESCRIPTION":"USV SUW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCUM-****X","MAPPINGP":"2097","MAPPINGA":"3097","DESCRIPTION":"USV MIW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCA--****X","MAPPINGP":"2098","MAPPINGA":"3098","DESCRIPTION":"ASW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCS--****X","MAPPINGP":"2099","MAPPINGA":"3099","DESCRIPTION":"SUW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCM--****X","MAPPINGP":"2100","MAPPINGA":"3100","DESCRIPTION":"MIW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCP--****X","MAPPINGP":"2101","MAPPINGA":"3101","DESCRIPTION":"Picket Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCR--****X","MAPPINGP":"2102","MAPPINGA":"3102","DESCRIPTION":"Rendezvous Control Point","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCC--****X","MAPPINGP":"2103","MAPPINGA":"3103","DESCRIPTION":"Rescue Control Point","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCE--****X","MAPPINGP":"2104","MAPPINGA":"3104","DESCRIPTION":"Replenishment Control Point","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPCN--****X","MAPPINGP":"2105","MAPPINGA":"3105","DESCRIPTION":"Noncombatant Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPB---****X","MAPPINGP":"2106","MAPPINGA":"2106","DESCRIPTION":"Subsurface Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBU--****X","MAPPINGP":"2107","MAPPINGA":"2107","DESCRIPTION":"UUV Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBUA-****X","MAPPINGP":"2108","MAPPINGA":"2108","DESCRIPTION":"ASW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBUS-****X","MAPPINGP":"2109","MAPPINGA":"2109","DESCRIPTION":"SUW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBUM-****X","MAPPINGP":"2110","MAPPINGA":"2110","DESCRIPTION":"MIW Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBS--****X","MAPPINGP":"2111","MAPPINGA":"2111","DESCRIPTION":"Submarine Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"G*G*GPBSA-****X","MAPPINGP":"2112","MAPPINGA":"2112","DESCRIPTION":"ASW Submarine Control Station","WIDTH":"42","HEIGHT":"29"},{"SYMBOLID":"E*N*AA----*****","MAPPINGP":"6000","DESCRIPTION":"Aftershock","WIDTH":"34","HEIGHT":"34"},{"SYMBOLID":"E*N*AB----*****","MAPPINGP":"6001","DESCRIPTION":"Avalanche","WIDTH":"30","HEIGHT":"35"},{"SYMBOLID":"E*N*AC----*****","MAPPINGP":"6002","DESCRIPTION":"Earthquake Epicenter","WIDTH":"38","HEIGHT":"38"},{"SYMBOLID":"E*N*AD----*****","MAPPINGP":"6003","DESCRIPTION":"Landslide","WIDTH":"39","HEIGHT":"31"},{"SYMBOLID":"E*N*AE----*****","MAPPINGP":"6004","DESCRIPTION":"Subsidence","WIDTH":"42","HEIGHT":"18"},{"SYMBOLID":"E*N*AG----*****","MAPPINGP":"6006","DESCRIPTION":"Volcanic Threat","WIDTH":"34","HEIGHT":"31"},{"SYMBOLID":"E*N*BB----*****","MAPPINGP":"6007","DESCRIPTION":"Drought","WIDTH":"36","HEIGHT":"25"},{"SYMBOLID":"E*N*BC----*****","MAPPINGP":"6008","DESCRIPTION":"Flood","WIDTH":"32","HEIGHT":"27"},{"SYMBOLID":"E*N*BF----*****","MAPPINGP":"6009","DESCRIPTION":"Inversion","WIDTH":"30","HEIGHT":"28"},{"SYMBOLID":"E*N*BM----*****","MAPPINGP":"6010","DESCRIPTION":"Tsunami","WIDTH":"36","HEIGHT":"26"},{"SYMBOLID":"E*N*CA----*****","MAPPINGP":"6011","DESCRIPTION":"Bird Infestation","WIDTH":"40","HEIGHT":"30"},{"SYMBOLID":"E*N*CB----*****","MAPPINGP":"6012","DESCRIPTION":"Insect Infestation","WIDTH":"44","HEIGHT":"26"},{"SYMBOLID":"E*N*CC----*****","MAPPINGP":"6013","DESCRIPTION":"Microbial Infestation","WIDTH":"40","HEIGHT":"18"},{"SYMBOLID":"E*N*CD----*****","MAPPINGP":"6014","DESCRIPTION":"Reptile Infestation","WIDTH":"36","HEIGHT":"22"},{"SYMBOLID":"E*N*CE----*****","MAPPINGP":"6015","DESCRIPTION":"Rodent Infestation","WIDTH":"38","HEIGHT":"28"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SymbolConstantsC={"SYMBOLCONSTANTS":{"SYMBOL":[{"SYMBOLID":"BS_BASIC_SHAPES","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Basic Shapes","HIERARCHY":"0.X","ALPHAHIERARCHY":"BS"},{"SYMBOLID":"BS_LINE--------","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line","HIERARCHY":"0.X.1","ALPHAHIERARCHY":"BS.LINE","PATH":"Basic Shapes"},{"SYMBOLID":"BS_AREA--------","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area","HIERARCHY":"0.X.2","ALPHAHIERARCHY":"BS.AREA","PATH":"Basic Shapes"},{"SYMBOLID":"BS_CROSS--------","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cross","HIERARCHY":"0.X.3","ALPHAHIERARCHY":"BS.CROSS","PATH":"Basic Shapes"},{"SYMBOLID":"BS_ELLIPSE-----","GEOMETRY":"area","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ellipse","HIERARCHY":"0.X.4","ALPHAHIERARCHY":"BS.ELLIPSE","PATH":"Basic Shapes"},{"SYMBOLID":"BS_RECTANGLE---","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Rectangle","HIERARCHY":"0.X.5","ALPHAHIERARCHY":"BS.RECTANGLE","PATH":"Basic Shapes"},{"SYMBOLID":"BUFFERED_SHAPES","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"AM.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6","ALPHAHIERARCHY":"BS.BBS"},{"SYMBOLID":"BBS_LINE-------","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Line","HIERARCHY":"0.X.6.1","ALPHAHIERARCHY":"BS.BBS.LINE"},{"SYMBOLID":"BBS_AREA-------","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6.2","ALPHAHIERARCHY":"BS.BBS.AREA"},{"SYMBOLID":"BBS_POINT------","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Basic Shapes","HIERARCHY":"0.X.6.2","ALPHAHIERARCHY":"BS.BBS.POINT"},{"SYMBOLID":"BBS_RECTANGLE--","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"AM.T.","DESCRIPTION":"Buffered Rectangle","HIERARCHY":"0.X.6.3","ALPHAHIERARCHY":"BS.BBS.RECT"},{"SYMBOLID":"G*-*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tactical Graphics","HIERARCHY":"2.X","ALPHAHIERARCHY":"TACGRP"},{"SYMBOLID":"G*T*------****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tasks","HIERARCHY":"2.X.1","ALPHAHIERARCHY":"TACGRP.TSK","PATH":"Tactical Graphics"},{"SYMBOLID":"G*T*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Block Task","HIERARCHY":"2.X.1.1","ALPHAHIERARCHY":"TACGRP.TSK.BLK","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*H-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Breach","HIERARCHY":"2.X.1.2","ALPHAHIERARCHY":"TACGRP.TSK.BRH","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*Y-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass","HIERARCHY":"2.X.1.3","ALPHAHIERARCHY":"TACGRP.TSK.BYS","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*C-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Canalize","HIERARCHY":"2.X.1.4","ALPHAHIERARCHY":"TACGRP.TSK.CNZ","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*X-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Clear","HIERARCHY":"2.X.1.5","ALPHAHIERARCHY":"TACGRP.TSK.CLR","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*J-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Contain","HIERARCHY":"2.X.1.6","ALPHAHIERARCHY":"TACGRP.TSK.CNT","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*K-----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Counterattack (CATK)","HIERARCHY":"2.X.1.7","ALPHAHIERARCHY":"TACGRP.TSK.CATK","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*KF----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Counterattack by Fire","HIERARCHY":"2.X.1.7.1","ALPHAHIERARCHY":"TACGRP.TSK.CATK.CATKF","PATH":"Tactical Graphics/Tasks/Counterattack (CATK)"},{"SYMBOLID":"G*T*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"W","DESCRIPTION":"Delay","HIERARCHY":"2.X.1.8","ALPHAHIERARCHY":"TACGRP.TSK.DLY","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*D-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Destroy","HIERARCHY":"2.X.1.9","ALPHAHIERARCHY":"TACGRP.TSK.DSTY","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*T-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Disrupt Tasks","HIERARCHY":"2.X.1.10","ALPHAHIERARCHY":"TACGRP.TSK.DRT","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*F-----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Fix Task","HIERARCHY":"2.X.1.11","ALPHAHIERARCHY":"TACGRP.TSK.FIX","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*A-----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T","DESCRIPTION":"Follow and Assume","HIERARCHY":"2.X.1.12","ALPHAHIERARCHY":"TACGRP.TSK.FLWASS","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*AS----****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Follow and Support","HIERARCHY":"2.X.1.12.1","ALPHAHIERARCHY":"TACGRP.TSK.FLWASS.FLWSUP","PATH":"Tactical Graphics/Tasks/Follow and Assume"},{"SYMBOLID":"G*T*I-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Interdict","HIERARCHY":"2.X.1.13","ALPHAHIERARCHY":"TACGRP.TSK.ITDT","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*E-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Isolate","HIERARCHY":"2.X.1.14","ALPHAHIERARCHY":"TACGRP.TSK.ISL","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*N-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Neutralize","HIERARCHY":"2.X.1.15","ALPHAHIERARCHY":"TACGRP.TSK.NEUT","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*O-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Occupy","HIERARCHY":"2.X.1.16","ALPHAHIERARCHY":"TACGRP.TSK.OCC","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*P-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Penetrate","HIERARCHY":"2.X.1.17","ALPHAHIERARCHY":"TACGRP.TSK.PNE","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*R-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Relief in Place","HIERARCHY":"2.X.1.18","ALPHAHIERARCHY":"TACGRP.TSK.RIP","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*Q-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Retain","HIERARCHY":"2.X.1.19","ALPHAHIERARCHY":"TACGRP.TSK.RTN","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*M-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Retirement","HIERARCHY":"2.X.1.20","ALPHAHIERARCHY":"TACGRP.TSK.RTM","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*S-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Secure","HIERARCHY":"2.X.1.21","ALPHAHIERARCHY":"TACGRP.TSK.SCE","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*U-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Security","HIERARCHY":"2.X.1.22","ALPHAHIERARCHY":"TACGRP.TSK.SEC","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*US----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"4","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Screen","HIERARCHY":"2.X.1.22.1","ALPHAHIERARCHY":"TACGRP.TSK.SEC.SCN","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*UG----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"4","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Guard","HIERARCHY":"2.X.1.22.2","ALPHAHIERARCHY":"TACGRP.TSK.SEC.GUD","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*UC----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"4","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Cover","HIERARCHY":"2.X.1.22.3","ALPHAHIERARCHY":"TACGRP.TSK.SEC.COV","PATH":"Tactical Graphics/Tasks/Security"},{"SYMBOLID":"G*T*Z-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Seize","HIERARCHY":"2.X.1.23","ALPHAHIERARCHY":"TACGRP.TSK.SZE","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*W-----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Withdraw","HIERARCHY":"2.X.1.24","ALPHAHIERARCHY":"TACGRP.TSK.WDR","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*WP----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Withdraw Under Pressure","HIERARCHY":"2.X.1.24.1","ALPHAHIERARCHY":"TACGRP.TSK.WDR.WDRUP","PATH":"Tactical Graphics/Tasks/Withdraw"},{"SYMBOLID":"G*T*V-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Cordon and Search","HIERARCHY":"2.X.1.25","ALPHAHIERARCHY":"TACGRP.TSK.CRDSRC","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*2-----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Cordon and Knock","HIERARCHY":"2.X.1.26","ALPHAHIERARCHY":"TACGRP.TSK.CRDKNK","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*T*G-----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Suppress","HIERARCHY":"2.X.1.27","ALPHAHIERARCHY":"TACGRP.TSK.SUPPR","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*G*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control and General Maneuver","HIERARCHY":"2.X.2","ALPHAHIERARCHY":"TACGRP.C2GM","PATH":"Tactical Graphics"},{"SYMBOLID":"G*G*G-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"General","HIERARCHY":"2.X.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*GP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GPU---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Under Sea Warfare","HIERARCHY":"2.X.2.1.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPUU--****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Underwater","HIERARCHY":"2.X.2.1.1.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.UH2","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUUD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Datum","HIERARCHY":"2.X.2.1.1.1.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.UH2.DTM","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUB-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Brief Contact","HIERARCHY":"2.X.2.1.1.1.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.UH2.BCON","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUL-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Lost Contact","HIERARCHY":"2.X.2.1.1.1.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.UH2.LCON","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUUS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underwater Sinker","HIERARCHY":"2.X.2.1.1.1.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.UH2.SNK","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Underwater"},{"SYMBOLID":"G*G*GPUY--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy","HIERARCHY":"2.X.2.1.1.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUYP-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Pattern Center","HIERARCHY":"2.X.2.1.1.1.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.PTNCTR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Directional Frequency Analyzing and Recording (DIFAR)","HIERARCHY":"2.X.2.1.1.1.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.DIFAR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYL-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Low Frequency Analyzing and Recording (LOFAR)","HIERARCHY":"2.X.2.1.1.1.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.LOFAR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYC-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Command Active Sonobuoy System (CASS)","HIERARCHY":"2.X.2.1.1.1.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.CASS","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Directional Command Active Sonobuoy System (DICASS)","HIERARCHY":"2.X.2.1.1.1.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.DICASS","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYB-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Bathythermograph Transmitting (BT)","HIERARCHY":"2.X.2.1.1.1.2.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.BT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy ANM","HIERARCHY":"2.X.2.1.1.1.2.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.ANM","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYV-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Vertical Line Array DIFAR (VLAD)","HIERARCHY":"2.X.2.1.1.1.2.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.VLAD","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYT-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy ATAC","HIERARCHY":"2.X.2.1.1.1.2.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.ATAC","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYR-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Range Only (RO)","HIERARCHY":"2.X.2.1.1.1.2.10","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.RO","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYK-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Kingpin","HIERARCHY":"2.X.2.1.1.1.2.11","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.KGP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUYX-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sonobuoy Expired","HIERARCHY":"2.X.2.1.1.1.2.12","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SNBY.EXP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Sonobuoy"},{"SYMBOLID":"G*G*GPUS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search","HIERARCHY":"2.X.2.1.1.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SRH","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare"},{"SYMBOLID":"G*G*GPUSA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search Area","HIERARCHY":"2.X.2.1.1.1.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SRH.ARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPUSD-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dip Position","HIERARCHY":"2.X.2.1.1.1.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SRH.DIPPSN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPUSC-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Search Center","HIERARCHY":"2.X.2.1.1.1.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.USW.SRH.CTR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Under Sea Warfare/Search"},{"SYMBOLID":"G*G*GPR---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Reference Point","HIERARCHY":"2.X.2.1.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPRS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Special Point","HIERARCHY":"2.X.2.1.1.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.SPLPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Nav Reference Point","HIERARCHY":"2.X.2.1.1.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.NAVREF","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"DLRP","HIERARCHY":"2.X.2.1.1.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.DLRP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRI--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Point of Interest","HIERARCHY":"2.X.2.1.1.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.PNTINR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Point of Intended Movement (PIM)","HIERARCHY":"2.X.2.1.1.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.PIM","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Marshall Point","HIERARCHY":"2.X.2.1.1.2.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.MRSH","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Waypoint","HIERARCHY":"2.X.2.1.1.2.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.WAP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPRC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Corridor Tab","HIERARCHY":"2.X.2.1.1.2.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.REFPNT.CRDRTB","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Reference Point"},{"SYMBOLID":"G*G*GPW---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Weapon","HIERARCHY":"2.X.2.1.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPWA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Aim Point","HIERARCHY":"2.X.2.1.1.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.AIMPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Drop Point","HIERARCHY":"2.X.2.1.1.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.DRPPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Entry Point","HIERARCHY":"2.X.2.1.1.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.ENTPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWG--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ground Zero","HIERARCHY":"2.X.2.1.1.3.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.GRDZRO","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"MSL Detect Point","HIERARCHY":"2.X.2.1.1.3.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.MSLPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWI--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Impact Point","HIERARCHY":"2.X.2.1.1.3.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.IMTPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPWP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Predicted Impact Point","HIERARCHY":"2.X.2.1.1.3.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.WPN.PIPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Weapon"},{"SYMBOLID":"G*G*GPF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Formation","HIERARCHY":"2.X.2.1.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.FRMN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.","DESCRIPTION":"Harbor General","HIERARCHY":"2.X.2.1.1.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.HBR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPHQ--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point Q","HIERARCHY":"2.X.2.1.1.5.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.HBR.PNTQ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point A","HIERARCHY":"2.X.2.1.1.5.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.HBR.PNTA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHY--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point Y","HIERARCHY":"2.X.2.1.1.5.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.HBR.PNTY","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPHX--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Harbor Point X","HIERARCHY":"2.X.2.1.1.5.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.HBR.PNTX","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Harbor General"},{"SYMBOLID":"G*G*GPO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route","HIERARCHY":"2.X.2.1.1.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPOZ--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Rendezvous","HIERARCHY":"2.X.2.1.1.6.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE.RDV","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Diversions","HIERARCHY":"2.X.2.1.1.6.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE.DVSN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Waypoint","HIERARCHY":"2.X.2.1.1.6.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE.WAP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route PIM","HIERARCHY":"2.X.2.1.1.6.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE.PIM","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPOR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Route Point R","HIERARCHY":"2.X.2.1.1.6.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.RTE.PNTR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Route"},{"SYMBOLID":"G*G*GPA---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control","HIERARCHY":"2.X.2.1.1.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPAP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Combat Air Patrol (CAP)","HIERARCHY":"2.X.2.1.1.7.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.CAP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Airborne Early Warning (AEW)","HIERARCHY":"2.X.2.1.1.7.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ABNEW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAT--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control TACAN","HIERARCHY":"2.X.2.1.1.7.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.TCN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAK--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Tanking","HIERARCHY":"2.X.2.1.1.7.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.TAK","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Antisubmarine Warfare, Fixed Wing","HIERARCHY":"2.X.2.1.1.7.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ASBWF","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAH--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Antisubmarine Warfare, Rotary Wing","HIERARCHY":"2.X.2.1.1.7.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ASBWR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAO--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Tomcat","HIERARCHY":"2.X.2.1.1.7.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.TMC","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Rescue","HIERARCHY":"2.X.2.1.1.7.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.RSC","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAL--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Replenish","HIERARCHY":"2.X.2.1.1.7.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.RPH","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Strike IP","HIERARCHY":"2.X.2.1.1.7.11","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.SKEIP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAB--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control SUCAP - Fixed Wing","HIERARCHY":"2.X.2.1.1.7.13","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.SUWF","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control SUCAP - Rotary Wing","HIERARCHY":"2.X.2.1.1.7.14","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.SUWR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control MIW - Fixed Wing","HIERARCHY":"2.X.2.1.1.7.15","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.MIWF","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control MIW - Rotary Wing","HIERARCHY":"2.X.2.1.1.7.16","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.MIWR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAF--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Unmanned Aerial System (UAS/UA)","HIERARCHY":"2.X.2.1.1.7.17","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.UA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAG--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control VTUA","HIERARCHY":"2.X.2.1.1.7.18","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.VTUA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAI--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Orbit","HIERARCHY":"2.X.2.1.1.7.19","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ORB","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAJ--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Orbit - Figure Eight","HIERARCHY":"2.X.2.1.1.7.20","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ORBF8","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Orbit - Race Track","HIERARCHY":"2.X.2.1.1.7.21","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ORBRT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPAN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Air Control Orbit - Random, Closed","HIERARCHY":"2.X.2.1.1.7.22","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTL.ORBRD","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Air Control"},{"SYMBOLID":"G*G*GPP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.H1.T.W.W1.N.","DESCRIPTION":"Action Point","HIERARCHY":"2.X.2.1.1.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPPK--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Check Point","HIERARCHY":"2.X.2.1.1.8.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.CHKPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Contact Point","HIERARCHY":"2.X.2.1.1.8.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.CONPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPO--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"N.","DESCRIPTION":"Coordination Point","HIERARCHY":"2.X.2.1.1.8.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.CRDPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPD--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Decision Point","HIERARCHY":"2.X.2.1.1.8.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.DCNPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPL--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Linkup Point","HIERARCHY":"2.X.2.1.1.8.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.LNKUPT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Passage Point","HIERARCHY":"2.X.2.1.1.8.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.PSSPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Rally Point","HIERARCHY":"2.X.2.1.1.8.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.RAYPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Release Point (RP)","HIERARCHY":"2.X.2.1.1.8.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.RELPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Start Point (SP)","HIERARCHY":"2.X.2.1.1.8.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.STRPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPW--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.N.","DESCRIPTION":"Waypoint","HIERARCHY":"2.X.2.1.1.8.10","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.WAP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Point"},{"SYMBOLID":"G*G*GPPA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Amnesty Point","HIERARCHY":"2.X.2.1.1.8.11","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.AMNPNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Action Points"},{"SYMBOLID":"G*G*GPPN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.H.W.W1.N.","DESCRIPTION":"Entry Control Point","HIERARCHY":"2.X.2.1.1.8.12","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.ACTPNT.ECPNT","PATH":"Tactical Graphics/Tasks"},{"SYMBOLID":"G*G*GPC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Surface Control Station","HIERARCHY":"2.X.2.1.1.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPCU--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Unmanned Surface Vehicle (USV) Control Station","HIERARCHY":"2.X.2.1.1.9.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.USV","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCUR-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Remote Multimission Vehicle (RMV) USV Control Station","HIERARCHY":"2.X.2.1.1.9.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.USV.RMV","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station/Unmanned Surface Vehicle (USV) Control Station"},{"SYMBOLID":"G*G*GPCUA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"USV - Antisubmarine Warfare Control Station","HIERARCHY":"2.X.2.1.1.9.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.USV.ASW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station/Unmanned Surface Vehicle (USV) Control Station"},{"SYMBOLID":"G*G*GPCUS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"USV - Surface Warfare Control Station","HIERARCHY":"2.X.2.1.1.9.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.USV.SUW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station/Unmanned Surface Vehicle (USV) Control Station"},{"SYMBOLID":"G*G*GPCUM-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"USV - Mine Warfare Control Station","HIERARCHY":"2.X.2.1.1.9.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.USV.MIW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station/Unmanned Surface Vehicle (USV) Control Station"},{"SYMBOLID":"G*G*GPCA--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"ASW Control Station","HIERARCHY":"2.X.2.1.1.9.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.ASW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"SUW Control Station","HIERARCHY":"2.X.2.1.1.9.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.SUW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"MIW Control Station","HIERARCHY":"2.X.2.1.1.9.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.MIW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Picket Control Station","HIERARCHY":"2.X.2.1.1.9.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.PKT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rendezvous Control Point","HIERARCHY":"2.X.2.1.1.9.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.RDV","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rescue Control Point","HIERARCHY":"2.X.2.1.1.9.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.RSC","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCE--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Replenishment Control Point","HIERARCHY":"2.X.2.1.1.9.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.REP","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPCN--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Noncombatant Control Station","HIERARCHY":"2.X.2.1.1.9.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.SCTL.NCBTT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Sea Surface Control Station"},{"SYMBOLID":"G*G*GPB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Subsurface Control Station","HIERARCHY":"2.X.2.1.1.10","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points"},{"SYMBOLID":"G*G*GPBU--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Unmanned Underwater Vehicle (UUV) Control Station","HIERARCHY":"2.X.2.1.1.10.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.UUV","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station"},{"SYMBOLID":"G*G*GPBUA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"UUV - Antisubmarine Warfare Control Station","HIERARCHY":"2.X.2.1.1.10.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.UUV.ASW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station/Unmanned Underwater Vehicle (UUV) Control Station"},{"SYMBOLID":"G*G*GPBUS-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"UUV - Surface Warfare Control Station","HIERARCHY":"2.X.2.1.1.10.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.UUV.SUW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station/Unmanned Underwater Vehicle (UUV) Control Station"},{"SYMBOLID":"G*G*GPBUM-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"UUV - Mine Warfare Control Station","HIERARCHY":"2.X.2.1.1.10.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.UUV.MIW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station/Unmanned Underwater Vehicle (UUV) Control Station"},{"SYMBOLID":"G*G*GPBS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Submarine Control Station","HIERARCHY":"2.X.2.1.1.10.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.SBSTN","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station"},{"SYMBOLID":"G*G*GPBSA-****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"ASW Submarine Control Station","HIERARCHY":"2.X.2.1.1.10.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.PNT.UCTL.SBSTN.ASW","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Points/Subsurface Control Station/Submarine Control Station"},{"SYMBOLID":"G*G*GL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GLB---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"B.N.T.T1.","DESCRIPTION":"Boundary","HIERARCHY":"2.X.2.1.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE.BNDS","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Forward Line of Own Troops","HIERARCHY":"2.X.2.1.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE.FLOT","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"N.","DESCRIPTION":"Line of Contact (LC)","HIERARCHY":"2.X.2.1.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE.LOC","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLP---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Phase Line","HIERARCHY":"2.X.2.1.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE.PHELNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GLL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Light Line","HIERARCHY":"2.X.2.1.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.LNE.LITLNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Lines"},{"SYMBOLID":"G*G*GA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS","PATH":"Tactical Graphics/Command and Control and General Maneuver/General"},{"SYMBOLID":"G*G*GAG---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"General Area","HIERARCHY":"2.X.2.1.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.GENARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Assembly Area","HIERARCHY":"2.X.2.1.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.ABYARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Engagement Area (General)","HIERARCHY":"2.X.2.1.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.EMTARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Fortified Area","HIERARCHY":"2.X.2.1.3.4","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.FTFDAR","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Drop Zone","HIERARCHY":"2.X.2.1.3.5","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.DRPZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAX---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Extraction Zone","HIERARCHY":"2.X.2.1.3.6","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.EZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAL---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Landing Zone (LZ)","HIERARCHY":"2.X.2.1.3.7","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.LZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAP---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.T.","DESCRIPTION":"Pickup Zone (PZ)","HIERARCHY":"2.X.2.1.3.8","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.PZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAS---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Search Area/Reconnaissance Area","HIERARCHY":"2.X.2.1.3.9","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.SRHARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAY---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Limited Access Area","HIERARCHY":"2.X.2.1.3.10","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.LAARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*GAZ---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Airfield Zone","HIERARCHY":"2.X.2.1.3.11","ALPHAHIERARCHY":"TACGRP.C2GM.GNL.ARS.AIRFZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/General/Areas"},{"SYMBOLID":"G*G*A-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Aviation","HIERARCHY":"2.X.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*AP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.PNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*APP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Air Control Point (ACP)","HIERARCHY":"2.X.2.2.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.PNT.ACP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Communications Checkpoint (CCP)","HIERARCHY":"2.X.2.2.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.PNT.COMMCP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APU---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pull-Up Point (PUP)","HIERARCHY":"2.X.2.2.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.PNT.PUP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*APD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"N.","DESCRIPTION":"Downed Aircrew Pickup Point","HIERARCHY":"2.X.2.2.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.PNT.DAPP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Points"},{"SYMBOLID":"G*G*AL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*ALC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"X.X1.T.W.W1.AM.","DESCRIPTION":"Air Corridor","HIERARCHY":"2.X.2.2.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE.ACDR","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"X.X1.T.W.W1.AM.","DESCRIPTION":"Minimum Risk Route (MRR)","HIERARCHY":"2.X.2.2.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE.MRR","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALS---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"X.X1.T.W.W1.AM.","DESCRIPTION":"Standard-Use Army Aircraft Flight Route (SAAFR)","HIERARCHY":"2.X.2.2.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE.SAAFR","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALU---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"X.X1.T.W.W1.AM.","DESCRIPTION":"Unmanned Aircraft (UA) Route","HIERARCHY":"2.X.2.2.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE.UAR","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*ALL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"X.X1.T.W.W1.AM.","DESCRIPTION":"Low Level Transit Route (LLTR)","HIERARCHY":"2.X.2.2.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.LNE.LLTR","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Lines"},{"SYMBOLID":"G*G*AA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation"},{"SYMBOLID":"G*G*AAR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"Restricted Operations Zone (ROZ)","HIERARCHY":"2.X.2.2.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.ROZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"Short-Range Air Defense Engagement Zone (SHORADEZ)","HIERARCHY":"2.X.2.2.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.SHRDEZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAH---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"High Density Airspace Control Zone (HIDACZ)","HIERARCHY":"2.X.2.2.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.HIDACZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAM---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"Missile Engagement Zone (MEZ)","HIERARCHY":"2.X.2.2.3.4","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.MEZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*AAML--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"Low Altitude MEZ","HIERARCHY":"2.X.2.2.3.4.1","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.MEZ.LAMEZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas/Missile Engagement Zone (MEZ)"},{"SYMBOLID":"G*G*AAMH--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.T.W.W1.","DESCRIPTION":"High Altitude MEZ","HIERARCHY":"2.X.2.2.3.4.2","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.MEZ.HAMEZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas/Missile Engagement Zone (MEZ)"},{"SYMBOLID":"G*G*AAW---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Weapons Free Zone","HIERARCHY":"2.X.2.2.3.5","ALPHAHIERARCHY":"TACGRP.C2GM.AVN.ARS.WFZ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Aviation/Areas"},{"SYMBOLID":"G*G*P-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Deception","HIERARCHY":"2.X.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*PD----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Dummy (Deception/Decoy)","HIERARCHY":"2.X.2.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DMY","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PA----****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Axis of Advance for Feint","HIERARCHY":"2.X.2.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.AAFF","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PF----****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Direction of Attack for Feint","HIERARCHY":"2.X.2.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DAFF","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PM----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Decoy Mined Area","HIERARCHY":"2.X.2.3.4","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DMA","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PY----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Decoy Mined Area, Fenced","HIERARCHY":"2.X.2.3.5","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DMAF","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PN----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dummy Minefield - Static","HIERARCHY":"2.X.2.3.6","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DMYMS","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*PC----****X","GEOMETRY":"area","DRAWCATEGORY":"15","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.N.","DESCRIPTION":"Dummy Minefield - Dynamic","HIERARCHY":"2.X.2.3.7","ALPHAHIERARCHY":"TACGRP.C2GM.DCPN.DMYMD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Deception"},{"SYMBOLID":"G*G*D-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Defense","HIERARCHY":"2.X.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.DEF","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*DP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.4.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DPT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Target Reference","HIERARCHY":"2.X.2.4.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.TGTREF","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points"},{"SYMBOLID":"G*G*DPO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Observation Post (OP)/Outpost","HIERARCHY":"2.X.2.4.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points"},{"SYMBOLID":"G*G*DPOC--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Combat Outpost","HIERARCHY":"2.X.2.4.1.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST.CBTPST","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOR--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Observation Post Occupied Dismounted Recon","HIERARCHY":"2.X.2.4.1.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST.RECON","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOF--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Forward Observer Position Outpost","HIERARCHY":"2.X.2.4.1.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST.FWDOP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPOS--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sensor Outpost/Listening Post (OP/LP)","HIERARCHY":"2.X.2.4.1.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST.SOP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DPON--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"NBC Observation Post Dismounted","HIERARCHY":"2.X.2.4.1.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.PNT.OBSPST.CBRNOP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Points/Observation Post-Outpost"},{"SYMBOLID":"G*G*DL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.4.2","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.LNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Forward Edge of Battle Area","HIERARCHY":"2.X.2.4.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.LNE.FEBA","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Lines"},{"SYMBOLID":"G*G*DLP---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Principal Direction of Fire (PDF)","HIERARCHY":"2.X.2.4.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.LNE.PDF","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Lines"},{"SYMBOLID":"G*G*DA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.4.3","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.ARS","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense"},{"SYMBOLID":"G*G*DAB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.N.T.","DESCRIPTION":"Battle Position","HIERARCHY":"2.X.2.4.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.ARS.BTLPSN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas"},{"SYMBOLID":"G*G*DABP--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.N.T.","DESCRIPTION":"Battle Position Prepared but not Occupied","HIERARCHY":"2.X.2.4.3.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.ARS.BTLPSN.PBNO","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas/Battle Position"},{"SYMBOLID":"G*G*DAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Engagement Area (Defense)","HIERARCHY":"2.X.2.4.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.DEF.ARS.EMTARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/Defense/Areas"},{"SYMBOLID":"G*G*O-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Offense","HIERARCHY":"2.X.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.OFF","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*OP----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.2.5.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.PNT","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OPP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Point of Departure","HIERARCHY":"2.X.2.5.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.PNT.PNTD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Points"},{"SYMBOLID":"G*G*OL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.2.5.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OLA---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Axis of Advance","HIERARCHY":"2.X.2.5.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLAV--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Aviation","HIERARCHY":"2.X.2.5.2.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.AVN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAA--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"A.","DESCRIPTION":"Axis of Advance Airborne","HIERARCHY":"2.X.2.5.2.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.ABN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAR--****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Attack, Rotary Wing","HIERARCHY":"2.X.2.5.2.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.ATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAG--****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Axis of Advance Ground","HIERARCHY":"2.X.2.5.2.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.GRD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance"},{"SYMBOLID":"G*G*OLAGM-****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Ground Main Attack","HIERARCHY":"2.X.2.5.2.1.4.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.GRD.MANATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance/Axis of Advance Ground"},{"SYMBOLID":"G*G*OLAGS-****X","GEOMETRY":"line","DRAWCATEGORY":"5","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Axis of Advance Ground Supporting Attack","HIERARCHY":"2.X.2.5.2.1.4.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.AXSADV.GRD.SUPATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Axis of Advance/Axis of Advance Ground"},{"SYMBOLID":"G*G*OLK---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Direction of Attack","HIERARCHY":"2.X.2.5.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.DIRATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLKA--****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"N.","DESCRIPTION":"Direction of Attack Aviation","HIERARCHY":"2.X.2.5.2.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.DIRATK.AVN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack"},{"SYMBOLID":"G*G*OLKG--****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Direction of Attack Ground","HIERARCHY":"2.X.2.5.2.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.DIRATK.GRD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack"},{"SYMBOLID":"G*G*OLKGM-****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Direction of Attack Ground Main Attack","HIERARCHY":"2.X.2.5.2.2.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.DIRATK.GRD.MANATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack/Direction of Attack Ground"},{"SYMBOLID":"G*G*OLKGS-****X","GEOMETRY":"line","DRAWCATEGORY":"4","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Direction of Attack Ground Supporting Attack","HIERARCHY":"2.X.2.5.2.2.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.DIRATK.GRD.SUPATK","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines/Direction of Attack/Direction of Attack Ground"},{"SYMBOLID":"G*G*OLF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Final Coordination Line","HIERARCHY":"2.X.2.5.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.FCL","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLI---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Infiltration Lane","HIERARCHY":"2.X.2.5.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.INFNLE","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Limit Of Advance (LOA)","HIERARCHY":"2.X.2.5.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.LMTADV","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLT---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line of Departure (LD)","HIERARCHY":"2.X.2.5.2.6","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.LD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Line of Departure/Line of Contact (LD/LC)","HIERARCHY":"2.X.2.5.2.7","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.LDLC","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OLP---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Probable Line of Deployment (PLD)","HIERARCHY":"2.X.2.5.2.8","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.LNE.PLD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Lines"},{"SYMBOLID":"G*G*OA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.2.5.3","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense"},{"SYMBOLID":"G*G*OAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Assault Position","HIERARCHY":"2.X.2.5.3.1","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.ASTPSN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAK---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Attack Position","HIERARCHY":"2.X.2.5.3.2","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.ATKPSN","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAF---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Attack by Fire Position","HIERARCHY":"2.X.2.5.3.3","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.AFP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAS---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Support by Fire Position","HIERARCHY":"2.X.2.5.3.4","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.SFP","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAO---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Objective","HIERARCHY":"2.X.2.5.3.5","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.OBJ","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*OAP---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Penetration Box","HIERARCHY":"2.X.2.5.3.6","ALPHAHIERARCHY":"TACGRP.C2GM.OFF.ARS.PBX","PATH":"Tactical Graphics/Command and Control and General Maneuver/Offense/Areas"},{"SYMBOLID":"G*G*S-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Special","HIERARCHY":"2.X.2.6","ALPHAHIERARCHY":"TACGRP.C2GM.SPL","PATH":"Tactical Graphics/Command and Control and General Maneuver"},{"SYMBOLID":"G*G*SL----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Line","HIERARCHY":"2.X.2.6.1","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.LNE","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special"},{"SYMBOLID":"G*G*SLA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ambush","HIERARCHY":"2.X.2.6.1.1","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.LNE.AMB","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLH---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Holding Line","HIERARCHY":"2.X.2.6.1.2","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.LNE.HGL","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Release Line","HIERARCHY":"2.X.2.6.1.3","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.LNE.REL","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SLB---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Bridgehead","HIERARCHY":"2.X.2.6.1.4","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.LNE.BRGH","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Line"},{"SYMBOLID":"G*G*SA----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Area","HIERARCHY":"2.X.2.6.2","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special"},{"SYMBOLID":"G*G*SAO---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area of Operations (AO)","HIERARCHY":"2.X.2.6.2.1","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA.AOO","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Airhead","HIERARCHY":"2.X.2.6.2.2","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA.AHD","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAE---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Encirclement","HIERARCHY":"2.X.2.6.2.3","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA.ENCMT","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAN---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Named Area of Interest (NAI)","HIERARCHY":"2.X.2.6.2.4","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA.NAI","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*G*SAT---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Targeted Area of Interest (TAI)","HIERARCHY":"2.X.2.6.2.5","ALPHAHIERARCHY":"TACGRP.C2GM.SPL.ARA.TAI","PATH":"Tactical Graphics/Command and Control and General Maneuver/Special/Area"},{"SYMBOLID":"G*M*------****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mobility/Survivability","HIERARCHY":"2.X.3","ALPHAHIERARCHY":"TACGRP.MOBSU","PATH":"Tactical Graphics"},{"SYMBOLID":"G*M*O-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacles","HIERARCHY":"2.X.3.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*OG----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"General (Obstacles)","HIERARCHY":"2.X.3.1.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OGB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.T1.","DESCRIPTION":"Obstacle Belt","HIERARCHY":"2.X.3.1.1.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL.BLT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Obstacle Line","HIERARCHY":"2.X.3.1.1.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL.LNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGZ---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Obstacle Zone","HIERARCHY":"2.X.3.1.1.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL.Z","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGF---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Obstacle Free Area","HIERARCHY":"2.X.3.1.1.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL.OFA","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OGR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Obstacle Restricted Area","HIERARCHY":"2.X.3.1.1.5","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.GNL.ORA","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/General"},{"SYMBOLID":"G*M*OS----****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Abatis","HIERARCHY":"2.X.3.1.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ABS","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OA----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Obstacles","HIERARCHY":"2.X.3.1.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OAD---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Ditch","HIERARCHY":"2.X.3.1.3.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.ATD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OADU--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Under Construction","HIERARCHY":"2.X.3.1.3.1.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.ATD.ATDUC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Ditch"},{"SYMBOLID":"G*M*OADC--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Complete","HIERARCHY":"2.X.3.1.3.1.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.ATD.ATDC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Ditch"},{"SYMBOLID":"G*M*OAR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Ditch Reinforced with Antitank Mines","HIERARCHY":"2.X.3.1.3.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.ATDATM","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OAO---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles","HIERARCHY":"2.X.3.1.3.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.TDTSM","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OAOF--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Fixed and Prefabricated","HIERARCHY":"2.X.3.1.3.3.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.TDTSM.FIXPFD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAOM--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Moveable","HIERARCHY":"2.X.3.1.3.3.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.TDTSM.MVB","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAOP--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Obstacles Moveable and Prefabricated","HIERARCHY":"2.X.3.1.3.3.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.TDTSM.MVBPFD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles/Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles"},{"SYMBOLID":"G*M*OAW---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Antitank Wall","HIERARCHY":"2.X.3.1.3.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.ATO.ATW","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Antitank Obstacles"},{"SYMBOLID":"G*M*OB----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Booby Trap","HIERARCHY":"2.X.3.1.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.BBY","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OM----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mines","HIERARCHY":"2.X.3.1.5","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OMU---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Unspecified Mine","HIERARCHY":"2.X.3.1.5.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.USPMNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine","HIERARCHY":"2.X.3.1.5.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.ATMNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine With Antihandling Device","HIERARCHY":"2.X.3.1.5.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.ATMAHD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OME---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antitank Mine, Directional","HIERARCHY":"2.X.3.1.5.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.ATMDIR","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Antipersonnel Mine","HIERARCHY":"2.X.3.1.5.5","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.APMNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMW---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wide Area Mines","HIERARCHY":"2.X.3.1.5.6","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.WAMNE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OMC---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Mine Cluster","HIERARCHY":"2.X.3.1.5.7","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNE.MCLST","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Mines"},{"SYMBOLID":"G*M*OF----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Minefields","HIERARCHY":"2.X.3.1.6","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNEFLD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OFS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.W.A.","DESCRIPTION":"Minefield (Static)","HIERARCHY":"2.X.3.1.6.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNEFLD.STC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.N.W.","DESCRIPTION":"Minefield (Dynamic)","HIERARCHY":"2.X.3.1.6.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNEFLD.DYN","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFG---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","MODIFIERS":"W.W1.","DESCRIPTION":"Minefields Gap","HIERARCHY":"2.X.3.1.6.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNEFLD.GAP","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OFA---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"N.","DESCRIPTION":"Mined Area","HIERARCHY":"2.X.3.1.6.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.MNEFLD.MNDARA","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Minefields"},{"SYMBOLID":"G*M*OE----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Effect","HIERARCHY":"2.X.3.1.7","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.OBSEFT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OEB---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Block Obstacle Effect","HIERARCHY":"2.X.3.1.7.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.OBSEFT.BLK","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OEF---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Fix (Obstacle Effect)","HIERARCHY":"2.X.3.1.7.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.OBSEFT.FIX","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OET---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Turn","HIERARCHY":"2.X.3.1.7.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.OBSEFT.TUR","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OED---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Disrupt Obstacle Effect","HIERARCHY":"2.X.3.1.7.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.OBSEFT.DRT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Obstacle Effect"},{"SYMBOLID":"G*M*OU----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Unexploded Ordnance Area (UXO)","HIERARCHY":"2.X.3.1.8","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.UXO","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OR----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Roadblocks, Craters, and Blown Bridges","HIERARCHY":"2.X.3.1.9","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.RCBB","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*ORP---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Planned","HIERARCHY":"2.X.3.1.9.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.RCBB.PLND","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORS---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Explosives State of Readiness 1 (Safe)","HIERARCHY":"2.X.3.1.9.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.RCBB.SAFE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Explosives State of Readiness 2 (Armed - but Passable)","HIERARCHY":"2.X.3.1.9.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.RCBB.ABP","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*ORC---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"RCBB Roadblock Complete (Executed)","HIERARCHY":"2.X.3.1.9.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.RCBB.EXCD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Roadblocks, Craters, and Blown Bridges"},{"SYMBOLID":"G*M*OT----****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Trip Wire","HIERARCHY":"2.X.3.1.10","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.TRIPWR","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OW----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Wire Obstacle","HIERARCHY":"2.X.3.1.11","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OWU---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Unspecified","HIERARCHY":"2.X.3.1.11.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.USP","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWS---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Single Fence","HIERARCHY":"2.X.3.1.11.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.SNGFNC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWD---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Fence","HIERARCHY":"2.X.3.1.11.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.DBLFNC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWA---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Apron Fence","HIERARCHY":"2.X.3.1.11.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.DAFNC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWL---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Low Wire Fence","HIERARCHY":"2.X.3.1.11.5","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.LWFNC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWH---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle High Wire Fence","HIERARCHY":"2.X.3.1.11.6","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.HWFNC","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWC---****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Concertina","HIERARCHY":"2.X.3.1.11.7","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.CCTA","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle"},{"SYMBOLID":"G*M*OWCS--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Single Concertina","HIERARCHY":"2.X.3.1.11.7.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.CCTA.SNG","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*OWCD--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Double Strand Concertina","HIERARCHY":"2.X.3.1.11.7.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.CCTA.DBLSTD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*OWCT--****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Wire Obstacle Triple Strand Concertina","HIERARCHY":"2.X.3.1.11.7.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.WREOBS.CCTA.TRISTD","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Wire Obstacle/Concertina"},{"SYMBOLID":"G*M*OH----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Aviation","HIERARCHY":"2.X.3.1.12","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.AVN","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles"},{"SYMBOLID":"G*M*OHT---****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tower","HIERARCHY":"2.X.3.1.12.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.AVN.TWR","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Aviation"},{"SYMBOLID":"G*M*OHTL--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Aviation Tower Low","HIERARCHY":"2.X.3.1.12.1.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.AVN.TWR.LOW","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Aviation/Tower"},{"SYMBOLID":"G*M*OHTH--****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Aviation Tower High","HIERARCHY":"2.X.3.1.12.1.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.AVN.TWR.HIGH","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Aviation/Tower"},{"SYMBOLID":"G*M*OHO---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Overhead Wire","HIERARCHY":"2.X.3.1.12.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBST.AVN.TWR.HIGH","PATH":"Tactical Graphics/Mobility-Survivability/Obstacles/Aviation"},{"SYMBOLID":"G*M*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Bypass","HIERARCHY":"2.X.3.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*BD----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Obstacle Bypass Difficulty","HIERARCHY":"2.X.3.2.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.DFTY","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass"},{"SYMBOLID":"G*M*BDE---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Easy","HIERARCHY":"2.X.3.2.1.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.DFTY.ESY","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BDD---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Difficult","HIERARCHY":"2.X.3.2.1.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.DFTY.DFT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BDI---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Bypass Impossible","HIERARCHY":"2.X.3.2.1.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.DFTY.IMP","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Obstacle Bypass Difficulty"},{"SYMBOLID":"G*M*BC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Crossing Site/Water Crossing","HIERARCHY":"2.X.3.2.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass"},{"SYMBOLID":"G*M*BCA---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Assault Crossing Area","HIERARCHY":"2.X.3.2.2.1","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.ASTCA","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCB---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Bridge or Gap","HIERARCHY":"2.X.3.2.2.2","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.BRG","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCF---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Ferry","HIERARCHY":"2.X.3.2.2.3","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.FRY","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCE---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ford Easy","HIERARCHY":"2.X.3.2.2.4","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.FRDESY","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCD---****X","GEOMETRY":"line","DRAWCATEGORY":"15","MAXPOINTS":"3","MINPOINTS":"3","DESCRIPTION":"Ford Difficult","HIERARCHY":"2.X.3.2.2.5","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.FRDDFT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCL---****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Lane","HIERARCHY":"2.X.3.2.2.6","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.LANE","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCR---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Raft Site","HIERARCHY":"2.X.3.2.2.7","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.RFT","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*BCP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Engineer Regulating Point","HIERARCHY":"2.X.3.2.2.8","ALPHAHIERARCHY":"TACGRP.MOBSU.OBSTBP.CSGSTE.ERP","PATH":"Tactical Graphics/Mobility-Survivability/Obstacle Bypass/Crossing Site-Water Crossing"},{"SYMBOLID":"G*M*S-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Survivability","HIERARCHY":"2.X.3.3","ALPHAHIERARCHY":"TACGRP.MOBSU.SU","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*SE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Earthwork, Small Trench or Fortification","HIERARCHY":"2.X.3.3.1","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.ESTOF","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SF----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fort","HIERARCHY":"2.X.3.3.2","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.FRT","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SL----****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Fortified Line","HIERARCHY":"2.X.3.3.3","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.FTFDLN","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SW----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Foxhole, Emplacement or Weapon Site","HIERARCHY":"2.X.3.3.4","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.FEWS","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SP----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"B.T.","DESCRIPTION":"Strong Point","HIERARCHY":"2.X.3.3.5","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.STRGPT","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SS----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Shelter","HIERARCHY":"2.X.3.3.6","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.SUFSHL","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*SU----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Underground Shelter","HIERARCHY":"2.X.3.3.7","ALPHAHIERARCHY":"TACGRP.MOBSU.SU.UGDSHL","PATH":"Tactical Graphics/Mobility-Survivability/Survivability"},{"SYMBOLID":"G*M*N-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Nuclear, Biological, and Chemical","HIERARCHY":"2.X.3.4","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN","PATH":"Tactical Graphics/Mobility-Survivability"},{"SYMBOLID":"G*M*NM----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"4","MINPOINTS":"4","DESCRIPTION":"Minimum Safe Distance Zones","HIERARCHY":"2.X.3.4.1","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.MSDZ","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NZ----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"C.H.N.Q.T.V.W.Y.","DESCRIPTION":"Nuclear Detonations Ground Zero","HIERARCHY":"2.X.3.4.2","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.NDGZ","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NF----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fallout Producing","HIERARCHY":"2.X.3.4.3","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.FAOTP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NR----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Radioactive Area","HIERARCHY":"2.X.3.4.4","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.RADA","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NB----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Biologically Contaminated Area","HIERARCHY":"2.X.3.4.5","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.BIOCA","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NC----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Chemically Contaminated Area","HIERARCHY":"2.X.3.4.6","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.CMLCA","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NE----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Release Events","HIERARCHY":"2.X.3.4.7","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.REEVNT","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NEB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.Q.T.W.Y.","DESCRIPTION":"Biological Event","HIERARCHY":"2.X.3.4.7.1","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.REEVNT.BIO","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Release Events"},{"SYMBOLID":"G*M*NEC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.N.Q.T.W.Y.","DESCRIPTION":"Chemical Event","HIERARCHY":"2.X.3.4.7.2","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.REEVNT.CML","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Release Events"},{"SYMBOLID":"G*M*ND----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Decontamination (DECON) Points","HIERARCHY":"2.X.3.4.8","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*M*NDP---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Unspecified","HIERARCHY":"2.X.3.4.8.1","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.USP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDA---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Alternate Decon Site/Point Unspecified","HIERARCHY":"2.X.3.4.8.2","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.ALTUSP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Troops","HIERARCHY":"2.X.3.4.8.3","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.TRP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDE---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Equipment","HIERARCHY":"2.X.3.4.8.4","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.EQT","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Equipment and Troops","HIERARCHY":"2.X.3.4.8.5","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.EQTTRP","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDO---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Operational Decontamination","HIERARCHY":"2.X.3.4.8.6","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.OPDECN","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NDD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Decon Site/Point Thorough Decontamination","HIERARCHY":"2.X.3.4.8.7","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DECONP.TRGH","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical/Decontamination (DECON) Points"},{"SYMBOLID":"G*M*NL----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Dose Rate Contour Lines","HIERARCHY":"2.X.3.4.9","ALPHAHIERARCHY":"TACGRP.MOBSU.CBRN.DRCL","PATH":"Tactical Graphics/Mobility-Survivability/Nuclear, Biological, and Chemical"},{"SYMBOLID":"G*F*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fire Support","HIERARCHY":"2.X.4","ALPHAHIERARCHY":"TACGRP.FSUPP","PATH":"Tactical Graphics"},{"SYMBOLID":"G*F*P-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.4.1","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*PT----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target","HIERARCHY":"2.X.4.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.TGT","PATH":"Tactical Graphics/Fire Support/Points"},{"SYMBOLID":"G*F*PTS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.H1.T.","DESCRIPTION":"Point/Single Target","HIERARCHY":"2.X.4.1.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.TGT.PTGT","PATH":"Tactical Graphics/Fire Support/Points/Target"},{"SYMBOLID":"G*F*PTN---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Nuclear Target","HIERARCHY":"2.X.4.1.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.TGT.NUCTGT","PATH":"Tactical Graphics/Fire Support/Points/Target"},{"SYMBOLID":"G*F*PC----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control","HIERARCHY":"2.X.4.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT","PATH":"Tactical Graphics/Fire Support/Points"},{"SYMBOLID":"G*F*PCF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.","DESCRIPTION":"Fire Support Station","HIERARCHY":"2.X.4.1.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.FSS","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Survey Control Point","HIERARCHY":"2.X.4.1.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.SCP","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Firing Point","HIERARCHY":"2.X.4.1.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.FP","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCR---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Reload Point","HIERARCHY":"2.X.4.1.2.4","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.RP","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Hide Point","HIERARCHY":"2.X.4.1.2.5","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.HP","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*PCL---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Launch Point","HIERARCHY":"2.X.4.1.2.6","ALPHAHIERARCHY":"TACGRP.FSUPP.PNT.C2PNT.LP","PATH":"Tactical Graphics/Fire Support/Points/Command and Control"},{"SYMBOLID":"G*F*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.4.2","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*LT----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Linear Target","HIERARCHY":"2.X.4.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.LNRTGT","PATH":"Tactical Graphics/Fire Support/Lines"},{"SYMBOLID":"G*F*LTS---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Linear Smoke Target","HIERARCHY":"2.X.4.2.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.LNRTGT.LSTGT","PATH":"Tactical Graphics/Fire Support/Lines/Linear Target"},{"SYMBOLID":"G*F*LTF---****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.T1.","DESCRIPTION":"Final Protective Fire","HIERARCHY":"2.X.4.2.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.LNRTGT.FPF","PATH":"Tactical Graphics/Fire Support/Lines/Linear Target"},{"SYMBOLID":"G*F*LC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control Lines","HIERARCHY":"2.X.4.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE","PATH":"Tactical Graphics/Fire Support/Lines"},{"SYMBOLID":"G*F*LCF---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Fire Support Coordination Line","HIERARCHY":"2.X.4.2.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE.FSCL","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCC---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Coordinated Fire Line (CFL)","HIERARCHY":"2.X.4.2.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE.CFL","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCN---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"No-Fire Line (NFL)","HIERARCHY":"2.X.4.2.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE.NFL","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCR---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.W.W1.","DESCRIPTION":"Restrictive Fire Line (RFL)","HIERARCHY":"2.X.4.2.2.4","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE.RFL","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*LCM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"W.W1.","DESCRIPTION":"Munition Flight Path (MFP)","HIERARCHY":"2.X.4.2.2.5","ALPHAHIERARCHY":"TACGRP.FSUPP.LNE.C2LNE.MFP","PATH":"Tactical Graphics/Fire Support/Lines/Command and Control Lines"},{"SYMBOLID":"G*F*A-----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Areas","HIERARCHY":"2.X.4.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS","PATH":"Tactical Graphics/Fire Support"},{"SYMBOLID":"G*F*AT----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Area Target","HIERARCHY":"2.X.4.3.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*ATR---****X","GEOMETRY":"area","DRAWCATEGORY":"17","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.AM.AN.","DESCRIPTION":"Rectangular Target","HIERARCHY":"2.X.4.3.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT.RTGTGT","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATC---****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.AM.","DESCRIPTION":"Circular Target","HIERARCHY":"2.X.4.3.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT.CIRTGT","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATG---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Group of Targets","HIERARCHY":"2.X.4.3.1.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT.SGTGT","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATS---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.","DESCRIPTION":"Smoke Area","HIERARCHY":"2.X.4.3.1.4","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT.SMK","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*ATB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bomb Area","HIERARCHY":"2.X.4.3.1.5","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.ARATGT.BMARA","PATH":"Tactical Graphics/Fire Support/Areas/Area Target"},{"SYMBOLID":"G*F*AC----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Command and Control Areas","HIERARCHY":"2.X.4.3.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*ACS---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"T.W.W1.","DESCRIPTION":"Fire Support Area (FSA)","HIERARCHY":"2.X.4.3.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FSA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACSI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1","DESCRIPTION":"Fire Support Area (FSA) Irregular","HIERARCHY":"2.X.4.3.2.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FSA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACSR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Fire Support Area (FSA) Rectangular","HIERARCHY":"2.X.4.3.2.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FSA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACSC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Fire Support Area (FSA) Circular","HIERARCHY":"2.X.4.3.2.1.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FSA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Fire Support Area (FSA)"},{"SYMBOLID":"G*F*ACA---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Airspace Coordination Area (ACA)","HIERARCHY":"2.X.4.3.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ACA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACAI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"X.X1.H2.T.W.W1.","DESCRIPTION":"Airspace Coordination Area (ACA) Irregular","HIERARCHY":"2.X.4.3.2.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ACA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACAR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.X.X1.H2.W.W1.AM.","DESCRIPTION":"Airspace Coordination Area (ACA) Rectangular","HIERARCHY":"2.X.4.3.2.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ACA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACAC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.X.X1.H2.W.W1.AM.","DESCRIPTION":"Airspace Coordination Area (ACA) Circular","HIERARCHY":"2.X.4.3.2.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ACA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Airspace Coordination Area (ACA)"},{"SYMBOLID":"G*F*ACF---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"T.W.W1.","DESCRIPTION":"Free Fire Area (FFA)","HIERARCHY":"2.X.4.3.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FFA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACFI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Free Fire Area (FFA) Irregular","HIERARCHY":"2.X.4.3.2.3.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FFA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACFR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Free Fire Area (FFA) Rectangular","HIERARCHY":"2.X.4.3.2.3.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FFA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACFC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Free Fire Area (FFA) Circular","HIERARCHY":"2.X.4.3.2.3.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.FFA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Free Fire Area (FFA)"},{"SYMBOLID":"G*F*ACN---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"No-Fire Area (NFA)","HIERARCHY":"2.X.4.3.2.4","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.NFA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACNI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"No-Fire Area (NFA) Irregular","HIERARCHY":"2.X.4.3.2.4.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.NFA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA)"},{"SYMBOLID":"G*F*ACNR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"No-Fire Area (NFA) Rectangular","HIERARCHY":"2.X.4.3.2.4.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.NFA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA)"},{"SYMBOLID":"G*F*ACNC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"No-Fire Area (NFA) Circular","HIERARCHY":"2.X.4.3.2.4.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.NFA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/No-Fire Area (NFA)"},{"SYMBOLID":"G*F*ACR---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Restrictive Fire Area (RFA)","HIERARCHY":"2.X.4.3.2.5","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.RFA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACRI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Restrictive Fire Area (RFA) Irregular","HIERARCHY":"2.X.4.3.2.5.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.RFA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA)"},{"SYMBOLID":"G*F*ACRR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Restrictive Fire Area (RFA) Rectangular","HIERARCHY":"2.X.4.3.2.5.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.RFA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA)"},{"SYMBOLID":"G*F*ACRC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Restrictive Fire Area (RFA) Circular","HIERARCHY":"2.X.4.3.2.5.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.RFA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Restrictive Fire Area (RFA)"},{"SYMBOLID":"G*F*ACP---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Position Area for Artillery (PAA)","HIERARCHY":"2.X.4.3.2.6","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.PAA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACPR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"AM.","DESCRIPTION":"Position Area for Artillery (PAA) Rectangular","HIERARCHY":"2.X.4.3.2.6.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.PAA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Position Area for Artillery (PAA)"},{"SYMBOLID":"G*F*ACPC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"AM.","DESCRIPTION":"Position Area For Artillery (PAA) Circular","HIERARCHY":"2.X.4.3.2.6.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.PAA.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Position Area for Artillery (PAA)"},{"SYMBOLID":"G*F*ACE---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Sensor Zone","HIERARCHY":"2.X.4.3.2.7","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.SNSZ","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACEI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Sensor Zone Irregular","HIERARCHY":"2.X.4.3.2.7.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.SNSZ.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Sensor Zone"},{"SYMBOLID":"G*F*ACER--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Sensor Zone Rectangular","HIERARCHY":"2.X.4.3.2.7.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.SNSZ.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Sensor Zone"},{"SYMBOLID":"G*F*ACEC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Sensor Zone Circular","HIERARCHY":"2.X.4.3.2.7.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.SNSZ.CIRCL","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Sensor Zone"},{"SYMBOLID":"G*F*ACD---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dead Space Area (DA)","HIERARCHY":"2.X.4.3.2.8","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.DA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACDI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Dead Space Area (DA) Irregular","HIERARCHY":"2.X.4.3.2.8.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.DA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Dead Space Area (DA)"},{"SYMBOLID":"G*F*ACDR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Dead Space Area (DA) Rectangular","HIERARCHY":"2.X.4.3.2.8.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.DA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Dead Space Area (DA)"},{"SYMBOLID":"G*F*ACDC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Dead Space Area (DA) Circular","HIERARCHY":"2.X.4.3.2.8.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.DA.CIRCL","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Dead Space Area (DA)"},{"SYMBOLID":"G*F*ACZ---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Zone of Responsibility (ZOR)","HIERARCHY":"2.X.4.3.2.9","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ZOR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACZI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Zone of Responsibility (ZOR) Irregular","HIERARCHY":"2.X.4.3.2.9.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ZOR.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Zone of Responsibility (ZOR)"},{"SYMBOLID":"G*F*ACZR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Zone of Responsibility (ZOR) Rectangular","HIERARCHY":"2.X.4.3.2.9.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ZOR.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Zone of Responsibility (ZOR)"},{"SYMBOLID":"G*F*ACZC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Zone of Responsibility (ZOR) Circular","HIERARCHY":"2.X.4.3.2.9.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.ZOR.CIRCL","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Zone of Responsibility (ZOR)"},{"SYMBOLID":"G*F*ACB---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Build-Up Area (TBA)","HIERARCHY":"2.X.4.3.2.10","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TBA","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACBI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Target Build-Up Area (TBA) Irregular","HIERARCHY":"2.X.4.3.2.10.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TBA.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Build-Up Area (TBA)"},{"SYMBOLID":"G*F*ACBR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Target Build-Up Area (TBA) Rectangular","HIERARCHY":"2.X.4.3.2.10.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TBA.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Build-Up Area (TBA)"},{"SYMBOLID":"G*F*ACBC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Target Build-Up Area (TBA) Circular","HIERARCHY":"2.X.4.3.2.10.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TBA.CIRCL","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Build-Up Area (TBA)"},{"SYMBOLID":"G*F*ACV---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Value Area (TVAR)","HIERARCHY":"2.X.4.3.2.11","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TVAR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*ACVI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Target Value Area (TVAR) Irregular","HIERARCHY":"2.X.4.3.2.11.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TVAR.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Value Area (TVAR)"},{"SYMBOLID":"G*F*ACVR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Target Value Area (TVAR) Rectangular","HIERARCHY":"2.X.4.3.2.11.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TVAR.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Value Area (TVAR)"},{"SYMBOLID":"G*F*ACVC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Target Value Area (TVAR) Circular","HIERARCHY":"2.X.4.3.2.11.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TVAR.CIRCL","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas/Target Value Area (TVAR)"},{"SYMBOLID":"G*F*ACT---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Terminally Guided Munition Footprint (TGMF)","HIERARCHY":"2.X.4.3.2.12","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.C2ARS.TGMF","PATH":"Tactical Graphics/Fire Support/Areas/Command and Control Areas"},{"SYMBOLID":"G*F*AZ----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Target Acquisition Zones","HIERARCHY":"2.X.4.3.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*AZI---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Artillery Target Intelligence (ATI)","HIERARCHY":"2.X.4.3.3.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.ATIZ","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZII--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Irregular","HIERARCHY":"2.X.4.3.3.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI)"},{"SYMBOLID":"G*F*AZIR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Rectangular","HIERARCHY":"2.X.4.3.3.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI)"},{"SYMBOLID":"G*F*AZIC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Artillery Target Intelligence (ATI) Zone Circular","HIERARCHY":"2.X.4.3.3.1.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.ATIZ.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Artillery Target Intelligence (ATI)"},{"SYMBOLID":"G*F*AZX---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Call for Fire Zone (CFFZ)","HIERARCHY":"2.X.4.3.3.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFFZ","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZXI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Call For Fire Zone (CFFZ) Irregular","HIERARCHY":"2.X.4.3.3.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone (CFFZ)"},{"SYMBOLID":"G*F*AZXR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Call For Fire Zone (CFFZ) Rectangular","HIERARCHY":"2.X.4.3.3.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone (CFFZ)"},{"SYMBOLID":"G*F*AZXC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM","DESCRIPTION":"Call For Fire Zone (CFFZ) Circular","HIERARCHY":"2.X.4.3.3.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFFZ.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Call for Fire Zone (CFFZ)"},{"SYMBOLID":"G*F*AZC---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Censor Zone","HIERARCHY":"2.X.4.3.3.4","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CNS","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZCI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Censor Zone Irregular","HIERARCHY":"2.X.4.3.3.4.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CNS.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Zone"},{"SYMBOLID":"G*F*AZCR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM","DESCRIPTION":"Censor Zone Rectangular","HIERARCHY":"2.X.4.3.3.4.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CNS.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Zone"},{"SYMBOLID":"G*F*AZCC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Censor Zone Circular","HIERARCHY":"2.X.4.3.3.4.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CNS.RTG.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Censor Zone"},{"SYMBOLID":"G*F*AZF---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Critical Friendly Zone (CFZ)","HIERARCHY":"2.X.4.3.3.6","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFZ","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones"},{"SYMBOLID":"G*F*AZFI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.W.W1.","DESCRIPTION":"Critical Friendly Zone (CFZ) Irregular","HIERARCHY":"2.X.4.3.3.6.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFZ.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone (CFZ)"},{"SYMBOLID":"G*F*AZFR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Critical Friendly Zone (CFZ) Rectangular","HIERARCHY":"2.X.4.3.3.6.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFZ.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone (CFZ)"},{"SYMBOLID":"G*F*AZFC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.W.W1.AM.","DESCRIPTION":"Critical Friendly Zone (CFZ) Circular","HIERARCHY":"2.X.4.3.3.6.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.TGTAQZ.CFZ.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Target Acquisition Zones/Critical Friendly Zone (CFZ)"},{"SYMBOLID":"G*F*AX----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Radar Range Fans","HIERARCHY":"2.X.4.3.4","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.WPNRF","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*AXC---****X","GEOMETRY":"area","DRAWCATEGORY":"19","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.AM.","DESCRIPTION":"Circular Range Fan","HIERARCHY":"2.X.4.3.4.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.WPNRF.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Radar Range Fans"},{"SYMBOLID":"G*F*AXS---****X","GEOMETRY":"area","DRAWCATEGORY":"18","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.AM.AN.","DESCRIPTION":"Sector Range Fan","HIERARCHY":"2.X.4.3.4.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.WPNRF.SCR","PATH":"Tactical Graphics/Fire Support/Areas/Radar Range Fans"},{"SYMBOLID":"G*F*AK----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Kill Box","HIERARCHY":"2.X.4.3.5","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX","PATH":"Tactical Graphics/Fire Support/Areas"},{"SYMBOLID":"G*F*AKB---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Blue","HIERARCHY":"2.X.4.3.5.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.BLUE","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box"},{"SYMBOLID":"G*F*AKBC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Kill Box Blue Circular","HIERARCHY":"2.X.4.3.5.1.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.BLUE.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Blue"},{"SYMBOLID":"G*F*AKBI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.","DESCRIPTION":"Kill Box Blue Irregular","HIERARCHY":"2.X.4.3.5.1.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.BLUE.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Blue"},{"SYMBOLID":"G*F*AKBR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.","DESCRIPTION":"Kill Box Blue Rectangular","HIERARCHY":"2.X.4.3.5.1.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.BLUE.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Blue"},{"SYMBOLID":"G*F*AKP---****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Purple","HIERARCHY":"2.X.4.3.5.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.PURPLE","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box"},{"SYMBOLID":"G*F*AKPC--****X","GEOMETRY":"area","DRAWCATEGORY":"16","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"W.W1.T.AM.X.","DESCRIPTION":"Kill Box Purple Circular","HIERARCHY":"2.X.4.3.5.2.1","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.PURPLE.CIRCLR","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Purple"},{"SYMBOLID":"G*F*AKPI--****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"W.W1.T.X.","DESCRIPTION":"Kill Box Purple Irregular","HIERARCHY":"2.X.4.3.5.2.2","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.PURPLE.IRR","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Purple"},{"SYMBOLID":"G*F*AKPR--****X","GEOMETRY":"area","DRAWCATEGORY":"20","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"W.W1.T.AM.X.","DESCRIPTION":"Kill Box Purple Rectangular","HIERARCHY":"2.X.4.3.5.2.3","ALPHAHIERARCHY":"TACGRP.FSUPP.ARS.KLBOX.PURPLE.RTG","PATH":"Tactical Graphics/Fire Support/Areas/Kill Box/Purple"},{"SYMBOLID":"G*S*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Combat Service Support","HIERARCHY":"2.X.5","ALPHAHIERARCHY":"TACGRP.CSS","PATH":"Tactical Graphics"},{"SYMBOLID":"G*S*P-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Points","HIERARCHY":"2.X.5.1","ALPHAHIERARCHY":"TACGRP.CSS.PNT","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*PX----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.T1.W.W1.N.>","DESCRIPTION":"Ambulance Exchange Point","HIERARCHY":"2.X.5.1.1","ALPHAHIERARCHY":"TACGRP.CSS.PNT.AEP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PC----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Cannibalization Point","HIERARCHY":"2.X.5.1.2","ALPHAHIERARCHY":"TACGRP.CSS.PNT.CBNP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PY----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Casualty Collection Point","HIERARCHY":"2.X.5.1.3","ALPHAHIERARCHY":"TACGRP.CSS.PNT.CCP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PT----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Civilian Collection Point","HIERARCHY":"2.X.5.1.4","ALPHAHIERARCHY":"TACGRP.CSS.PNT.CVP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PD----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Detainee Collection Point","HIERARCHY":"2.X.5.1.5","ALPHAHIERARCHY":"TACGRP.CSS.PNT.DCP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Enemy Prisoner of War Collection Point","HIERARCHY":"2.X.5.1.6","ALPHAHIERARCHY":"TACGRP.CSS.PNT.EPWCP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PL----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Logistics Release Point","HIERARCHY":"2.X.5.1.7","ALPHAHIERARCHY":"TACGRP.CSS.PNT.LRP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Maintenance Collection Point","HIERARCHY":"2.X.5.1.8","ALPHAHIERARCHY":"TACGRP.CSS.PNT.MCP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PR----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Rearm, Refuel and Resupply Point","HIERARCHY":"2.X.5.1.9","ALPHAHIERARCHY":"TACGRP.CSS.PNT.RRRP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PU----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Refuel on the Move Point","HIERARCHY":"2.X.5.1.10","ALPHAHIERARCHY":"TACGRP.CSS.PNT.ROM","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Traffic Control Post (TCP)","HIERARCHY":"2.X.5.1.11","ALPHAHIERARCHY":"TACGRP.CSS.PNT.TCP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PI----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Trailer Transfer Point","HIERARCHY":"2.X.5.1.12","ALPHAHIERARCHY":"TACGRP.CSS.PNT.TTP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PN----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Unit Maintenance Collection Point","HIERARCHY":"2.X.5.1.13","ALPHAHIERARCHY":"TACGRP.CSS.PNT.UMC","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PS----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Supply Points","HIERARCHY":"2.X.5.1.14","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PSZ---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point General","HIERARCHY":"2.X.5.1.14.1","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.GNL","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSA---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class I","HIERARCHY":"2.X.5.1.14.2","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS1","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSB---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class II","HIERARCHY":"2.X.5.1.14.3","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS2","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSC---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class III","HIERARCHY":"2.X.5.1.14.4","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS3","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSD---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class IV","HIERARCHY":"2.X.5.1.14.5","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS4","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSE---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class V","HIERARCHY":"2.X.5.1.14.6","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS5","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSF---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VI","HIERARCHY":"2.X.5.1.14.7","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS6","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSG---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VII","HIERARCHY":"2.X.5.1.14.8","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS7","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSH---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class VIII","HIERARCHY":"2.X.5.1.14.9","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS8","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSI---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class IX","HIERARCHY":"2.X.5.1.14.10","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS9","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PSJ---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Supply Point Class X","HIERARCHY":"2.X.5.1.14.11","ALPHAHIERARCHY":"TACGRP.CSS.PNT.SPT.CLS10","PATH":"Tactical Graphics/Combat Service Support/Points/Supply Points"},{"SYMBOLID":"G*S*PA----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","MODIFIERS":"N.","DESCRIPTION":"Ammunition Points","HIERARCHY":"2.X.5.1.15","ALPHAHIERARCHY":"TACGRP.CSS.PNT.AP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*PAS---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Ammunition Supply Point (ASP)","HIERARCHY":"2.X.5.1.15.1","ALPHAHIERARCHY":"TACGRP.CSS.PNT.AP.ASP","PATH":"Tactical Graphics/Combat Service Support/Points/Ammunition Points"},{"SYMBOLID":"G*S*PAT---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.W.W1.N.","DESCRIPTION":"Ammunition Transfer Point (ATP)","HIERARCHY":"2.X.5.1.15.2","ALPHAHIERARCHY":"TACGRP.CSS.PNT.AP.ATP","PATH":"Tactical Graphics/Combat Service Support/Points/Ammunition Points"},{"SYMBOLID":"G*S*PP----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"H.T.T1.W.W1.","DESCRIPTION":"Medevac Pick-Up Point","HIERARCHY":"2.X.5.1.16","ALPHAHIERARCHY":"TACGRP.CSS.PNT.MPP","PATH":"Tactical Graphics/Combat Service Support/Points"},{"SYMBOLID":"G*S*L-----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"2.X.5.2","ALPHAHIERARCHY":"TACGRP.CSS.LNE","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*LC----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Convoys","HIERARCHY":"2.X.5.2.1","ALPHAHIERARCHY":"TACGRP.CSS.LNE.CNY","PATH":"Tactical Graphics/Combat Service Support/Lines"},{"SYMBOLID":"G*S*LCM---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"A.H.H1.W.W1.","DESCRIPTION":"Moving Convoy","HIERARCHY":"2.X.5.2.1.1","ALPHAHIERARCHY":"TACGRP.CSS.LNE.CNY.MCNY","PATH":"Tactical Graphics/Combat Service Support/Lines/Convoys"},{"SYMBOLID":"G*S*LCH---****X","GEOMETRY":"line","DRAWCATEGORY":"9","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"A.H.H1.W.W1.","DESCRIPTION":"Halted Convoy","HIERARCHY":"2.X.5.2.1.2","ALPHAHIERARCHY":"TACGRP.CSS.LNE.CNY.HCNY","PATH":"Tactical Graphics/Combat Service Support/Lines/Convoys"},{"SYMBOLID":"G*S*LR----****X","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Supply Routes","HIERARCHY":"2.X.5.2.2","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT","PATH":"Tactical Graphics/Combat Service Support/Lines"},{"SYMBOLID":"G*S*LRM---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Main Supply Route","HIERARCHY":"2.X.5.2.2.1","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT.MSRUT","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRA---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Alternate Supply Route","HIERARCHY":"2.X.5.2.2.2","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT.ASRUT","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRO---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route One-Way Traffic","HIERARCHY":"2.X.5.2.2.3","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT.1WTRFF","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRT---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route Alternating Traffic","HIERARCHY":"2.X.5.2.2.4","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT.ATRFF","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*LRW---****X","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","MODIFIERS":"T.","DESCRIPTION":"Supply Route Two-Way Traffic","HIERARCHY":"2.X.5.2.2.5","ALPHAHIERARCHY":"TACGRP.CSS.LNE.SLPRUT.2WTRFF","PATH":"Tactical Graphics/Combat Service Support/Lines/Supply Routes"},{"SYMBOLID":"G*S*A-----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Area","HIERARCHY":"2.X.5.3","ALPHAHIERARCHY":"TACGRP.CSS.ARA","PATH":"Tactical Graphics/Combat Service Support"},{"SYMBOLID":"G*S*AD----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Detainee Holding Area","HIERARCHY":"2.X.5.3.1","ALPHAHIERARCHY":"TACGRP.CSS.ARA.DHA","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AE----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Enemy Prisoner of War Holding Area","HIERARCHY":"2.X.5.3.2","ALPHAHIERARCHY":"TACGRP.CSS.ARA.EPWHA","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AR----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Forward Arming and Refueling Area","HIERARCHY":"2.X.5.3.3","ALPHAHIERARCHY":"TACGRP.CSS.ARA.FARP","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AH----****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Refugee Holding Area","HIERARCHY":"2.X.5.3.4","ALPHAHIERARCHY":"TACGRP.CSS.ARA.RHA","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*AS----****X","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Support Areas","HIERARCHY":"2.X.5.3.5","ALPHAHIERARCHY":"TACGRP.CSS.ARA.SUPARS","PATH":"Tactical Graphics/Combat Service Support/Area"},{"SYMBOLID":"G*S*ASB---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Brigade Support Area (BSA)","HIERARCHY":"2.X.5.3.5.1","ALPHAHIERARCHY":"TACGRP.CSS.ARA.SUPARS.BSA","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*S*ASD---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Division Support Area (DSA)","HIERARCHY":"2.X.5.3.5.2","ALPHAHIERARCHY":"TACGRP.CSS.ARA.SUPARS.DSA","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*S*ASR---****X","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"T.","DESCRIPTION":"Regimental Support Area (RSA)","HIERARCHY":"2.X.5.3.5.3","ALPHAHIERARCHY":"TACGRP.CSS.ARA.SUPARS.RSA","PATH":"Tactical Graphics/Combat Service Support/Area/Support Areas"},{"SYMBOLID":"G*O*------****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Other","HIERARCHY":"2.X.6","ALPHAHIERARCHY":"TACGRP.OTH","PATH":"Tactical Graphics"},{"SYMBOLID":"G*O*E-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Emergency","HIERARCHY":"2.X.6.1","ALPHAHIERARCHY":"TACGRP.OTH.ER","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*ED----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ditched Aircraft","HIERARCHY":"2.X.6.1.1","ALPHAHIERARCHY":"TACGRP.OTH.ER.DTHAC","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*EP----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Person in Water","HIERARCHY":"2.X.6.1.2","ALPHAHIERARCHY":"TACGRP.OTH.ER.PIW","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*ES----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"T.T1.H.W.W1.N.","DESCRIPTION":"Emergency Distress Call","HIERARCHY":"2.X.6.1.4","ALPHAHIERARCHY":"TACGRP.OTH.ER.DSTC","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*EV----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Distressed Vessel","HIERARCHY":"2.X.6.1.3","ALPHAHIERARCHY":"TACGRP.OTH.ER.DSTVES","PATH":"Tactical Graphics/Other/Emergency"},{"SYMBOLID":"G*O*H-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hazard","HIERARCHY":"2.X.6.2","ALPHAHIERARCHY":"TACGRP.OTH.HAZ","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*HM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Mine-Like Hazard","HIERARCHY":"2.X.6.2.1","ALPHAHIERARCHY":"TACGRP.OTH.HAZ.SML","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HN----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Navigational Hazard","HIERARCHY":"2.X.6.2.2","ALPHAHIERARCHY":"TACGRP.OTH.HAZ.NVGL","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HI----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Iceberg Hazard","HIERARCHY":"2.X.6.2.3","ALPHAHIERARCHY":"TACGRP.OTH.HAZ.IB","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*HO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Oil Rig Hazard","HIERARCHY":"2.X.6.2.4","ALPHAHIERARCHY":"TACGRP.OTH.HAZ.OLRG","PATH":"Tactical Graphics/Other/Hazard"},{"SYMBOLID":"G*O*S-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Sea Subsurface Returns","HIERARCHY":"2.X.6.3","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*SB----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bottom Return/Non-Milco","HIERARCHY":"2.X.6.3.1","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.BTMRTN","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*SBM---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Installation/Manmade","HIERARCHY":"2.X.6.3.1.1","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.BTMRTN.INS","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Non-Milco"},{"SYMBOLID":"G*O*SBN---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Seabed Rock/Stone Obstacle","HIERARCHY":"2.X.6.3.1.2","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.BTMRTN.SBRSOO","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Non-Milco"},{"SYMBOLID":"G*O*SBW---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck, Nondangerous","HIERARCHY":"2.X.6.3.1.3","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.BTMRTN.WRKND","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Non-Milco"},{"SYMBOLID":"G*O*SBX---****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck, Dangerous","HIERARCHY":"2.X.6.3.1.4","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.BTMRTN.WRKD","PATH":"Tactical Graphics/Other/Sea Subsurface Returns/Bottom Return-Non-Milco"},{"SYMBOLID":"G*O*SM----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Marine Life","HIERARCHY":"2.X.6.3.2","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.MARLFE","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*SS----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Anomaly","HIERARCHY":"2.X.6.3.3","ALPHAHIERARCHY":"TACGRP.OTH.SSUBSR.SA","PATH":"Tactical Graphics/Other/Sea Subsurface Returns"},{"SYMBOLID":"G*O*B-----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line","HIERARCHY":"2.X.6.4","ALPHAHIERARCHY":"TACGRP.OTH.BERLNE","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*BE----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Electronic","HIERARCHY":"2.X.6.4.1","ALPHAHIERARCHY":"TACGRP.OTH.BERLNE.ELC","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BA----****X","GEOMETRY":"line","DRAWCATEGORY":"2","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Acoustic","HIERARCHY":"2.X.6.4.2","ALPHAHIERARCHY":"TACGRP.OTH.BERLNE.ACU","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BT----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Torpedo","HIERARCHY":"2.X.6.4.3","ALPHAHIERARCHY":"TACGRP.OTH.BERLNE.TPD","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*BO----****X","GEOMETRY":"line","DRAWCATEGORY":"6","MAXPOINTS":"2","MINPOINTS":"2","DESCRIPTION":"Bearing Line Electro-Optical Intercept","HIERARCHY":"2.X.6.4.4","ALPHAHIERARCHY":"TACGRP.OTH.BERLNE.EOPI","PATH":"Tactical Graphics/Other/Bearing Line"},{"SYMBOLID":"G*O*F-----****X","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fix","HIERARCHY":"2.X.6.5","ALPHAHIERARCHY":"TACGRP.OTH.FIX","PATH":"Tactical Graphics/Other"},{"SYMBOLID":"G*O*FA----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Acoustic","HIERARCHY":"2.X.6.5.1","ALPHAHIERARCHY":"TACGRP.OTH.FIX.ACU","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"G*O*FE----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Electro-Magnetic","HIERARCHY":"2.X.6.5.2","ALPHAHIERARCHY":"TACGRP.OTH.FIX.EM","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"G*O*FO----****X","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fix Electro-Optical","HIERARCHY":"2.X.6.5.3","ALPHAHIERARCHY":"TACGRP.OTH.FIX.EOP","PATH":"Tactical Graphics/Other/Fix"},{"SYMBOLID":"W--------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"METOC","HIERARCHY":"3.X","ALPHAHIERARCHY":"METOC"},{"SYMBOLID":"WA-------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Atmospheric","HIERARCHY":"3.X.1","ALPHAHIERARCHY":"METOC.AMPHC","PATH":"METOC"},{"SYMBOLID":"WA--P----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Pressure Systems","HIERARCHY":"3.X.1.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-PL----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Low Pressure Center","HIERARCHY":"3.X.1.1.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LOWCTR","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WAS-PC----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cyclone Center","HIERARCHY":"3.X.1.1.1.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LOWCTR.CYC","PATH":"METOC/Atmospheric/Pressure Systems/Low Pressure Center"},{"SYMBOLID":"WAS-PLT---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause Low","HIERARCHY":"3.X.1.1.1.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LOWCTR.TROPLW","PATH":"METOC/Atmospheric/Pressure Systems/Low Pressure Center"},{"SYMBOLID":"WAS-PH----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"High Pressure Center","HIERARCHY":"3.X.1.1.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.HGHCTR","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WAS-PA----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Anticyclone Center","HIERARCHY":"3.X.1.1.2.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.HGHCTR.ACYC","PATH":"METOC/Atmospheric/Pressure Systems/High Pressure Center"},{"SYMBOLID":"WAS-PHT---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause High","HIERARCHY":"3.X.1.1.2.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.HGHCTR.TROPHG","PATH":"METOC/Atmospheric/Pressure Systems/High Pressure Center"},{"SYMBOLID":"WA-DPF-----L---","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Frontal Systems","HIERARCHY":"3.X.1.1.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WA-DPFC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Front","HIERARCHY":"3.X.1.1.3.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.CLDFRN","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFCU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Cold Front","HIERARCHY":"3.X.1.1.3.1.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.CLDFRN.UPP","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFC-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Frontogenisis","HIERARCHY":"3.X.1.1.3.1.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.CLDFRN.FRGS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFC-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cold Frontolysis","HIERARCHY":"3.X.1.1.3.1.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.CLDFRN.FRLS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Cold Front"},{"SYMBOLID":"WA-DPFW----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Front","HIERARCHY":"3.X.1.1.3.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.WRMFRN","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFWU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Warm Front","HIERARCHY":"3.X.1.1.3.2.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.WRMFRN.UPP","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFW-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Frontogenisis","HIERARCHY":"3.X.1.1.3.2.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.WRMFRN.FRGS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFW-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Warm Frontolysis","HIERARCHY":"3.X.1.1.3.2.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.WRMFRN.FRLS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Warm Front"},{"SYMBOLID":"WA-DPFO----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Occluded Front","HIERARCHY":"3.X.1.1.3.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.OCD","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFOU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Occluded Front","HIERARCHY":"3.X.1.1.3.3.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.OCD.UPP","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Occluded Front"},{"SYMBOLID":"WA-DPFO-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Occluded Frontolysis","HIERARCHY":"3.X.1.1.3.3.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.OCD.FRLS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Occluded Front"},{"SYMBOLID":"WA-DPFS----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Front","HIERARCHY":"3.X.1.1.3.4","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.STAT","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems"},{"SYMBOLID":"WA-DPFSU---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Stationary Front","HIERARCHY":"3.X.1.1.3.4.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.STAT.UPP","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA-DPFS-FG-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Frontogenesis","HIERARCHY":"3.X.1.1.3.4.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.STAT.FRGS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA-DPFS-FY-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stationary Frontolysis","HIERARCHY":"3.X.1.1.3.4.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.FRNSYS.STAT.FRLS","PATH":"METOC/Atmospheric/Pressure Systems/Frontal Systems/Stationary Front"},{"SYMBOLID":"WA--PX---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Lines","HIERARCHY":"3.X.1.1.4","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE","PATH":"METOC/Atmospheric/Pressure Systems"},{"SYMBOLID":"WA-DPXT----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Trough Axis","HIERARCHY":"3.X.1.1.4.1","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.TRUAXS","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXR----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ridge Axis","HIERARCHY":"3.X.1.1.4.2","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.RDGAXS","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXSQ---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Severe Squall Line","HIERARCHY":"3.X.1.1.4.3","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.SSL","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXIL---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Instability Line","HIERARCHY":"3.X.1.1.4.4","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.ISTB","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXSH---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Shear Line","HIERARCHY":"3.X.1.1.4.5","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.SHA","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXITCZ-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Inter-Tropical Convergance Zone","HIERARCHY":"3.X.1.1.4.6","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.ITCZ","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXCV---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Convergance Line","HIERARCHY":"3.X.1.1.4.7","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.CNGLNE","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WA-DPXITD--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Inter-Tropical Discontinuity","HIERARCHY":"3.X.1.1.4.8","ALPHAHIERARCHY":"METOC.AMPHC.PRS.LNE.ITD","PATH":"METOC/Atmospheric/Pressure Systems/Lines"},{"SYMBOLID":"WAS-T----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Turbulence","HIERARCHY":"3.X.1.2","ALPHAHIERARCHY":"METOC.AMPHC.TRB","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-TL----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Turbulence","HIERARCHY":"3.X.1.2.1","ALPHAHIERARCHY":"METOC.AMPHC.TRB.LIT","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TM----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Turbulence","HIERARCHY":"3.X.1.2.2","ALPHAHIERARCHY":"METOC.AMPHC.TRB.MOD","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TS----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Turbulence","HIERARCHY":"3.X.1.2.3","ALPHAHIERARCHY":"METOC.AMPHC.TRB.SVR","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-TE----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Extreme Turbulence","HIERARCHY":"3.X.1.2.4","ALPHAHIERARCHY":"METOC.AMPHC.TRB.EXT","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-T-MW--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mountain Waves","HIERARCHY":"3.X.1.2.5","ALPHAHIERARCHY":"METOC.AMPHC.TRB.MNTWAV","PATH":"METOC/Atmospheric/Turbulence"},{"SYMBOLID":"WAS-I----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Icing","HIERARCHY":"3.X.1.3","ALPHAHIERARCHY":"METOC.AMPHC.ICG","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-IC----P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Clear Icing","HIERARCHY":"3.X.1.3.1","ALPHAHIERARCHY":"METOC.AMPHC.ICG.CLR","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-ICL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Clear Icing","HIERARCHY":"3.X.1.3.1.1","ALPHAHIERARCHY":"METOC.AMPHC.ICG.CLR.LIT","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-ICM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Clear Icing","HIERARCHY":"3.X.1.3.1.2","ALPHAHIERARCHY":"METOC.AMPHC.ICG.CLR.MOD","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-ICS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Clear Icing","HIERARCHY":"3.X.1.3.1.3","ALPHAHIERARCHY":"METOC.AMPHC.ICG.CLR.SVR","PATH":"METOC/Atmospheric/Icing/Clear Icing"},{"SYMBOLID":"WAS-IR-----P---","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rime Icing","HIERARCHY":"3.X.1.3.2","ALPHAHIERARCHY":"METOC.AMPHC.ICG.RIME","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-IRL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rime Icing","HIERARCHY":"3.X.1.3.2.1","ALPHAHIERARCHY":"METOC.AMPHC.ICG.RIME.LIT","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IRM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Rime Icing","HIERARCHY":"3.X.1.3.2.2","ALPHAHIERARCHY":"METOC.AMPHC.ICG.RIME.MOD","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IRS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Rime Icing","HIERARCHY":"3.X.1.3.2.3","ALPHAHIERARCHY":"METOC.AMPHC.ICG.RIME.SVR","PATH":"METOC/Atmospheric/Icing/Rime Icing"},{"SYMBOLID":"WAS-IM-----P---","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mixed Icing","HIERARCHY":"3.X.1.3.3","ALPHAHIERARCHY":"METOC.AMPHC.ICG.MIX","PATH":"METOC/Atmospheric/Icing"},{"SYMBOLID":"WAS-IML---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Mixed Icing","HIERARCHY":"3.X.1.3.3.1","ALPHAHIERARCHY":"METOC.AMPHC.ICG.MIX.LIT","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WAS-IMM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Mixed Icing","HIERARCHY":"3.X.1.3.3.2","ALPHAHIERARCHY":"METOC.AMPHC.ICG.MIX.MOD","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WAS-IMS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Mixed Icing","HIERARCHY":"3.X.1.3.3.3","ALPHAHIERARCHY":"METOC.AMPHC.ICG.MIX.SVR","PATH":"METOC/Atmospheric/Icing/Mixed Icing"},{"SYMBOLID":"WA--W----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Winds","HIERARCHY":"3.X.1.4","ALPHAHIERARCHY":"METOC.AMPHC.WND","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-WC----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Calm Winds","HIERARCHY":"3.X.1.4.1","ALPHAHIERARCHY":"METOC.AMPHC.WND.CALM","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WAS-WP----P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"2","MINPOINTS":"2","MODIFIERS":"Z.Q.","DESCRIPTION":"Wind Plot","HIERARCHY":"3.X.1.4.2","ALPHAHIERARCHY":"METOC.AMPHC.WND.PLT","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA-DWJ-----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jet Stream","HIERARCHY":"3.X.1.4.3","ALPHAHIERARCHY":"METOC.AMPHC.WND.JTSM","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA-DWS-----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Stream Line","HIERARCHY":"3.X.1.4.4","ALPHAHIERARCHY":"METOC.AMPHC.WND.SMLNE","PATH":"METOC/Atmospheric/Winds"},{"SYMBOLID":"WA--CC---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Cloud Coverage","HIERARCHY":"3.X.1.5","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA--CCCS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Cloud Coverage Symbols","HIERARCHY":"3.X.1.5.1","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM","PATH":"METOC/Atmospheric/Cloud Coverage"},{"SYMBOLID":"WAS-CCCSCSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Clear Sky","HIERARCHY":"3.X.1.5.1.1","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.SKC","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSFCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Few Coverage","HIERARCHY":"3.X.1.5.1.2","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.FEW","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSSCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Scattered Coverage","HIERARCHY":"3.X.1.5.1.3","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.SCT","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSBCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Broken Coverage","HIERARCHY":"3.X.1.5.1.4","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.BKN","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSOCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Overcast Coverage","HIERARCHY":"3.X.1.5.1.5","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.OVC","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WAS-CCCSOBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sky Totally or Partially Obscured","HIERARCHY":"3.X.1.5.1.6","ALPHAHIERARCHY":"METOC.AMPHC.CUDCOV.SYM.STOPO","PATH":"METOC/Atmospheric/Cloud Coverage/Cloud Coverage Symbols"},{"SYMBOLID":"WA--WS---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Weather Symbols","HIERARCHY":"3.X.1.6","ALPHAHIERARCHY":"METOC.AMPHC.WTH","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-WSR--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain","HIERARCHY":"3.X.1.6.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSR-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Rain","HIERARCHY":"3.X.1.6.1.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMLIT","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Rain","HIERARCHY":"3.X.1.6.1.1.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMLIT.CTSLIT","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Light Rain"},{"SYMBOLID":"WAS-WSR-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Rain","HIERARCHY":"3.X.1.6.1.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMMOD","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Rain","HIERARCHY":"3.X.1.6.1.2.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMMOD.CTSMOD","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Moderate Rain"},{"SYMBOLID":"WAS-WSR-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Rain","HIERARCHY":"3.X.1.6.1.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMHVY","PATH":"METOC/Atmospheric/Weather Symbols/Rain"},{"SYMBOLID":"WAS-WSR-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Rain","HIERARCHY":"3.X.1.6.1.3.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RA.INMHVY.CTSHVY","PATH":"METOC/Atmospheric/Weather Symbols/Rain/Intermittent Heavy Rain"},{"SYMBOLID":"WAS-WSRF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Freezing Rain","HIERARCHY":"3.X.1.6.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZRA","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSRFL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Freezing Rain","HIERARCHY":"3.X.1.6.2.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZRA.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Rain"},{"SYMBOLID":"WAS-WSRFMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Freezing Rain","HIERARCHY":"3.X.1.6.2.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZRA.MODHVY","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Rain"},{"SYMBOLID":"WAS-WSRS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain Showers","HIERARCHY":"3.X.1.6.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASWR","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSRSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain Showers","HIERARCHY":"3.X.1.6.3.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASWR.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSRSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Rain Showers","HIERARCHY":"3.X.1.6.3.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASWR.MODHVY","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSRST-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Torrential Rain Showers","HIERARCHY":"3.X.1.6.3.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASWR.TOR","PATH":"METOC/Atmospheric/Weather Symbols/Rain Showers"},{"SYMBOLID":"WAS-WSD--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Drizzle","HIERARCHY":"3.X.1.6.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSD-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Drizzle","HIERARCHY":"3.X.1.6.4.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMLIT","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Drizzle","HIERARCHY":"3.X.1.6.4.1.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMLIT.CTSLIT","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Light Drizzle"},{"SYMBOLID":"WAS-WSD-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Drizzle","HIERARCHY":"3.X.1.6.4.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMMOD","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Drizzle","HIERARCHY":"3.X.1.6.4.2.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMMOD.CTSMOD","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Moderate Drizzle"},{"SYMBOLID":"WAS-WSD-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Drizzle","HIERARCHY":"3.X.1.6.4.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMHVY","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle"},{"SYMBOLID":"WAS-WSD-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Drizzle","HIERARCHY":"3.X.1.6.4.3.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DZ.INMHVY.CTSHVY","PATH":"METOC/Atmospheric/Weather Symbols/Drizzle/Intermittent Heavy Drizzle"},{"SYMBOLID":"WAS-WSDF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Freezing Drizzle","HIERARCHY":"3.X.1.6.5","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZDZ","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSDFL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Freezing Drizzle","HIERARCHY":"3.X.1.6.5.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZDZ.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Drizzle"},{"SYMBOLID":"WAS-WSDFMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Freezing Drizzle","HIERARCHY":"3.X.1.6.5.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZDZ.MODHVY","PATH":"METOC/Atmospheric/Weather Symbols/Freezing Drizzle"},{"SYMBOLID":"WAS-WSM--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Rain and Snow Mixed","HIERARCHY":"3.X.1.6.6","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASN","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSM-L-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain or Drizzle and Snow","HIERARCHY":"3.X.1.6.6.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASN.RDSLIT","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSM-MHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Heavy Rain or Drizzle and Snow","HIERARCHY":"3.X.1.6.6.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASN.RDSMH","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSMSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Rain and Snow Showers","HIERARCHY":"3.X.1.6.6.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASN.SWRLIT","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSMSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Rain and Snow Showers","HIERARCHY":"3.X.1.6.6.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.RASN.SWRMOD","PATH":"METOC/Atmospheric/Weather Symbols/Rain and Snow Mixed"},{"SYMBOLID":"WAS-WSS--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Snow","HIERARCHY":"3.X.1.6.7","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSS-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Light Snow","HIERARCHY":"3.X.1.6.7.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMLIT","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-LCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Light Snow","HIERARCHY":"3.X.1.6.7.1.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMLIT.CTSLIT","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Light Snow"},{"SYMBOLID":"WAS-WSS-MIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Moderate Snow","HIERARCHY":"3.X.1.6.7.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMMOD","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-MCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Moderate Snow","HIERARCHY":"3.X.1.6.7.2.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMMOD.CTSMOD","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Moderate Snow"},{"SYMBOLID":"WAS-WSS-HIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Intermittent Heavy Snow","HIERARCHY":"3.X.1.6.7.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMHVY","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSS-HCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Continuous Heavy Snow","HIERARCHY":"3.X.1.6.7.3.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.INMHVY.CTSHVY","PATH":"METOC/Atmospheric/Weather Symbols/Snow/Intermittent Heavy Snow"},{"SYMBOLID":"WAS-WSSBLMP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light/Moderate Blowing Snow","HIERARCHY":"3.X.1.6.7.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.BLSNLM","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSSBH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Heavy Blowing Snow","HIERARCHY":"3.X.1.6.7.5","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SN.BLSNHY","PATH":"METOC/Atmospheric/Weather Symbols/Snow"},{"SYMBOLID":"WAS-WSSG--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Grains","HIERARCHY":"3.X.1.6.8","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SG","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSSS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Snow Showers","HIERARCHY":"3.X.1.6.9","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SSWR","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSSSL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Snow Showers","HIERARCHY":"3.X.1.6.9.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SSWR.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Snow Showers"},{"SYMBOLID":"WAS-WSSSMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Heavy Snow Showers","HIERARCHY":"3.X.1.6.9.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.SSWR.MODHVY","PATH":"METOC/Atmospheric/Weather Symbols/Snow Showers"},{"SYMBOLID":"WAS-WSGR-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hail","HIERARCHY":"3.X.1.6.10","ALPHAHIERARCHY":"METOC.AMPHC.WTH.HL","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSGRL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hail - Light not Associated With Thunder","HIERARCHY":"3.X.1.6.10.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.HL.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Hail"},{"SYMBOLID":"WAS-WSGRMHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hail - Moderate/Heavy not Associated With Thunder","HIERARCHY":"3.X.1.6.10.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.HL.MODHVY","PATH":"METOC/Atmospheric/Weather Symbols/Hail"},{"SYMBOLID":"WAS-WSIC--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Crystals","HIERARCHY":"3.X.1.6.11","ALPHAHIERARCHY":"METOC.AMPHC.WTH.IC","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSPL-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Pellets","HIERARCHY":"3.X.1.6.12","ALPHAHIERARCHY":"METOC.AMPHC.WTH.PE","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSPLL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Ice Pellets","HIERARCHY":"3.X.1.6.12.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.PE.LIT","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WSPLM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate Ice Pellets","HIERARCHY":"3.X.1.6.12.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.PE.MOD","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WSPLH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Heavy Ice Pellets","HIERARCHY":"3.X.1.6.12.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.PE.HVY","PATH":"METOC/Atmospheric/Weather Symbols/Ice Pellets"},{"SYMBOLID":"WAS-WST--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Storms","HIERARCHY":"3.X.1.6.13","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WST-NPP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm - No Precipitation","HIERARCHY":"3.X.1.6.13.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.TS","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTMR-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Light to Moderate With Rain/Snow - No Hail","HIERARCHY":"3.X.1.6.13.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.TSLMNH","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTHR-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Heavy With Rain/Snow - No Hail","HIERARCHY":"3.X.1.6.13.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.TSHVNH","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTMH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Light to Moderate - With Hail","HIERARCHY":"3.X.1.6.13.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.TSLMWH","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSTHH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunderstorm Heavy - With Hail","HIERARCHY":"3.X.1.6.13.5","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.TSHVWH","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-FCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Funnel Cloud (Tornado/Waterspout)","HIERARCHY":"3.X.1.6.13.6","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.FC","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-SQP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Squall","HIERARCHY":"3.X.1.6.13.7","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.SQL","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WST-LGP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lightning","HIERARCHY":"3.X.1.6.13.8","ALPHAHIERARCHY":"METOC.AMPHC.WTH.STMS.LTG","PATH":"METOC/Atmospheric/Weather Symbols/Storms"},{"SYMBOLID":"WAS-WSFG-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fog","HIERARCHY":"3.X.1.6.14","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSFGPSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Shallow Patches","HIERARCHY":"3.X.1.6.14.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.SHWPTH","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGCSP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Shallow Continuous","HIERARCHY":"3.X.1.6.14.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.SHWCTS","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGP-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Patchy","HIERARCHY":"3.X.1.6.14.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.PTHY","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGSVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Sky Visible","HIERARCHY":"3.X.1.6.14.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.SKYVSB","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGSOP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Sky Obscured","HIERARCHY":"3.X.1.6.14.5","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.SKYOBD","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGFVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Freezing, Sky Visible","HIERARCHY":"3.X.1.6.14.6","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.FZSV","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSFGFOP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog - Freezing, Sky Not Visible","HIERARCHY":"3.X.1.6.14.7","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FG.FZSNV","PATH":"METOC/Atmospheric/Weather Symbols/Fog"},{"SYMBOLID":"WAS-WSBR--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mist","HIERARCHY":"3.X.1.6.15","ALPHAHIERARCHY":"METOC.AMPHC.WTH.MIST","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSFU--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Smoke Point","HIERARCHY":"3.X.1.6.16","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FU","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSHZ--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Haze","HIERARCHY":"3.X.1.6.17","ALPHAHIERARCHY":"METOC.AMPHC.WTH.HZ","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS--SD--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dust or Sand","HIERARCHY":"3.X.1.6.18","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DT/SD","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSDSLMP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light to Moderate Dust/Sand Storm","HIERARCHY":"3.X.1.6.18.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DT/SD.LITMOD","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDSS-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Severe Dust/Sand Storm","HIERARCHY":"3.X.1.6.18.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DT/SD.SVR","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDD--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dust Devil","HIERARCHY":"3.X.1.6.18.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DT/SD.DTDVL","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSDB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Blowing Dust or Sand","HIERARCHY":"3.X.1.6.18.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.DT/SD.BLDTSD","PATH":"METOC/Atmospheric/Weather Symbols/Dust or Sand"},{"SYMBOLID":"WAS-WSTS-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tropical Storm Systems","HIERARCHY":"3.X.1.6.19","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TPLSYS","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSTSD-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Depression","HIERARCHY":"3.X.1.6.19.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TPLSYS.TROPDN","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSTSS-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Storm","HIERARCHY":"3.X.1.6.19.2","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TPLSYS.TROPSM","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSTSH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hurricane/Typhoon","HIERARCHY":"3.X.1.6.19.3","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TPLSYS.HC","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WA-DWSTSWA--A--","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Storm Wind Areas and Date/Time Labels","HIERARCHY":"3.X.1.6.19.4","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TPLSYS.TSWADL","PATH":"METOC/Atmospheric/Weather Symbols/Tropical Storm Systems"},{"SYMBOLID":"WAS-WSVE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Eruption","HIERARCHY":"3.X.1.6.20","ALPHAHIERARCHY":"METOC.AMPHC.WTH.VOLERN","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSVA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Ash","HIERARCHY":"3.X.1.6.20.1","ALPHAHIERARCHY":"METOC.AMPHC.WTH.VOLERN.VOLASH","PATH":"METOC/Atmospheric/Weather Symbols/Volcanic Eruption"},{"SYMBOLID":"WAS-WST-LVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Tropopause Level","HIERARCHY":"3.X.1.6.21","ALPHAHIERARCHY":"METOC.AMPHC.WTH.TROPLV","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSF-LVP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Freezing Level","HIERARCHY":"3.X.1.6.22","ALPHAHIERARCHY":"METOC.AMPHC.WTH.FZLVL","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WAS-WSUKP-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Precipiation of Unknown Type and Intensity","HIERARCHY":"3.X.1.6.23","ALPHAHIERARCHY":"METOC.AMPHC.WTH.POUTAI","PATH":"METOC/Atmospheric/Weather Symbols"},{"SYMBOLID":"WA--BA---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bounded Areas of Weather","HIERARCHY":"3.X.1.7","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA-DBAIF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"IFR","HIERARCHY":"3.X.1.7.1","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.IFR","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAMV----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"MVFR","HIERARCHY":"3.X.1.7.2","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.MVFR","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBATB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Turbulence","HIERARCHY":"3.X.1.7.3","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.TRB","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAI-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Icing","HIERARCHY":"3.X.1.7.4","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.ICG","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBALPNC--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Precipiation Non-Convective","HIERARCHY":"3.X.1.7.5","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.LPNCI","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBALPC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Precipitation Convective","HIERARCHY":"3.X.1.7.5.1","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.LPNCI.LPC","PATH":"METOC/Atmospheric/Bounded Areas of Weather/Precipiation Non-Convective"},{"SYMBOLID":"WA-DBAFP----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Frozen Precipitation","HIERARCHY":"3.X.1.7.6","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.FZPPN","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAT-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Thunderstorm","HIERARCHY":"3.X.1.7.7","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.TS","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAFG----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Weather Fog","HIERARCHY":"3.X.1.7.8","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.FG","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAD-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Weather Sand","HIERARCHY":"3.X.1.7.9","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.DT/SD","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA-DBAFF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","MODIFIERS":"H.H1.","DESCRIPTION":"Weather Freeform","HIERARCHY":"3.X.1.7.10","ALPHAHIERARCHY":"METOC.AMPHC.BDAWTH.ODFF","PATH":"METOC/Atmospheric/Bounded Areas of Weather"},{"SYMBOLID":"WA--IP---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Isopleths","HIERARCHY":"3.X.1.8","ALPHAHIERARCHY":"METOC.AMPHC.ISP","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WA-DIPIB---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isobar Surface","HIERARCHY":"3.X.1.8.1","ALPHAHIERARCHY":"METOC.AMPHC.ISP.ISB","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPCO---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Upper Air","HIERARCHY":"3.X.1.8.2","ALPHAHIERARCHY":"METOC.AMPHC.ISP.CTUR","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPIS---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isotherm","HIERARCHY":"3.X.1.8.3","ALPHAHIERARCHY":"METOC.AMPHC.ISP.IST","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPIT---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isotach","HIERARCHY":"3.X.1.8.4","ALPHAHIERARCHY":"METOC.AMPHC.ISP.ISH","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPID---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isodrosotherm","HIERARCHY":"3.X.1.8.5","ALPHAHIERARCHY":"METOC.AMPHC.ISP.ISD","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPTH---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Isopleths Thickness","HIERARCHY":"3.X.1.8.6","ALPHAHIERARCHY":"METOC.AMPHC.ISP.THK","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WA-DIPFF---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Operator Freeform","HIERARCHY":"3.X.1.8.7","ALPHAHIERARCHY":"METOC.AMPHC.ISP.ODFF","PATH":"METOC/Atmospheric/Isopleths"},{"SYMBOLID":"WAS-G----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"State of the Ground","HIERARCHY":"3.X.1.9","ALPHAHIERARCHY":"METOC.AMPHC.STOG","PATH":"METOC/Atmospheric"},{"SYMBOLID":"WAS-GN---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Without Snow or Measureable Ice Cover","HIERARCHY":"3.X.1.9.1","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC","PATH":"METOC/Atmospheric/State of the Ground"},{"SYMBOLID":"WAS-GND-NCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Sand","HIERARCHY":"3.X.1.9.1.1","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.SUFDRY","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Moist","HIERARCHY":"3.X.1.9.1.2","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.SUFMST","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNW-SWP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Wet, Standing Water in Small or Large Pools","HIERARCHY":"3.X.1.9.1.3","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.SUFWET","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNFL--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Flooded","HIERARCHY":"3.X.1.9.1.4","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.SUFFLD","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNFZ--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Surface Frozen","HIERARCHY":"3.X.1.9.1.5","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.SUFFZN","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNG-TIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Glaze (Thin Ice) on Ground","HIERARCHY":"3.X.1.9.1.6","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.GLZGRD","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDN-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Dust or Sand not Covering Ground Completely","HIERARCHY":"3.X.1.9.1.7","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.LDNCGC","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDTCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thin Loose Dry Dust or Sand Covering Ground Completely","HIERARCHY":"3.X.1.9.1.8","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.TLDCGC","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNLDMCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Moderate/Thick Loose Dry Dust or Sand Covering Ground Completely","HIERARCHY":"3.X.1.9.1.9","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.MLDCGC","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GNDEWCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Extremely Dry With Cracks","HIERARCHY":"3.X.1.9.1.10","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WOSMIC.EXTDWC","PATH":"METOC/Atmospheric/State of the Ground/Without Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GS---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"With Snow or Measureable Ice Cover","HIERARCHY":"3.X.1.9.2","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC","PATH":"METOC/Atmospheric/State of the Ground"},{"SYMBOLID":"WAS-GSI---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Predominately Ice Covered","HIERARCHY":"3.X.1.9.2.1","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.PDMIC","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Compact or Wet Snow (With or Without Ice) Covering Less than One-Hald of Ground","HIERARCHY":"3.X.1.9.2.2","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.CWSNLH","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Compact or Wet Snow Covering At Least One-Half Ground, but Ground not Completely Covered","HIERARCHY":"3.X.1.9.2.3","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.CSNALH","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCCEP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Even Layer of Compact or Wet Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.4","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.ELCSCG","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSCCUP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Uneven Layer of Compact or Wet Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.5","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.ULCSCG","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Snow Covering Less than One-Half of Ground","HIERARCHY":"3.X.1.9.2.6","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.LDSNLH","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Loose Dry Snow Covering at Least One-Half Ground, but not Completely Covered","HIERARCHY":"3.X.1.9.2.7","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.LDSALH","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLCEP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Even Layer of Loose Dry Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.8","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.ELDSCG","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSLCUP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Uneven Layer of Loose Dry Snow Covering Ground Completely","HIERARCHY":"3.X.1.9.2.9","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.ULDSCG","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WAS-GSSDC-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Covering Ground Completely, Deep Drifts","HIERARCHY":"3.X.1.9.2.10","ALPHAHIERARCHY":"METOC.AMPHC.STOG.WSMIC.SCGC","PATH":"METOC/Atmospheric/State of the Ground/With Snow or Measureable Ice Cover"},{"SYMBOLID":"WO-------------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Oceanic","HIERARCHY":"3.X.2","ALPHAHIERARCHY":"METOC.OCA","PATH":"METOC"},{"SYMBOLID":"WO--I----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Systems","HIERARCHY":"3.X.2.1","ALPHAHIERARCHY":"METOC.OCA.ISYS","PATH":"METOC/Oceanic"},{"SYMBOLID":"WOS-IB----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Icebergs","HIERARCHY":"3.X.2.1.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IBM---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Icebergs","HIERARCHY":"3.X.2.1.1.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.MNY","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Belts and Strips","HIERARCHY":"3.X.2.1.1.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.BAS","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBG---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Iceberg - General","HIERARCHY":"3.X.2.1.1.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.GNL","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBMG--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Icebergs - General","HIERARCHY":"3.X.2.1.1.4","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.MNYGNL","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bergy Bit","HIERARCHY":"3.X.2.1.1.5","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.BB","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBBBM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Bergy Bits","HIERARCHY":"3.X.2.1.1.6","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.MNYBB","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBGL--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Growler","HIERARCHY":"3.X.2.1.1.7","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.GWL","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBGLM-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Many Growlers","HIERARCHY":"3.X.2.1.1.8","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.MNYGWL","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBF---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Floeberg","HIERARCHY":"3.X.2.1.1.9","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.FBG","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WOS-IBII--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Island","HIERARCHY":"3.X.2.1.1.10","ALPHAHIERARCHY":"METOC.OCA.ISYS.IB.II","PATH":"METOC/Oceanic/Ice Systems/Icebergs"},{"SYMBOLID":"WO--IC---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ice Concentration","HIERARCHY":"3.X.2.1.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.ICN","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ICWB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bergy Water","HIERARCHY":"3.X.2.1.2.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.ICN.BW","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ICWR--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Water With Radar Targets","HIERARCHY":"3.X.2.1.2.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.ICN.WWRT","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ICIF--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Free","HIERARCHY":"3.X.2.1.2.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.ICN.IF","PATH":"METOC/Oceanic/Ice Systems/Ice Concentration"},{"SYMBOLID":"WOS-ID---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dynamic Processes","HIERARCHY":"3.X.2.1.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.DYNPRO","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IDC---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Convergence","HIERARCHY":"3.X.2.1.3.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.DYNPRO.CNG","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-IDD---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Divergence","HIERARCHY":"3.X.2.1.3.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.DYNPRO.DVG","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-IDS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Shearing or Shear Zone","HIERARCHY":"3.X.2.1.3.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.DYNPRO.SHAZ","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WO-DIDID---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Drift (Direction)","HIERARCHY":"3.X.2.1.3.4","ALPHAHIERARCHY":"METOC.OCA.ISYS.DYNPRO.ID","PATH":"METOC/Oceanic/Ice Systems/Dynamic Processes"},{"SYMBOLID":"WOS-II----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sea Ice","HIERARCHY":"3.X.2.1.4","ALPHAHIERARCHY":"METOC.OCA.ISYS.SI","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-IITM--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Thickness (Observed)","HIERARCHY":"3.X.2.1.4.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.SI.ITOBS","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WOS-IITE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ice Thickness (Estimated)","HIERARCHY":"3.X.2.1.4.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.SI.ITEST","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WOS-IIP---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Melt Puddles or Flooded Ice","HIERARCHY":"3.X.2.1.4.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.SI.MPOFI","PATH":"METOC/Oceanic/Ice Systems/Sea Ice"},{"SYMBOLID":"WO--IL---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Limits","HIERARCHY":"3.X.2.1.5","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WO-DILOV---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Visual Observation","HIERARCHY":"3.X.2.1.5.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.LOVO","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILUC---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Undercast","HIERARCHY":"3.X.2.1.5.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.LOU","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILOR---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Limit of Radar Observation","HIERARCHY":"3.X.2.1.5.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.LORO","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIEO--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Observed Ice Edge","HIERARCHY":"3.X.2.1.5.4","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.OIEOB","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIEE--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Estimated Ice Edge","HIERARCHY":"3.X.2.1.5.5","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.EIEOB","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO-DILIER--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ice Edge From Radar","HIERARCHY":"3.X.2.1.5.6","ALPHAHIERARCHY":"METOC.OCA.ISYS.LMT.IEOBFR","PATH":"METOC/Oceanic/Ice Systems/Limits"},{"SYMBOLID":"WO--IO---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Openings in the Ice","HIERARCHY":"3.X.2.1.6","ALPHAHIERARCHY":"METOC.OCA.ISYS.OITI","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WO-DIOC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cracks","HIERARCHY":"3.X.2.1.6.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.OITI.CRK","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOCS---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cracks Specific-Location","HIERARCHY":"3.X.2.1.6.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.OITI.CRKASL","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOL----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ice Openings-Lead","HIERARCHY":"3.X.2.1.6.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.OITI.LED","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WO-DIOLF---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Frozen Lead","HIERARCHY":"3.X.2.1.6.4","ALPHAHIERARCHY":"METOC.OCA.ISYS.OITI.FZLED","PATH":"METOC/Oceanic/Ice Systems/Openings in the Ice"},{"SYMBOLID":"WOS-ISC---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow Cover","HIERARCHY":"3.X.2.1.7","ALPHAHIERARCHY":"METOC.OCA.ISYS.SC","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ISS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sastrugi","HIERARCHY":"3.X.2.1.7.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.SC.SWO","PATH":"METOC/Oceanic/Ice Systems/Snow Cover"},{"SYMBOLID":"WOS-IT---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Topographical Features","HIERARCHY":"3.X.2.1.8","ALPHAHIERARCHY":"METOC.OCA.ISYS.TOPFTR","PATH":"METOC/Oceanic/Ice Systems"},{"SYMBOLID":"WOS-ITRH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ridges or Hummocks","HIERARCHY":"3.X.2.1.8.1","ALPHAHIERARCHY":"METOC.OCA.ISYS.TOPFTR.HUM","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WOS-ITR---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rafting","HIERARCHY":"3.X.2.1.8.2","ALPHAHIERARCHY":"METOC.OCA.ISYS.TOPFTR.RFTG","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WOS-ITBB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Jammed Brash Barrier","HIERARCHY":"3.X.2.1.8.3","ALPHAHIERARCHY":"METOC.OCA.ISYS.TOPFTR.JBB","PATH":"METOC/Oceanic/Ice Systems/Topographical Features"},{"SYMBOLID":"WO--H----------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hydrography","HIERARCHY":"3.X.2.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--HD---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Depth","HIERARCHY":"3.X.2.2.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DPH","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HDS---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","MODIFIERS":"X.","DESCRIPTION":"Soundings","HIERARCHY":"3.X.2.2.1.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DPH.SNDG","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDL---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Depth Curve","HIERARCHY":"3.X.2.2.1.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DPH.CRV","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDC---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Depth Contour","HIERARCHY":"3.X.2.2.1.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DPH.CTUR","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO-DHDDA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Depth Area","HIERARCHY":"3.X.2.2.1.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DPH.ARA","PATH":"METOC/Oceanic/Hydrography/Depth"},{"SYMBOLID":"WO--HC---------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Coastal Hydrography","HIERARCHY":"3.X.2.2.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WO-DHCC----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Coastline","HIERARCHY":"3.X.2.2.2.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.CSTLN","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCI-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Island","HIERARCHY":"3.X.2.2.2.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.ISND","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCB-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach","HIERARCHY":"3.X.2.2.2.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.BEH","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCW-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Water","HIERARCHY":"3.X.2.2.2.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.H2O","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCF--------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Foreshore","HIERARCHY":"3.X.2.2.2.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.FSH1","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography"},{"SYMBOLID":"WO-DHCF----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Foreshore Line","HIERARCHY":"3.X.2.2.2.5.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.FSH1.FSH2","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography/Foreshore"},{"SYMBOLID":"WO-DHCF-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Foreshore Area","HIERARCHY":"3.X.2.2.2.5.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.CSTHYD.FSH1.FSH3","PATH":"METOC/Oceanic/Hydrography/Coastal Hydrography/Foreshore"},{"SYMBOLID":"WO-DHP---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ports and Harbors","HIERARCHY":"3.X.2.2.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WO--HPB--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Ports","HIERARCHY":"3.X.2.2.3.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WOS-HPB-O-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Berths (Onshore)","HIERARCHY":"3.X.2.2.3.1.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.BRHSO","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPB-A-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Berths (Anchor)","HIERARCHY":"3.X.2.2.3.1.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.BRHSA","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPBA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Anchorage","HIERARCHY":"3.X.2.2.3.1.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.ANCRG1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBA---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Anchorage Line","HIERARCHY":"3.X.2.2.3.1.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.ANCRG2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Anchorage Area","HIERARCHY":"3.X.2.2.3.1.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.ANCRG3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPCP--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Call in Point","HIERARCHY":"3.X.2.2.3.1.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.CIP","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WO-DHPBP---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Pier","HIERARCHY":"3.X.2.2.3.1.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.PRT.PWQ","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Ports"},{"SYMBOLID":"WOS-HPF--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Fishing","HIERARCHY":"3.X.2.2.3.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FSG","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WOS-HPFH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fishing Harbor","HIERARCHY":"3.X.2.2.3.2.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FSG.FSGHBR","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fish Stakes/Traps/Weirs","HIERARCHY":"3.X.2.2.3.2.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FSG.FSTK1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFS---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fish Stakes/Traps/Weirs","HIERARCHY":"3.X.2.2.3.2.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FSG.FSTK2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WOS-HPFF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Fish Stakes/Traps/Weirs","HIERARCHY":"3.X.2.2.3.2.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FSG.FSTK3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Fishing"},{"SYMBOLID":"WO--HPM--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Facilities","HIERARCHY":"3.X.2.2.3.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WO-DHPMD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Drydock","HIERARCHY":"3.X.2.2.3.3.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.DDCK","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPML--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Landing Place","HIERARCHY":"3.X.2.2.3.3.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.LNDPLC","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Offshore Loading Facility Point","HIERARCHY":"3.X.2.2.3.3.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.OSLF1","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO---L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Offshore Loading Facility Line","HIERARCHY":"3.X.2.2.3.3.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.OSLF2","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMO----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Offshore Loading Facility Area","HIERARCHY":"3.X.2.2.3.3.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.OSLF3","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMRA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ramp Above Water","HIERARCHY":"3.X.2.2.3.3.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.RAMPAW","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPMRB--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ramp Below Water","HIERARCHY":"3.X.2.2.3.3.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.RAMPBW","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-R-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Landing Ring","HIERARCHY":"3.X.2.2.3.3.8","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.LNDRNG","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-FC-L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ferry Crossing","HIERARCHY":"3.X.2.2.3.3.9","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.FRYCSG","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPM-CC-L---","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cable Ferry Crossing","HIERARCHY":"3.X.2.2.3.3.10","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.CFCSG","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WOS-HPD---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Dolphin","HIERARCHY":"3.X.2.2.3.3.11","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.FAC.DOPN","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Facilities"},{"SYMBOLID":"WO-DHPSP-------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Shoreline Protection","HIERARCHY":"3.X.2.2.3.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.SHRLNE","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors"},{"SYMBOLID":"WO-DHPSPA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jetty Above Water","HIERARCHY":"3.X.2.2.3.4.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.SHRLNE.BWGJAW","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO-DHPSPB--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Jetty Below Water","HIERARCHY":"3.X.2.2.3.4.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.SHRLNE.BWGJBW","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO-DHPSPS--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Seawall","HIERARCHY":"3.X.2.2.3.4.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.PRTHBR.SHRLNE.SW","PATH":"METOC/Oceanic/Hydrography/Ports and Harbors/Shoreline Protection"},{"SYMBOLID":"WO--HA---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Aids to Navigation","HIERARCHY":"3.X.2.2.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HABA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Beacon","HIERARCHY":"3.X.2.2.4.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.BCN","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABB--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Buoy Default","HIERARCHY":"3.X.2.2.4.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.BUOY","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABM--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Marker","HIERARCHY":"3.X.2.2.4.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.MRK","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABP-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Perches/Stakes","HIERARCHY":"3.X.2.2.4.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.PRH1","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HABP--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Perches/Stakes","HIERARCHY":"3.X.2.2.4.4.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.PRH1.PRH2","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation/Perches-Stakes"},{"SYMBOLID":"WO-DHABP----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Perches/Stakes","HIERARCHY":"3.X.2.2.4.4.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.PRH1.PRH3","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation/Perches-Stakes"},{"SYMBOLID":"WOS-HAL---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light","HIERARCHY":"3.X.2.2.4.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.LIT","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WO-DHALLA--L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Leading Line","HIERARCHY":"3.X.2.2.4.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.LDGLNE","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HALV--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Light Vessel/Lightship","HIERARCHY":"3.X.2.2.4.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.LITVES","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WOS-HALH--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lighthouse","HIERARCHY":"3.X.2.2.4.8","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.ATN.LITHSE","PATH":"METOC/Oceanic/Hydrography/Aids to Navigation"},{"SYMBOLID":"WO--HH---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Dangers/Hazards","HIERARCHY":"3.X.2.2.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-HHRS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock Submerged","HIERARCHY":"3.X.2.2.5.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.RCKSBM","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHRA--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock Awashed","HIERARCHY":"3.X.2.2.5.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.RCKAWD","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHD-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Underwater Hazard","HIERARCHY":"3.X.2.2.5.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.UH2DAN","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDF-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Foul Ground","HIERARCHY":"3.X.2.2.5.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.FLGRD1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDF--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Foul Ground Point","HIERARCHY":"3.X.2.2.5.4.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.FLGRD1.FLGRD2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Foul Ground"},{"SYMBOLID":"WO-DHHDF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Foul Ground Area","HIERARCHY":"3.X.2.2.5.4.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.FLGRD1.FLGRD3","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Foul Ground"},{"SYMBOLID":"WO-DHHDK-------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Kelp/Seaweed","HIERARCHY":"3.X.2.2.5.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.KLP1","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDK--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Kelp/Seaweed Point","HIERARCHY":"3.X.2.2.5.5.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.KLP1.KLP2","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDK----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Kelp/Seaweed Area","HIERARCHY":"3.X.2.2.5.5.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.KLP1.KLP3","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Kelp-Seaweed"},{"SYMBOLID":"WOS-HHDMD------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mine-Naval","HIERARCHY":"3.X.2.2.5.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.MNENAV","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDMDBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mine-Naval (Doubtful)","HIERARCHY":"3.X.2.2.5.6.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.MNENAV.DBT","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Mine-Naval"},{"SYMBOLID":"WOS-HHDMDFP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mine-Naval (Definite)","HIERARCHY":"3.X.2.2.5.6.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.MNENAV.DEFN","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Mine-Naval"},{"SYMBOLID":"WOS-HHDS--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snags/Stumps","HIERARCHY":"3.X.2.2.5.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.SNAG","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDW--P----","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Wreck","HIERARCHY":"3.X.2.2.5.8","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.WRK","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDWA-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck (Uncovers)","HIERARCHY":"3.X.2.2.5.8.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.WRK.UCOV","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Wreck"},{"SYMBOLID":"WOS-HHDWB-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Wreck (Submerged)","HIERARCHY":"3.X.2.2.5.8.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.WRK.SBM","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards/Wreck"},{"SYMBOLID":"WO-DHHDB---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Breaker","HIERARCHY":"3.X.2.2.5.9","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.BRKS","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDR---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Reef","HIERARCHY":"3.X.2.2.5.10","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.REEF","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WOS-HHDE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Eddies/Overfalls/Tide Rips","HIERARCHY":"3.X.2.2.5.11","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.EOTR","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO-DHHDD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Discolored Water","HIERARCHY":"3.X.2.2.5.12","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.DANHAZ.DCDH2O","PATH":"METOC/Oceanic/Hydrography/Dangers-Hazards"},{"SYMBOLID":"WO--BF---------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Features","HIERARCHY":"3.X.2.2.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-BFC--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Characteristics","HIERARCHY":"3.X.2.2.6.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR","PATH":"METOC/Oceanic/Hydrography/Bottom Features"},{"SYMBOLID":"WOS-BFC-S-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sand","HIERARCHY":"3.X.2.2.6.1.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.SD","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-M-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Mud","HIERARCHY":"3.X.2.2.6.1.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.MUD","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-CLP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Clay","HIERARCHY":"3.X.2.2.6.1.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.CLAY","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-SIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Silt","HIERARCHY":"3.X.2.2.6.1.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.SLT","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-STP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Stones","HIERARCHY":"3.X.2.2.6.1.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.STNE","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-G-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Gravel","HIERARCHY":"3.X.2.2.6.1.6","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.GVL","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-P-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pebbles","HIERARCHY":"3.X.2.2.6.1.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.PBL","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-CBP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Cobbles","HIERARCHY":"3.X.2.2.6.1.8","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.COBL","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-R-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rock","HIERARCHY":"3.X.2.2.6.1.9","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.RCK","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-COP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Coral","HIERARCHY":"3.X.2.2.6.1.10","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.CRL","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFC-SHP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Shell","HIERARCHY":"3.X.2.2.6.1.11","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.BTMCHR.SHE","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Bottom Characteristics"},{"SYMBOLID":"WOS-BFQ--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Qualifying Terms","HIERARCHY":"3.X.2.2.6.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.QLFYTM","PATH":"METOC/Oceanic/Hydrography/Bottom Features"},{"SYMBOLID":"WOS-BFQ-F-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fine","HIERARCHY":"3.X.2.2.6.2.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.QLFYTM.FNE","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WOS-BFQ-M-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Medium","HIERARCHY":"3.X.2.2.6.2.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.QLFYTM.MDM","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WOS-BFQ-C-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Coarse","HIERARCHY":"3.X.2.2.6.2.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.BTMFAT.QLFYTM.CSE","PATH":"METOC/Oceanic/Hydrography/Bottom Features/Qualifying Terms"},{"SYMBOLID":"WO--TCC--------","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Tide and Current","HIERARCHY":"3.X.2.2.7","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR","PATH":"METOC/Oceanic/Hydrography"},{"SYMBOLID":"WOS-TCCW--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Water Turbulence","HIERARCHY":"3.X.2.2.7.1","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR.H2OTRB","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO-DTCCCFE-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Ebb Tide","HIERARCHY":"3.X.2.2.7.2","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR.EBB","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO-DTCCCFF-L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Flood Tide","HIERARCHY":"3.X.2.2.7.3","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR.FLOOD","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WOS-TCCTD-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tide Data Point","HIERARCHY":"3.X.2.2.7.4","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR.TDEDP","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WOS-TCCTG-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tide Gauge","HIERARCHY":"3.X.2.2.7.5","ALPHAHIERARCHY":"METOC.OCA.HYDGRY.TDECUR.TDEG","PATH":"METOC/Oceanic/Hydrography/Tide and Current"},{"SYMBOLID":"WO--O----------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Oceanography","HIERARCHY":"3.X.2.3","ALPHAHIERARCHY":"METOC.OCA.OCNGRY","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--OB---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bioluminescence","HIERARCHY":"3.X.2.3.1","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM","PATH":"METOC/Oceanic/Oceanography"},{"SYMBOLID":"WO-DOBVA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 1-2","HIERARCHY":"3.X.2.3.1.1","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR1-2","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 2-3","HIERARCHY":"3.X.2.3.1.2","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR2-3","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVC----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 3-4","HIERARCHY":"3.X.2.3.1.3","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR3-4","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVD----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 4-5","HIERARCHY":"3.X.2.3.1.4","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR4-5","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVE----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 5-6","HIERARCHY":"3.X.2.3.1.5","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR5-6","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVF----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 6-7","HIERARCHY":"3.X.2.3.1.6","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR6-7","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVG----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 7-8","HIERARCHY":"3.X.2.3.1.7","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR7-8","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVH----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 8-9","HIERARCHY":"3.X.2.3.1.8","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR8-9","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO-DOBVI----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"VDR Level 9-10","HIERARCHY":"3.X.2.3.1.9","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BIOLUM.VDR9-0","PATH":"METOC/Oceanic/Oceanography/Bioluminescence"},{"SYMBOLID":"WO--BS---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Beach Slope","HIERARCHY":"3.X.2.3.2","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BEHSPE","PATH":"METOC/Oceanic/Oceanography"},{"SYMBOLID":"WO-DBSF-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Flat","HIERARCHY":"3.X.2.3.2.1","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BEHSPE.FLT","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBSG-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Gentle","HIERARCHY":"3.X.2.3.2.2","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BEHSPE.GTL","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBSM-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Moderate","HIERARCHY":"3.X.2.3.2.3","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BEHSPE.MOD","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO-DBST-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Beach Slope Steep","HIERARCHY":"3.X.2.3.2.4","ALPHAHIERARCHY":"METOC.OCA.OCNGRY.BEHSPE.STP","PATH":"METOC/Oceanic/Oceanography/Beach Slope"},{"SYMBOLID":"WO--G----------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Geophysics/Acoustics","HIERARCHY":"3.X.2.4","ALPHAHIERARCHY":"METOC.OCA.GPHY","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO--GM---------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Mine Warefare Bottom Descriptors","HIERARCHY":"3.X.2.4.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD","PATH":"METOC/Oceanic/Geophysics-Acoustics"},{"SYMBOLID":"WO--GMS--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw-Bottom Sediments","HIERARCHY":"3.X.2.4.1.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMSR----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Solid Rock","HIERARCHY":"3.X.2.4.1.1.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.SLDRCK","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSC----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clay","HIERARCHY":"3.X.2.4.1.1.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.CLAY","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSVS--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Course Sand","HIERARCHY":"3.X.2.4.1.1.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.VCSESD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Coarse Sand","HIERARCHY":"3.X.2.4.1.1.4","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.CSESD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSM---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Medium Sand","HIERARCHY":"3.X.2.4.1.1.5","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.MDMSD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Fine Sand","HIERARCHY":"3.X.2.4.1.1.6","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.FNESD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSSVF--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Fine Sand","HIERARCHY":"3.X.2.4.1.1.7","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.VFNESD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIVF--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Very Fine Silt","HIERARCHY":"3.X.2.4.1.1.8","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.VFNSLT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Fine Silt","HIERARCHY":"3.X.2.4.1.1.9","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.FNESLT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIM---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Medium Silt","HIERARCHY":"3.X.2.4.1.1.10","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.MDMSLT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSIC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Coarse Silt","HIERARCHY":"3.X.2.4.1.1.11","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.CSESLT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMSB----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Boulders","HIERARCHY":"3.X.2.4.1.1.12","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.BLDS","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-CO--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Oyster Shells","HIERARCHY":"3.X.2.4.1.1.13","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.COBLOS","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-PH--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Pebbles Shells","HIERARCHY":"3.X.2.4.1.1.14","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.PBLSHE","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMS-SH--A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Sand and Shells","HIERARCHY":"3.X.2.4.1.1.15","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.SD&SHE","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGML-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Sediments Land","HIERARCHY":"3.X.2.4.1.1.16","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.LND","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMN-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Sediments No Data","HIERARCHY":"3.X.2.4.1.1.17","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBS.NODAT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw-Bottom Sediments"},{"SYMBOLID":"WO-DGMR--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Bottom Roughness","HIERARCHY":"3.X.2.4.1.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.BTMRGN","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMRS----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Smooth","HIERARCHY":"3.X.2.4.1.2.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.BTMRGN.SMH","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMRM----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Moderate","HIERARCHY":"3.X.2.4.1.2.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.BTMRGN.MOD","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMRR----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Roughness Rough","HIERARCHY":"3.X.2.4.1.2.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.BTMRGN.RGH","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Bottom Roughness"},{"SYMBOLID":"WO-DGMC--------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Clutter (Bottom)","HIERARCHY":"3.X.2.4.1.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.CTRB","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMCL----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter Low","HIERARCHY":"3.X.2.4.1.3.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.CTRB.LW","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMCM----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter Medium","HIERARCHY":"3.X.2.4.1.3.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.CTRB.MDM","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMCH----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Clutter High","HIERARCHY":"3.X.2.4.1.3.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.CTRB.HGH","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Clutter Low"},{"SYMBOLID":"WO-DGMIB-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Impact Burial","HIERARCHY":"3.X.2.4.1.4","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMIBA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 0","HIERARCHY":"3.X.2.4.1.4.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR.0","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 10","HIERARCHY":"3.X.2.4.1.4.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR.0-10","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 20","HIERARCHY":"3.X.2.4.1.4.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR.10-20","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBD---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 75","HIERARCHY":"3.X.2.4.1.4.4","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR.20-75","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMIBE---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Impact Burial 75-100","HIERARCHY":"3.X.2.4.1.4.5","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.IMTBUR.75-100","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Impact Burial"},{"SYMBOLID":"WO-DGMBC-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw Bottom Category","HIERARCHY":"3.X.2.4.1.5","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBC","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMBCA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category A","HIERARCHY":"3.X.2.4.1.5.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBC.A","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBCB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category B","HIERARCHY":"3.X.2.4.1.5.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBC.B","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBCC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Category C","HIERARCHY":"3.X.2.4.1.5.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBC.C","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Category"},{"SYMBOLID":"WO-DGMBT-------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Miw Bottom Type","HIERARCHY":"3.X.2.4.1.6","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors"},{"SYMBOLID":"WO-DGMBTA---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A1","HIERARCHY":"3.X.2.4.1.6.1","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.A1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTB---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A2","HIERARCHY":"3.X.2.4.1.6.2","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.A2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTC---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type A3","HIERARCHY":"3.X.2.4.1.6.3","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.A3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTD---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B1","HIERARCHY":"3.X.2.4.1.6.4","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.B1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTE---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B2","HIERARCHY":"3.X.2.4.1.6.5","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.B2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTF---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type B3","HIERARCHY":"3.X.2.4.1.6.6","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.B3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTG---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C1","HIERARCHY":"3.X.2.4.1.6.7","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.C1","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTH---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C2","HIERARCHY":"3.X.2.4.1.6.8","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.C2","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO-DGMBTI---A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Bottom Type C3","HIERARCHY":"3.X.2.4.1.6.9","ALPHAHIERARCHY":"METOC.OCA.GPHY.MNEWBD.MIWBT.C3","PATH":"METOC/Oceanic/Geophysics-Acoustics/Mine Warefare Bottom Descriptors/Miw Bottom Type"},{"SYMBOLID":"WO--L----------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Limits","HIERARCHY":"3.X.2.5","ALPHAHIERARCHY":"METOC.OCA.LMT","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO-DL-ML---L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Maritime Limit Boundary","HIERARCHY":"3.X.2.5.1","ALPHAHIERARCHY":"METOC.OCA.LMT.MARTLB","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-MA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Maritime Area","HIERARCHY":"3.X.2.5.2","ALPHAHIERARCHY":"METOC.OCA.LMT.MARTAR","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-RA---L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Restricted Area","HIERARCHY":"3.X.2.5.3","ALPHAHIERARCHY":"METOC.OCA.LMT.RSDARA","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-SA----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Swept Area","HIERARCHY":"3.X.2.5.4","ALPHAHIERARCHY":"METOC.OCA.LMT.SWPARA","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-TA----A--","GEOMETRY":"area","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Training Area","HIERARCHY":"3.X.2.5.5","ALPHAHIERARCHY":"METOC.OCA.LMT.TRGARA","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO-DL-O-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Operator Defined","HIERARCHY":"3.X.2.5.6","ALPHAHIERARCHY":"METOC.OCA.LMT.OD","PATH":"METOC/Oceanic/Limits"},{"SYMBOLID":"WO--M----------","GEOMETRY":"line","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Man-Made Structures","HIERARCHY":"3.X.2.6","ALPHAHIERARCHY":"METOC.OCA.MMD","PATH":"METOC/Oceanic"},{"SYMBOLID":"WO-DMCA----L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Cable","HIERARCHY":"3.X.2.6.1","ALPHAHIERARCHY":"METOC.OCA.MMD.SUBCBL","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMCC-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Submerged Crib","HIERARCHY":"3.X.2.6.2","ALPHAHIERARCHY":"METOC.OCA.MMD.SBMCRB","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMCD----L---","GEOMETRY":"line","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Canal","HIERARCHY":"3.X.2.6.3","ALPHAHIERARCHY":"METOC.OCA.MMD.CNL","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MF----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Ford","HIERARCHY":"3.X.2.6.4","ALPHAHIERARCHY":"METOC.OCA.MMD.FRD","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-ML----P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Lock","HIERARCHY":"3.X.2.6.5","ALPHAHIERARCHY":"METOC.OCA.MMD.LCK","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MOA---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Oil/Gas Rig","HIERARCHY":"3.X.2.6.6","ALPHAHIERARCHY":"METOC.OCA.MMD.OLRG","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMOA-----A--","GEOMETRY":"area","DRAWCATEGORY":"3","MAXPOINTS":"10000","MINPOINTS":"3","DESCRIPTION":"Oil Rig Field","HIERARCHY":"3.X.2.6.7","ALPHAHIERARCHY":"METOC.OCA.MMD.OLRGFD","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WO-DMPA----L---","GEOMETRY":"line","DRAWCATEGORY":"1","MAXPOINTS":"10000","MINPOINTS":"2","DESCRIPTION":"Pipelines/Pipe","HIERARCHY":"3.X.2.6.8","ALPHAHIERARCHY":"METOC.OCA.MMD.PPELNE","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WOS-MPA---P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Pile/Piling/Post","HIERARCHY":"3.X.2.6.9","ALPHAHIERARCHY":"METOC.OCA.MMD.PLE","PATH":"METOC/Oceanic/Man-Made Structures"},{"SYMBOLID":"WS-------------","GEOMETRY":"area","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Space","HIERARCHY":"3.X.3","ALPHAHIERARCHY":"METOC.SPC","PATH":"METOC"},{"SYMBOLID":"E*N*------*****","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Natural Events","HIERARCHY":"6.X.2","ALPHAHIERARCHY":"EMS.NATEVT","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*N*A-----*****","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Geologic","HIERARCHY":"6.X.2.1","ALPHAHIERARCHY":"EMS.NATEVT.GEO","PATH":"Emergency Management Symbols/Natural Events"},{"SYMBOLID":"E*N*AA----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Aftershock","HIERARCHY":"6.X.2.1.1","ALPHAHIERARCHY":"EMS.NATEVT.GEO.AFTSHK","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*AB----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Avalanche","HIERARCHY":"6.X.2.1.2","ALPHAHIERARCHY":"EMS.NATEVT.GEO.AVL","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*AC----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Earthquake Epicenter","HIERARCHY":"6.X.2.1.3","ALPHAHIERARCHY":"EMS.NATEVT.GEO.EQKEPI","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*AD----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Landslide","HIERARCHY":"6.X.2.1.4","ALPHAHIERARCHY":"EMS.NATEVT.GEO.LNDSLD","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*AE----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Subsidence","HIERARCHY":"6.X.2.1.5","ALPHAHIERARCHY":"EMS.NATEVT.GEO.SBSDNC","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"WAS-WSVE--P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Eruption","HIERARCHY":"6.X.2.1.6","ALPHAHIERARCHY":"EMS.NATEVT.GEO.VOLERN","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*AG----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Volcanic Threat","HIERARCHY":"6.X.2.1.7","ALPHAHIERARCHY":"EMS.NATEVT.GEO.VLCTHT","PATH":"Emergency Management Symbols/Natural Events/Geologic"},{"SYMBOLID":"E*N*B-----*****","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Hydro-Meteorological","HIERARCHY":"6.X.2.2","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET","PATH":"Emergency Management Symbols/Natural Events"},{"SYMBOLID":"WAS-WSD-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Drizzle","HIERARCHY":"6.X.2.2.1","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.DZ","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"E*N*BB----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Drought","HIERARCHY":"6.X.2.2.2","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.DRGHT","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"E*N*BC----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Flood","HIERARCHY":"6.X.2.2.3","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.FLOOD","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSFGSOP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Fog","HIERARCHY":"6.X.2.2.4","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.FG","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSGRL-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Hail","HIERARCHY":"6.X.2.2.5","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.HL","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"E*N*BF----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Inversion","HIERARCHY":"6.X.2.2.6","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.INV","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSR-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rain","HIERARCHY":"6.X.2.2.7","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.RA","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSDSLMP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Sand Dust Storm","HIERARCHY":"6.X.2.2.8","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.DT/SD","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSS-LIP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Snow","HIERARCHY":"6.X.2.2.9","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.SN","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSTMH-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Thunder Storm","HIERARCHY":"6.X.2.2.9","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.TSTRM","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WST-FCP----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tornado","HIERARCHY":"6.X.2.2.10","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.TNDO","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"WAS-WSTSS-P----","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tropical Cyclone","HIERARCHY":"6.X.2.2.11","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.TRPCYC","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"E*N*BM----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Tsunami","HIERARCHY":"6.X.2.2.12","ALPHAHIERARCHY":"EMS.NATEVT.HYDMET.TSNMI","PATH":"Emergency Management Symbols/Natural Events/Hydro-Meteorological"},{"SYMBOLID":"E*N*C-----*****","GEOMETRY":"point","DRAWCATEGORY":"0","MAXPOINTS":"0","MINPOINTS":"0","DESCRIPTION":"Infestation","HIERARCHY":"6.X.2.3","ALPHAHIERARCHY":"EMS.NATEVT.INFST","PATH":"Emergency Management Symbols/Natural Events"},{"SYMBOLID":"E*N*CA----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Bird Infestation","HIERARCHY":"6.X.2.3.1","ALPHAHIERARCHY":"EMS.NATEVT.INFST.BIRD","PATH":"Emergency Management Symbols/Natural Events/Infestation"},{"SYMBOLID":"E*N*CB----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Insect Infestation","HIERARCHY":"6.X.2.3.2","ALPHAHIERARCHY":"EMS.NATEVT.INFST.INSCT","PATH":"Emergency Management Symbols/Natural Events/Infestation"},{"SYMBOLID":"E*N*CC----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Microbial Infestation","HIERARCHY":"6.X.2.3.3","ALPHAHIERARCHY":"EMS.NATEVT.INFST.MICROB","PATH":"Emergency Management Symbols/Natural Events/Infestation"},{"SYMBOLID":"E*N*CD----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Reptile Infestation","HIERARCHY":"6.X.2.3.4","ALPHAHIERARCHY":"EMS.NATEVT.INFST.REPT","PATH":"Emergency Management Symbols/Natural Events/Infestation"},{"SYMBOLID":"E*N*CE----*****","GEOMETRY":"point","DRAWCATEGORY":"8","MAXPOINTS":"1","MINPOINTS":"1","DESCRIPTION":"Rodent Infestation","HIERARCHY":"6.X.2.3.5","ALPHAHIERARCHY":"EMS.NATEVT.INFST.RDNT","PATH":"Emergency Management Symbols/Natural Events/Infestation"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitFontMappingsC={"UNITFONTMAPPINGS":{"SYMBOL":[{"SYMBOLID":"S***------*****","DESCRIPTION":"Warfighting Symbology"},{"SYMBOLID":"S*P*------*****","DESCRIPTION":"Space Track"},{"SYMBOLID":"S*P*S-----*****","DESCRIPTION":"Satellite","MAPPING1U":"1000","MAPPING1F":"1000","MAPPING1N":"1000","MAPPING1H":"1000"},{"SYMBOLID":"S*P*V-----*****","DESCRIPTION":"Crewed Space Vehicle","MAPPING1U":"1001","MAPPING1F":"1001","MAPPING1N":"1001","MAPPING1H":"1001"},{"SYMBOLID":"S*P*T-----*****","DESCRIPTION":"Space Station","MAPPING1U":"1002","MAPPING1F":"1002","MAPPING1N":"1002","MAPPING1H":"1002","MAPPING2":"1003","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*P*L-----*****","DESCRIPTION":"Space Launch Vehicle","MAPPING1U":"1004","MAPPING1F":"1004","MAPPING1N":"1004","MAPPING1H":"1004"},{"SYMBOLID":"S*A*------*****","DESCRIPTION":"Air Track"},{"SYMBOLID":"S*A*M-----*****","DESCRIPTION":"Military","MAPPING1U":"1005","MAPPING1F":"1005","MAPPING1N":"1005","MAPPING1H":"1005"},{"SYMBOLID":"S*A*MF----*****","DESCRIPTION":"Fixed Wing","MAPPING1U":"1006","MAPPING1F":"1006","MAPPING1N":"1006","MAPPING1H":"1006"},{"SYMBOLID":"S*A*MFB---*****","DESCRIPTION":"Fixed Wing Bomber","MAPPING1U":"1007","MAPPING1F":"1007","MAPPING1N":"1007","MAPPING1H":"1007"},{"SYMBOLID":"S*A*MFF---*****","DESCRIPTION":"Fixed Wing Fighter","MAPPING1U":"1008","MAPPING1F":"1008","MAPPING1N":"1008","MAPPING1H":"1008"},{"SYMBOLID":"S*A*MFFI--*****","DESCRIPTION":"Fixed Wing Interceptor","MAPPING1U":"1009","MAPPING1F":"1009","MAPPING1N":"1009","MAPPING1H":"1009"},{"SYMBOLID":"S*A*MFT---*****","DESCRIPTION":"Fixed Wing Trainer","MAPPING1U":"1010","MAPPING1F":"1010","MAPPING1N":"1010","MAPPING1H":"1010"},{"SYMBOLID":"S*A*MFA---*****","DESCRIPTION":"Attack/Strike","MAPPING1U":"1011","MAPPING1F":"1011","MAPPING1N":"1011","MAPPING1H":"1011"},{"SYMBOLID":"S*A*MFL---*****","DESCRIPTION":"Fixed Wing VSTOL","MAPPING1U":"1012","MAPPING1F":"1012","MAPPING1N":"1012","MAPPING1H":"1012"},{"SYMBOLID":"S*A*MFK---*****","DESCRIPTION":"Fixed Wing Tanker","MAPPING1U":"1013","MAPPING1F":"1013","MAPPING1N":"1013","MAPPING1H":"1013"},{"SYMBOLID":"S*A*MFKB--*****","DESCRIPTION":"Fixed Wing Tanker Boom-Only","MAPPING1U":"1014","MAPPING1F":"1014","MAPPING1N":"1014","MAPPING1H":"1014"},{"SYMBOLID":"S*A*MFKD--*****","DESCRIPTION":"Fixed Wing Tanker Drouge-Only","MAPPING1U":"1015","MAPPING1F":"1015","MAPPING1N":"1015","MAPPING1H":"1015"},{"SYMBOLID":"S*A*MFC---*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Transport)","MAPPING1U":"1016","MAPPING1F":"1016","MAPPING1N":"1016","MAPPING1H":"1016"},{"SYMBOLID":"S*A*MFCL--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Light)","MAPPING1U":"1017","MAPPING1F":"1017","MAPPING1N":"1017","MAPPING1H":"1017"},{"SYMBOLID":"S*A*MFCM--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Medium)","MAPPING1U":"1018","MAPPING1F":"1018","MAPPING1N":"1018","MAPPING1H":"1018"},{"SYMBOLID":"S*A*MFCH--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Heavy)","MAPPING1U":"1019","MAPPING1F":"1019","MAPPING1N":"1019","MAPPING1H":"1019"},{"SYMBOLID":"S*A*MFJ---*****","DESCRIPTION":"Fixed Wing ECM/Jammer","MAPPING1U":"1020","MAPPING1F":"1020","MAPPING1N":"1020","MAPPING1H":"1020"},{"SYMBOLID":"S*A*MFO---*****","DESCRIPTION":"Fixed Wing MEDEVAC","MAPPING1U":"1021","MAPPING1F":"1021","MAPPING1N":"1021","MAPPING1H":"1021"},{"SYMBOLID":"S*A*MFR---*****","DESCRIPTION":"Fixed Wing Reconnaissance","MAPPING1U":"1022","MAPPING1F":"1022","MAPPING1N":"1022","MAPPING1H":"1022"},{"SYMBOLID":"S*A*MFRW--*****","DESCRIPTION":"Fixed Wing Airborne Early Warning (AEW)","MAPPING1U":"1023","MAPPING1F":"1023","MAPPING1N":"1023","MAPPING1H":"1023"},{"SYMBOLID":"S*A*MFRZ--*****","DESCRIPTION":"Fixed Wing Electronic Surveillance Measures","MAPPING1U":"1024","MAPPING1F":"1024","MAPPING1N":"1024","MAPPING1H":"1024"},{"SYMBOLID":"S*A*MFRX--*****","DESCRIPTION":"Fixed Wing Photographic","MAPPING1U":"1025","MAPPING1F":"1025","MAPPING1N":"1025","MAPPING1H":"1025"},{"SYMBOLID":"S*A*MFP---*****","DESCRIPTION":"Fixed Wing Patrol","MAPPING1U":"1026","MAPPING1F":"1026","MAPPING1N":"1026","MAPPING1H":"1026"},{"SYMBOLID":"S*A*MFPN--*****","DESCRIPTION":"Patrol Antisurface Warfare (ASUW)","MAPPING1U":"1027","MAPPING1F":"1027","MAPPING1N":"1027","MAPPING1H":"1027"},{"SYMBOLID":"S*A*MFPM--*****","DESCRIPTION":"Fixed Wing Mine Countermeasures","MAPPING1U":"1028","MAPPING1F":"1028","MAPPING1N":"1028","MAPPING1H":"1028"},{"SYMBOLID":"S*A*MFU---*****","DESCRIPTION":"Fixed Wing Utility","MAPPING1U":"1029","MAPPING1F":"1029","MAPPING1N":"1029","MAPPING1H":"1029"},{"SYMBOLID":"S*A*MFUL--*****","DESCRIPTION":"Fixed Wing Utility (Light)","MAPPING1U":"1030","MAPPING1F":"1030","MAPPING1N":"1030","MAPPING1H":"1030"},{"SYMBOLID":"S*A*MFUM--*****","DESCRIPTION":"Fixed Wing Utility (Medium)","MAPPING1U":"1031","MAPPING1F":"1031","MAPPING1N":"1031","MAPPING1H":"1031"},{"SYMBOLID":"S*A*MFUH--*****","DESCRIPTION":"Fixed Wing Utility (Heavy)","MAPPING1U":"1032","MAPPING1F":"1032","MAPPING1N":"1032","MAPPING1H":"1032"},{"SYMBOLID":"S*A*MFY---*****","DESCRIPTION":"Fixed Wing Communications (C3I)","MAPPING1U":"1033","MAPPING1F":"1033","MAPPING1N":"1033","MAPPING1H":"1033"},{"SYMBOLID":"S*A*MFH---*****","DESCRIPTION":"Fixed Wing Combat Search and Rescue (CSAR)","MAPPING1U":"1034","MAPPING1F":"1034","MAPPING1N":"1034","MAPPING1H":"1034"},{"SYMBOLID":"S*A*MFD---*****","DESCRIPTION":"Fixed Wing Airborne Command Post (C2)","MAPPING1U":"1035","MAPPING1F":"1035","MAPPING1N":"1035","MAPPING1H":"1035"},{"SYMBOLID":"S*A*MFQ---*****","DESCRIPTION":"Drone (RPV/UAV) Fixed Wing","MAPPING1U":"1036","MAPPING1F":"1036","MAPPING1N":"1036","MAPPING1H":"1036"},{"SYMBOLID":"S*A*MFQA--*****","DESCRIPTION":"Drone Attack","MAPPING1U":"1037","MAPPING1F":"1037","MAPPING1N":"1037","MAPPING1H":"1037"},{"SYMBOLID":"S*A*MFQB--*****","DESCRIPTION":"Drone Bomber","MAPPING1U":"1038","MAPPING1F":"1038","MAPPING1N":"1038","MAPPING1H":"1038"},{"SYMBOLID":"S*A*MFQC--*****","DESCRIPTION":"Drone Cargo","MAPPING1U":"1039","MAPPING1F":"1039","MAPPING1N":"1039","MAPPING1H":"1039"},{"SYMBOLID":"S*A*MFQD--*****","DESCRIPTION":"Drone (RPV/UAV) Airborne Command Post","MAPPING1U":"1040","MAPPING1F":"1040","MAPPING1N":"1040","MAPPING1H":"1040"},{"SYMBOLID":"S*A*MFQF--*****","DESCRIPTION":"Drone Fighter","MAPPING1U":"1041","MAPPING1F":"1041","MAPPING1N":"1041","MAPPING1H":"1041"},{"SYMBOLID":"S*A*MFQH--*****","DESCRIPTION":"Search & Rescue (CSAR)","MAPPING1U":"1042","MAPPING1F":"1042","MAPPING1N":"1042","MAPPING1H":"1042"},{"SYMBOLID":"S*A*MFQJ--*****","DESCRIPTION":"Drone Electronic Countermeasures (Jammer)","MAPPING1U":"1043","MAPPING1F":"1043","MAPPING1N":"1043","MAPPING1H":"1043"},{"SYMBOLID":"S*A*MFQK--*****","DESCRIPTION":"Drone Tanker","MAPPING1U":"1044","MAPPING1F":"1044","MAPPING1N":"1044","MAPPING1H":"1044"},{"SYMBOLID":"S*A*MFQL--*****","DESCRIPTION":"Drone Vstol","MAPPING1U":"1045","MAPPING1F":"1045","MAPPING1N":"1045","MAPPING1H":"1045"},{"SYMBOLID":"S*A*MFQM--*****","DESCRIPTION":"Drone Special Operations Forces (SOF)","MAPPING1U":"1046","MAPPING1F":"1046","MAPPING1N":"1046","MAPPING1H":"1046"},{"SYMBOLID":"S*A*MFQI--*****","DESCRIPTION":"Drone Mine Countermeasures","MAPPING1U":"1047","MAPPING1F":"1047","MAPPING1N":"1047","MAPPING1H":"1047"},{"SYMBOLID":"S*A*MFQN--*****","DESCRIPTION":"Drone Anti-Surface Warfare (ASUW)","MAPPING1U":"1048","MAPPING1F":"1048","MAPPING1N":"1048","MAPPING1H":"1048"},{"SYMBOLID":"S*A*MFQP--*****","DESCRIPTION":"Drone Patrol","MAPPING1U":"1049","MAPPING1F":"1049","MAPPING1N":"1049","MAPPING1H":"1049"},{"SYMBOLID":"S*A*MFQR--*****","DESCRIPTION":"Drone Reconnaissance","MAPPING1U":"1050","MAPPING1F":"1050","MAPPING1N":"1050","MAPPING1H":"1050"},{"SYMBOLID":"S*A*MFQRW-*****","DESCRIPTION":"Drone Airborne Early Warning (AEW)","MAPPING1U":"1051","MAPPING1F":"1051","MAPPING1N":"1051","MAPPING1H":"1051"},{"SYMBOLID":"S*A*MFQRZ-*****","DESCRIPTION":"Drone Electronic Surveillance Measures","MAPPING1U":"1052","MAPPING1F":"1052","MAPPING1N":"1052","MAPPING1H":"1052"},{"SYMBOLID":"S*A*MFQRX-*****","DESCRIPTION":"Drone Photographic","MAPPING1U":"1053","MAPPING1F":"1053","MAPPING1N":"1053","MAPPING1H":"1053"},{"SYMBOLID":"S*A*MFQS--*****","DESCRIPTION":"Drone Anti-Submarine Warfare (ASW)","MAPPING1U":"1054","MAPPING1F":"1054","MAPPING1N":"1054","MAPPING1H":"1054"},{"SYMBOLID":"S*A*MFQT--*****","DESCRIPTION":"Drone Trainer","MAPPING1U":"1055","MAPPING1F":"1055","MAPPING1N":"1055","MAPPING1H":"1055"},{"SYMBOLID":"S*A*MFQU--*****","DESCRIPTION":"Drone Utility Fixed Wing","MAPPING1U":"1056","MAPPING1F":"1056","MAPPING1N":"1056","MAPPING1H":"1056"},{"SYMBOLID":"S*A*MFQY--*****","DESCRIPTION":"Drone Communications (C3I)","MAPPING1U":"1057","MAPPING1F":"1057","MAPPING1N":"1057","MAPPING1H":"1057"},{"SYMBOLID":"S*A*MFQO--*****","DESCRIPTION":"Drone Medevac","MAPPING1U":"1058","MAPPING1F":"1058","MAPPING1N":"1058","MAPPING1H":"1058"},{"SYMBOLID":"S*A*MFS---*****","DESCRIPTION":"Antisubmarine Warfare (ASW) Carrier Based","MAPPING1U":"1059","MAPPING1F":"1059","MAPPING1N":"1059","MAPPING1H":"1059"},{"SYMBOLID":"S*A*MFM---*****","DESCRIPTION":"Fixed Wing Special Operations Forces (SOF)","MAPPING1U":"1060","MAPPING1F":"1060","MAPPING1N":"1060","MAPPING1H":"1060"},{"SYMBOLID":"S*A*MH----*****","DESCRIPTION":"Rotary Wing","MAPPING1U":"1061","MAPPING1F":"1061","MAPPING1N":"1061","MAPPING1H":"1061"},{"SYMBOLID":"S*A*MHA---*****","DESCRIPTION":"Rotary Wing Attack","MAPPING1U":"1062","MAPPING1F":"1062","MAPPING1N":"1062","MAPPING1H":"1062"},{"SYMBOLID":"S*A*MHS---*****","DESCRIPTION":"Antisubmarine Warfare/MPA ROTARY WING","MAPPING1U":"1063","MAPPING1F":"1063","MAPPING1N":"1063","MAPPING1H":"1063"},{"SYMBOLID":"S*A*MHU---*****","DESCRIPTION":"Rotary Wing Utility","MAPPING1U":"1064","MAPPING1F":"1064","MAPPING1N":"1064","MAPPING1H":"1064"},{"SYMBOLID":"S*A*MHUL--*****","DESCRIPTION":"Rotary Wing Utility (Light)","MAPPING1U":"1065","MAPPING1F":"1065","MAPPING1N":"1065","MAPPING1H":"1065"},{"SYMBOLID":"S*A*MHUM--*****","DESCRIPTION":"Rotary Wing Utility (Medium)","MAPPING1U":"1066","MAPPING1F":"1066","MAPPING1N":"1066","MAPPING1H":"1066"},{"SYMBOLID":"S*A*MHUH--*****","DESCRIPTION":"Rotary Wing Utility (Heavy)","MAPPING1U":"1067","MAPPING1F":"1067","MAPPING1N":"1067","MAPPING1H":"1067"},{"SYMBOLID":"S*A*MHI---*****","DESCRIPTION":"Rotary Wing Mine Countermeasures","MAPPING1U":"1068","MAPPING1F":"1068","MAPPING1N":"1068","MAPPING1H":"1068"},{"SYMBOLID":"S*A*MHH---*****","DESCRIPTION":"Rotary Wing Combat Search and Rescue(Military)","MAPPING1U":"1069","MAPPING1F":"1069","MAPPING1N":"1069","MAPPING1H":"1069"},{"SYMBOLID":"S*A*MHR---*****","DESCRIPTION":"Rotary Wing Reconnaissance","MAPPING1U":"1070","MAPPING1F":"1070","MAPPING1N":"1070","MAPPING1H":"1070"},{"SYMBOLID":"S*A*MHQ---*****","DESCRIPTION":"Drone (RPV/UAV) Rotary Wing","MAPPING1U":"1071","MAPPING1F":"1071","MAPPING1N":"1071","MAPPING1H":"1071"},{"SYMBOLID":"S*A*MHC---*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Transport)","MAPPING1U":"1072","MAPPING1F":"1072","MAPPING1N":"1072","MAPPING1H":"1072"},{"SYMBOLID":"S*A*MHCL--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Light)","MAPPING1U":"1073","MAPPING1F":"1073","MAPPING1N":"1073","MAPPING1H":"1073"},{"SYMBOLID":"S*A*MHCM--*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Medium)","MAPPING1U":"1074","MAPPING1F":"1074","MAPPING1N":"1074","MAPPING1H":"1074"},{"SYMBOLID":"S*A*MHCH--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Heavy)","MAPPING1U":"1075","MAPPING1F":"1075","MAPPING1N":"1075","MAPPING1H":"1075"},{"SYMBOLID":"S*A*MHT---*****","DESCRIPTION":"Rotary Wing Trainer","MAPPING1U":"1076","MAPPING1F":"1076","MAPPING1N":"1076","MAPPING1H":"1076"},{"SYMBOLID":"S*A*MHO---*****","DESCRIPTION":"Rotary Wing MEDEVAC","MAPPING1U":"1077","MAPPING1F":"1077","MAPPING1N":"1077","MAPPING1H":"1077"},{"SYMBOLID":"S*A*MHM---*****","DESCRIPTION":"Rotary Wing Special Operations Forces","MAPPING1U":"1078","MAPPING1F":"1078","MAPPING1N":"1078","MAPPING1H":"1078"},{"SYMBOLID":"S*A*MHD---*****","DESCRIPTION":"Rotary Wing Airborne Command Post","MAPPING1U":"1079","MAPPING1F":"1079","MAPPING1N":"1079","MAPPING1H":"1079"},{"SYMBOLID":"S*A*MHK---*****","DESCRIPTION":"Rotary Wing Tanker","MAPPING1U":"1080","MAPPING1F":"1080","MAPPING1N":"1080","MAPPING1H":"1080"},{"SYMBOLID":"S*A*MHJ---*****","DESCRIPTION":"Rotary Wing ECM/Jammer(TANKER)","MAPPING1U":"1081","MAPPING1F":"1081","MAPPING1N":"1081","MAPPING1H":"1081"},{"SYMBOLID":"S*A*ML----*****","DESCRIPTION":"Military Aircraft Lighter Than Air","MAPPING1U":"1082","MAPPING1F":"1082","MAPPING1N":"1082","MAPPING1H":"1082"},{"SYMBOLID":"S*A*MV----*****","DESCRIPTION":"VIP","MAPPING1U":"2167","MAPPING1F":"2167","MAPPING1N":"2167","MAPPING1H":"2167"},{"SYMBOLID":"S*A*ME----*****","DESCRIPTION":"Escort","MAPPING1U":"2168","MAPPING1F":"2168","MAPPING1N":"2168","MAPPING1H":"2168"},{"SYMBOLID":"S*A*W-----*****","DESCRIPTION":"Air Track Weapon","MAPPING1U":"1083","MAPPING1F":"1083","MAPPING1N":"1083","MAPPING1H":"1083","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WM----*****","DESCRIPTION":"Missile In Flight","MAPPING1U":"1083","MAPPING1F":"1083","MAPPING1N":"1083","MAPPING1H":"1083","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMS---*****","DESCRIPTION":"Surface Launched Missile","MAPPING1U":"1085","MAPPING1F":"1085","MAPPING1N":"1085","MAPPING1H":"1085","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSS--*****","DESCRIPTION":"Surface to Surface Missile (SSM)","MAPPING1U":"1086","MAPPING1F":"1086","MAPPING1N":"1086","MAPPING1H":"1086","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSA--*****","DESCRIPTION":"Surface To Air Missile (SAM)","MAPPING1U":"1087","MAPPING1F":"1087","MAPPING1N":"1087","MAPPING1H":"1087","MAPPING2":"1084","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSU--*****","DESCRIPTION":"Surface to Subsurface Missile","MAPPING1U":"1088","MAPPING1F":"1088","MAPPING1N":"1088","MAPPING1H":"1088","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMSB--*****","DESCRIPTION":"Anti-Ballistic Missile (ABM)","MAPPING1U":"1089","MAPPING1F":"1089","MAPPING1N":"1089","MAPPING1H":"1089","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMA---*****","DESCRIPTION":"Air Launched Missile","MAPPING1U":"1090","MAPPING1F":"1090","MAPPING1N":"1090","MAPPING1H":"1090","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAS--*****","DESCRIPTION":"Air To Surface Missile (ASM)","MAPPING1U":"1091","MAPPING1F":"1091","MAPPING1N":"1091","MAPPING1H":"1091","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAA--*****","DESCRIPTION":"Air To Air Missile (AAM)","MAPPING1U":"1093","MAPPING1F":"1093","MAPPING1N":"1093","MAPPING1H":"1093","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMAP--*****","DESCRIPTION":"Air to Space Missile","MAPPING1U":"1094","MAPPING1F":"1094","MAPPING1N":"1094","MAPPING1H":"1094","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMU---*****","DESCRIPTION":"Subsurface To Surface Missile (S/SSM)","MAPPING1U":"1095","MAPPING1F":"1095","MAPPING1N":"1095","MAPPING1H":"1095","MAPPING2":"401","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMCM--*****","DESCRIPTION":"Cruise Missile","MAPPING1U":"1096","MAPPING1F":"1096","MAPPING1N":"1096","MAPPING1H":"1096","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WMB---*****","DESCRIPTION":"Ballistic Missile","MAPPING1U":"1097","MAPPING1F":"1097","MAPPING1N":"1097","MAPPING1H":"1097","MAPPING2":"400","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"S*A*WD----*****","DESCRIPTION":"Decoy","MAPPING1U":"1099","MAPPING1F":"1099","MAPPING1N":"1099","MAPPING1H":"1099"},{"SYMBOLID":"S*A*WB----*****","DESCRIPTION":"Bomb","MAPPING1U":"1098","MAPPING1F":"1098","MAPPING1N":"1098","MAPPING1H":"1098"},{"SYMBOLID":"S*A*C-----*****","DESCRIPTION":"Civil Aircraft","MAPPING1U":"1100","MAPPING1F":"1100","MAPPING1N":"1100","MAPPING1H":"1100"},{"SYMBOLID":"S*A*CF----*****","DESCRIPTION":"Civil Fixed Wing","MAPPING1U":"1101","MAPPING1F":"1101","MAPPING1N":"1101","MAPPING1H":"1101","MAPPING2":"402","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*A*CH----*****","DESCRIPTION":"Civil Rotary Wing","MAPPING1U":"1102","MAPPING1F":"1102","MAPPING1N":"1102","MAPPING1H":"1102","MAPPING2":"403","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*A*CL----*****","DESCRIPTION":"Civil Aircraft Lighter Than Air","MAPPING1U":"1103","MAPPING1F":"1103","MAPPING1N":"1103","MAPPING1H":"1103","MAPPING2":"404","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*------*****","DESCRIPTION":"Ground Track"},{"SYMBOLID":"S*G*U-----*****","DESCRIPTION":"Unit"},{"SYMBOLID":"S*G*UC----*****","DESCRIPTION":"Combat","MAPPING1U":"1104","MAPPING1F":"1104","MAPPING1N":"1104","MAPPING1H":"1104"},{"SYMBOLID":"S*G*UCD---*****","DESCRIPTION":"Air Defense","MAPPING1U":"1105","MAPPING1F":"1106","MAPPING1N":"1107","MAPPING1H":"1108"},{"SYMBOLID":"S*G*UCDS--*****","DESCRIPTION":"Short Range","MAPPING1U":"1109","MAPPING1F":"1110","MAPPING1N":"1111","MAPPING1H":"1112"},{"SYMBOLID":"S*G*UCDSC-*****","DESCRIPTION":"Chaparral","MAPPING1U":"1113","MAPPING1F":"1114","MAPPING1N":"1115","MAPPING1H":"1116"},{"SYMBOLID":"S*G*UCDSS-*****","DESCRIPTION":"Stinger","MAPPING1U":"1117","MAPPING1F":"1118","MAPPING1N":"1119","MAPPING1H":"1120"},{"SYMBOLID":"S*G*UCDSV-*****","DESCRIPTION":"Vulcan","MAPPING1U":"1121","MAPPING1F":"1122","MAPPING1N":"1123","MAPPING1H":"1124"},{"SYMBOLID":"S*G*UCDM--*****","DESCRIPTION":"Air Defense Missile","MAPPING1U":"1125","MAPPING1F":"1126","MAPPING1N":"1127","MAPPING1H":"1128"},{"SYMBOLID":"S*G*UCDML-*****","DESCRIPTION":"Air Defense Missile Light","MAPPING1U":"1129","MAPPING1F":"1130","MAPPING1N":"1131","MAPPING1H":"1132"},{"SYMBOLID":"S*G*UCDMLA*****","DESCRIPTION":"Air Defense Missile Motorized (Avenger)","MAPPING1U":"1133","MAPPING1F":"1134","MAPPING1N":"1135","MAPPING1H":"1136"},{"SYMBOLID":"S*G*UCDMM-*****","DESCRIPTION":"Air Defense Missile Medium","MAPPING1U":"1137","MAPPING1F":"1138","MAPPING1N":"1139","MAPPING1H":"1140"},{"SYMBOLID":"S*G*UCDMH-*****","DESCRIPTION":"Air Defense Missile Heavy","MAPPING1U":"1141","MAPPING1F":"1142","MAPPING1N":"1143","MAPPING1H":"1144"},{"SYMBOLID":"S*G*UCDH--*****","DESCRIPTION":"H/MAD","MAPPING1U":"1145","MAPPING1F":"1146","MAPPING1N":"1147","MAPPING1H":"1148"},{"SYMBOLID":"S*G*UCDHH-*****","DESCRIPTION":"Hawk","MAPPING1U":"1149","MAPPING1F":"1150","MAPPING1N":"1151","MAPPING1H":"1152"},{"SYMBOLID":"S*G*UCDHP-*****","DESCRIPTION":"Patriot","MAPPING1U":"1153","MAPPING1F":"1154","MAPPING1N":"1155","MAPPING1H":"1156"},{"SYMBOLID":"S*G*UCDG--*****","DESCRIPTION":"Gun Unit","MAPPING1U":"1157","MAPPING1F":"1158","MAPPING1N":"1159","MAPPING1H":"1160"},{"SYMBOLID":"S*G*UCDC--*****","DESCRIPTION":"Air Defense Composite","MAPPING1U":"1161","MAPPING1F":"1162","MAPPING1N":"1163","MAPPING1H":"1164"},{"SYMBOLID":"S*G*UCDT--*****","DESCRIPTION":"Targeting Unit","MAPPING1U":"1165","MAPPING1F":"1166","MAPPING1N":"1167","MAPPING1H":"1168"},{"SYMBOLID":"S*G*UCDO--*****","DESCRIPTION":"Theater Missile Defense Unit","MAPPING1U":"1169","MAPPING1F":"1170","MAPPING1N":"1171","MAPPING1H":"1172"},{"SYMBOLID":"S*G*UCA---*****","DESCRIPTION":"Armor","MAPPING1U":"1173","MAPPING1F":"1173","MAPPING1N":"1173","MAPPING1H":"1173"},{"SYMBOLID":"S*G*UCAT--*****","DESCRIPTION":"Armor Track","MAPPING1U":"1173","MAPPING1F":"1173","MAPPING1N":"1173","MAPPING1H":"1173"},{"SYMBOLID":"S*G*UCATA-*****","DESCRIPTION":"Armor Track Airborne","MAPPING1U":"1174","MAPPING1F":"1174","MAPPING1N":"1174","MAPPING1H":"1174"},{"SYMBOLID":"S*G*UCATW-*****","DESCRIPTION":"Armor Track Amphibious","MAPPING1U":"1175","MAPPING1F":"1176","MAPPING1N":"1177","MAPPING1H":"1178"},{"SYMBOLID":"S*G*UCATWR*****","DESCRIPTION":"Armor Track Amphibious Recovery","MAPPING1U":"1179","MAPPING1F":"1180","MAPPING1N":"1181","MAPPING1H":"1182"},{"SYMBOLID":"S*G*UCATL-*****","DESCRIPTION":"Armor Track, Light","MAPPING1U":"1183","MAPPING1F":"1183","MAPPING1N":"1183","MAPPING1H":"1183"},{"SYMBOLID":"S*G*UCATM-*****","DESCRIPTION":"Armor Track, Medium","MAPPING1U":"1184","MAPPING1F":"1184","MAPPING1N":"1184","MAPPING1H":"1184"},{"SYMBOLID":"S*G*UCATH-*****","DESCRIPTION":"Armor Track, Heavy","MAPPING1U":"1185","MAPPING1F":"1185","MAPPING1N":"1185","MAPPING1H":"1185"},{"SYMBOLID":"S*G*UCATR-*****","DESCRIPTION":"Armor Track, Recovery","MAPPING1U":"1186","MAPPING1F":"1186","MAPPING1N":"1186","MAPPING1H":"1186"},{"SYMBOLID":"S*G*UCAW--*****","DESCRIPTION":"Armor, Wheeled","MAPPING1U":"1187","MAPPING1F":"1187","MAPPING1N":"1187","MAPPING1H":"1187"},{"SYMBOLID":"S*G*UCAWS-*****","DESCRIPTION":"Armor, Wheeled Air Assault","MAPPING1U":"1188","MAPPING1F":"1188","MAPPING1N":"1188","MAPPING1H":"1188"},{"SYMBOLID":"S*G*UCAWA-*****","DESCRIPTION":"Armor, Wheeled Airborne","MAPPING1U":"1189","MAPPING1F":"1189","MAPPING1N":"1189","MAPPING1H":"1189"},{"SYMBOLID":"S*G*UCAWW-*****","DESCRIPTION":"Armor, Wheeled Amphibious","MAPPING1U":"1190","MAPPING1F":"1191","MAPPING1N":"1192","MAPPING1H":"1193"},{"SYMBOLID":"S*G*UCAWWR*****","DESCRIPTION":"Armor, Wheeled Amphibious Recovery","MAPPING1U":"1194","MAPPING1F":"1195","MAPPING1N":"1196","MAPPING1H":"1197"},{"SYMBOLID":"S*G*UCAWL-*****","DESCRIPTION":"Armor, Wheeled Light","MAPPING1U":"1198","MAPPING1F":"1198","MAPPING1N":"1198","MAPPING1H":"1198"},{"SYMBOLID":"S*G*UCAWM-*****","DESCRIPTION":"Armor, Wheeled Medium","MAPPING1U":"1199","MAPPING1F":"1199","MAPPING1N":"1199","MAPPING1H":"1199"},{"SYMBOLID":"S*G*UCAWH-*****","DESCRIPTION":"Armor, Wheeled Heavy","MAPPING1U":"1200","MAPPING1F":"1200","MAPPING1N":"1200","MAPPING1H":"1200"},{"SYMBOLID":"S*G*UCAWR-*****","DESCRIPTION":"Armor, Wheeled Recovery","MAPPING1U":"1201","MAPPING1F":"1201","MAPPING1N":"1201","MAPPING1H":"1201"},{"SYMBOLID":"S*G*UCAA--*****","DESCRIPTION":"Anti Armor","MAPPING1U":"1202","MAPPING1F":"1203","MAPPING1N":"1204","MAPPING1H":"1205"},{"SYMBOLID":"S*G*UCAAD-*****","DESCRIPTION":"Anti Armor Dismounted","MAPPING1U":"1202","MAPPING1F":"1203","MAPPING1N":"1204","MAPPING1H":"1205"},{"SYMBOLID":"S*G*UCAAL-*****","DESCRIPTION":"Anti Armor Light","MAPPING1U":"1206","MAPPING1F":"1207","MAPPING1N":"1208","MAPPING1H":"1209"},{"SYMBOLID":"S*G*UCAAM-*****","DESCRIPTION":"Anti Armor Airborne","MAPPING1U":"1210","MAPPING1F":"1211","MAPPING1N":"1212","MAPPING1H":"1213"},{"SYMBOLID":"S*G*UCAAS-*****","DESCRIPTION":"Anti Armor Air Assault","MAPPING1U":"1214","MAPPING1F":"1215","MAPPING1N":"1216","MAPPING1H":"1217"},{"SYMBOLID":"S*G*UCAAU-*****","DESCRIPTION":"Anti Armor Mountain","MAPPING1U":"1218","MAPPING1F":"1219","MAPPING1N":"1220","MAPPING1H":"1221"},{"SYMBOLID":"S*G*UCAAC-*****","DESCRIPTION":"Anti Armor Arctic","MAPPING1U":"1222","MAPPING1F":"1223","MAPPING1N":"1224","MAPPING1H":"1225"},{"SYMBOLID":"S*G*UCAAA-*****","DESCRIPTION":"Anti Armor Armored","MAPPING1U":"1226","MAPPING1F":"1227","MAPPING1N":"1228","MAPPING1H":"1229"},{"SYMBOLID":"S*G*UCAAAT*****","DESCRIPTION":"Anti Armor Armored Tracked","MAPPING1U":"1226","MAPPING1F":"1227","MAPPING1N":"1228","MAPPING1H":"1229"},{"SYMBOLID":"S*G*UCAAAW*****","DESCRIPTION":"Anti Armor Armored Wheeled","MAPPING1U":"1230","MAPPING1F":"1231","MAPPING1N":"1232","MAPPING1H":"1233"},{"SYMBOLID":"S*G*UCAAAS*****","DESCRIPTION":"Anti Armor Armored Air Assault","MAPPING1U":"1234","MAPPING1F":"1235","MAPPING1N":"1236","MAPPING1H":"1237"},{"SYMBOLID":"S*G*UCAAO-*****","DESCRIPTION":"Anti Armor Motorized","MAPPING1U":"1238","MAPPING1F":"1239","MAPPING1N":"1240","MAPPING1H":"1241"},{"SYMBOLID":"S*G*UCAAOS*****","DESCRIPTION":"Anti Armor Motorized Air Assault","MAPPING1U":"1242","MAPPING1F":"1243","MAPPING1N":"1244","MAPPING1H":"1245"},{"SYMBOLID":"S*G*UCV---*****","DESCRIPTION":"Aviation","MAPPING1U":"1246","MAPPING1F":"1246","MAPPING1N":"1246","MAPPING1H":"1246"},{"SYMBOLID":"S*G*UCVF--*****","DESCRIPTION":"Aviation Fixed Wing","MAPPING1U":"1247","MAPPING1F":"1247","MAPPING1N":"1247","MAPPING1H":"1247"},{"SYMBOLID":"S*G*UCVFU-*****","DESCRIPTION":"Utility Fixed Wing","MAPPING1U":"1248","MAPPING1F":"1248","MAPPING1N":"1248","MAPPING1H":"1248"},{"SYMBOLID":"S*G*UCVFA-*****","DESCRIPTION":"Fixed Wing Attack","MAPPING1U":"1249","MAPPING1F":"1249","MAPPING1N":"1249","MAPPING1H":"1249"},{"SYMBOLID":"S*G*UCVFR-*****","DESCRIPTION":"Recon Fixed Wing","MAPPING1U":"1250","MAPPING1F":"1250","MAPPING1N":"1250","MAPPING1H":"1250"},{"SYMBOLID":"S*G*UCVR--*****","DESCRIPTION":"Aviation Rotary Wing","MAPPING1U":"1251","MAPPING1F":"1251","MAPPING1N":"1251","MAPPING1H":"1251"},{"SYMBOLID":"S*G*UCVRA-*****","DESCRIPTION":"Attack Rotary Wing","MAPPING1U":"1252","MAPPING1F":"1252","MAPPING1N":"1252","MAPPING1H":"1252"},{"SYMBOLID":"S*G*UCVRS-*****","DESCRIPTION":"Scout Rotary Wing","MAPPING1U":"1253","MAPPING1F":"1253","MAPPING1N":"1253","MAPPING1H":"1253"},{"SYMBOLID":"S*G*UCVRW-*****","DESCRIPTION":"Antisubmarine Warfare Rotary Wing","MAPPING1U":"1254","MAPPING1F":"1254","MAPPING1N":"1254","MAPPING1H":"1254"},{"SYMBOLID":"S*G*UCVRU-*****","DESCRIPTION":"Utility Rotary Wing","MAPPING1U":"1255","MAPPING1F":"1255","MAPPING1N":"1255","MAPPING1H":"1255"},{"SYMBOLID":"S*G*UCVRUL*****","DESCRIPTION":"Light Utility Rotary Wing","MAPPING1U":"1256","MAPPING1F":"1256","MAPPING1N":"1256","MAPPING1H":"1256"},{"SYMBOLID":"S*G*UCVRUM*****","DESCRIPTION":"Medium Utility Rotary Wing","MAPPING1U":"1257","MAPPING1F":"1257","MAPPING1N":"1257","MAPPING1H":"1257"},{"SYMBOLID":"S*G*UCVRUH*****","DESCRIPTION":"Heavy Utility Rotary Wing","MAPPING1U":"1258","MAPPING1F":"1258","MAPPING1N":"1258","MAPPING1H":"1258"},{"SYMBOLID":"S*G*UCVRUC*****","DESCRIPTION":"C2 Rotary Wing","MAPPING1U":"1259","MAPPING1F":"1259","MAPPING1N":"1259","MAPPING1H":"1259"},{"SYMBOLID":"S*G*UCVRUE*****","DESCRIPTION":"Medevac Rotary Wing","MAPPING1U":"1260","MAPPING1F":"1260","MAPPING1N":"1260","MAPPING1H":"1260"},{"SYMBOLID":"S*G*UCVRM-*****","DESCRIPTION":"Mine Countermeasure Rotary Wing","MAPPING1U":"1261","MAPPING1F":"1261","MAPPING1N":"1261","MAPPING1H":"1261"},{"SYMBOLID":"S*G*UCVS--*****","DESCRIPTION":"Search and Rescue","MAPPING1U":"1262","MAPPING1F":"1262","MAPPING1N":"1262","MAPPING1H":"1262"},{"SYMBOLID":"S*G*UCVC--*****","DESCRIPTION":"Aviation Composite","MAPPING1U":"1263","MAPPING1F":"1263","MAPPING1N":"1263","MAPPING1H":"1263"},{"SYMBOLID":"S*G*UCVV--*****","DESCRIPTION":"Vertical/Short Takeoff And Landing (V/Stol)","MAPPING1U":"1264","MAPPING1F":"1264","MAPPING1N":"1264","MAPPING1H":"1264"},{"SYMBOLID":"S*G*UCVU--*****","DESCRIPTION":"Unmanned Aerial Vehicle","MAPPING1U":"1265","MAPPING1F":"1265","MAPPING1N":"1265","MAPPING1H":"1265"},{"SYMBOLID":"S*G*UCVUF-*****","DESCRIPTION":"Unmanned Aerial Vehicle Fixed Wing","MAPPING1U":"1266","MAPPING1F":"1266","MAPPING1N":"1266","MAPPING1H":"1266"},{"SYMBOLID":"S*G*UCVUR-*****","DESCRIPTION":"Unmanned Aerial Vehicle Rotary Wing","MAPPING1U":"1267","MAPPING1F":"1267","MAPPING1N":"1267","MAPPING1H":"1267"},{"SYMBOLID":"S*G*UCI---*****","DESCRIPTION":"Infantry","MAPPING1U":"1268","MAPPING1F":"1269","MAPPING1N":"1270","MAPPING1H":"1271"},{"SYMBOLID":"S*G*UCIL--*****","DESCRIPTION":"Infantry Light","MAPPING1U":"1272","MAPPING1F":"1273","MAPPING1N":"1274","MAPPING1H":"1275"},{"SYMBOLID":"S*G*UCIM--*****","DESCRIPTION":"Infantry Motorized","MAPPING1U":"1276","MAPPING1F":"1277","MAPPING1N":"1278","MAPPING1H":"1279"},{"SYMBOLID":"S*G*UCIO--*****","DESCRIPTION":"Infantry Mountain","MAPPING1U":"1280","MAPPING1F":"1281","MAPPING1N":"1282","MAPPING1H":"1283"},{"SYMBOLID":"S*G*UCIA--*****","DESCRIPTION":"Infantry Airborne","MAPPING1U":"1284","MAPPING1F":"1285","MAPPING1N":"1286","MAPPING1H":"1287"},{"SYMBOLID":"S*G*UCIS--*****","DESCRIPTION":"Infantry Air Assault","MAPPING1U":"1288","MAPPING1F":"1289","MAPPING1N":"1290","MAPPING1H":"1291"},{"SYMBOLID":"S*G*UCIZ--*****","DESCRIPTION":"Infantry Mechanized","MAPPING1U":"1292","MAPPING1F":"1293","MAPPING1N":"1294","MAPPING1H":"1295"},{"SYMBOLID":"S*G*UCIN--*****","DESCRIPTION":"Infantry Naval","MAPPING1U":"1296","MAPPING1F":"1297","MAPPING1N":"1298","MAPPING1H":"1299"},{"SYMBOLID":"S*G*UCII--*****","DESCRIPTION":"Infantry Fighting Vehicle","MAPPING1U":"1300","MAPPING1F":"1301","MAPPING1N":"1302","MAPPING1H":"1303"},{"SYMBOLID":"S*G*UCIC--*****","DESCRIPTION":"Infantry Arctic","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"1092"},{"SYMBOLID":"S*G*UCE---*****","DESCRIPTION":"Engineer","MAPPING1U":"1304","MAPPING1F":"1304","MAPPING1N":"1304","MAPPING1H":"1304"},{"SYMBOLID":"S*G*UCEC--*****","DESCRIPTION":"Engineer Combat","MAPPING1U":"1305","MAPPING1F":"1305","MAPPING1N":"1305","MAPPING1H":"1305"},{"SYMBOLID":"S*G*UCECS-*****","DESCRIPTION":"Engineer Combat Air Assault","MAPPING1U":"1306","MAPPING1F":"1306","MAPPING1N":"1306","MAPPING1H":"1306"},{"SYMBOLID":"S*G*UCECA-*****","DESCRIPTION":"Engineer Combat Airborne","MAPPING1U":"1307","MAPPING1F":"1307","MAPPING1N":"1307","MAPPING1H":"1307"},{"SYMBOLID":"S*G*UCECC-*****","DESCRIPTION":"Engineer Combat Arctic","MAPPING1U":"1308","MAPPING1F":"1308","MAPPING1N":"1308","MAPPING1H":"1308"},{"SYMBOLID":"S*G*UCECL-*****","DESCRIPTION":"Engineer Combat Light (Sapper)","MAPPING1U":"1309","MAPPING1F":"1309","MAPPING1N":"1309","MAPPING1H":"1309"},{"SYMBOLID":"S*G*UCECM-*****","DESCRIPTION":"Engineer Combat Medium","MAPPING1U":"1310","MAPPING1F":"1310","MAPPING1N":"1310","MAPPING1H":"1310"},{"SYMBOLID":"S*G*UCECH-*****","DESCRIPTION":"Engineer Combat Heavy","MAPPING1U":"1311","MAPPING1F":"1311","MAPPING1N":"1311","MAPPING1H":"1311"},{"SYMBOLID":"S*G*UCECT-*****","DESCRIPTION":"Engineer Combat Mechanized (Track)","MAPPING1U":"1312","MAPPING1F":"1312","MAPPING1N":"1312","MAPPING1H":"1312"},{"SYMBOLID":"S*G*UCECW-*****","DESCRIPTION":"Engineer Combat Motorized","MAPPING1U":"1313","MAPPING1F":"1314","MAPPING1N":"1315","MAPPING1H":"1316"},{"SYMBOLID":"S*G*UCECO-*****","DESCRIPTION":"Engineer Combat Mountain","MAPPING1U":"1317","MAPPING1F":"1317","MAPPING1N":"1317","MAPPING1H":"1317"},{"SYMBOLID":"S*G*UCECR-*****","DESCRIPTION":"Engineer Combat Recon","MAPPING1U":"1318","MAPPING1F":"1319","MAPPING1N":"1320","MAPPING1H":"1321"},{"SYMBOLID":"S*G*UCEN--*****","DESCRIPTION":"Engineer Construction","MAPPING1U":"1322","MAPPING1F":"1322","MAPPING1N":"1322","MAPPING1H":"1322"},{"SYMBOLID":"S*G*UCENN-*****","DESCRIPTION":"Engineer Naval Construction","MAPPING1U":"1323","MAPPING1F":"1323","MAPPING1N":"1323","MAPPING1H":"1323"},{"SYMBOLID":"S*G*UCF---*****","DESCRIPTION":"Field Artillery","MAPPING1U":"1324","MAPPING1F":"1324","MAPPING1N":"1324","MAPPING1H":"1324"},{"SYMBOLID":"S*G*UCFH--*****","DESCRIPTION":"Howitzer/Gun","MAPPING1U":"1324","MAPPING1F":"1324","MAPPING1N":"1324","MAPPING1H":"1324"},{"SYMBOLID":"S*G*UCFHE-*****","DESCRIPTION":"Self-Propelled","MAPPING1U":"1325","MAPPING1F":"1325","MAPPING1N":"1325","MAPPING1H":"1325"},{"SYMBOLID":"S*G*UCFHS-*****","DESCRIPTION":"Howitzer/Gun Air Assault","MAPPING1U":"1326","MAPPING1F":"1326","MAPPING1N":"1326","MAPPING1H":"1326"},{"SYMBOLID":"S*G*UCFHA-*****","DESCRIPTION":"Howitzer/Gun Airborne","MAPPING1U":"1327","MAPPING1F":"1327","MAPPING1N":"1327","MAPPING1H":"1327"},{"SYMBOLID":"S*G*UCFHC-*****","DESCRIPTION":"Arctic","MAPPING1U":"1328","MAPPING1F":"1328","MAPPING1N":"1328","MAPPING1H":"1328"},{"SYMBOLID":"S*G*UCFHO-*****","DESCRIPTION":"Howitzer/Gun Mountain","MAPPING1U":"1329","MAPPING1F":"1329","MAPPING1N":"1329","MAPPING1H":"1329"},{"SYMBOLID":"S*G*UCFHL-*****","DESCRIPTION":"Howitzer/Gun Light","MAPPING1U":"1330","MAPPING1F":"1330","MAPPING1N":"1330","MAPPING1H":"1330"},{"SYMBOLID":"S*G*UCFHM-*****","DESCRIPTION":"Howitzer/Gun Medium","MAPPING1U":"1331","MAPPING1F":"1331","MAPPING1N":"1331","MAPPING1H":"1331"},{"SYMBOLID":"S*G*UCFHH-*****","DESCRIPTION":"Heavy","MAPPING1U":"1332","MAPPING1F":"1332","MAPPING1N":"1332","MAPPING1H":"1332"},{"SYMBOLID":"S*G*UCFHX-*****","DESCRIPTION":"Amphibious","MAPPING1U":"1333","MAPPING1F":"1334","MAPPING1N":"1335","MAPPING1H":"1336"},{"SYMBOLID":"S*G*UCFR--*****","DESCRIPTION":"Rocket","MAPPING1U":"1337","MAPPING1F":"1337","MAPPING1N":"1337","MAPPING1H":"1337"},{"SYMBOLID":"S*G*UCFRS-*****","DESCRIPTION":"Rocket Single Rocket Launcher","MAPPING1U":"1338","MAPPING1F":"1338","MAPPING1N":"1338","MAPPING1H":"1338"},{"SYMBOLID":"S*G*UCFRSS*****","DESCRIPTION":"Single Rocket Self-Propelled","MAPPING1U":"1339","MAPPING1F":"1339","MAPPING1N":"1339","MAPPING1H":"1339"},{"SYMBOLID":"S*G*UCFRSR*****","DESCRIPTION":"Single Rocket Truck","MAPPING1U":"1340","MAPPING1F":"1340","MAPPING1N":"1340","MAPPING1H":"1340"},{"SYMBOLID":"S*G*UCFRST*****","DESCRIPTION":"Single Rocket Towed","MAPPING1U":"1341","MAPPING1F":"1341","MAPPING1N":"1341","MAPPING1H":"1341"},{"SYMBOLID":"S*G*UCFRM-*****","DESCRIPTION":"Multi Rocket Launcher","MAPPING1U":"1342","MAPPING1F":"1342","MAPPING1N":"1342","MAPPING1H":"1342"},{"SYMBOLID":"S*G*UCFRMS*****","DESCRIPTION":"Multi Rocket Self-Propelled","MAPPING1U":"1343","MAPPING1F":"1343","MAPPING1N":"1343","MAPPING1H":"1343"},{"SYMBOLID":"S*G*UCFRMR*****","DESCRIPTION":"Multi Rocket Truck","MAPPING1U":"1344","MAPPING1F":"1344","MAPPING1N":"1344","MAPPING1H":"1344"},{"SYMBOLID":"S*G*UCFRMT*****","DESCRIPTION":"Multi Rocket Towed","MAPPING1U":"1345","MAPPING1F":"1345","MAPPING1N":"1345","MAPPING1H":"1345"},{"SYMBOLID":"S*G*UCFT--*****","DESCRIPTION":"Target Acquisition","MAPPING1U":"1346","MAPPING1F":"1346","MAPPING1N":"1346","MAPPING1H":"1346"},{"SYMBOLID":"S*G*UCFTR-*****","DESCRIPTION":"Target Acquisition Radar","MAPPING1U":"1347","MAPPING1F":"1347","MAPPING1N":"1347","MAPPING1H":"1347"},{"SYMBOLID":"S*G*UCFTS-*****","DESCRIPTION":"Sound","MAPPING1U":"1348","MAPPING1F":"1349","MAPPING1N":"1350","MAPPING1H":"1351","MAPPING2":"405","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFTF-*****","DESCRIPTION":"Flash (Optical)","MAPPING1U":"1352","MAPPING1F":"1352","MAPPING1N":"1352","MAPPING1H":"1352"},{"SYMBOLID":"S*G*UCFTC-*****","DESCRIPTION":"Colt/Fist","MAPPING1U":"1353","MAPPING1F":"1354","MAPPING1N":"1355","MAPPING1H":"1356"},{"SYMBOLID":"S*G*UCFTCD*****","DESCRIPTION":"Dismounted Colt/Fist","MAPPING1U":"1357","MAPPING1F":"1358","MAPPING1N":"1359","MAPPING1H":"1360"},{"SYMBOLID":"S*G*UCFTCM*****","DESCRIPTION":"Tracked Colt/Fist","MAPPING1U":"1361","MAPPING1F":"1362","MAPPING1N":"1363","MAPPING1H":"1364"},{"SYMBOLID":"S*G*UCFTA-*****","DESCRIPTION":"Anglico","MAPPING1U":"1365","MAPPING1F":"1366","MAPPING1N":"1367","MAPPING1H":"1368"},{"SYMBOLID":"S*G*UCFM--*****","DESCRIPTION":"Field Artillery Mortar","MAPPING1U":"1369","MAPPING1F":"1369","MAPPING1N":"1369","MAPPING1H":"1369"},{"SYMBOLID":"S*G*UCFMS-*****","DESCRIPTION":"Self-Propelled (SP) Tracked Mortar","MAPPING1U":"1370","MAPPING1F":"1370","MAPPING1N":"1370","MAPPING1H":"1370"},{"SYMBOLID":"S*G*UCFMW-*****","DESCRIPTION":"SP Wheeled Mortar","MAPPING1U":"1371","MAPPING1F":"1371","MAPPING1N":"1371","MAPPING1H":"1371"},{"SYMBOLID":"S*G*UCFMT-*****","DESCRIPTION":"Towed Mortar","MAPPING1U":"1372","MAPPING1F":"1372","MAPPING1N":"1372","MAPPING1H":"1372"},{"SYMBOLID":"S*G*UCFMTA*****","DESCRIPTION":"Towed Airborne Mortar","MAPPING1U":"1373","MAPPING1F":"1373","MAPPING1N":"1373","MAPPING1H":"1373"},{"SYMBOLID":"S*G*UCFMTS*****","DESCRIPTION":"Towed Air Assault Mortar","MAPPING1U":"1374","MAPPING1F":"1374","MAPPING1N":"1374","MAPPING1H":"1374"},{"SYMBOLID":"S*G*UCFMTC*****","DESCRIPTION":"Towed Arctic Mortar","MAPPING1U":"1375","MAPPING1F":"1375","MAPPING1N":"1375","MAPPING1H":"1375"},{"SYMBOLID":"S*G*UCFMTO*****","DESCRIPTION":"Towed Mountain Mortar","MAPPING1U":"1376","MAPPING1F":"1376","MAPPING1N":"1376","MAPPING1H":"1376"},{"SYMBOLID":"S*G*UCFML-*****","DESCRIPTION":"Amphibious Mortar","MAPPING1U":"1377","MAPPING1F":"1378","MAPPING1N":"1379","MAPPING1H":"1380"},{"SYMBOLID":"S*G*UCFS--*****","DESCRIPTION":"Artillery Survey","MAPPING1U":"1381","MAPPING1F":"1381","MAPPING1N":"1381","MAPPING1H":"1381","MAPPING2":"1382","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSS-*****","DESCRIPTION":"Artillery Survey Air Assault","MAPPING1U":"1383","MAPPING1F":"1383","MAPPING1N":"1383","MAPPING1H":"1383","MAPPING2":"1384","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSA-*****","DESCRIPTION":"Artillery Survey Airborne","MAPPING1U":"1385","MAPPING1F":"1385","MAPPING1N":"1385","MAPPING1H":"1385","MAPPING2":"1386","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSL-*****","DESCRIPTION":"Artillery Survey Light","MAPPING1U":"1387","MAPPING1F":"1387","MAPPING1N":"1387","MAPPING1H":"1387","MAPPING2":"1388","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFSO-*****","DESCRIPTION":"Artillery Survey Mountain","MAPPING1U":"1389","MAPPING1F":"1389","MAPPING1N":"1389","MAPPING1H":"1389","MAPPING2":"1390","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UCFO--*****","DESCRIPTION":"Field Artillery Meteorological","MAPPING1U":"1391","MAPPING1F":"1391","MAPPING1N":"1391","MAPPING1H":"1391"},{"SYMBOLID":"S*G*UCFOS-*****","DESCRIPTION":"Air Assault Meteorological","MAPPING1U":"1392","MAPPING1F":"1392","MAPPING1N":"1392","MAPPING1H":"1392"},{"SYMBOLID":"S*G*UCFOA-*****","DESCRIPTION":"Airborne Meteorological","MAPPING1U":"1393","MAPPING1F":"1393","MAPPING1N":"1393","MAPPING1H":"1393"},{"SYMBOLID":"S*G*UCFOL-*****","DESCRIPTION":"Light Meteorological","MAPPING1U":"1394","MAPPING1F":"1394","MAPPING1N":"1394","MAPPING1H":"1394"},{"SYMBOLID":"S*G*UCFOO-*****","DESCRIPTION":"Mountain Meteorological","MAPPING1U":"1395","MAPPING1F":"1395","MAPPING1N":"1395","MAPPING1H":"1395"},{"SYMBOLID":"S*G*UCR---*****","DESCRIPTION":"Combat Reconnaissance","MAPPING1U":"1396","MAPPING1F":"1397","MAPPING1N":"1398","MAPPING1H":"1399"},{"SYMBOLID":"S*G*UCRH--*****","DESCRIPTION":"Reconnaissance Horse","MAPPING1U":"1400","MAPPING1F":"1400","MAPPING1N":"1400","MAPPING1H":"1400"},{"SYMBOLID":"S*G*UCRV--*****","DESCRIPTION":"Reconnaissance Cavalry","MAPPING1U":"1401","MAPPING1F":"1402","MAPPING1N":"1403","MAPPING1H":"1404"},{"SYMBOLID":"S*G*UCRVA-*****","DESCRIPTION":"Reconnaissance Cavalry Armored","MAPPING1U":"1405","MAPPING1F":"1406","MAPPING1N":"1407","MAPPING1H":"1408"},{"SYMBOLID":"S*G*UCRVM-*****","DESCRIPTION":"Reconnaissance Cavalry Motorized","MAPPING1U":"1409","MAPPING1F":"1410","MAPPING1N":"1411","MAPPING1H":"1412"},{"SYMBOLID":"S*G*UCRVG-*****","DESCRIPTION":"Reconnaissance Cavalry Ground","MAPPING1U":"1413","MAPPING1F":"1414","MAPPING1N":"1415","MAPPING1H":"1416"},{"SYMBOLID":"S*G*UCRVO-*****","DESCRIPTION":"Reconnaissance Cavalry Air","MAPPING1U":"1417","MAPPING1F":"1418","MAPPING1N":"1419","MAPPING1H":"1420"},{"SYMBOLID":"S*G*UCRC--*****","DESCRIPTION":"Reconnaissance Arctic","MAPPING1U":"1421","MAPPING1F":"1422","MAPPING1N":"1423","MAPPING1H":"1424"},{"SYMBOLID":"S*G*UCRS--*****","DESCRIPTION":"Reconnaissance Air Assault","MAPPING1U":"1425","MAPPING1F":"1426","MAPPING1N":"1427","MAPPING1H":"1428"},{"SYMBOLID":"S*G*UCRA--*****","DESCRIPTION":"Reconnaissance Airborne","MAPPING1U":"1429","MAPPING1F":"1430","MAPPING1N":"1431","MAPPING1H":"1432"},{"SYMBOLID":"S*G*UCRO--*****","DESCRIPTION":"Reconnaissance Mountain","MAPPING1U":"1433","MAPPING1F":"1434","MAPPING1N":"1435","MAPPING1H":"1436"},{"SYMBOLID":"S*G*UCRL--*****","DESCRIPTION":"Reconnaissance Light","MAPPING1U":"1437","MAPPING1F":"1438","MAPPING1N":"1439","MAPPING1H":"1440"},{"SYMBOLID":"S*G*UCRR--*****","DESCRIPTION":"Reconnaissance Marine","MAPPING1U":"1441","MAPPING1F":"1442","MAPPING1N":"1443","MAPPING1H":"1444"},{"SYMBOLID":"S*G*UCRRD-*****","DESCRIPTION":"Reconnaissance Marine Division","MAPPING1U":"1445","MAPPING1F":"1446","MAPPING1N":"1447","MAPPING1H":"1448"},{"SYMBOLID":"S*G*UCRRF-*****","DESCRIPTION":"Reconnaissance Marine Force","MAPPING1U":"1449","MAPPING1F":"1450","MAPPING1N":"1451","MAPPING1H":"1452"},{"SYMBOLID":"S*G*UCRRL-*****","DESCRIPTION":"Reconnaissance Marine Light Armored (LAR)","MAPPING1U":"1453","MAPPING1F":"1454","MAPPING1N":"1455","MAPPING1H":"1456"},{"SYMBOLID":"S*G*UCRX--*****","DESCRIPTION":"Reconnaissance Long Range Surveillance (LRS)","MAPPING1U":"1457","MAPPING1F":"1458","MAPPING1N":"1459","MAPPING1H":"1460"},{"SYMBOLID":"S*G*UCM---*****","DESCRIPTION":"Missile (Surf-Surf)","MAPPING1U":"1461","MAPPING1F":"1461","MAPPING1N":"1461","MAPPING1H":"1461"},{"SYMBOLID":"S*G*UCMT--*****","DESCRIPTION":"Missile (Surf-Surf) Tactical","MAPPING1U":"1462","MAPPING1F":"1462","MAPPING1N":"1462","MAPPING1H":"1462"},{"SYMBOLID":"S*G*UCMS--*****","DESCRIPTION":"Missile (Surf-Surf) Strategic","MAPPING1U":"1463","MAPPING1F":"1463","MAPPING1N":"1463","MAPPING1H":"1463"},{"SYMBOLID":"S*G*UCS---*****","DESCRIPTION":"Internal Security Forces","MAPPING1U":"1464","MAPPING1F":"1464","MAPPING1N":"1464","MAPPING1H":"1464"},{"SYMBOLID":"S*G*UCSW--*****","DESCRIPTION":"Internal Security Forces Riverine","MAPPING1U":"1465","MAPPING1F":"1466","MAPPING1N":"1467","MAPPING1H":"1468"},{"SYMBOLID":"S*G*UCSG--*****","DESCRIPTION":"Internal Security Forces Ground","MAPPING1U":"1469","MAPPING1F":"1469","MAPPING1N":"1469","MAPPING1H":"1469"},{"SYMBOLID":"S*G*UCSGD-*****","DESCRIPTION":"Internal Security Forces Dismounted","MAPPING1U":"1470","MAPPING1F":"1471","MAPPING1N":"1472","MAPPING1H":"1473"},{"SYMBOLID":"S*G*UCSGM-*****","DESCRIPTION":"Internal Security Forces Motorized","MAPPING1U":"1474","MAPPING1F":"1475","MAPPING1N":"1476","MAPPING1H":"1477"},{"SYMBOLID":"S*G*UCSGA-*****","DESCRIPTION":"Internal Security Forces Mechanized","MAPPING1U":"1478","MAPPING1F":"1478","MAPPING1N":"1478","MAPPING1H":"1478"},{"SYMBOLID":"S*G*UCSM--*****","DESCRIPTION":"Internal Security Forces Wheeled Mechanized","MAPPING1U":"1479","MAPPING1F":"1479","MAPPING1N":"1479","MAPPING1H":"1479"},{"SYMBOLID":"S*G*UCSR--*****","DESCRIPTION":"Internal Security Forces Railroad","MAPPING1U":"1480","MAPPING1F":"1480","MAPPING1N":"1480","MAPPING1H":"1480"},{"SYMBOLID":"S*G*UCSA--*****","DESCRIPTION":"Internal Security Forces Aviation","MAPPING1U":"1481","MAPPING1F":"1481","MAPPING1N":"1481","MAPPING1H":"1481"},{"SYMBOLID":"S*G*UCL---*****","DESCRIPTION":"Surveillance Unit","MAPPING1U":"1890","MAPPING1F":"1890","MAPPING1N":"1890","MAPPING1H":"1890"},{"SYMBOLID":"S*G*UU----*****","DESCRIPTION":"Combat Support","MAPPING1U":"1482","MAPPING1F":"1482","MAPPING1N":"1482","MAPPING1H":"1482"},{"SYMBOLID":"S*G*UUA---*****","DESCRIPTION":"Combat Support NBC","MAPPING1U":"1483","MAPPING1F":"1483","MAPPING1N":"1483","MAPPING1H":"1483"},{"SYMBOLID":"S*G*UUAC--*****","DESCRIPTION":"Combat Support Chemical","MAPPING1U":"1484","MAPPING1F":"1484","MAPPING1N":"1484","MAPPING1H":"1484"},{"SYMBOLID":"S*G*UUACC-*****","DESCRIPTION":"Smoke/Decon","MAPPING1U":"1485","MAPPING1F":"1485","MAPPING1N":"1485","MAPPING1H":"1485"},{"SYMBOLID":"S*G*UUACCK*****","DESCRIPTION":"Mechanized Smoke/Decon","MAPPING1U":"1486","MAPPING1F":"1486","MAPPING1N":"1486","MAPPING1H":"1486"},{"SYMBOLID":"S*G*UUACCM*****","DESCRIPTION":"Motorized Smoke/Decon","MAPPING1U":"1487","MAPPING1F":"1488","MAPPING1N":"1489","MAPPING1H":"1490"},{"SYMBOLID":"S*G*UUACS-*****","DESCRIPTION":"Smoke","MAPPING1U":"1491","MAPPING1F":"1491","MAPPING1N":"1491","MAPPING1H":"1491"},{"SYMBOLID":"S*G*UUACSM*****","DESCRIPTION":"Motorized Smoke","MAPPING1U":"1492","MAPPING1F":"1493","MAPPING1N":"1494","MAPPING1H":"1495"},{"SYMBOLID":"S*G*UUACSA*****","DESCRIPTION":"Armor Smoke","MAPPING1U":"1496","MAPPING1F":"1496","MAPPING1N":"1496","MAPPING1H":"1496"},{"SYMBOLID":"S*G*UUACR-*****","DESCRIPTION":"Chemical Recon","MAPPING1U":"1497","MAPPING1F":"1498","MAPPING1N":"1499","MAPPING1H":"1500"},{"SYMBOLID":"S*G*UUACRW*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle","MAPPING1U":"1501","MAPPING1F":"1502","MAPPING1N":"1503","MAPPING1H":"1504"},{"SYMBOLID":"S*G*UUACRS*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle Reconnaissance Surveillance","MAPPING1U":"1505","MAPPING1F":"1506","MAPPING1N":"1507","MAPPING1H":"1508"},{"SYMBOLID":"S*G*UUAN--*****","DESCRIPTION":"Combat Support NBC Nuclear","MAPPING1U":"1509","MAPPING1F":"1509","MAPPING1N":"1509","MAPPING1H":"1509"},{"SYMBOLID":"S*G*UUAB--*****","DESCRIPTION":"Combat Support NBC Biological","MAPPING1U":"1510","MAPPING1F":"1510","MAPPING1N":"1510","MAPPING1H":"1510"},{"SYMBOLID":"S*G*UUABR-*****","DESCRIPTION":"Recon Equipped","MAPPING1U":"1511","MAPPING1F":"1512","MAPPING1N":"1513","MAPPING1H":"1514"},{"SYMBOLID":"S*G*UUAD--*****","DESCRIPTION":"NBC Decontamination","MAPPING1U":"1515","MAPPING1F":"1515","MAPPING1N":"1515","MAPPING1H":"1515"},{"SYMBOLID":"S*G*UUM---*****","DESCRIPTION":"Military Intelligence","MAPPING1U":"1516","MAPPING1F":"1516","MAPPING1N":"1516","MAPPING1H":"1516"},{"SYMBOLID":"S*G*UUMA--*****","DESCRIPTION":"Aerial Exploitation","MAPPING1U":"1517","MAPPING1F":"1517","MAPPING1N":"1517","MAPPING1H":"1517"},{"SYMBOLID":"S*G*UUMS--*****","DESCRIPTION":"Signal Intelligence (SIGINT)","MAPPING1U":"1518","MAPPING1F":"1518","MAPPING1N":"1518","MAPPING1H":"1518"},{"SYMBOLID":"S*G*UUMSE-*****","DESCRIPTION":"Electronic Warfare","MAPPING1U":"1519","MAPPING1F":"1519","MAPPING1N":"1519","MAPPING1H":"1519"},{"SYMBOLID":"S*G*UUMSEA*****","DESCRIPTION":"Armored Wheeled Vehicle","MAPPING1U":"600","MAPPING1F":"601","MAPPING1N":"602","MAPPING1H":"603","MAPPING2":"1520","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUMSED*****","DESCRIPTION":"Direction Finding","MAPPING1U":"1521","MAPPING1F":"1521","MAPPING1N":"1521","MAPPING1H":"1521"},{"SYMBOLID":"S*G*UUMSEI*****","DESCRIPTION":"Intercept","MAPPING1U":"1522","MAPPING1F":"1522","MAPPING1N":"1522","MAPPING1H":"1522"},{"SYMBOLID":"S*G*UUMSEJ*****","DESCRIPTION":"Jamming","MAPPING1U":"1523","MAPPING1F":"1524","MAPPING1N":"1525","MAPPING1H":"1526"},{"SYMBOLID":"S*G*UUMSET*****","DESCRIPTION":"Theater","MAPPING1U":"1527","MAPPING1F":"1528","MAPPING1N":"1529","MAPPING1H":"1530"},{"SYMBOLID":"S*G*UUMSEC*****","DESCRIPTION":"Corps","MAPPING1U":"1531","MAPPING1F":"1532","MAPPING1N":"1533","MAPPING1H":"1534"},{"SYMBOLID":"S*G*UUMC--*****","DESCRIPTION":"Counter Intelligence","MAPPING1U":"1535","MAPPING1F":"1535","MAPPING1N":"1535","MAPPING1H":"1535"},{"SYMBOLID":"S*G*UUMR--*****","DESCRIPTION":"Counter Intelligence Surveillance","MAPPING1U":"1536","MAPPING1F":"1536","MAPPING1N":"1536","MAPPING1H":"1536"},{"SYMBOLID":"S*G*UUMRG-*****","DESCRIPTION":"Ground Surveillance Radar","MAPPING1U":"1537","MAPPING1F":"1537","MAPPING1N":"1537","MAPPING1H":"1537"},{"SYMBOLID":"S*G*UUMRS-*****","DESCRIPTION":"Surveillance Sensor","MAPPING1U":"1538","MAPPING1F":"1539","MAPPING1N":"1540","MAPPING1H":"1541","MAPPING2":"1542","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUMRSS*****","DESCRIPTION":"Sensor SCM","MAPPING1U":"1543","MAPPING1F":"1544","MAPPING1N":"1545","MAPPING1H":"1546","MAPPING2":"1542","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUMRX-*****","DESCRIPTION":"Ground Station Module","MAPPING1U":"1547","MAPPING1F":"1547","MAPPING1N":"1547","MAPPING1H":"1547"},{"SYMBOLID":"S*G*UUMMO-*****","DESCRIPTION":"Surveillance Meteorological","MAPPING1U":"1548","MAPPING1F":"1548","MAPPING1N":"1548","MAPPING1H":"1548"},{"SYMBOLID":"S*G*UUMO--*****","DESCRIPTION":"Military Intelligence Operations","MAPPING1U":"1549","MAPPING1F":"1549","MAPPING1N":"1549","MAPPING1H":"1549"},{"SYMBOLID":"S*G*UUMT--*****","DESCRIPTION":"Tactical Exploit","MAPPING1U":"1550","MAPPING1F":"1550","MAPPING1N":"1550","MAPPING1H":"1550"},{"SYMBOLID":"S*G*UUMQ--*****","DESCRIPTION":"Interrogation","MAPPING1U":"1551","MAPPING1F":"1551","MAPPING1N":"1551","MAPPING1H":"1551"},{"SYMBOLID":"S*G*UUMJ--*****","DESCRIPTION":"Joint Intelligence Center","MAPPING1U":"1552","MAPPING1F":"1552","MAPPING1N":"1552","MAPPING1H":"1552"},{"SYMBOLID":"S*G*UUL---*****","DESCRIPTION":"Law Enforcement Unit","MAPPING1U":"1553","MAPPING1F":"1553","MAPPING1N":"1553","MAPPING1H":"1553"},{"SYMBOLID":"S*G*UULS--*****","DESCRIPTION":"Shore Patrol","MAPPING1U":"1554","MAPPING1F":"1554","MAPPING1N":"1554","MAPPING1H":"1554"},{"SYMBOLID":"S*G*UULM--*****","DESCRIPTION":"Military Police","MAPPING1U":"1555","MAPPING1F":"1555","MAPPING1N":"1555","MAPPING1H":"1555"},{"SYMBOLID":"S*G*UULC--*****","DESCRIPTION":"Civilian Law Enforcement","MAPPING1U":"1556","MAPPING1F":"1556","MAPPING1N":"1556","MAPPING1H":"1556"},{"SYMBOLID":"S*G*UULF--*****","DESCRIPTION":"Security Police (Air)","MAPPING1U":"1557","MAPPING1F":"1557","MAPPING1N":"1557","MAPPING1H":"1557"},{"SYMBOLID":"S*G*UULD--*****","DESCRIPTION":"Central Intelligence Division (CID)","MAPPING1U":"1558","MAPPING1F":"1558","MAPPING1N":"1558","MAPPING1H":"1558"},{"SYMBOLID":"S*G*UUS---*****","DESCRIPTION":"Signal Unit","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562"},{"SYMBOLID":"S*G*UUSA--*****","DESCRIPTION":"Area","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1563","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSC--*****","DESCRIPTION":"Communication Configured Package","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1564","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSCL-*****","DESCRIPTION":"Large Communication Configured Package (LCCP)","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1565","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSO--*****","DESCRIPTION":"Command Operations","MAPPING1U":"1559","MAPPING2":"1566","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSF--*****","DESCRIPTION":"Forward Communications","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1567","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSM--*****","DESCRIPTION":"Multiple Subscriber Element","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1568","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSMS-*****","DESCRIPTION":"Small Extension Node","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1569","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSML-*****","DESCRIPTION":"Large Extension Node","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1570","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSMN-*****","DESCRIPTION":"Node Center","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1571","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSR--*****","DESCRIPTION":"Radio Unit","MAPPING1U":"1572","MAPPING1F":"1573","MAPPING1N":"1574","MAPPING1H":"1575"},{"SYMBOLID":"S*G*UUSRS-*****","DESCRIPTION":"Tactical Satellite","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1576","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSRT-*****","DESCRIPTION":"Teletype Center","MAPPING1U":"1577","MAPPING1F":"1578","MAPPING1N":"1579","MAPPING1H":"1580"},{"SYMBOLID":"S*G*UUSRW-*****","DESCRIPTION":"Relay","MAPPING1U":"1581","MAPPING1F":"1582","MAPPING1N":"1583","MAPPING1H":"1584"},{"SYMBOLID":"S*G*UUSS--*****","DESCRIPTION":"Signal Support","MAPPING1U":"1559","MAPPING1F":"1560","MAPPING1N":"1561","MAPPING1H":"1562","MAPPING2":"1585","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUSW--*****","DESCRIPTION":"Telephone Switch","MAPPING1U":"1586","MAPPING1F":"1587","MAPPING1N":"1588","MAPPING1H":"1589"},{"SYMBOLID":"S*G*UUSX--*****","DESCRIPTION":"Electronic Ranging","MAPPING1U":"1590","MAPPING1F":"1590","MAPPING1N":"1590","MAPPING1H":"1590","MAPPING2":"1591","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*UUI---*****","DESCRIPTION":"Information Warfare Unit","MAPPING1U":"1592","MAPPING1F":"1592","MAPPING1N":"1592","MAPPING1H":"1592"},{"SYMBOLID":"S*G*UUP---*****","DESCRIPTION":"Landing Support","MAPPING1U":"612","MAPPING1F":"613","MAPPING1N":"614","MAPPING1H":"615","MAPPING2":"1593","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UUE---*****","DESCRIPTION":"Explosive Ordnance Disposal","MAPPING1U":"1594","MAPPING1F":"1594","MAPPING1N":"1594","MAPPING1H":"1594"},{"SYMBOLID":"S*G*US----*****","DESCRIPTION":"Combat Service Support","MAPPING1U":"1595","MAPPING1F":"1595","MAPPING1N":"1595","MAPPING1H":"1595"},{"SYMBOLID":"S*G*USA---*****","DESCRIPTION":"Administrative (ADMIN)","MAPPING1U":"1596","MAPPING1F":"1596","MAPPING1N":"1596","MAPPING1H":"1596"},{"SYMBOLID":"S*G*USAT--*****","DESCRIPTION":"Admin Theater","MAPPING1U":"1597","MAPPING1F":"1598","MAPPING1N":"1599","MAPPING1H":"1600"},{"SYMBOLID":"S*G*USAC--*****","DESCRIPTION":"Admin Corps","MAPPING1U":"1601","MAPPING1F":"1602","MAPPING1N":"1603","MAPPING1H":"1604"},{"SYMBOLID":"S*G*USAJ--*****","DESCRIPTION":"Judge Advocate General (JAG)","MAPPING1U":"1605","MAPPING1F":"1605","MAPPING1N":"1605","MAPPING1H":"1605"},{"SYMBOLID":"S*G*USAJT-*****","DESCRIPTION":"JAG Theater","MAPPING1U":"1606","MAPPING1F":"1607","MAPPING1N":"1608","MAPPING1H":"1609"},{"SYMBOLID":"S*G*USAJC-*****","DESCRIPTION":"JAG Corps","MAPPING1U":"1610","MAPPING1F":"1611","MAPPING1N":"1612","MAPPING1H":"1613"},{"SYMBOLID":"S*G*USAO--*****","DESCRIPTION":"Postal","MAPPING1U":"1614","MAPPING1F":"1614","MAPPING1N":"1614","MAPPING1H":"1614"},{"SYMBOLID":"S*G*USAOT-*****","DESCRIPTION":"Postal Theater","MAPPING1U":"1615","MAPPING1F":"1616","MAPPING1N":"1617","MAPPING1H":"1618"},{"SYMBOLID":"S*G*USAOC-*****","DESCRIPTION":"Postal Corps","MAPPING1U":"1619","MAPPING1F":"1620","MAPPING1N":"1621","MAPPING1H":"1622"},{"SYMBOLID":"S*G*USAF--*****","DESCRIPTION":"Finance","MAPPING1U":"1623","MAPPING1F":"1623","MAPPING1N":"1623","MAPPING1H":"1623"},{"SYMBOLID":"S*G*USAFT-*****","DESCRIPTION":"Finance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1623","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAFC-*****","DESCRIPTION":"Finance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1623","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAS--*****","DESCRIPTION":"Personnel Services","MAPPING1U":"1624","MAPPING1F":"1624","MAPPING1N":"1624","MAPPING1H":"1624"},{"SYMBOLID":"S*G*USAST-*****","DESCRIPTION":"Personnel Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1624","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USASC-*****","DESCRIPTION":"Personnel Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1624","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAM--*****","DESCRIPTION":"Mortuary/Graves Registry","MAPPING1U":"1625","MAPPING1F":"1625","MAPPING1N":"1625","MAPPING1H":"1625"},{"SYMBOLID":"S*G*USAMT-*****","DESCRIPTION":"Mortuary/Graves Registry Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1625","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAMC-*****","DESCRIPTION":"Mortuary/Graves Registry Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1625","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAR--*****","DESCRIPTION":"Religious/Chaplain","MAPPING1U":"1626","MAPPING1F":"1626","MAPPING1N":"1626","MAPPING1H":"1626"},{"SYMBOLID":"S*G*USART-*****","DESCRIPTION":"Religious/Chaplain Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1626","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USARC-*****","DESCRIPTION":"Religious/Chaplain Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1626","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAP--*****","DESCRIPTION":"Public Affairs","MAPPING1U":"1627","MAPPING1F":"1627","MAPPING1N":"1627","MAPPING1H":"1627"},{"SYMBOLID":"S*G*USAPT-*****","DESCRIPTION":"Public Affairs Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1627","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPC-*****","DESCRIPTION":"Public Affairs Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1627","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPB-*****","DESCRIPTION":"Public Affairs Broadcast","MAPPING1U":"1628","MAPPING1F":"1628","MAPPING1N":"1628","MAPPING1H":"1628"},{"SYMBOLID":"S*G*USAPBT*****","DESCRIPTION":"Public Affairs Broadcast Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1628","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPBC*****","DESCRIPTION":"Public Affairs Broadcast Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1628","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPM-*****","DESCRIPTION":"Public Affairs Joint Information Bureau (JIB)","MAPPING1U":"1630","MAPPING1F":"1630","MAPPING1N":"1630","MAPPING1H":"1630"},{"SYMBOLID":"S*G*USAPMT*****","DESCRIPTION":"Public Affairs JIB Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1630","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAPMC*****","DESCRIPTION":"Public Affairs JIB Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1630","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAX--*****","DESCRIPTION":"Replacement Holding Unit (RHU)","MAPPING1U":"1631","MAPPING1F":"1631","MAPPING1N":"1631","MAPPING1H":"1631"},{"SYMBOLID":"S*G*USAXT-*****","DESCRIPTION":"RHU Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1631","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAXC-*****","DESCRIPTION":"RHU Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1631","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAL--*****","DESCRIPTION":"Labor","MAPPING1U":"1633","MAPPING1F":"1633","MAPPING1N":"1633","MAPPING1H":"1633"},{"SYMBOLID":"S*G*USALT-*****","DESCRIPTION":"Labor Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1633","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USALC-*****","DESCRIPTION":"Labor Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1633","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAW--*****","DESCRIPTION":"Morale, Welfare, Recreation (MWR)","MAPPING1U":"1634","MAPPING1F":"1634","MAPPING1N":"1634","MAPPING1H":"1634"},{"SYMBOLID":"S*G*USAWT-*****","DESCRIPTION":"MWR Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1634","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAWC-*****","DESCRIPTION":"MWR Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1634","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAQ--*****","DESCRIPTION":"Quartermaster (Supply)","MAPPING1U":"1636","MAPPING1F":"1636","MAPPING1N":"1636","MAPPING1H":"1636"},{"SYMBOLID":"S*G*USAQT-*****","DESCRIPTION":"Quartermaster (Supply) Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1636","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USAQC-*****","DESCRIPTION":"Quartermaster (Supply) Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1636","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USM---*****","DESCRIPTION":"Medical","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640"},{"SYMBOLID":"S*G*USMT--*****","DESCRIPTION":"Medical Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644"},{"SYMBOLID":"S*G*USMC--*****","DESCRIPTION":"Medical Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648"},{"SYMBOLID":"S*G*USMM--*****","DESCRIPTION":"Medical Treatment Facility","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMMT-*****","DESCRIPTION":"Medical Treatment Facility Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMMC-*****","DESCRIPTION":"Medical Treatment Facility Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1649","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMV--*****","DESCRIPTION":"Medical Veterinary","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMVT-*****","DESCRIPTION":"Medical Veterinary Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMVC-*****","DESCRIPTION":"Medical Veterinary Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1650","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMD--*****","DESCRIPTION":"Medical Dental","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMDT-*****","DESCRIPTION":"Medical Dental Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMDC-*****","DESCRIPTION":"Medical Dental Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1651","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMP--*****","DESCRIPTION":"Medical Psychological","MAPPING1U":"1637","MAPPING1F":"1638","MAPPING1N":"1639","MAPPING1H":"1640","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMPT-*****","DESCRIPTION":"Medical Psychological Theater","MAPPING1U":"1641","MAPPING1F":"1642","MAPPING1N":"1643","MAPPING1H":"1644","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USMPC-*****","DESCRIPTION":"Medical Psychological Corps","MAPPING1U":"1645","MAPPING1F":"1646","MAPPING1N":"1647","MAPPING1H":"1648","MAPPING2":"1652","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS---*****","DESCRIPTION":"Supply","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656"},{"SYMBOLID":"S*G*USST--*****","DESCRIPTION":"Supply Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660"},{"SYMBOLID":"S*G*USSC--*****","DESCRIPTION":"Supply Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664"},{"SYMBOLID":"S*G*USS1--*****","DESCRIPTION":"Supply Class I","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS1T-*****","DESCRIPTION":"Supply Class I Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS1C-*****","DESCRIPTION":"Supply Class I Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1665","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2--*****","DESCRIPTION":"Supply Class II","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2T-*****","DESCRIPTION":"Supply Class II Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS2C-*****","DESCRIPTION":"Supply Class II Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1666","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3--*****","DESCRIPTION":"Supply Class III","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3T-*****","DESCRIPTION":"Supply Class III Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3C-*****","DESCRIPTION":"Supply Class III Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1667","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3A-*****","DESCRIPTION":"Supply Class III Aviation","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3AT*****","DESCRIPTION":"Supply Class III Aviation Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS3AC*****","DESCRIPTION":"Supply Class III Aviation Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1668","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4--*****","DESCRIPTION":"Supply Class IV","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4T-*****","DESCRIPTION":"Supply Class IV Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS4C-*****","DESCRIPTION":"Supply Class IV Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1669","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5--*****","DESCRIPTION":"Supply Class V","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5T-*****","DESCRIPTION":"Supply Class V Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS5C-*****","DESCRIPTION":"Supply Class V Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1670","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6--*****","DESCRIPTION":"Supply Class VI","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6T-*****","DESCRIPTION":"Supply Class VI Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS6C-*****","DESCRIPTION":"Supply Class VI Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1671","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7--*****","DESCRIPTION":"Supply Class VII","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7T-*****","DESCRIPTION":"Supply Class VII Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS7C-*****","DESCRIPTION":"Supply Class VII Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1672","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS8--*****","DESCRIPTION":"Supply Class VIII","MAPPING1U":"1673","MAPPING1F":"1674","MAPPING1N":"1675","MAPPING1H":"1676"},{"SYMBOLID":"S*G*USS8T-*****","DESCRIPTION":"Supply Class VIII Theater","MAPPING1U":"1677","MAPPING1F":"1678","MAPPING1N":"1679","MAPPING1H":"1680"},{"SYMBOLID":"S*G*USS8C-*****","DESCRIPTION":"Supply Class VIII Corps","MAPPING1U":"1681","MAPPING1F":"1682","MAPPING1N":"1683","MAPPING1H":"1684"},{"SYMBOLID":"S*G*USS9--*****","DESCRIPTION":"Supply Class IX","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS9T-*****","DESCRIPTION":"Supply Class IX Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USS9C-*****","DESCRIPTION":"Supply Class IX Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1685","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSX--*****","DESCRIPTION":"Supply Class X","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSXT-*****","DESCRIPTION":"Supply Class X Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSXC-*****","DESCRIPTION":"Supply Class X Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1686","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSL--*****","DESCRIPTION":"Supply Laundry/Bath","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSLT-*****","DESCRIPTION":"Supply Laundry/Bath Theater","MAPPING1U":"1657","MAPPING1F":"1658","MAPPING1N":"1659","MAPPING1H":"1660","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSLC-*****","DESCRIPTION":"Supply Laundry/Bath Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1687","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSW--*****","DESCRIPTION":"Supply Water","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWT-*****","DESCRIPTION":"Supply Water Theater","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWC-*****","DESCRIPTION":"Supply Water Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1688","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWP-*****","DESCRIPTION":"Supply Water Purification","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWPT*****","DESCRIPTION":"Supply Water Purification Theater","MAPPING1U":"1653","MAPPING1F":"1654","MAPPING1N":"1655","MAPPING1H":"1656","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USSWPC*****","DESCRIPTION":"Supply Water Purification Corps","MAPPING1U":"1661","MAPPING1F":"1662","MAPPING1N":"1663","MAPPING1H":"1664","MAPPING2":"1689","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UST---*****","DESCRIPTION":"Transportation","MAPPING1U":"1690","MAPPING1F":"1690","MAPPING1N":"1690","MAPPING1H":"1690"},{"SYMBOLID":"S*G*USTT--*****","DESCRIPTION":"Transportation Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1690","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTC--*****","DESCRIPTION":"Transportation Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1690","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTM--*****","DESCRIPTION":"Movement Control Center (MCC)","MAPPING1U":"1691","MAPPING1F":"1691","MAPPING1N":"1691","MAPPING1H":"1691"},{"SYMBOLID":"S*G*USTMT-*****","DESCRIPTION":"MCC Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1691","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTMC-*****","DESCRIPTION":"MCC Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1691","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTR--*****","DESCRIPTION":"Railhead","MAPPING1U":"1692","MAPPING1F":"1692","MAPPING1N":"1692","MAPPING1H":"1692"},{"SYMBOLID":"S*G*USTRT-*****","DESCRIPTION":"Railhead Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1692","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTRC-*****","DESCRIPTION":"Railhead Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1692","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTS--*****","DESCRIPTION":"SPOD/SPOE","MAPPING1U":"1693","MAPPING1F":"1693","MAPPING1N":"1693","MAPPING1H":"1693"},{"SYMBOLID":"S*G*USTST-*****","DESCRIPTION":"SPOD/SPOE Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1693","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTSC-*****","DESCRIPTION":"SPOD/SPOE Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1693","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTA--*****","DESCRIPTION":"APOD/APOE","MAPPING1U":"1694","MAPPING1F":"1694","MAPPING1N":"1694","MAPPING1H":"1694"},{"SYMBOLID":"S*G*USTAT-*****","DESCRIPTION":"APOD/APOE Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1694","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTAC-*****","DESCRIPTION":"APOD/APOE Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1694","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTI--*****","DESCRIPTION":"Missile","MAPPING1U":"1695","MAPPING1F":"1695","MAPPING1N":"1695","MAPPING1H":"1695"},{"SYMBOLID":"S*G*USTIT-*****","DESCRIPTION":"Missile Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1695","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USTIC-*****","DESCRIPTION":"Missile Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1695","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USX---*****","DESCRIPTION":"Maintenance","MAPPING1U":"1696","MAPPING1F":"1696","MAPPING1N":"1696","MAPPING1H":"1696"},{"SYMBOLID":"S*G*USXT--*****","DESCRIPTION":"Maintenance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1696","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXC--*****","DESCRIPTION":"Maintenance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1696","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXH--*****","DESCRIPTION":"Maintenance Heavy","MAPPING1U":"1697","MAPPING1F":"1697","MAPPING1N":"1697","MAPPING1H":"1697"},{"SYMBOLID":"S*G*USXHT-*****","DESCRIPTION":"Maintenance Heavy Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1697","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXHC-*****","DESCRIPTION":"Maintenance Heavy Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1697","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXR--*****","DESCRIPTION":"Maintenance Recovery","MAPPING1U":"1698","MAPPING1F":"1698","MAPPING1N":"1698","MAPPING1H":"1698"},{"SYMBOLID":"S*G*USXRT-*****","DESCRIPTION":"Maintenance Recovery Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1698","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXRC-*****","DESCRIPTION":"Maintenance Recovery Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1698","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXO--*****","DESCRIPTION":"Ordnance","MAPPING1U":"1699","MAPPING1F":"1699","MAPPING1N":"1699","MAPPING1H":"1699"},{"SYMBOLID":"S*G*USXOT-*****","DESCRIPTION":"Ordnance Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1699","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOC-*****","DESCRIPTION":"Ordnance Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1699","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOM-*****","DESCRIPTION":"Ordnance Missile","MAPPING1U":"1700","MAPPING1F":"1700","MAPPING1N":"1700","MAPPING1H":"1700"},{"SYMBOLID":"S*G*USXOMT*****","DESCRIPTION":"Ordnance Missile Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1700","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXOMC*****","DESCRIPTION":"Ordnance Missile Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1700","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXE--*****","DESCRIPTION":"Electro-Optical","MAPPING1U":"1701","MAPPING1F":"1701","MAPPING1N":"1701","MAPPING1H":"1701"},{"SYMBOLID":"S*G*USXET-*****","DESCRIPTION":"Electro-Optical Theater","MAPPING1U":"640","MAPPING1F":"641","MAPPING1N":"642","MAPPING1H":"643","MAPPING2":"1701","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*USXEC-*****","DESCRIPTION":"Electro-Optical Corps","MAPPING1U":"648","MAPPING1F":"649","MAPPING1N":"650","MAPPING1H":"651","MAPPING2":"1701","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*UH----*****","DESCRIPTION":"Special C2 Headquarters Component"},{"SYMBOLID":"S*G*E-----*****","DESCRIPTION":"Ground Track Equipment"},{"SYMBOLID":"S*G*EW----*****","DESCRIPTION":"Weapon"},{"SYMBOLID":"S*G*EWM---*****","DESCRIPTION":"Missile Launcher","MAPPING1U":"1702","MAPPING1F":"1702","MAPPING1N":"1702","MAPPING1H":"1702"},{"SYMBOLID":"S*G*EWMA--*****","DESCRIPTION":"Air Defense (AD) Missile Launcher","MAPPING1U":"1703","MAPPING1F":"1703","MAPPING1N":"1703","MAPPING1H":"1703"},{"SYMBOLID":"S*G*EWMAS-*****","DESCRIPTION":"Short Range AD Missile Launcher","MAPPING1U":"1704","MAPPING1F":"1704","MAPPING1N":"1704","MAPPING1H":"1704"},{"SYMBOLID":"S*G*EWMASR*****","DESCRIPTION":"Short Range Transporter Launcher and Radar (TLAR)","MAPPING1U":"1705","MAPPING1F":"1705","MAPPING1N":"1705","MAPPING1H":"1705"},{"SYMBOLID":"S*G*EWMASE*****","DESCRIPTION":"Short Range Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1706","MAPPING1F":"1706","MAPPING1N":"1706","MAPPING1H":"1706"},{"SYMBOLID":"S*G*EWMAI-*****","DESCRIPTION":"Intermediate Range AD Missile Launcher","MAPPING1U":"1707","MAPPING1F":"1707","MAPPING1N":"1707","MAPPING1H":"1707"},{"SYMBOLID":"S*G*EWMAIR*****","DESCRIPTION":"Intermediate Transporter Launcher and Radar (TLAR)","MAPPING1U":"1708","MAPPING1F":"1708","MAPPING1N":"1708","MAPPING1H":"1708"},{"SYMBOLID":"S*G*EWMAIE*****","DESCRIPTION":"Intermediate Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1709","MAPPING1F":"1709","MAPPING1N":"1709","MAPPING1H":"1709"},{"SYMBOLID":"S*G*EWMAL-*****","DESCRIPTION":"Long Range AD Missile Launcher","MAPPING1U":"1710","MAPPING1F":"1710","MAPPING1N":"1710","MAPPING1H":"1710"},{"SYMBOLID":"S*G*EWMALR*****","DESCRIPTION":"Long Range Transporter Launcher and Radar (TLAR)","MAPPING1U":"1711","MAPPING1F":"1711","MAPPING1N":"1711","MAPPING1H":"1711"},{"SYMBOLID":"S*G*EWMALE*****","DESCRIPTION":"Long Range Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1712","MAPPING1F":"1712","MAPPING1N":"1712","MAPPING1H":"1712"},{"SYMBOLID":"S*G*EWMAT-*****","DESCRIPTION":"AD Missile Launcher Theater","MAPPING1U":"1713","MAPPING1F":"1713","MAPPING1N":"1713","MAPPING1H":"1713"},{"SYMBOLID":"S*G*EWMATR*****","DESCRIPTION":"Theater Transporter Launcher and Radar (TLAR)","MAPPING1U":"1714","MAPPING1F":"1714","MAPPING1N":"1714","MAPPING1H":"1714"},{"SYMBOLID":"S*G*EWMATE*****","DESCRIPTION":"Theater Transporter Erector Launcher and Radar (TELAR)","MAPPING1U":"1715","MAPPING1F":"1715","MAPPING1N":"1715","MAPPING1H":"1715"},{"SYMBOLID":"S*G*EWMS--*****","DESCRIPTION":"Surf-Surf (SS) Missile Launcher","MAPPING1U":"1716","MAPPING1F":"1716","MAPPING1N":"1716","MAPPING1H":"1716"},{"SYMBOLID":"S*G*EWMSS-*****","DESCRIPTION":"Short Range SS Missile Launcher","MAPPING1U":"1717","MAPPING1F":"1717","MAPPING1N":"1717","MAPPING1H":"1717"},{"SYMBOLID":"S*G*EWMSI-*****","DESCRIPTION":"Intermediate Range SS Missile Launcher","MAPPING1U":"1718","MAPPING1F":"1718","MAPPING1N":"1718","MAPPING1H":"1718"},{"SYMBOLID":"S*G*EWMSL-*****","DESCRIPTION":"Long Range SS Missile Launcher","MAPPING1U":"1719","MAPPING1F":"1719","MAPPING1N":"1719","MAPPING1H":"1719"},{"SYMBOLID":"S*G*EWMT--*****","DESCRIPTION":"Missile Launcher Antitank (AT)","MAPPING1U":"1720","MAPPING1F":"1720","MAPPING1N":"1720","MAPPING1H":"1720"},{"SYMBOLID":"S*G*EWMTL-*****","DESCRIPTION":"Missile Launcher AT Light","MAPPING1U":"1721","MAPPING1F":"1721","MAPPING1N":"1721","MAPPING1H":"1721"},{"SYMBOLID":"S*G*EWMTM-*****","DESCRIPTION":"Missile Launcher AT Medium","MAPPING1U":"1722","MAPPING1F":"1722","MAPPING1N":"1722","MAPPING1H":"1722"},{"SYMBOLID":"S*G*EWMTH-*****","DESCRIPTION":"Missile Launcher AT Heavy","MAPPING1U":"1723","MAPPING1F":"1723","MAPPING1N":"1723","MAPPING1H":"1723"},{"SYMBOLID":"S*G*EWS---*****","DESCRIPTION":"Weapon Single Rocket Launcher","MAPPING1U":"1724","MAPPING1F":"1724","MAPPING1N":"1724","MAPPING1H":"1724"},{"SYMBOLID":"S*G*EWSL--*****","DESCRIPTION":"Single Rocket Launcher Light","MAPPING1U":"1725","MAPPING1F":"1725","MAPPING1N":"1725","MAPPING1H":"1725"},{"SYMBOLID":"S*G*EWSM--*****","DESCRIPTION":"Single Rocket Launcher Medium","MAPPING1U":"1726","MAPPING1F":"1726","MAPPING1N":"1726","MAPPING1H":"1726"},{"SYMBOLID":"S*G*EWSH--*****","DESCRIPTION":"Single Rocket Launcher Heavy","MAPPING1U":"1727","MAPPING1F":"1727","MAPPING1N":"1727","MAPPING1H":"1727"},{"SYMBOLID":"S*G*EWX---*****","DESCRIPTION":"Multiple Rocket Launcher","MAPPING1U":"1728","MAPPING1F":"1728","MAPPING1N":"1728","MAPPING1H":"1728"},{"SYMBOLID":"S*G*EWXL--*****","DESCRIPTION":"Multiple Rocket Launcher Light","MAPPING1U":"1729","MAPPING1F":"1729","MAPPING1N":"1729","MAPPING1H":"1729"},{"SYMBOLID":"S*G*EWXM--*****","DESCRIPTION":"Multiple Rocket Launcher Medium","MAPPING1U":"1730","MAPPING1F":"1730","MAPPING1N":"1730","MAPPING1H":"1730"},{"SYMBOLID":"S*G*EWXH--*****","DESCRIPTION":"Multiple Rocket Launcher Heavy","MAPPING1U":"1731","MAPPING1F":"1731","MAPPING1N":"1731","MAPPING1H":"1731"},{"SYMBOLID":"S*G*EWT---*****","DESCRIPTION":"Anti-Tank Rocket Launcher","MAPPING1U":"1732","MAPPING1F":"1732","MAPPING1N":"1732","MAPPING1H":"1732"},{"SYMBOLID":"S*G*EWTL--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Light","MAPPING1U":"1733","MAPPING1F":"1733","MAPPING1N":"1733","MAPPING1H":"1733"},{"SYMBOLID":"S*G*EWTM--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Medium","MAPPING1U":"1734","MAPPING1F":"1734","MAPPING1N":"1734","MAPPING1H":"1734"},{"SYMBOLID":"S*G*EWTH--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Heavy","MAPPING1U":"1735","MAPPING1F":"1735","MAPPING1N":"1735","MAPPING1H":"1735"},{"SYMBOLID":"S*G*EWR---*****","DESCRIPTION":"Rifle/Automatic Weapon","MAPPING1U":"1736","MAPPING1F":"1736","MAPPING1N":"1736","MAPPING1H":"1736"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Rifle","MAPPING1U":"1737","MAPPING1F":"1737","MAPPING1N":"1737","MAPPING1H":"1737"},{"SYMBOLID":"S*G*EWRL--*****","DESCRIPTION":"Light Machine Gun","MAPPING1U":"1738","MAPPING1F":"1738","MAPPING1N":"1738","MAPPING1H":"1738"},{"SYMBOLID":"S*G*EWRH--*****","DESCRIPTION":"Heavy Machine Gun","MAPPING1U":"1739","MAPPING1F":"1739","MAPPING1N":"1739","MAPPING1H":"1739"},{"SYMBOLID":"S*G*EWZ---*****","DESCRIPTION":"Grenade Launcher","MAPPING1U":"1740","MAPPING1F":"1740","MAPPING1N":"1740","MAPPING1H":"1740"},{"SYMBOLID":"S*G*EWZL--*****","DESCRIPTION":"Grenade Launcher Light","MAPPING1U":"1741","MAPPING1F":"1741","MAPPING1N":"1741","MAPPING1H":"1741"},{"SYMBOLID":"S*G*EWZM--*****","DESCRIPTION":"Grenade Launcher Medium","MAPPING1U":"1742","MAPPING1F":"1742","MAPPING1N":"1742","MAPPING1H":"1742"},{"SYMBOLID":"S*G*EWZH--*****","DESCRIPTION":"Grenade Launcher Heavy","MAPPING1U":"1743","MAPPING1F":"1743","MAPPING1N":"1743","MAPPING1H":"1743"},{"SYMBOLID":"S*G*EWO---*****","DESCRIPTION":"Weapon Mortar","MAPPING1U":"1744","MAPPING1F":"1744","MAPPING1N":"1744","MAPPING1H":"1744"},{"SYMBOLID":"S*G*EWOL--*****","DESCRIPTION":"Mortar Light","MAPPING1U":"1745","MAPPING1F":"1745","MAPPING1N":"1745","MAPPING1H":"1745"},{"SYMBOLID":"S*G*EWOM--*****","DESCRIPTION":"Mortar Medium","MAPPING1U":"1746","MAPPING1F":"1746","MAPPING1N":"1746","MAPPING1H":"1746"},{"SYMBOLID":"S*G*EWOH--*****","DESCRIPTION":"Mortar Heavy","MAPPING1U":"1747","MAPPING1F":"1747","MAPPING1N":"1747","MAPPING1H":"1747"},{"SYMBOLID":"S*G*EWH---*****","DESCRIPTION":"Howitzer","MAPPING1U":"1748","MAPPING1F":"1748","MAPPING1N":"1748","MAPPING1H":"1748"},{"SYMBOLID":"S*G*EWHL--*****","DESCRIPTION":"Howitzer Light","MAPPING1U":"1749","MAPPING1F":"1749","MAPPING1N":"1749","MAPPING1H":"1749"},{"SYMBOLID":"S*G*EWHLS-*****","DESCRIPTION":"Howitzer Light Self-Propelled","MAPPING1U":"1750","MAPPING1F":"1750","MAPPING1N":"1750","MAPPING1H":"1750"},{"SYMBOLID":"S*G*EWHM--*****","DESCRIPTION":"Howitzer Medium","MAPPING1U":"1751","MAPPING1F":"1751","MAPPING1N":"1751","MAPPING1H":"1751"},{"SYMBOLID":"S*G*EWHMS-*****","DESCRIPTION":"Howitzer Medium Self-Propelled","MAPPING1U":"1752","MAPPING1F":"1752","MAPPING1N":"1752","MAPPING1H":"1752"},{"SYMBOLID":"S*G*EWHH--*****","DESCRIPTION":"Howitzer Heavy","MAPPING1U":"1753","MAPPING1F":"1753","MAPPING1N":"1753","MAPPING1H":"1753"},{"SYMBOLID":"S*G*EWHHS-*****","DESCRIPTION":"Howitzer Heavy Self-Propelled","MAPPING1U":"1754","MAPPING1F":"1754","MAPPING1N":"1754","MAPPING1H":"1754"},{"SYMBOLID":"S*G*EWG---*****","DESCRIPTION":"Anti-Tank Gun","MAPPING1U":"1755","MAPPING1F":"1755","MAPPING1N":"1755","MAPPING1H":"1755"},{"SYMBOLID":"S*G*EWGL--*****","DESCRIPTION":"Anti-Tank Gun Light","MAPPING1U":"1756","MAPPING1F":"1756","MAPPING1N":"1756","MAPPING1H":"1756"},{"SYMBOLID":"S*G*EWGM--*****","DESCRIPTION":"Anti-Tank Gun Medium","MAPPING1U":"1757","MAPPING1F":"1757","MAPPING1N":"1757","MAPPING1H":"1757"},{"SYMBOLID":"S*G*EWGH--*****","DESCRIPTION":"Anti-Tank Gun Heavy","MAPPING1U":"1758","MAPPING1F":"1758","MAPPING1N":"1758","MAPPING1H":"1758"},{"SYMBOLID":"S*G*EWGR--*****","DESCRIPTION":"Anti-Tank Gun Recoilless","MAPPING1U":"1759","MAPPING1F":"1759","MAPPING1N":"1759","MAPPING1H":"1759"},{"SYMBOLID":"S*G*EWD---*****","DESCRIPTION":"Direct Fire Gun","MAPPING1U":"1760","MAPPING1F":"1760","MAPPING1N":"1760","MAPPING1H":"1760"},{"SYMBOLID":"S*G*EWDL--*****","DESCRIPTION":"Direct Fire Gun Light","MAPPING1U":"1761","MAPPING1F":"1761","MAPPING1N":"1761","MAPPING1H":"1761"},{"SYMBOLID":"S*G*EWDLS-*****","DESCRIPTION":"Direct Fire Gun Light Self-Propelled","MAPPING1U":"1762","MAPPING1F":"1762","MAPPING1N":"1762","MAPPING1H":"1762"},{"SYMBOLID":"S*G*EWDM--*****","DESCRIPTION":"Direct Fire Gun Medium","MAPPING1U":"1763","MAPPING1F":"1763","MAPPING1N":"1763","MAPPING1H":"1763"},{"SYMBOLID":"S*G*EWDMS-*****","DESCRIPTION":"Direct Fire Gun Medium Self-Propelled","MAPPING1U":"1764","MAPPING1F":"1764","MAPPING1N":"1764","MAPPING1H":"1764"},{"SYMBOLID":"S*G*EWDH--*****","DESCRIPTION":"Direct Fire Gun Heavy","MAPPING1U":"1765","MAPPING1F":"1765","MAPPING1N":"1765","MAPPING1H":"1765"},{"SYMBOLID":"S*G*EWDHS-*****","DESCRIPTION":"Direct Fire Gun Heavy Self-Propelled","MAPPING1U":"1766","MAPPING1F":"1766","MAPPING1N":"1766","MAPPING1H":"1766"},{"SYMBOLID":"S*G*EWA---*****","DESCRIPTION":"Air Defense Gun","MAPPING1U":"1767","MAPPING1F":"1767","MAPPING1N":"1767","MAPPING1H":"1767"},{"SYMBOLID":"S*G*EWAL--*****","DESCRIPTION":"Air Defense Gun Light","MAPPING1U":"1768","MAPPING1F":"1768","MAPPING1N":"1768","MAPPING1H":"1768"},{"SYMBOLID":"S*G*EWAM--*****","DESCRIPTION":"Air Defense Gun Medium","MAPPING1U":"1769","MAPPING1F":"1769","MAPPING1N":"1769","MAPPING1H":"1769"},{"SYMBOLID":"S*G*EWAH--*****","DESCRIPTION":"Air Defense Gun Heavy","MAPPING1U":"1770","MAPPING1F":"1770","MAPPING1N":"1770","MAPPING1H":"1770"},{"SYMBOLID":"S*G*EV----*****","DESCRIPTION":"Ground Vehicle","MAPPING1U":"1771","MAPPING1F":"1771","MAPPING1N":"1771","MAPPING1H":"1771"},{"SYMBOLID":"S*G*EVA---*****","DESCRIPTION":"Armored Vehicle","MAPPING1U":"1772","MAPPING1F":"1772","MAPPING1N":"1772","MAPPING1H":"1772"},{"SYMBOLID":"S*G*EVAT--*****","DESCRIPTION":"Tank","MAPPING1U":"1773","MAPPING1F":"1773","MAPPING1N":"1773","MAPPING1H":"1773"},{"SYMBOLID":"S*G*EVATL-*****","DESCRIPTION":"Tank Light","MAPPING1U":"1774","MAPPING1F":"1774","MAPPING1N":"1774","MAPPING1H":"1774"},{"SYMBOLID":"S*G*EVATLR*****","DESCRIPTION":"Tank Light Recovery","MAPPING1U":"1775","MAPPING1F":"1775","MAPPING1N":"1775","MAPPING1H":"1775"},{"SYMBOLID":"S*G*EVATM-*****","DESCRIPTION":"Tank Medium","MAPPING1U":"1776","MAPPING1F":"1776","MAPPING1N":"1776","MAPPING1H":"1776"},{"SYMBOLID":"S*G*EVATMR*****","DESCRIPTION":"Tank Medium Recovery","MAPPING1U":"1777","MAPPING1F":"1777","MAPPING1N":"1777","MAPPING1H":"1777"},{"SYMBOLID":"S*G*EVATH-*****","DESCRIPTION":"Tank Heavy","MAPPING1U":"1778","MAPPING1F":"1778","MAPPING1N":"1778","MAPPING1H":"1778"},{"SYMBOLID":"S*G*EVATHR*****","DESCRIPTION":"Tank Heavy Recovery","MAPPING1U":"1779","MAPPING1F":"1779","MAPPING1N":"1779","MAPPING1H":"1779"},{"SYMBOLID":"S*G*EVAA--*****","DESCRIPTION":"Armored Personnel Carrier","MAPPING1U":"1780","MAPPING1F":"1780","MAPPING1N":"1780","MAPPING1H":"1780"},{"SYMBOLID":"S*G*EVAAR-*****","DESCRIPTION":"Armored Personnel Carrier Recovery","MAPPING1U":"1781","MAPPING1F":"1781","MAPPING1N":"1781","MAPPING1H":"1781"},{"SYMBOLID":"S*G*EVAI--*****","DESCRIPTION":"Armored Infantry","MAPPING1U":"1782","MAPPING1F":"1782","MAPPING1N":"1782","MAPPING1H":"1782"},{"SYMBOLID":"S*G*EVAC--*****","DESCRIPTION":"C2V/ACV","MAPPING1U":"1783","MAPPING1F":"1783","MAPPING1N":"1783","MAPPING1H":"1783"},{"SYMBOLID":"S*G*EVAS--*****","DESCRIPTION":"Combat Service Support Vehicle","MAPPING1U":"1784","MAPPING1F":"1784","MAPPING1N":"1784","MAPPING1H":"1784"},{"SYMBOLID":"S*G*EVAL--*****","DESCRIPTION":"Light Armored Vehicle","MAPPING1U":"1785","MAPPING1F":"1785","MAPPING1N":"1785","MAPPING1H":"1785"},{"SYMBOLID":"S*G*EVU---*****","DESCRIPTION":"Utility Vehicle","MAPPING1U":"1786","MAPPING1F":"1786","MAPPING1N":"1786","MAPPING1H":"1786"},{"SYMBOLID":"S*G*EVUB--*****","DESCRIPTION":"Bus","MAPPING1U":"1787","MAPPING1F":"1787","MAPPING1N":"1787","MAPPING1H":"1787"},{"SYMBOLID":"S*G*EVUS--*****","DESCRIPTION":"Semi","MAPPING1U":"1788","MAPPING1F":"1788","MAPPING1N":"1788","MAPPING1H":"1788"},{"SYMBOLID":"S*G*EVUSL-*****","DESCRIPTION":"Semi Light","MAPPING1U":"1789","MAPPING1F":"1789","MAPPING1N":"1789","MAPPING1H":"1789"},{"SYMBOLID":"S*G*EVUSM-*****","DESCRIPTION":"Semi Medium","MAPPING1U":"1790","MAPPING1F":"1790","MAPPING1N":"1790","MAPPING1H":"1790"},{"SYMBOLID":"S*G*EVUSH-*****","DESCRIPTION":"Semi Heavy","MAPPING1U":"1791","MAPPING1F":"1791","MAPPING1N":"1791","MAPPING1H":"1791"},{"SYMBOLID":"S*G*EVUL--*****","DESCRIPTION":"Limited Cross-Country Truck","MAPPING1U":"1792","MAPPING1F":"1792","MAPPING1N":"1792","MAPPING1H":"1792"},{"SYMBOLID":"S*G*EVUX--*****","DESCRIPTION":"Cross-Country Truck","MAPPING1U":"1793","MAPPING1F":"1793","MAPPING1N":"1793","MAPPING1H":"1793"},{"SYMBOLID":"S*G*EVUR--*****","DESCRIPTION":"Water Craft","MAPPING1U":"1794","MAPPING1F":"1794","MAPPING1N":"1794","MAPPING1H":"1794"},{"SYMBOLID":"S*G*EVUT--*****","DESCRIPTION":"Tow Truck","MAPPING1U":"1795","MAPPING1F":"1795","MAPPING1N":"1795","MAPPING1H":"1795"},{"SYMBOLID":"S*G*EVUTL-*****","DESCRIPTION":"Tow Truck Light","MAPPING1U":"1796","MAPPING1F":"1796","MAPPING1N":"1796","MAPPING1H":"1796"},{"SYMBOLID":"S*G*EVUTH-*****","DESCRIPTION":"Tow Truck Heavy","MAPPING1U":"1797","MAPPING1F":"1797","MAPPING1N":"1797","MAPPING1H":"1797"},{"SYMBOLID":"S*G*EVUA--*****","DESCRIPTION":"Ambulance","MAPPING1U":"1798","MAPPING1F":"1798","MAPPING1N":"1798","MAPPING1H":"1798"},{"SYMBOLID":"S*G*EVUAA-*****","DESCRIPTION":"Ambulance Armored","MAPPING1U":"1799","MAPPING1F":"1799","MAPPING1N":"1799","MAPPING1H":"1799"},{"SYMBOLID":"S*G*EVE---*****","DESCRIPTION":"Engineer Vehicle","MAPPING1U":"1800","MAPPING1F":"1800","MAPPING1N":"1800","MAPPING1H":"1800"},{"SYMBOLID":"S*G*EVEB--*****","DESCRIPTION":"Engineer Vehicle Bridge","MAPPING1U":"1894","MAPPING1F":"1894","MAPPING1N":"1894","MAPPING1H":"1894"},{"SYMBOLID":"S*G*EVEE--*****","DESCRIPTION":"Earthmover","MAPPING1U":"1801","MAPPING1F":"1801","MAPPING1N":"1801","MAPPING1H":"1801"},{"SYMBOLID":"S*G*EVEC--*****","DESCRIPTION":"Construction Vehicle","MAPPING1U":"1802","MAPPING1F":"1802","MAPPING1N":"1802","MAPPING1H":"1802"},{"SYMBOLID":"S*G*EVEM--*****","DESCRIPTION":"Mine Laying Vehicle","MAPPING1U":"1803","MAPPING1F":"1803","MAPPING1N":"1803","MAPPING1H":"1803"},{"SYMBOLID":"S*G*EVEMV-*****","DESCRIPTION":"Armored Carrier with Volcano","MAPPING1U":"1804","MAPPING1F":"1804","MAPPING1N":"1804","MAPPING1H":"1804"},{"SYMBOLID":"S*G*EVEML-*****","DESCRIPTION":"Truck Mounted with Volcano","MAPPING1U":"1805","MAPPING1F":"1805","MAPPING1N":"1805","MAPPING1H":"1805"},{"SYMBOLID":"S*G*EVEA--*****","DESCRIPTION":"Mine Clearing Vehicle","MAPPING1U":"1806","MAPPING1F":"1806","MAPPING1N":"1806","MAPPING1H":"1806"},{"SYMBOLID":"S*G*EVEAA-*****","DESCRIPTION":"Armored Mounted Mine Clearing Vehicle","MAPPING1U":"1807","MAPPING1F":"1807","MAPPING1N":"1807","MAPPING1H":"1807"},{"SYMBOLID":"S*G*EVEAT-*****","DESCRIPTION":"Trailer Mounted Mine Clearing Vehicle","MAPPING1U":"1808","MAPPING1F":"1808","MAPPING1N":"1808","MAPPING1H":"1808"},{"SYMBOLID":"S*G*EVED--*****","DESCRIPTION":"Dozer","MAPPING1U":"1809","MAPPING1F":"1809","MAPPING1N":"1809","MAPPING1H":"1809"},{"SYMBOLID":"S*G*EVEDA-*****","DESCRIPTION":"Armored Dozer","MAPPING1U":"1810","MAPPING1F":"1810","MAPPING1N":"1810","MAPPING1H":"1810"},{"SYMBOLID":"S*G*EVES--*****","DESCRIPTION":"Armored Assault","MAPPING1U":"1811","MAPPING1F":"1811","MAPPING1N":"1811","MAPPING1H":"1811"},{"SYMBOLID":"S*G*EVER--*****","DESCRIPTION":"Armored Engineer Recon Vehicle (AERV)","MAPPING1U":"1812","MAPPING1F":"1812","MAPPING1N":"1812","MAPPING1H":"1812"},{"SYMBOLID":"S*G*EVEH--*****","DESCRIPTION":"Backhoe","MAPPING1U":"1813","MAPPING1F":"1813","MAPPING1N":"1813","MAPPING1H":"1813"},{"SYMBOLID":"S*G*EVEF--*****","DESCRIPTION":"Ferry Transporter","MAPPING1U":"1814","MAPPING1F":"1814","MAPPING1N":"1814","MAPPING1H":"1814"},{"SYMBOLID":"S*G*EVT---*****","DESCRIPTION":"Train Locomotive","MAPPING1U":"1815","MAPPING1F":"1815","MAPPING1N":"1815","MAPPING1H":"1815"},{"SYMBOLID":"S*G*EVC---*****","DESCRIPTION":"Civilian Vehicle","MAPPING1U":"1816","MAPPING1F":"1816","MAPPING1N":"1816","MAPPING1H":"1816"},{"SYMBOLID":"S*G*EVCA--*****","DESCRIPTION":"Civilian Automobile","MAPPING1U":"1817","MAPPING1F":"1817","MAPPING1N":"1817","MAPPING1H":"1817","MAPPING2":"1818","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAL-*****","DESCRIPTION":"Civilian Compact Automobile","MAPPING1U":"1819","MAPPING1F":"1819","MAPPING1N":"1819","MAPPING1H":"1819","MAPPING2":"1820","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAM-*****","DESCRIPTION":"Civilian Midsize Automobile","MAPPING1U":"1821","MAPPING1F":"1821","MAPPING1N":"1821","MAPPING1H":"1821","MAPPING2":"1822","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCAH-*****","DESCRIPTION":"Civilian Automobile Sedan","MAPPING1U":"1823","MAPPING1F":"1823","MAPPING1N":"1823","MAPPING1H":"1823","MAPPING2":"1824","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCO--*****","DESCRIPTION":"Civilian Open-Bed Truck","MAPPING1U":"1825","MAPPING1F":"1825","MAPPING1N":"1825","MAPPING1H":"1825","MAPPING2":"1826","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOL-*****","DESCRIPTION":"Civilian Pickup Truck","MAPPING1U":"1827","MAPPING1F":"1827","MAPPING1N":"1827","MAPPING1H":"1827","MAPPING2":"1828","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOM-*****","DESCRIPTION":"Civilian Small Open-Bed Truck","MAPPING1U":"1829","MAPPING1F":"1829","MAPPING1N":"1829","MAPPING1H":"1829","MAPPING2":"1830","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCOH-*****","DESCRIPTION":"Civilian Large Open-Bed Truck","MAPPING1U":"1831","MAPPING1F":"1831","MAPPING1N":"1831","MAPPING1H":"1831","MAPPING2":"1832","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCM--*****","DESCRIPTION":"Civilian Multi-Passenger Vehicle","MAPPING1U":"1833","MAPPING1F":"1833","MAPPING1N":"1833","MAPPING1H":"1833","MAPPING2":"1834","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCML-*****","DESCRIPTION":"Civilian Multi-Passenger Van","MAPPING1U":"1835","MAPPING1F":"1835","MAPPING1N":"1835","MAPPING1H":"1835","MAPPING2":"1836","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCMM-*****","DESCRIPTION":"Civilian Small Bus","MAPPING1U":"1837","MAPPING1F":"1837","MAPPING1N":"1837","MAPPING1H":"1837","MAPPING2":"1838","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCMH-*****","DESCRIPTION":"Civilian Large Bus","MAPPING1U":"1839","MAPPING1F":"1839","MAPPING1N":"1839","MAPPING1H":"1839","MAPPING2":"1840","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCU--*****","DESCRIPTION":"Civilian Utility Vehicle","MAPPING1U":"1841","MAPPING1F":"1841","MAPPING1N":"1841","MAPPING1H":"1841","MAPPING2":"1842","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUL-*****","DESCRIPTION":"Civilian Sport Utility Vehicle (SUV)","MAPPING1U":"1843","MAPPING1F":"1843","MAPPING1N":"1843","MAPPING1H":"1843","MAPPING2":"1844","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUM-*****","DESCRIPTION":"Civilian Utility Small Box Truck","MAPPING1U":"1845","MAPPING1F":"1845","MAPPING1N":"1845","MAPPING1H":"1845","MAPPING2":"1846","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCUH-*****","DESCRIPTION":"Civilian Utility Large Box Truck","MAPPING1U":"1847","MAPPING1F":"1847","MAPPING1N":"1847","MAPPING1H":"1847","MAPPING2":"1848","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJ--*****","DESCRIPTION":"Civilian Jeep Type Vehicle","MAPPING1U":"1849","MAPPING1F":"1849","MAPPING1N":"1849","MAPPING1H":"1849","MAPPING2":"1850","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJL-*****","DESCRIPTION":"Civilian Small/Light Jeep Type Vehicle","MAPPING1U":"1851","MAPPING1F":"1851","MAPPING1N":"1851","MAPPING1H":"1851","MAPPING2":"1852","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJM-*****","DESCRIPTION":"Civilian Medium Jeep Type Vehicle","MAPPING1U":"1853","MAPPING1F":"1853","MAPPING1N":"1853","MAPPING1H":"1853","MAPPING2":"1854","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCJH-*****","DESCRIPTION":"Civilian Large/Heavy Jeep Type Vehicle","MAPPING1U":"1855","MAPPING1F":"1855","MAPPING1N":"1855","MAPPING1H":"1855","MAPPING2":"1856","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCT--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Box Trailer","MAPPING1U":"1857","MAPPING1F":"1857","MAPPING1N":"1857","MAPPING1H":"1857","MAPPING2":"1858","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTL-*****","DESCRIPTION":"Civilian Small/Light Box Trailer","MAPPING1U":"1859","MAPPING1F":"1859","MAPPING1N":"1859","MAPPING1H":"1859","MAPPING2":"1860","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTM-*****","DESCRIPTION":"Civilian Medium Box Trailer","MAPPING1U":"1861","MAPPING1F":"1861","MAPPING1N":"1861","MAPPING1H":"1861","MAPPING2":"1862","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCTH-*****","DESCRIPTION":"Civilian Large/Heavy Box Trailer","MAPPING1U":"1863","MAPPING1F":"1863","MAPPING1N":"1863","MAPPING1H":"1863","MAPPING2":"1864","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCF--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Flatbed Trailer","MAPPING1U":"1865","MAPPING1F":"1865","MAPPING1N":"1865","MAPPING1H":"1865","MAPPING2":"1866","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFL-*****","DESCRIPTION":"Civilian Small/Light Flatbed Trailer","MAPPING1U":"1867","MAPPING1F":"1867","MAPPING1N":"1867","MAPPING1H":"1867","MAPPING2":"1868","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFM-*****","DESCRIPTION":"Civilian Medium Flatbed Trailer","MAPPING1U":"1869","MAPPING1F":"1869","MAPPING1N":"1869","MAPPING1H":"1869","MAPPING2":"1870","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVCFH-*****","DESCRIPTION":"Civilian Large/Heavy Flatbed Trailer","MAPPING1U":"1871","MAPPING1F":"1871","MAPPING1N":"1871","MAPPING1H":"1871","MAPPING2":"1872","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*G*EVS---*****","DESCRIPTION":"Missile Support","MAPPING1U":"1874","MAPPING1F":"1874","MAPPING1N":"1874","MAPPING1H":"1874"},{"SYMBOLID":"S*G*EVST--*****","DESCRIPTION":"Transloader","MAPPING1U":"1875","MAPPING1F":"1875","MAPPING1N":"1875","MAPPING1H":"1875"},{"SYMBOLID":"S*G*EVSR--*****","DESCRIPTION":"Transporter"},{"SYMBOLID":"S*G*EVSC--*****","DESCRIPTION":"Crane/Loading Device","MAPPING1U":"1877","MAPPING1F":"1877","MAPPING1N":"1877","MAPPING1H":"1877"},{"SYMBOLID":"S*G*EVSP--*****","DESCRIPTION":"Propellant Transporter","MAPPING1U":"1878","MAPPING1F":"1878","MAPPING1N":"1878","MAPPING1H":"1878"},{"SYMBOLID":"S*G*EVSW--*****","DESCRIPTION":"Warhead Transporter","MAPPING1U":"1879","MAPPING1F":"1879","MAPPING1N":"1879","MAPPING1H":"1879"},{"SYMBOLID":"S*G*EVM---*****","DESCRIPTION":"Pack Animal(s)","MAPPING1U":"1873","MAPPING1F":"1873","MAPPING1N":"1873","MAPPING1H":"1873"},{"SYMBOLID":"S*G*ES----*****","DESCRIPTION":"Equipment Sensor","MAPPING1U":"1880","MAPPING1F":"1880","MAPPING1N":"1880","MAPPING1H":"1880"},{"SYMBOLID":"S*G*ESR---*****","DESCRIPTION":"Sensor Radar","MAPPING1U":"1881","MAPPING1F":"1881","MAPPING1N":"1881","MAPPING1H":"1881"},{"SYMBOLID":"S*G*ESE---*****","DESCRIPTION":"Emplaced Sensor","MAPPING1U":"1882","MAPPING1F":"1882","MAPPING1N":"1882","MAPPING1H":"1882"},{"SYMBOLID":"S*G*EX----*****","DESCRIPTION":"Special"},{"SYMBOLID":"S*G*EXL---*****","DESCRIPTION":"Laser","MAPPING1U":"1884","MAPPING1F":"1884","MAPPING1N":"1884","MAPPING1H":"1884"},{"SYMBOLID":"S*G*EXN---*****","DESCRIPTION":"NBC Equipment","MAPPING1U":"1885","MAPPING1F":"1885","MAPPING1N":"1885","MAPPING1H":"1885"},{"SYMBOLID":"S*G*EXF---*****","DESCRIPTION":"Flame Thrower","MAPPING1U":"1886","MAPPING1F":"1886","MAPPING1N":"1886","MAPPING1H":"1886"},{"SYMBOLID":"S*G*EXM---*****","DESCRIPTION":"Land Mines","MAPPING1U":"1887","MAPPING1F":"1887","MAPPING1N":"1887","MAPPING1H":"1887"},{"SYMBOLID":"S*G*EXMC--*****","DESCRIPTION":"Claymore","MAPPING1U":"1888","MAPPING1F":"1888","MAPPING1N":"1888","MAPPING1H":"1888"},{"SYMBOLID":"S*G*EXML--*****","DESCRIPTION":"Less Than Lethal","MAPPING1U":"1889","MAPPING1F":"1889","MAPPING1N":"1889","MAPPING1H":"1889"},{"SYMBOLID":"S*G*EXI---*****","DESCRIPTION":"IED","MAPPING1U":"1883","MAPPING1F":"1883","MAPPING1N":"1883","MAPPING1H":"1883"},{"SYMBOLID":"S*G*EXI---*****","DESCRIPTION":"VBIED","MAPPING1U":"1883","MAPPING1F":"1883","MAPPING1N":"1883","MAPPING1H":"1883"},{"SYMBOLID":"S*G*I-----*****","DESCRIPTION":"Installation"},{"SYMBOLID":"S*G*IR----*****","DESCRIPTION":"Raw Material Production/Storage","MAPPING1U":"1897","MAPPING1F":"1897","MAPPING1N":"1897","MAPPING1H":"1897"},{"SYMBOLID":"S*G*IRM---*****","DESCRIPTION":"Raw Material Production/Storage Mine","MAPPING1U":"1898","MAPPING1F":"1898","MAPPING1N":"1898","MAPPING1H":"1898"},{"SYMBOLID":"S*G*IRP---*****","DESCRIPTION":"Petroleum/Gas/Oil","MAPPING1U":"1899","MAPPING1F":"1899","MAPPING1N":"1899","MAPPING1H":"1899"},{"SYMBOLID":"S*G*IRN---*****","DESCRIPTION":"NBC","MAPPING1U":"1900","MAPPING1F":"1900","MAPPING1N":"1900","MAPPING1H":"1900"},{"SYMBOLID":"S*G*IRNB--*****","DESCRIPTION":"Production/Storage NBC Biological","MAPPING1U":"1901","MAPPING1F":"1901","MAPPING1N":"1901","MAPPING1H":"1901"},{"SYMBOLID":"S*G*IRNC--*****","DESCRIPTION":"Production/Storage NBC Chemical","MAPPING1U":"1902","MAPPING1F":"1902","MAPPING1N":"1902","MAPPING1H":"1902"},{"SYMBOLID":"S*G*IRNN--*****","DESCRIPTION":"Production/Storage NBC Nuclear","MAPPING1U":"1903","MAPPING1F":"1903","MAPPING1N":"1903","MAPPING1H":"1903"},{"SYMBOLID":"S*G*IP----*****","DESCRIPTION":"Processing Facility","MAPPING1U":"1904","MAPPING1F":"1904","MAPPING1N":"1904","MAPPING1H":"1904"},{"SYMBOLID":"S*G*IPD---*****","DESCRIPTION":"Processing Facility Decontamination","MAPPING1U":"1905","MAPPING1F":"1905","MAPPING1N":"1905","MAPPING1H":"1905"},{"SYMBOLID":"S*G*IE----*****","DESCRIPTION":"Equipment Manufacture","MAPPING1U":"1906","MAPPING1F":"1906","MAPPING1N":"1906","MAPPING1H":"1906"},{"SYMBOLID":"S*G*IU----*****","DESCRIPTION":"Service, Reasearch, Utility Facility","MAPPING1U":"1907","MAPPING1F":"1907","MAPPING1N":"1907","MAPPING1H":"1907"},{"SYMBOLID":"S*G*IUR---*****","DESCRIPTION":"Technological Research Facility","MAPPING1U":"1908","MAPPING1F":"1908","MAPPING1N":"1908","MAPPING1H":"1908"},{"SYMBOLID":"S*G*IUT---*****","DESCRIPTION":"Telecommunications Facility","MAPPING1U":"1909","MAPPING1F":"1909","MAPPING1N":"1909","MAPPING1H":"1909"},{"SYMBOLID":"S*G*IUE---*****","DESCRIPTION":"Electric Power Facility","MAPPING1U":"1910","MAPPING1F":"1910","MAPPING1N":"1910","MAPPING1H":"1910"},{"SYMBOLID":"S*G*IUEN--*****","DESCRIPTION":"Nuclear Plant","MAPPING1U":"1911","MAPPING1F":"1911","MAPPING1N":"1911","MAPPING1H":"1911"},{"SYMBOLID":"S*G*IUED--*****","DESCRIPTION":"Dam","MAPPING1U":"1912","MAPPING1F":"1912","MAPPING1N":"1912","MAPPING1H":"1912"},{"SYMBOLID":"S*G*IUEF--*****","DESCRIPTION":"Fossil Fuel","MAPPING1U":"1913","MAPPING1F":"1913","MAPPING1N":"1913","MAPPING1H":"1913"},{"SYMBOLID":"S*G*IUP---*****","DESCRIPTION":"Public Water Services","MAPPING1U":"1914","MAPPING1F":"1914","MAPPING1N":"1914","MAPPING1H":"1914"},{"SYMBOLID":"S*G*IM----*****","DESCRIPTION":"Military Materiel Facility"},{"SYMBOLID":"S*G*IMF---*****","DESCRIPTION":"Nuclear Energy","MAPPING1U":"1915","MAPPING1F":"1915","MAPPING1N":"1915","MAPPING1H":"1915"},{"SYMBOLID":"S*G*IMFA--*****","DESCRIPTION":"Atomic Energy Reactor","MAPPING1U":"1916","MAPPING1F":"1916","MAPPING1N":"1916","MAPPING1H":"1916"},{"SYMBOLID":"S*G*IMFP--*****","DESCRIPTION":"Nuclear Material Production","MAPPING1U":"1917","MAPPING1F":"1917","MAPPING1N":"1917","MAPPING1H":"1917"},{"SYMBOLID":"S*G*IMFPW-*****","DESCRIPTION":"Weapons Grade","MAPPING1U":"1918","MAPPING1F":"1918","MAPPING1N":"1918","MAPPING1H":"1918"},{"SYMBOLID":"S*G*IMFS--*****","DESCRIPTION":"Nuclear Material Storage","MAPPING1U":"1919","MAPPING1F":"1919","MAPPING1N":"1919","MAPPING1H":"1919"},{"SYMBOLID":"S*G*IMA---*****","DESCRIPTION":"Aircraft Production & Assembly","MAPPING1U":"1920","MAPPING1F":"1920","MAPPING1N":"1920","MAPPING1H":"1920"},{"SYMBOLID":"S*G*IME---*****","DESCRIPTION":"Ammunition And Explosives Production","MAPPING1U":"1921","MAPPING1F":"1921","MAPPING1N":"1921","MAPPING1H":"1921"},{"SYMBOLID":"S*G*IMG---*****","DESCRIPTION":"Armament Production","MAPPING1U":"1922","MAPPING1F":"1922","MAPPING1N":"1922","MAPPING1H":"1922"},{"SYMBOLID":"S*G*IMV---*****","DESCRIPTION":"Military Vehicle Production","MAPPING1U":"1923","MAPPING1F":"1923","MAPPING1N":"1923","MAPPING1H":"1923"},{"SYMBOLID":"S*G*IMN---*****","DESCRIPTION":"Engineering Equipment Production","MAPPING1U":"1924","MAPPING1F":"1924","MAPPING1N":"1924","MAPPING1H":"1924"},{"SYMBOLID":"S*G*IMNB--*****","DESCRIPTION":"Engineering Equipment Production Bridge","MAPPING1U":"1925","MAPPING1F":"1925","MAPPING1N":"1925","MAPPING1H":"1925"},{"SYMBOLID":"S*G*IMC---*****","DESCRIPTION":"Chemical & Biological Warfare Production","MAPPING1U":"1926","MAPPING1F":"1926","MAPPING1N":"1926","MAPPING1H":"1926"},{"SYMBOLID":"S*G*IMS---*****","DESCRIPTION":"Ship Construction","MAPPING1U":"1927","MAPPING1F":"1927","MAPPING1N":"1927","MAPPING1H":"1927"},{"SYMBOLID":"S*G*IMM---*****","DESCRIPTION":"Missile & Space System Production","MAPPING1U":"1928","MAPPING1F":"1928","MAPPING1N":"1928","MAPPING1H":"1928"},{"SYMBOLID":"S*G*IG----*****","DESCRIPTION":"Government Leadership","MAPPING1U":"1929","MAPPING1F":"1929","MAPPING1N":"1929","MAPPING1H":"1929"},{"SYMBOLID":"S*G*IB----*****","DESCRIPTION":"Military Base/Facility","MAPPING1U":"1930","MAPPING1F":"1930","MAPPING1N":"1930","MAPPING1H":"1930"},{"SYMBOLID":"S*G*IBA---*****","DESCRIPTION":"Airport/Airbase","MAPPING1U":"1931","MAPPING1F":"1931","MAPPING1N":"1931","MAPPING1H":"1931"},{"SYMBOLID":"S*G*IBN---*****","DESCRIPTION":"Seaport/Naval Base","MAPPING1U":"1932","MAPPING1F":"1932","MAPPING1N":"1932","MAPPING1H":"1932"},{"SYMBOLID":"S*G*IT----*****","DESCRIPTION":"Transport Facility","MAPPING1U":"1933","MAPPING1F":"1933","MAPPING1N":"1933","MAPPING1H":"1933"},{"SYMBOLID":"S*G*IX----*****","DESCRIPTION":"Medical Facility","MAPPING1U":"660","MAPPING1F":"661","MAPPING1N":"662","MAPPING1H":"663"},{"SYMBOLID":"S*G*IXH---*****","DESCRIPTION":"Hospital","MAPPING1U":"660","MAPPING1F":"661","MAPPING1N":"662","MAPPING1H":"663","MAPPING2":"1935","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*G*IC----*****","DESCRIPTION":"Tented Camp","MAPPING1U":"1891","MAPPING1F":"1891","MAPPING1N":"1891","MAPPING1H":"1891"},{"SYMBOLID":"S*G*ICD---*****","DESCRIPTION":"Tented Camp, Displaced Persons/Refugees","MAPPING1U":"1892","MAPPING1F":"1892","MAPPING1N":"1892","MAPPING1H":"1892"},{"SYMBOLID":"S*G*ICT---*****","DESCRIPTION":"Tented Training Camp","MAPPING1U":"1893","MAPPING1F":"1893","MAPPING1N":"1893","MAPPING1H":"1893"},{"SYMBOLID":"S*G*IW----*****","DESCRIPTION":"Warehouse/Storage Facility","MAPPING1U":"1895","MAPPING1F":"1895","MAPPING1N":"1895","MAPPING1H":"1895"},{"SYMBOLID":"S*S*------*****","DESCRIPTION":"Sea Surface Track"},{"SYMBOLID":"S*S*C-----*****","DESCRIPTION":"Sea Surface Track Combatant","MAPPING1U":"1936","MAPPING1F":"1936","MAPPING1N":"1936","MAPPING1H":"1936","MAPPING2":"1937","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*CL----*****","DESCRIPTION":"Line","MAPPING1U":"1938","MAPPING1F":"1938","MAPPING1N":"1938","MAPPING1H":"1938"},{"SYMBOLID":"S*S*CLCV--*****","DESCRIPTION":"Carrier","MAPPING1U":"1939","MAPPING1F":"1939","MAPPING1N":"1939","MAPPING1H":"1939"},{"SYMBOLID":"S*S*CLBB--*****","DESCRIPTION":"Battleship","MAPPING1U":"1940","MAPPING1F":"1940","MAPPING1N":"1940","MAPPING1H":"1940"},{"SYMBOLID":"S*S*CLCC--*****","DESCRIPTION":"Cruiser","MAPPING1U":"1941","MAPPING1F":"1941","MAPPING1N":"1941","MAPPING1H":"1941"},{"SYMBOLID":"S*S*CLDD--*****","DESCRIPTION":"Destroyer","MAPPING1U":"1942","MAPPING1F":"1942","MAPPING1N":"1942","MAPPING1H":"1942"},{"SYMBOLID":"S*S*CLFF--*****","DESCRIPTION":"Frigate/Corvette","MAPPING1U":"1943","MAPPING1F":"1943","MAPPING1N":"1943","MAPPING1H":"1943"},{"SYMBOLID":"S*S*CLLL--*****","DESCRIPTION":"Littoral Combatant","MAPPING1U":"1944","MAPPING1F":"1944","MAPPING1N":"1944","MAPPING1H":"1944"},{"SYMBOLID":"S*S*CLLLAS*****","DESCRIPTION":"Antisubmarine Warfare Mission Package","MAPPING1U":"1945","MAPPING1F":"1945","MAPPING1N":"1945","MAPPING1H":"1945"},{"SYMBOLID":"S*S*CLLLMI*****","DESCRIPTION":"Mine Warfare Mission Package","MAPPING1U":"1946","MAPPING1F":"1946","MAPPING1N":"1946","MAPPING1H":"1946"},{"SYMBOLID":"S*S*CLLLSU*****","DESCRIPTION":"Surface Warfare (SUW) Mission Package","MAPPING1U":"1947","MAPPING1F":"1947","MAPPING1N":"1947","MAPPING1H":"1947"},{"SYMBOLID":"S*S*CA----*****","DESCRIPTION":"Amphibious Warfare Ship","MAPPING1U":"1948","MAPPING1F":"1948","MAPPING1N":"1948","MAPPING1H":"1948"},{"SYMBOLID":"S*S*CALA--*****","DESCRIPTION":"Assault Vessel","MAPPING1U":"1949","MAPPING1F":"1949","MAPPING1N":"1949","MAPPING1H":"1949"},{"SYMBOLID":"S*S*CALS--*****","DESCRIPTION":"Landing Ship","MAPPING1U":"1950","MAPPING1F":"1950","MAPPING1N":"1950","MAPPING1H":"1950"},{"SYMBOLID":"S*S*CALSM-*****","DESCRIPTION":"Landing Ship Medium","MAPPING1U":"1951","MAPPING1F":"1951","MAPPING1N":"1951","MAPPING1H":"1951"},{"SYMBOLID":"S*S*CALST-*****","DESCRIPTION":"Landing Ship Tank","MAPPING1U":"1952","MAPPING1F":"1952","MAPPING1N":"1952","MAPPING1H":"1952"},{"SYMBOLID":"S*S*CALC--*****","DESCRIPTION":"Landing Craft","MAPPING1U":"1953","MAPPING1F":"1953","MAPPING1N":"1953","MAPPING1H":"1953"},{"SYMBOLID":"S*S*CM----*****","DESCRIPTION":"Mine Warfare Vessel","MAPPING1U":"1954","MAPPING1F":"1954","MAPPING1N":"1954","MAPPING1H":"1954"},{"SYMBOLID":"S*S*CMML--*****","DESCRIPTION":"Minelayer","MAPPING1U":"1955","MAPPING1F":"1955","MAPPING1N":"1955","MAPPING1H":"1955"},{"SYMBOLID":"S*S*CMMS--*****","DESCRIPTION":"Minesweeper","MAPPING1U":"1956","MAPPING1F":"1956","MAPPING1N":"1956","MAPPING1H":"1956"},{"SYMBOLID":"S*S*CMMH--*****","DESCRIPTION":"Minehunter","MAPPING1U":"1957","MAPPING1F":"1957","MAPPING1N":"1957","MAPPING1H":"1957"},{"SYMBOLID":"S*S*CMMA--*****","DESCRIPTION":"MCM Support","MAPPING1U":"1958","MAPPING1F":"1958","MAPPING1N":"1958","MAPPING1H":"1958"},{"SYMBOLID":"S*S*CP----*****","DESCRIPTION":"Sea Surface Combatant Patrol","MAPPING1U":"1959","MAPPING1F":"1959","MAPPING1N":"1959","MAPPING1H":"1959"},{"SYMBOLID":"S*S*CPSB--*****","DESCRIPTION":"Antisubmarine Warfare","MAPPING1U":"1960","MAPPING1F":"1960","MAPPING1N":"1960","MAPPING1H":"1960"},{"SYMBOLID":"S*S*CPSU--*****","DESCRIPTION":"Antisurface Warfare","MAPPING1U":"1961","MAPPING1F":"1961","MAPPING1N":"1961","MAPPING1H":"1961"},{"SYMBOLID":"S*S*CPSUM-*****","DESCRIPTION":"Anti-Ship Missile","MAPPING1U":"1962","MAPPING1F":"1962","MAPPING1N":"1962","MAPPING1H":"1962"},{"SYMBOLID":"S*S*CPSUT-*****","DESCRIPTION":"Torpedo(Antisurface Warfare)","MAPPING1U":"1963","MAPPING1F":"1963","MAPPING1N":"1963","MAPPING1H":"1963"},{"SYMBOLID":"S*S*CPSUG-*****","DESCRIPTION":"Antisurface Warfare Gun","MAPPING1U":"1964","MAPPING1F":"1964","MAPPING1N":"1964","MAPPING1H":"1964"},{"SYMBOLID":"S*S*CH----*****","DESCRIPTION":"Combatant Hovercraft","MAPPING1U":"1965","MAPPING1F":"1965","MAPPING1N":"1965","MAPPING1H":"1965"},{"SYMBOLID":"S*S*S-----*****","DESCRIPTION":"Sea Surface Station","MAPPING1U":"1966","MAPPING1F":"1966","MAPPING1N":"1966","MAPPING1H":"1966"},{"SYMBOLID":"S*S*SP----*****","DESCRIPTION":"Picket","MAPPING1U":"1967","MAPPING1F":"1967","MAPPING1N":"1967","MAPPING1H":"1967"},{"SYMBOLID":"S*S*SA----*****","DESCRIPTION":"ASW Ship","MAPPING1U":"1968","MAPPING1F":"1968","MAPPING1N":"1968","MAPPING1H":"1968"},{"SYMBOLID":"S*S*G-----*****","DESCRIPTION":"Navy Group","MAPPING1U":"1969","MAPPING1F":"1969","MAPPING1N":"1969","MAPPING1H":"1969"},{"SYMBOLID":"S*S*GT----*****","DESCRIPTION":"Navy Task Force","MAPPING1U":"1970","MAPPING1F":"1970","MAPPING1N":"1970","MAPPING1H":"1970"},{"SYMBOLID":"S*S*GG----*****","DESCRIPTION":"Navy Task Group","MAPPING1U":"1971","MAPPING1F":"1971","MAPPING1N":"1971","MAPPING1H":"1971"},{"SYMBOLID":"S*S*GU----*****","DESCRIPTION":"Navy Task Unit","MAPPING1U":"1972","MAPPING1F":"1972","MAPPING1N":"1972","MAPPING1H":"1972"},{"SYMBOLID":"S*S*GC----*****","DESCRIPTION":"Convoy","MAPPING1U":"1973","MAPPING1F":"1973","MAPPING1N":"1973","MAPPING1H":"1973"},{"SYMBOLID":"S*S*CD----*****","DESCRIPTION":"Surface Decoy","MAPPING1U":"1974","MAPPING1F":"1974","MAPPING1N":"1974","MAPPING1H":"1974"},{"SYMBOLID":"S*S*CU----*****","DESCRIPTION":"Unmanned Surface Vehicle (USV)","MAPPING1U":"1975","MAPPING1F":"1975","MAPPING1N":"1975","MAPPING1H":"1975"},{"SYMBOLID":"S*S*CUM---*****","DESCRIPTION":"USV Mine Countermeasures","MAPPING1U":"1976","MAPPING1F":"1976","MAPPING1N":"1976","MAPPING1H":"1976"},{"SYMBOLID":"S*S*CUS---*****","DESCRIPTION":"USV Antisubmarine Warfare","MAPPING1U":"1977","MAPPING1F":"1977","MAPPING1N":"1977","MAPPING1H":"1977"},{"SYMBOLID":"S*S*CUN---*****","DESCRIPTION":"USV Antisurface Warfare","MAPPING1U":"1978","MAPPING1F":"1978","MAPPING1N":"1978","MAPPING1H":"1978"},{"SYMBOLID":"S*S*CUR---*****","DESCRIPTION":"USV Remote Multimission Vehicle","MAPPING1U":"1979","MAPPING1F":"1979","MAPPING1N":"1979","MAPPING1H":"1979"},{"SYMBOLID":"S*S*N-----*****","DESCRIPTION":"Noncombatant","MAPPING1U":"1980","MAPPING1F":"1980","MAPPING1N":"1980","MAPPING1H":"1980"},{"SYMBOLID":"S*S*NR----*****","DESCRIPTION":"Underway Replenishment","MAPPING1U":"1981","MAPPING1F":"1981","MAPPING1N":"1981","MAPPING1H":"1981"},{"SYMBOLID":"S*S*NF----*****","DESCRIPTION":"Fleet Support","MAPPING1U":"1982","MAPPING1F":"1982","MAPPING1N":"1982","MAPPING1H":"1982"},{"SYMBOLID":"S*S*NI----*****","DESCRIPTION":"Intelligence","MAPPING1U":"1983","MAPPING1F":"1983","MAPPING1N":"1983","MAPPING1H":"1983"},{"SYMBOLID":"S*S*NS----*****","DESCRIPTION":"Service & Support Harbor","MAPPING1U":"1984","MAPPING1F":"1984","MAPPING1N":"1984","MAPPING1H":"1984"},{"SYMBOLID":"S*S*NM----*****","DESCRIPTION":"Hospital Ship","MAPPING1U":"1985","MAPPING1F":"1985","MAPPING1N":"1985","MAPPING1H":"1985"},{"SYMBOLID":"S*S*NH----*****","DESCRIPTION":"Noncombatant Hovercraft","MAPPING1U":"1986","MAPPING1F":"1986","MAPPING1N":"1986","MAPPING1H":"1986","MAPPING2":"1987","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*NN----*****","DESCRIPTION":"Noncombatant Station","MAPPING1U":"1988","MAPPING1F":"1988","MAPPING1N":"1988","MAPPING1H":"1988"},{"SYMBOLID":"S*S*NNR---*****","DESCRIPTION":"Rescue","MAPPING1U":"1989","MAPPING1F":"1989","MAPPING1N":"1989","MAPPING1H":"1989"},{"SYMBOLID":"S*S*X-----*****","DESCRIPTION":"Non-Military"},{"SYMBOLID":"S*S*XM----*****","DESCRIPTION":"Merchant","MAPPING1U":"1990","MAPPING1F":"1990","MAPPING1N":"1990","MAPPING1H":"1990","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMC---*****","DESCRIPTION":"Subsurface Non-military Cargo","MAPPING1U":"1992","MAPPING1F":"1992","MAPPING1N":"1992","MAPPING1H":"1992","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMR---*****","DESCRIPTION":"Roll On/Roll Off","MAPPING1U":"1993","MAPPING1F":"1993","MAPPING1N":"1993","MAPPING1H":"1993","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMO---*****","DESCRIPTION":"Oiler/Tanker","MAPPING1U":"1994","MAPPING1F":"1994","MAPPING1N":"1994","MAPPING1H":"1994","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMTU--*****","DESCRIPTION":"Tug","MAPPING1U":"1995","MAPPING1F":"1995","MAPPING1N":"1995","MAPPING1H":"1995","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMF---*****","DESCRIPTION":"Ferry","MAPPING1U":"1996","MAPPING1F":"1996","MAPPING1N":"1996","MAPPING1H":"1996","MAPPING1COLOR":"#000000","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMP---*****","DESCRIPTION":"Passenger","MAPPING1U":"1997","MAPPING1F":"1997","MAPPING1N":"1997","MAPPING1H":"1997","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMH---*****","DESCRIPTION":"Hazardous Materials (HAZMAT)","MAPPING1U":"1998","MAPPING1F":"1998","MAPPING1N":"1998","MAPPING1H":"1998","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XMTO--*****","DESCRIPTION":"Towing Vessel","MAPPING1U":"1999","MAPPING1F":"1999","MAPPING1N":"1999","MAPPING1H":"1999","MAPPING2":"1991","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XF----*****","DESCRIPTION":"Fishing","MAPPING1U":"2000","MAPPING1F":"2000","MAPPING1N":"2000","MAPPING1H":"2000","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFDF--*****","DESCRIPTION":"Drifter","MAPPING1U":"2002","MAPPING1F":"2002","MAPPING1N":"2002","MAPPING1H":"2002","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFDR--*****","DESCRIPTION":"Dredge","MAPPING1U":"2003","MAPPING1F":"2003","MAPPING1N":"2003","MAPPING1H":"2003","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XFTR--*****","DESCRIPTION":"Trawler","MAPPING1U":"2004","MAPPING1F":"2004","MAPPING1N":"2004","MAPPING1H":"2004","MAPPING2":"2001","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XR----*****","DESCRIPTION":"Leisure Craft","MAPPING1U":"2005","MAPPING1F":"2005","MAPPING1N":"2005","MAPPING1H":"2005","MAPPING2":"2006","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XL----*****","DESCRIPTION":"Law Enforcement Vessel","MAPPING1U":"2007","MAPPING1F":"2007","MAPPING1N":"2007","MAPPING1H":"2007","MAPPING2":"2008","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*XH----*****","DESCRIPTION":"Non-military Hovercraft","MAPPING1U":"2009","MAPPING1F":"2009","MAPPING1N":"2009","MAPPING1H":"2009","MAPPING2":"2010","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*S*O-----*****","DESCRIPTION":"Own Track"},{"SYMBOLID":"S*U*------*****","DESCRIPTION":"Subsurface Track"},{"SYMBOLID":"S*U*S-----*****","DESCRIPTION":"Submarine","MAPPING1U":"2017","MAPPING1F":"2017","MAPPING1N":"2017","MAPPING1H":"2017"},{"SYMBOLID":"S*U*SN----*****","DESCRIPTION":"Nuclear Propulsion","MAPPING1U":"2022","MAPPING1F":"2022","MAPPING1N":"2022","MAPPING1H":"2022"},{"SYMBOLID":"S*U*SNF---*****","DESCRIPTION":"Submarine Nuclear Surfaced","MAPPING1U":"2023","MAPPING1F":"2023","MAPPING1N":"2023","MAPPING1H":"2023"},{"SYMBOLID":"S*U*SNA---*****","DESCRIPTION":"Submarine Nuclear Attack (SSN)","MAPPING1U":"2024","MAPPING1F":"2024","MAPPING1N":"2024","MAPPING1H":"2024","MAPPING2":"2025","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNM---*****","DESCRIPTION":"Submarine Nuclear Missile Type Unknown","MAPPING1U":"2026","MAPPING1F":"2026","MAPPING1N":"2026","MAPPING1H":"2026","MAPPING2":"2027","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNG---*****","DESCRIPTION":"Submarine Nuclear Guided Missile (SSGN)","MAPPING1U":"2028","MAPPING1F":"2028","MAPPING1N":"2028","MAPPING1H":"2028","MAPPING2":"2029","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SNB---*****","DESCRIPTION":"Ballistic Missile Submarine (SSB)","MAPPING1U":"2030","MAPPING1F":"2030","MAPPING1N":"2030","MAPPING1H":"2030","MAPPING2":"2031","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SC----*****","DESCRIPTION":"Conventional Propulsion","MAPPING1U":"2032","MAPPING1F":"2032","MAPPING1N":"2032","MAPPING1H":"2032"},{"SYMBOLID":"S*U*SCF---*****","DESCRIPTION":"Conventional Propulsion Surfaced","MAPPING1U":"2033","MAPPING1F":"2033","MAPPING1N":"2033","MAPPING1H":"2033"},{"SYMBOLID":"S*U*SCA---*****","DESCRIPTION":"Attack Submarine (SS)","MAPPING1U":"2034","MAPPING1F":"2034","MAPPING1N":"2034","MAPPING1H":"2034","MAPPING2":"2035","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCM---*****","DESCRIPTION":"Conventional Propulsion Missile Submarine (TYPE UNKNOWN)","MAPPING1U":"2036","MAPPING1F":"2036","MAPPING1N":"2036","MAPPING1H":"2036","MAPPING2":"2037","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCG---*****","DESCRIPTION":"Guided Missile Submarine (SSG)","MAPPING1U":"2038","MAPPING1F":"2038","MAPPING1N":"2038","MAPPING1H":"2038","MAPPING2":"2039","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SCB---*****","DESCRIPTION":"Conventional Propulsion Ballistic Missile (SSB)","MAPPING1U":"2040","MAPPING1F":"2040","MAPPING1N":"2040","MAPPING1H":"2040","MAPPING2":"2041","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*U*SO----*****","DESCRIPTION":"Other Submersible","MAPPING1U":"2042","MAPPING1F":"2042","MAPPING1N":"2042","MAPPING1H":"2042"},{"SYMBOLID":"S*U*SOF---*****","DESCRIPTION":"Other Submersible Surfaced","MAPPING1U":"2043","MAPPING1F":"2043","MAPPING1N":"2043","MAPPING1H":"2043"},{"SYMBOLID":"S*U*SU----*****","DESCRIPTION":"Unmanned Underwater Vehicle (UUV)","MAPPING1U":"2046","MAPPING1F":"2046","MAPPING1N":"2046","MAPPING1H":"2046"},{"SYMBOLID":"S*U*SUM---*****","DESCRIPTION":"UUV Mine Warfare","MAPPING1U":"2047","MAPPING1F":"2047","MAPPING1N":"2047","MAPPING1H":"2047"},{"SYMBOLID":"S*U*SUS---*****","DESCRIPTION":"UUV Antisubmarine Warfare","MAPPING1U":"2048","MAPPING1F":"2048","MAPPING1N":"2048","MAPPING1H":"2048"},{"SYMBOLID":"S*U*SUN---*****","DESCRIPTION":"UUV Antisurface Warfare","MAPPING1U":"2049","MAPPING1F":"2049","MAPPING1N":"2049","MAPPING1H":"2049"},{"SYMBOLID":"S*U*SF----*****","DESCRIPTION":"Submarine Surfaced","MAPPING1U":"2018","MAPPING1F":"2018","MAPPING1N":"2018","MAPPING1H":"2018"},{"SYMBOLID":"S*U*SB----*****","DESCRIPTION":"Submarine Bottomed","MAPPING1U":"2019","MAPPING1F":"2019","MAPPING1N":"2019","MAPPING1H":"2019"},{"SYMBOLID":"S*U*SR----*****","DESCRIPTION":"Submarine Certsub","MAPPING1U":"2020","MAPPING1F":"2020","MAPPING1N":"2020","MAPPING1H":"2020"},{"SYMBOLID":"S*U*SX----*****","DESCRIPTION":"Non Submarine","MAPPING1U":"2021","MAPPING1F":"2021","MAPPING1N":"2021","MAPPING1H":"2021"},{"SYMBOLID":"S*U*S1----*****","DESCRIPTION":"Possub-1","MAPPING1U":"2050","MAPPING1F":"2050","MAPPING1N":"2050","MAPPING1H":"2050"},{"SYMBOLID":"S*U*S2----*****","DESCRIPTION":"Possub-2","MAPPING1U":"2051","MAPPING1F":"2051","MAPPING1N":"2051","MAPPING1H":"2051"},{"SYMBOLID":"S*U*S3----*****","DESCRIPTION":"Possub-3","MAPPING1U":"2052","MAPPING1F":"2052","MAPPING1N":"2052","MAPPING1H":"2052"},{"SYMBOLID":"S*U*S4----*****","DESCRIPTION":"Possub-4","MAPPING1U":"2053","MAPPING1F":"2053","MAPPING1N":"2053","MAPPING1H":"2053"},{"SYMBOLID":"S*U*SL----*****","DESCRIPTION":"ProbSub","MAPPING1U":"2054","MAPPING1F":"2054","MAPPING1N":"2054","MAPPING1H":"2054"},{"SYMBOLID":"S*U*SK----*****","DESCRIPTION":"Snorkeling","MAPPING1U":"2055","MAPPING1F":"2055","MAPPING1N":"2055","MAPPING1H":"2055"},{"SYMBOLID":"S*U*W-----*****","DESCRIPTION":"Underwater Weapon","MAPPING1U":"2056","MAPPING1F":"2056","MAPPING1N":"2056","MAPPING1H":"2056"},{"SYMBOLID":"S*U*WT----*****","DESCRIPTION":"Torpedo","MAPPING1U":"2057","MAPPING1F":"2057","MAPPING1N":"2057","MAPPING1H":"2057"},{"SYMBOLID":"S*U*WM----*****","DESCRIPTION":"Sea Mine","MAPPING1U":"2058","MAPPING1F":"2058","MAPPING1N":"2058","MAPPING1H":"2058","MAPPING2":"2059","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMD---*****","DESCRIPTION":"Sea Mine Neutralized","MAPPING1U":"2060","MAPPING1F":"2060","MAPPING1N":"2060","MAPPING1H":"2060","MAPPING2":"2059","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMG---*****","DESCRIPTION":"Sea Mine (Ground)","MAPPING1U":"2061","MAPPING1F":"2061","MAPPING1N":"2061","MAPPING1H":"2061","MAPPING2":"2062","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMGD--*****","DESCRIPTION":"Sea Mine (Ground) Neutralized","MAPPING1U":"2063","MAPPING1F":"2063","MAPPING1N":"2063","MAPPING1H":"2063","MAPPING2":"2064","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMGX--*****","DESCRIPTION":"Ground (Bottom) Excercise Mine","MAPPING1U":"2065","MAPPING1F":"2065","MAPPING1N":"2065","MAPPING1H":"2065","MAPPING2":"2062","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMGE--*****","DESCRIPTION":"Ground (Bottom) MILEC","MAPPING1U":"2066","MAPPING1F":"2066","MAPPING1N":"2066","MAPPING1H":"2066","MAPPING2":"2070","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMGC--*****","DESCRIPTION":"Ground (Bottom) MILCO","MAPPING1U":"2067","MAPPING1F":"2067","MAPPING1N":"2067","MAPPING1H":"2067","MAPPING2":"2070","MAPPING2COLOR":"FFA500"},{"SYMBOLID":"S*U*WMGR--*****","DESCRIPTION":"Ground (Bottom) Negative Reacquisition","MAPPING1U":"2068","MAPPING1F":"2068","MAPPING1N":"2068","MAPPING1H":"2068","MAPPING2":"2070","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMGO--*****","DESCRIPTION":"Ground (Bottom) Non-Mine Mike-Like Contact","MAPPING1U":"2069","MAPPING1F":"2069","MAPPING1N":"2069","MAPPING1H":"2069","MAPPING2":"2070","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMM---*****","DESCRIPTION":"Sea Mine (Moored)","MAPPING1U":"2072","MAPPING1F":"2072","MAPPING1N":"2072","MAPPING1H":"2072","MAPPING2":"2073","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMMD--*****","DESCRIPTION":"Sea Mine (Moored) Neutralized","MAPPING1U":"2074","MAPPING1F":"2074","MAPPING1N":"2074","MAPPING1H":"2074","MAPPING2":"2075","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMMX--*****","DESCRIPTION":"Moored Exercise Mine","MAPPING1U":"2076","MAPPING1F":"2076","MAPPING1N":"2076","MAPPING1H":"2076","MAPPING2":"2073","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMME--*****","DESCRIPTION":"Moored MILEC","MAPPING1U":"2077","MAPPING1F":"2077","MAPPING1N":"2077","MAPPING1H":"2077","MAPPING2":"2081","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMMC--*****","DESCRIPTION":"Moored MILCO","MAPPING1U":"2078","MAPPING1F":"2078","MAPPING1N":"2078","MAPPING1H":"2078","MAPPING2":"2081","MAPPING2COLOR":"FFA500"},{"SYMBOLID":"S*U*WMMR--*****","DESCRIPTION":"Moored Negative Reacquisition","MAPPING1U":"2079","MAPPING1F":"2079","MAPPING1N":"2079","MAPPING1H":"2079","MAPPING2":"2081","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMMO--*****","DESCRIPTION":"Moored Non-Mine Mine-Like Object","MAPPING1U":"2080","MAPPING1F":"2080","MAPPING1N":"2080","MAPPING1H":"2080","MAPPING2":"2081","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMF---*****","DESCRIPTION":"Sea Mine (Floating)","MAPPING1U":"2083","MAPPING1F":"2083","MAPPING1N":"2083","MAPPING1H":"2083","MAPPING2":"2084","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMFD--*****","DESCRIPTION":"Sea Mine (Floating) Neutralized","MAPPING1U":"2085","MAPPING1F":"2085","MAPPING1N":"2085","MAPPING1H":"2085","MAPPING2":"2086","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMFX--*****","DESCRIPTION":"Floating Exercise Mine","MAPPING1U":"2087","MAPPING1F":"2087","MAPPING1N":"2087","MAPPING1H":"2087","MAPPING2":"2084","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMFE--*****","DESCRIPTION":"Floating MILEC","MAPPING1U":"2088","MAPPING1F":"2088","MAPPING1N":"2088","MAPPING1H":"2088","MAPPING2":"2092","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMFC--*****","DESCRIPTION":"Floating MILCO","MAPPING1U":"2089","MAPPING1F":"2089","MAPPING1N":"2089","MAPPING1H":"2089","MAPPING2":"2092","MAPPING2COLOR":"FFA500"},{"SYMBOLID":"S*U*WMFR--*****","DESCRIPTION":"Floating Negative Reacquisition","MAPPING1U":"2090","MAPPING1F":"2090","MAPPING1N":"2090","MAPPING1H":"2090","MAPPING2":"2092","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMFO--*****","DESCRIPTION":"Floating Non-Mine Mine-Like Contact","MAPPING1U":"2091","MAPPING1F":"2091","MAPPING1N":"2091","MAPPING1H":"2091","MAPPING2":"2092","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMO---*****","DESCRIPTION":"Sea Mine (Other Position)","MAPPING1U":"2093","MAPPING1F":"2093","MAPPING1N":"2093","MAPPING1H":"2093","MAPPING2":"2094","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMOD--*****","DESCRIPTION":"Sea Mine (Other Position) Neutralized","MAPPING1U":"2095","MAPPING1F":"2095","MAPPING1N":"2095","MAPPING1H":"2095","MAPPING2":"2094","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMX---*****","DESCRIPTION":"General Exercise Mine","MAPPING1U":"2096","MAPPING1F":"2096","MAPPING1N":"2096","MAPPING1H":"2096","MAPPING2":"2094","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WME---*****","DESCRIPTION":"General MILEC","MAPPING1U":"2097","MAPPING1F":"2097","MAPPING1N":"2097","MAPPING1H":"2097","MAPPING2":"2104","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMA---*****","DESCRIPTION":"General Mine Anchor","MAPPING1U":"2098","MAPPING1F":"2098","MAPPING1N":"2098","MAPPING1H":"2098","MAPPING2":"2104","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMC---*****","DESCRIPTION":"General MILCO","MAPPING1U":"2099","MAPPING1F":"2099","MAPPING1N":"2099","MAPPING1H":"2099","MAPPING2":"2104","MAPPING2COLOR":"FFA500"},{"SYMBOLID":"S*U*WMR---*****","DESCRIPTION":"General Negative Reacquisition","MAPPING1U":"2100","MAPPING1F":"2100","MAPPING1N":"2100","MAPPING1H":"2100","MAPPING2":"2104","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMB---*****","DESCRIPTION":"General Obstructor","MAPPING1U":"2101","MAPPING1F":"2101","MAPPING1N":"2101","MAPPING1H":"2101","MAPPING2":"2104","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"S*U*WMBD--*****","DESCRIPTION":"General Obstructor Neutralized","MAPPING1U":"2102","MAPPING1F":"2102","MAPPING1N":"2102","MAPPING1H":"2102","MAPPING2":"2104","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WMN---*****","DESCRIPTION":"General Non-Mine Mine-Like Object","MAPPING1U":"2103","MAPPING1F":"2103","MAPPING1N":"2103","MAPPING1H":"2103","MAPPING2":"2104","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMS---*****","DESCRIPTION":"Rising Mine","MAPPING1U":"2106","MAPPING1F":"2106","MAPPING1N":"2106","MAPPING1H":"2106","MAPPING2":"2105","MAPPING2COLOR":"FF0000"},{"SYMBOLID":"S*U*WMSX--*****","DESCRIPTION":"Rising Exercise Mine","MAPPING1U":"2107","MAPPING1F":"2107","MAPPING1N":"2107","MAPPING1H":"2107","MAPPING2":"2105","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WMSD--*****","DESCRIPTION":"Rising Mine Neutralized","MAPPING1U":"2108","MAPPING1F":"2108","MAPPING1N":"2108","MAPPING1H":"2108","MAPPING2":"2105","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*WD----*****","DESCRIPTION":"Underwater Decoy","MAPPING1U":"2113","MAPPING1F":"2113","MAPPING1N":"2113","MAPPING1H":"2113"},{"SYMBOLID":"S*U*WDM---*****","DESCRIPTION":"Sea Mine Decoy","MAPPING1U":"2114","MAPPING1F":"2114","MAPPING1N":"2114","MAPPING1H":"2114","MAPPING2":"2115","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WDMG--*****","DESCRIPTION":"Ground (Bottom) Decoy","MAPPING1U":"2116","MAPPING1F":"2116","MAPPING1N":"2116","MAPPING1H":"2116","MAPPING2":"2117","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*WDMM--*****","DESCRIPTION":"Moored Decoy","MAPPING1U":"2118","MAPPING1F":"2118","MAPPING1N":"2118","MAPPING1H":"2118","MAPPING2":"2119","MAPPING2COLOR":"008000"},{"SYMBOLID":"S*U*N-----*****","DESCRIPTION":"Non-Submarine"},{"SYMBOLID":"S*U*ND----*****","DESCRIPTION":"Diver","MAPPING1U":"2120","MAPPING1F":"2120","MAPPING1N":"2120","MAPPING1H":"2120"},{"SYMBOLID":"S*U*E-----*****","DESCRIPTION":"Environmental Report Location","MAPPING2":"2124","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*V-----*****","DESCRIPTION":"Dive Report Location","MAPPING2":"2125","MAPPING2COLOR":"00FF00"},{"SYMBOLID":"S*U*X-----*****","DESCRIPTION":"Unexploded Ordnance Area (Subsurface)","MAPPING2":"2126","MAPPING2COLOR":"#FF0000"},{"SYMBOLID":"S*F*------*****","DESCRIPTION":"Special Operations Forces (SOF) Unit","MAPPING1U":"2131","MAPPING1F":"2131","MAPPING1N":"2131","MAPPING1H":"2131"},{"SYMBOLID":"S*F*A-----*****","DESCRIPTION":"SOF Unit Aviation","MAPPING1U":"2132","MAPPING1F":"2132","MAPPING1N":"2132","MAPPING1H":"2132"},{"SYMBOLID":"S*F*AF----*****","DESCRIPTION":"SOF Unit Fixed Wing","MAPPING1U":"2133","MAPPING1F":"2133","MAPPING1N":"2133","MAPPING1H":"2133"},{"SYMBOLID":"S*F*AFA---*****","DESCRIPTION":"SOF Unit Fixed Wing Attack","MAPPING1U":"2134","MAPPING1F":"2134","MAPPING1N":"2134","MAPPING1H":"2134"},{"SYMBOLID":"S*F*AFK---*****","DESCRIPTION":"SOF Unit Refuel","MAPPING1U":"2135","MAPPING1F":"2135","MAPPING1N":"2135","MAPPING1H":"2135"},{"SYMBOLID":"S*F*AFU---*****","DESCRIPTION":"SOF Unit Fixed Wing Utility","MAPPING1U":"2136","MAPPING1F":"2136","MAPPING1N":"2136","MAPPING1H":"2136"},{"SYMBOLID":"S*F*AFUL--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Light)","MAPPING1U":"2137","MAPPING1F":"2137","MAPPING1N":"2137","MAPPING1H":"2137"},{"SYMBOLID":"S*F*AFUM--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Medium)","MAPPING1U":"2138","MAPPING1F":"2138","MAPPING1N":"2138","MAPPING1H":"2138"},{"SYMBOLID":"S*F*AFUH--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Heavy)","MAPPING1U":"2139","MAPPING1F":"2139","MAPPING1N":"2139","MAPPING1H":"2139"},{"SYMBOLID":"S*F*AV----*****","DESCRIPTION":"SOF Unit V/STOL","MAPPING1U":"2140","MAPPING1F":"2140","MAPPING1N":"2140","MAPPING1H":"2140"},{"SYMBOLID":"S*F*AH----*****","DESCRIPTION":"SOF Unit Rotary Wing","MAPPING1U":"2141","MAPPING1F":"2141","MAPPING1N":"2141","MAPPING1H":"2141"},{"SYMBOLID":"S*F*AHH---*****","DESCRIPTION":"SOF Unit Rotary Wing Combat Search & Rescue","MAPPING1U":"2142","MAPPING1F":"2142","MAPPING1N":"2142","MAPPING1H":"2142"},{"SYMBOLID":"S*F*AHA---*****","DESCRIPTION":"SOF Unit Rotary Wing Attack","MAPPING1U":"2143","MAPPING1F":"2143","MAPPING1N":"2143","MAPPING1H":"2143"},{"SYMBOLID":"S*F*AHU---*****","DESCRIPTION":"SOF Unit Rotary Wing Utility","MAPPING1U":"2144","MAPPING1F":"2144","MAPPING1N":"2144","MAPPING1H":"2144"},{"SYMBOLID":"S*F*AHUL--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Light)","MAPPING1U":"2145","MAPPING1F":"2145","MAPPING1N":"2145","MAPPING1H":"2145"},{"SYMBOLID":"S*F*AHUM--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Medium)","MAPPING1U":"2146","MAPPING1F":"2146","MAPPING1N":"2146","MAPPING1H":"2146"},{"SYMBOLID":"S*F*AHUH--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Heavy)","MAPPING1U":"2147","MAPPING1F":"2147","MAPPING1N":"2147","MAPPING1H":"2147"},{"SYMBOLID":"S*F*N-----*****","DESCRIPTION":"SOF Unit SOF Unit Naval","MAPPING1U":"2148","MAPPING1F":"2148","MAPPING1N":"2148","MAPPING1H":"2148"},{"SYMBOLID":"S*F*NS----*****","DESCRIPTION":"SOF Unit Seal","MAPPING1U":"2149","MAPPING1F":"2149","MAPPING1N":"2149","MAPPING1H":"2149"},{"SYMBOLID":"S*F*NU----*****","DESCRIPTION":"SOF Unit Underwater Demolition Team","MAPPING1U":"2150","MAPPING1F":"2150","MAPPING1N":"2150","MAPPING1H":"2150"},{"SYMBOLID":"S*F*NB----*****","DESCRIPTION":"SOF Unit Special Boat","MAPPING1U":"2151","MAPPING1F":"2151","MAPPING1N":"2151","MAPPING1H":"2151","MAPPING2":"2152","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*NN----*****","DESCRIPTION":"SOF Unit Special SSNR","MAPPING1U":"2153","MAPPING1F":"2153","MAPPING1N":"2153","MAPPING1H":"2153"},{"SYMBOLID":"S*F*G-----*****","DESCRIPTION":"SOF Unit Ground","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"2154","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*F*GS----*****","DESCRIPTION":"SOF Unit Special Forces","MAPPING1U":"2158","MAPPING1F":"2158","MAPPING1N":"2158","MAPPING1H":"2158"},{"SYMBOLID":"S*F*GR----*****","DESCRIPTION":"SOF Unit Ranger","MAPPING1U":"604","MAPPING1F":"605","MAPPING1N":"606","MAPPING1H":"607","MAPPING2":"2159","MAPPING2COLOR":"#000000"},{"SYMBOLID":"S*F*GP----*****","DESCRIPTION":"SOF Unit Psychological Operations (PSYOP)","MAPPING1U":"2161","MAPPING1F":"2161","MAPPING1N":"2161","MAPPING1H":"2161","MAPPING2":"2162","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*GPA---*****","DESCRIPTION":"SOF Unit Fixed Wing Aviation (PSYOP)","MAPPING1U":"2163","MAPPING1F":"2163","MAPPING1N":"2163","MAPPING1H":"2163","MAPPING2":"2164","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"S*F*GC----*****","DESCRIPTION":"SOF Unit Civil Affairs","MAPPING1U":"2165","MAPPING1F":"2165","MAPPING1N":"2165","MAPPING1H":"2165"},{"SYMBOLID":"S*F*B-----*****","DESCRIPTION":"SOF Unit Support","MAPPING1U":"2166","MAPPING1F":"2166","MAPPING1N":"2166","MAPPING1H":"2166"},{"SYMBOLID":"S*Z*------*****","DESCRIPTION":"Unknown Battle Dimension","MAPPING1U":"999","MAPPING1F":"999","MAPPING1N":"999","MAPPING1H":"999"},{"SYMBOLID":"I*-*------*****","DESCRIPTION":"Signals Intelligence"},{"SYMBOLID":"I*P*------*****","DESCRIPTION":"Space Track"},{"SYMBOLID":"I*P*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*P*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*P*SCD---*****","DESCRIPTION":"Satellite Down-Link","MAPPING1U":"3000","MAPPING1F":"3000","MAPPING1N":"3000","MAPPING1H":"3000"},{"SYMBOLID":"I*P*SR----*****","DESCRIPTION":"Radar(Signal Intercept)"},{"SYMBOLID":"I*P*SRD---*****","DESCRIPTION":"Data Transmission(SPACE TRACK)","MAPPING1U":"3001","MAPPING1F":"3001","MAPPING1N":"3001","MAPPING1H":"3001"},{"SYMBOLID":"I*P*SRE---*****","DESCRIPTION":"Earth Surveillance","MAPPING1U":"3002","MAPPING1F":"3002","MAPPING1N":"3002","MAPPING1H":"3002"},{"SYMBOLID":"I*P*SRI---*****","DESCRIPTION":"IFF (Transponder)(SPACE TRACK)","MAPPING1U":"3003","MAPPING1F":"3003","MAPPING1N":"3003","MAPPING1H":"3003"},{"SYMBOLID":"I*P*SRM---*****","DESCRIPTION":"Multi-function(SPACE TRACK)","MAPPING1U":"3004","MAPPING1F":"3004","MAPPING1N":"3004","MAPPING1H":"3004"},{"SYMBOLID":"I*P*SRT---*****","DESCRIPTION":"Target Acquisition(Space Track)","MAPPING1U":"3005","MAPPING1F":"3005","MAPPING1N":"3005","MAPPING1H":"3005"},{"SYMBOLID":"I*P*SRS---*****","DESCRIPTION":"Space","MAPPING1U":"3006","MAPPING1F":"3006","MAPPING1N":"3006","MAPPING1H":"3006"},{"SYMBOLID":"I*P*SRU---*****","DESCRIPTION":"Unknown(Space Track)","MAPPING1U":"3007","MAPPING1F":"3007","MAPPING1N":"3007","MAPPING1H":"3007"},{"SYMBOLID":"I*A*------*****","DESCRIPTION":"Air Track"},{"SYMBOLID":"I*A*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*A*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*A*SCC---*****","DESCRIPTION":"Cellular/Mobile(AIR TRACK)","MAPPING1U":"3008","MAPPING1F":"3008","MAPPING1N":"3008","MAPPING1H":"3008"},{"SYMBOLID":"I*A*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(AIR TRACK)","MAPPING1U":"3009","MAPPING1F":"3009","MAPPING1N":"3009","MAPPING1H":"3009"},{"SYMBOLID":"I*A*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Air Track)","MAPPING1U":"3010","MAPPING1F":"3010","MAPPING1N":"3010","MAPPING1H":"3010"},{"SYMBOLID":"I*A*SCS---*****","DESCRIPTION":"Satellite Up-Link(Air Track)","MAPPING1U":"3011","MAPPING1F":"3011","MAPPING1N":"3011","MAPPING1H":"3011"},{"SYMBOLID":"I*A*SR----*****","DESCRIPTION":"Radar"},{"SYMBOLID":"I*A*SRAI--*****","DESCRIPTION":"Airborne Intercept","MAPPING1U":"3012","MAPPING1F":"3012","MAPPING1N":"3012","MAPPING1H":"3012"},{"SYMBOLID":"I*A*SRAS--*****","DESCRIPTION":"Airborne Search and Bombing","MAPPING1U":"3013","MAPPING1F":"3013","MAPPING1N":"3013","MAPPING1H":"3013"},{"SYMBOLID":"I*A*SRC---*****","DESCRIPTION":"Controlled Intercept(AIR TRACK)","MAPPING1U":"3014","MAPPING1F":"3014","MAPPING1N":"3014","MAPPING1H":"3014"},{"SYMBOLID":"I*A*SRD---*****","DESCRIPTION":"Data Transmission(AIR TRACK)","MAPPING1U":"3015","MAPPING1F":"3015","MAPPING1N":"3015","MAPPING1H":"3015"},{"SYMBOLID":"I*A*SRE---*****","DESCRIPTION":"Early Warning(AIR TRACK)","MAPPING1U":"3016","MAPPING1F":"3016","MAPPING1N":"3016","MAPPING1H":"3016"},{"SYMBOLID":"I*A*SRF---*****","DESCRIPTION":"Fire Control(AIR TRACK)","MAPPING1U":"3017","MAPPING1F":"3017","MAPPING1N":"3017","MAPPING1H":"3017"},{"SYMBOLID":"I*A*SRI---*****","DESCRIPTION":"IFF (Transponder)(AIR TRACK)","MAPPING1U":"3018","MAPPING1F":"3018","MAPPING1N":"3018","MAPPING1H":"3018"},{"SYMBOLID":"I*A*SRMA--*****","DESCRIPTION":"Missile Acquisition(AIR TRACK)","MAPPING1U":"3019","MAPPING1F":"3019","MAPPING1N":"3019","MAPPING1H":"3019"},{"SYMBOLID":"I*A*SRMD--*****","DESCRIPTION":"Missile Downlink","MAPPING1U":"3020","MAPPING1F":"3020","MAPPING1N":"3020","MAPPING1H":"3020"},{"SYMBOLID":"I*A*SRMG--*****","DESCRIPTION":"Missile Guidance(AIR TRACK)","MAPPING1U":"3021","MAPPING1F":"3021","MAPPING1N":"3021","MAPPING1H":"3021"},{"SYMBOLID":"I*A*SRMT--*****","DESCRIPTION":"Missile Tracking(AIR TRACK)","MAPPING1U":"3022","MAPPING1F":"3022","MAPPING1N":"3022","MAPPING1H":"3022"},{"SYMBOLID":"I*A*SRMF--*****","DESCRIPTION":"Multi-Function(AIR TRACK)","MAPPING1U":"3023","MAPPING1F":"3023","MAPPING1N":"3023","MAPPING1H":"3023"},{"SYMBOLID":"I*A*SRTI--*****","DESCRIPTION":"Target Illuminator(Air Track)","MAPPING1U":"3024","MAPPING1F":"3024","MAPPING1N":"3024","MAPPING1H":"3024"},{"SYMBOLID":"I*A*SRTA--*****","DESCRIPTION":"Target Acquisition(Air Track)","MAPPING1U":"3025","MAPPING1F":"3025","MAPPING1N":"3025","MAPPING1H":"3025"},{"SYMBOLID":"I*A*SRTT--*****","DESCRIPTION":"Target Tracking(Air Track)","MAPPING1U":"3026","MAPPING1F":"3026","MAPPING1N":"3026","MAPPING1H":"3026"},{"SYMBOLID":"I*A*SRU---*****","DESCRIPTION":"Unknown(Air Track)","MAPPING1U":"3027","MAPPING1F":"3027","MAPPING1N":"3027","MAPPING1H":"3027"},{"SYMBOLID":"I*G*------*****","DESCRIPTION":"Ground Track"},{"SYMBOLID":"I*G*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*G*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*G*SCC---*****","DESCRIPTION":"Cellular/Mobile(GROUND TRACK)","MAPPING1U":"3028","MAPPING1F":"3028","MAPPING1N":"3028","MAPPING1H":"3028"},{"SYMBOLID":"I*G*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(GROUND TRACK)","MAPPING1U":"3029","MAPPING1F":"3029","MAPPING1N":"3029","MAPPING1H":"3029"},{"SYMBOLID":"I*G*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Ground Track)","MAPPING1U":"3030","MAPPING1F":"3030","MAPPING1N":"3030","MAPPING1H":"3030"},{"SYMBOLID":"I*G*SCS---*****","DESCRIPTION":"Satellite Up-Link(Ground Track)","MAPPING1U":"3031","MAPPING1F":"3031","MAPPING1N":"3031","MAPPING1H":"3031"},{"SYMBOLID":"I*G*SCT---*****","DESCRIPTION":"Tropospheric Scatter","MAPPING1U":"3032","MAPPING1F":"3032","MAPPING1N":"3032","MAPPING1H":"3032"},{"SYMBOLID":"I*G*SR----*****","DESCRIPTION":"Radar(Signals Intelligence)"},{"SYMBOLID":"I*G*SRAT--*****","DESCRIPTION":"Air Traffic Control(GROUND TRACK)","MAPPING1U":"3033","MAPPING1F":"3033","MAPPING1N":"3033","MAPPING1H":"3033"},{"SYMBOLID":"I*G*SRAA--*****","DESCRIPTION":"Anti-Aircraft(GROUND TRACK)","MAPPING1U":"3034","MAPPING1F":"3034","MAPPING1N":"3034","MAPPING1H":"3034"},{"SYMBOLID":"I*G*SRB---*****","DESCRIPTION":"Battlefield Surveillance","MAPPING1U":"3035","MAPPING1F":"3035","MAPPING1N":"3035","MAPPING1H":"3035"},{"SYMBOLID":"I*G*SRCS--*****","DESCRIPTION":"Coastal Surveillance","MAPPING1U":"3036","MAPPING1F":"3036","MAPPING1N":"3036","MAPPING1H":"3036"},{"SYMBOLID":"I*G*SRCA--*****","DESCRIPTION":"Controlled Approach(GROUND TRACK)","MAPPING1U":"3037","MAPPING1F":"3037","MAPPING1N":"3037","MAPPING1H":"3037"},{"SYMBOLID":"I*G*SRD---*****","DESCRIPTION":"Data Transmission(GROUND TRACK)","MAPPING1U":"3038","MAPPING1F":"3038","MAPPING1N":"3038","MAPPING1H":"3038"},{"SYMBOLID":"I*G*SRE---*****","DESCRIPTION":"Early Warning(GROUND TRACK)","MAPPING1U":"3039","MAPPING1F":"3039","MAPPING1N":"3039","MAPPING1H":"3039"},{"SYMBOLID":"I*G*SRF---*****","DESCRIPTION":"Fire Control(GROUND TRACK)","MAPPING1U":"3040","MAPPING1F":"3040","MAPPING1N":"3040","MAPPING1H":"3040"},{"SYMBOLID":"I*G*SRH---*****","DESCRIPTION":"Height Finding(GROUND TRACK)","MAPPING1U":"3041","MAPPING1F":"3041","MAPPING1N":"3041","MAPPING1H":"3041"},{"SYMBOLID":"I*G*SRI---*****","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(GROUND TRACK)","MAPPING1U":"3042","MAPPING1F":"3042","MAPPING1N":"3042","MAPPING1H":"3042"},{"SYMBOLID":"I*G*SRMM--*****","DESCRIPTION":"Meteorological (Military)(GROUND TRACK)","MAPPING1U":"3043","MAPPING1F":"3043","MAPPING1N":"3043","MAPPING1H":"3043"},{"SYMBOLID":"I*G*SRMA--*****","DESCRIPTION":"Missile Acquisition(GROUND TRACK)","MAPPING1U":"3044","MAPPING1F":"3044","MAPPING1N":"3044","MAPPING1H":"3044"},{"SYMBOLID":"I*G*SRMG--*****","DESCRIPTION":"Missile Guidance(GROUND TRACK)","MAPPING1U":"3045","MAPPING1F":"3045","MAPPING1N":"3045","MAPPING1H":"3045"},{"SYMBOLID":"I*G*SRMT--*****","DESCRIPTION":"Missile Tracking(GROUND TRACK)","MAPPING1U":"3046","MAPPING1F":"3046","MAPPING1N":"3046","MAPPING1H":"3046"},{"SYMBOLID":"I*G*SRMF--*****","DESCRIPTION":"Multi-Function(GROUND TRACK)","MAPPING1U":"3047","MAPPING1F":"3047","MAPPING1N":"3047","MAPPING1H":"3047"},{"SYMBOLID":"I*G*SRS---*****","DESCRIPTION":"Shell Tracking","MAPPING1U":"3048","MAPPING1F":"3048","MAPPING1N":"3048","MAPPING1H":"3048"},{"SYMBOLID":"I*G*SRTA--*****","DESCRIPTION":"Target Acquisition(Radar)","MAPPING1U":"3049","MAPPING1F":"3049","MAPPING1N":"3049","MAPPING1H":"3049"},{"SYMBOLID":"I*G*SRTI--*****","DESCRIPTION":"Target Illuminator(Ground Track)","MAPPING1U":"3050","MAPPING1F":"3050","MAPPING1N":"3050","MAPPING1H":"3050"},{"SYMBOLID":"I*G*SRTT--*****","DESCRIPTION":"Target Tracking(Ground Track)","MAPPING1U":"3051","MAPPING1F":"3051","MAPPING1N":"3051","MAPPING1H":"3051"},{"SYMBOLID":"I*G*SRU---*****","DESCRIPTION":"Unknown(Ground Track)","MAPPING1U":"3052","MAPPING1F":"3052","MAPPING1N":"3052","MAPPING1H":"3052"},{"SYMBOLID":"I*S*------*****","DESCRIPTION":"Sea Surface Track"},{"SYMBOLID":"I*S*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*S*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*S*SCC---*****","DESCRIPTION":"Cellular/Mobile(SEA SURFACE TRACK)","MAPPING1U":"3053","MAPPING1F":"3053","MAPPING1N":"3053","MAPPING1H":"3053"},{"SYMBOLID":"I*S*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SEA SURFACE TRACK)","MAPPING1U":"3054","MAPPING1F":"3054","MAPPING1N":"3054","MAPPING1H":"3054"},{"SYMBOLID":"I*S*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Sea Surface Track)","MAPPING1U":"3055","MAPPING1F":"3055","MAPPING1N":"3055","MAPPING1H":"3055"},{"SYMBOLID":"I*S*SCS---*****","DESCRIPTION":"Satellite Up-Link(Sea Surface Track)","MAPPING1U":"3056","MAPPING1F":"3056","MAPPING1N":"3056","MAPPING1H":"3056"},{"SYMBOLID":"I*S*SR----*****","DESCRIPTION":"Radar(Sea Surface Track)"},{"SYMBOLID":"I*S*SRAT--*****","DESCRIPTION":"Air Traffic Control(SEA SURFACE TRACK)","MAPPING1U":"3057","MAPPING1F":"3057","MAPPING1N":"3057","MAPPING1H":"3057"},{"SYMBOLID":"I*S*SRAA--*****","DESCRIPTION":"Anti-Aircraft(SEA SURFACE TRACK)","MAPPING1U":"3058","MAPPING1F":"3058","MAPPING1N":"3058","MAPPING1H":"3058"},{"SYMBOLID":"I*S*SRCA--*****","DESCRIPTION":"Controlled Approach(SEA SURFACE TRACK)","MAPPING1U":"3059","MAPPING1F":"3059","MAPPING1N":"3059","MAPPING1H":"3059"},{"SYMBOLID":"I*S*SRCI--*****","DESCRIPTION":"Controlled Intercept(SEA SURFACE TRACK)","MAPPING1U":"3060","MAPPING1F":"3060","MAPPING1N":"3060","MAPPING1H":"3060"},{"SYMBOLID":"I*S*SRD---*****","DESCRIPTION":"Data Transmission(SEA SURFACE TRACK)","MAPPING1U":"3061","MAPPING1F":"3061","MAPPING1N":"3061","MAPPING1H":"3061"},{"SYMBOLID":"I*S*SRE---*****","DESCRIPTION":"Early Warning(SEA SURFACE TRACK)","MAPPING1U":"3062","MAPPING1F":"3062","MAPPING1N":"3062","MAPPING1H":"3062"},{"SYMBOLID":"I*S*SRF---*****","DESCRIPTION":"Fire Control(SEA SURFACE TRACK)","MAPPING1U":"3063","MAPPING1F":"3063","MAPPING1N":"3063","MAPPING1H":"3063"},{"SYMBOLID":"I*S*SRH---*****","DESCRIPTION":"Height Finding(SEA SURFACE TRACK)","MAPPING1U":"3064","MAPPING1F":"3064","MAPPING1N":"3064","MAPPING1H":"3064"},{"SYMBOLID":"I*S*SRI---*****","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(SEA SURFACE TRACK)","MAPPING1U":"3065","MAPPING1F":"3065","MAPPING1N":"3065","MAPPING1H":"3065"},{"SYMBOLID":"I*S*SRMM--*****","DESCRIPTION":"Meteorological (Military)(SEA SURFACE TRACK)","MAPPING1U":"3066","MAPPING1F":"3066","MAPPING1N":"3066","MAPPING1H":"3066"},{"SYMBOLID":"I*S*SRMA--*****","DESCRIPTION":"Missile Acquisition(SEA SURFACE TRACK)","MAPPING1U":"3067","MAPPING1F":"3067","MAPPING1N":"3067","MAPPING1H":"3067"},{"SYMBOLID":"I*S*SRMG--*****","DESCRIPTION":"Missile Guidance(SEA SURFACE TRACK)","MAPPING1U":"3068","MAPPING1F":"3068","MAPPING1N":"3068","MAPPING1H":"3068"},{"SYMBOLID":"I*S*SRMT--*****","DESCRIPTION":"Missile Tracking(SEA SURFACE TRACK)","MAPPING1U":"3069","MAPPING1F":"3069","MAPPING1N":"3069","MAPPING1H":"3069"},{"SYMBOLID":"I*S*SRMF--*****","DESCRIPTION":"Multi-Function(SEA SURFACE TRACK)","MAPPING1U":"3070","MAPPING1F":"3070","MAPPING1N":"3070","MAPPING1H":"3070"},{"SYMBOLID":"I*S*SRS---*****","DESCRIPTION":"Surface Search(Sea Surface Track)","MAPPING1U":"3071","MAPPING1F":"3071","MAPPING1N":"3071","MAPPING1H":"3071"},{"SYMBOLID":"I*S*SRTA--*****","DESCRIPTION":"Target Acquisition(Sea Surface Track)","MAPPING1U":"3072","MAPPING1F":"3072","MAPPING1N":"3072","MAPPING1H":"3072"},{"SYMBOLID":"I*S*SRTI--*****","DESCRIPTION":"Target Illuminator(Sea Surface Track)","MAPPING1U":"3073","MAPPING1F":"3073","MAPPING1N":"3073","MAPPING1H":"3073"},{"SYMBOLID":"I*S*SRTT--*****","DESCRIPTION":"Target Tracking(Sea Surface Track)","MAPPING1U":"3074","MAPPING1F":"3074","MAPPING1N":"3074","MAPPING1H":"3074"},{"SYMBOLID":"I*S*SRU---*****","DESCRIPTION":"Unknown(Sea Surface Track)","MAPPING1U":"3075","MAPPING1F":"3075","MAPPING1N":"3075","MAPPING1H":"3075"},{"SYMBOLID":"I*U*------*****","DESCRIPTION":"Subsurface Track"},{"SYMBOLID":"I*U*S-----*****","DESCRIPTION":"Signal Intercept"},{"SYMBOLID":"I*U*SC----*****","DESCRIPTION":"Communications"},{"SYMBOLID":"I*U*SCO---*****","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SUBSURFACE TRACK)","MAPPING1U":"3076","MAPPING1F":"3076","MAPPING1N":"3076","MAPPING1H":"3076"},{"SYMBOLID":"I*U*SCP---*****","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Subsurface Track)","MAPPING1U":"3077","MAPPING1F":"3077","MAPPING1N":"3077","MAPPING1H":"3077"},{"SYMBOLID":"I*U*SCS---*****","DESCRIPTION":"Satellite Up-Link(Subsurface Track)","MAPPING1U":"3078","MAPPING1F":"3078","MAPPING1N":"3078","MAPPING1H":"3078"},{"SYMBOLID":"I*U*SR----*****","DESCRIPTION":"Radar(Subsurface Track)"},{"SYMBOLID":"I*U*SRD---*****","DESCRIPTION":"Data Transmission(SUBSURFACE TRACK)","MAPPING1U":"3079","MAPPING1F":"3079","MAPPING1N":"3079","MAPPING1H":"3079"},{"SYMBOLID":"I*U*SRE---*****","DESCRIPTION":"Early Warning(SUBSURFACE TRACK)","MAPPING1U":"3080","MAPPING1F":"3080","MAPPING1N":"3080","MAPPING1H":"3080"},{"SYMBOLID":"I*U*SRM---*****","DESCRIPTION":"Multi-Function(Subsurface Track)","MAPPING1U":"3081","MAPPING1F":"3081","MAPPING1N":"3081","MAPPING1H":"3081"},{"SYMBOLID":"I*U*SRS---*****","DESCRIPTION":"Surface Search(Subsurface Track)","MAPPING1U":"3082","MAPPING1F":"3082","MAPPING1N":"3082","MAPPING1H":"3082"},{"SYMBOLID":"I*U*SRT---*****","DESCRIPTION":"Target Acquisition(Subsurface Track)","MAPPING1U":"3083","MAPPING1F":"3083","MAPPING1N":"3083","MAPPING1H":"3083"},{"SYMBOLID":"I*U*SRU---*****","DESCRIPTION":"Unknown(Subsurface Track)","MAPPING1U":"3084","MAPPING1F":"3084","MAPPING1N":"3084","MAPPING1H":"3084"},{"SYMBOLID":"O*-*------*****","DESCRIPTION":"Stability Operations"},{"SYMBOLID":"O*V*------*****","DESCRIPTION":"Violent Activities"},{"SYMBOLID":"O*V*A-----*****","DESCRIPTION":"Arson/Fire","MAPPING1U":"4000","MAPPING1F":"4000","MAPPING1N":"4000","MAPPING1H":"4000"},{"SYMBOLID":"O*V*M-----*****","DESCRIPTION":"Killing (General)","MAPPING1U":"4001","MAPPING1F":"4002","MAPPING1N":"4003","MAPPING1H":"4004"},{"SYMBOLID":"O*V*MA----*****","DESCRIPTION":"Murder","MAPPING1U":"4005","MAPPING1F":"4006","MAPPING1N":"4007","MAPPING1H":"4008"},{"SYMBOLID":"O*V*MB----*****","DESCRIPTION":"Execution","MAPPING1U":"4009","MAPPING1F":"4010","MAPPING1N":"4011","MAPPING1H":"4012"},{"SYMBOLID":"O*V*MC----*****","DESCRIPTION":"Assassination","MAPPING1U":"4013","MAPPING1F":"4014","MAPPING1N":"4015","MAPPING1H":"4016"},{"SYMBOLID":"O*V*B-----*****","DESCRIPTION":"Bomb/Bombing","MAPPING1U":"4017","MAPPING1F":"4017","MAPPING1N":"4017","MAPPING1H":"4017"},{"SYMBOLID":"O*V*Y-----*****","DESCRIPTION":"Booby Trap","MAPPING1U":"4018","MAPPING1F":"4018","MAPPING1N":"4018","MAPPING1H":"4018"},{"SYMBOLID":"O*V*D-----*****","DESCRIPTION":"Drive-By Shooting","MAPPING1U":"4019","MAPPING1F":"4019","MAPPING1N":"4019","MAPPING1H":"4019"},{"SYMBOLID":"O*V*S-----*****","DESCRIPTION":"Sniping","MAPPING1U":"4020","MAPPING1F":"4020","MAPPING1N":"4020","MAPPING1H":"4020"},{"SYMBOLID":"O*V*P-----*****","DESCRIPTION":"Poisoning","MAPPING1U":"4021","MAPPING1F":"4021","MAPPING1N":"4021","MAPPING1H":"4021"},{"SYMBOLID":"O*V*E-----*****","DESCRIPTION":"Explosion","MAPPING1U":"4022","MAPPING1F":"4022","MAPPING1N":"4022","MAPPING1H":"4022","MAPPING2":"406","MAPPING2COLOR":"#FFFF00"},{"SYMBOLID":"O*V*EI----*****","DESCRIPTION":"IED Explosion","MAPPING1U":"4023","MAPPING1F":"4023","MAPPING1N":"4023","MAPPING1H":"4023"},{"SYMBOLID":"O*V*EG----*****","DESCRIPTION":"Explosion, Grenade","MAPPING1U":"4508","MAPPING1F":"4508","MAPPING1N":"4508","MAPPING1H":"4508"},{"SYMBOLID":"O*V*EN----*****","DESCRIPTION":"Explosion, Incendiary","MAPPING1U":"4509","MAPPING1F":"4509","MAPPING1N":"4509","MAPPING1H":"4509"},{"SYMBOLID":"O*V*EM----*****","DESCRIPTION":"Explosion, Mine","MAPPING1U":"4510","MAPPING1F":"4510","MAPPING1N":"4510","MAPPING1H":"4510"},{"SYMBOLID":"O*V*EO----*****","DESCRIPTION":"Explosion, Mortar Fire","MAPPING1U":"4511","MAPPING1F":"4511","MAPPING1N":"4511","MAPPING1H":"4511"},{"SYMBOLID":"O*V*ER----*****","DESCRIPTION":"Explosion, Rocket","MAPPING1U":"4512","MAPPING1F":"4512","MAPPING1N":"4512","MAPPING1H":"4512"},{"SYMBOLID":"O*V*EV----*****","DESCRIPTION":"Explosion, Wheeled Vehicle","MAPPING1U":"4513","MAPPING1F":"4513","MAPPING1N":"4513","MAPPING1H":"4513"},{"SYMBOLID":"O*L*------*****","DESCRIPTION":"Locations"},{"SYMBOLID":"O*L*B-----*****","DESCRIPTION":"Black List Location","MAPPING1U":"4024","MAPPING1F":"4024","MAPPING1N":"4024","MAPPING1H":"4024"},{"SYMBOLID":"O*L*G-----*****","DESCRIPTION":"Gray List Location","MAPPING1U":"4025","MAPPING1F":"4025","MAPPING1N":"4025","MAPPING1H":"4025"},{"SYMBOLID":"O*L*W-----*****","DESCRIPTION":"White List Location","MAPPING1U":"4026","MAPPING1F":"4026","MAPPING1N":"4026","MAPPING1H":"4026"},{"SYMBOLID":"O*L*M-----*****","DESCRIPTION":"Mass Grave Location","MAPPING1U":"4027","MAPPING1F":"4027","MAPPING1N":"4027","MAPPING1H":"4027"},{"SYMBOLID":"O*L*E-----*****","DESCRIPTION":"Drug Lab","MAPPING1U":"4505","MAPPING1F":"4505","MAPPING1N":"4505","MAPPING1H":"4505"},{"SYMBOLID":"O*L*H-----*****","DESCRIPTION":"House/Residence","MAPPING1U":"4521","MAPPING1F":"4521","MAPPING1N":"4521","MAPPING1H":"4521"},{"SYMBOLID":"O*L*N-----*****","DESCRIPTION":"Cave Entrance","MAPPING1U":"4503","MAPPING1F":"4503","MAPPING1N":"4503","MAPPING1H":"4503"},{"SYMBOLID":"O*L*H-----*****","DESCRIPTION":"Palace/Presidential Residence","MAPPING1U":"4521","MAPPING1F":"4521","MAPPING1N":"4521","MAPPING1H":"4521"},{"SYMBOLID":"O*L*F-----*****","DESCRIPTION":"Polling Place","MAPPING1U":"4522","MAPPING1F":"4522","MAPPING1N":"4522","MAPPING1H":"4522"},{"SYMBOLID":"O*O*------*****","DESCRIPTION":"Operations"},{"SYMBOLID":"O*O*P-----*****","DESCRIPTION":"Patrolling","MAPPING1U":"4028","MAPPING1F":"4028","MAPPING1N":"4028","MAPPING1H":"4028"},{"SYMBOLID":"O*O*R-----*****","DESCRIPTION":"Recruitment"},{"SYMBOLID":"O*O*RW----*****","DESCRIPTION":"Recruitment (Willing)","MAPPING1U":"4029","MAPPING1F":"4029","MAPPING1N":"4029","MAPPING1H":"4029"},{"SYMBOLID":"O*O*RC----*****","DESCRIPTION":"Recruitment (Coerced/Impressed)","MAPPING1U":"4030","MAPPING1F":"4030","MAPPING1N":"4030","MAPPING1H":"4030"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Demonstration","MAPPING1U":"4031","MAPPING1F":"4031","MAPPING1N":"4031","MAPPING1H":"4031"},{"SYMBOLID":"O*O*M-----*****","DESCRIPTION":"Mine Laying","MAPPING1U":"4032","MAPPING1F":"4032","MAPPING1N":"4032","MAPPING1H":"4032"},{"SYMBOLID":"O*O*Y-----*****","DESCRIPTION":"Psychological Operations (Psyop)","MAPPING1U":"4033","MAPPING1F":"4033","MAPPING1N":"4033","MAPPING1H":"4033","MAPPING2":"4034","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YT----*****","DESCRIPTION":"Psyop (TV and Radio Propaganda)","MAPPING1U":"4035","MAPPING1F":"4036","MAPPING1N":"4037","MAPPING1H":"4038","MAPPING2":"4039","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YW----*****","DESCRIPTION":"Psyop (Written Propaganda)","MAPPING1U":"4043","MAPPING1F":"4043","MAPPING1N":"4043","MAPPING1H":"4043","MAPPING2":"4045","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*YH----*****","DESCRIPTION":"House-to-House Propaganda","MAPPING1U":"4044","MAPPING1F":"4044","MAPPING1N":"4044","MAPPING1H":"4044","MAPPING2":"4045","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*F-----*****","DESCRIPTION":"Foraging/Searching","MAPPING1U":"4046","MAPPING1F":"4046","MAPPING1N":"4046","MAPPING1H":"4046"},{"SYMBOLID":"O*O*S-----*****","DESCRIPTION":"Spy","MAPPING1U":"4047","MAPPING1F":"4047","MAPPING1N":"4047","MAPPING1H":"4047"},{"SYMBOLID":"O*O*O-----*****","DESCRIPTION":"Food Distribution","MAPPING1U":"4048","MAPPING1F":"4049","MAPPING1N":"4050","MAPPING1H":"4051"},{"SYMBOLID":"O*O*E-----*****","DESCRIPTION":"Extortion","MAPPING1U":"4052","MAPPING1F":"4052","MAPPING1N":"4052","MAPPING1H":"4052"},{"SYMBOLID":"O*O*H-----*****","DESCRIPTION":"Hijacking"},{"SYMBOLID":"O*O*HT----*****","DESCRIPTION":"Hijacking (Vehicle)","MAPPING1U":"4053","MAPPING1F":"4053","MAPPING1N":"4053","MAPPING1H":"4053"},{"SYMBOLID":"O*O*HA----*****","DESCRIPTION":"Hijacking (Airplane)","MAPPING1U":"4054","MAPPING1F":"4054","MAPPING1N":"4054","MAPPING1H":"4054","MAPPING2":"4055","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*HV----*****","DESCRIPTION":"Hijacking (Boat)","MAPPING1U":"4056","MAPPING1F":"4056","MAPPING1N":"4056","MAPPING1H":"4056","MAPPING2":"4057","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*K-----*****","DESCRIPTION":"Kidnapping","MAPPING1U":"4058","MAPPING1F":"4058","MAPPING1N":"4058","MAPPING1H":"4058"},{"SYMBOLID":"O*O*KA----*****","DESCRIPTION":"Attempted Kidnapping","MAPPING1U":"4059","MAPPING1F":"4059","MAPPING1N":"4059","MAPPING1H":"4059"},{"SYMBOLID":"O*O*A-----*****","DESCRIPTION":"Arrest","MAPPING1U":"4060","MAPPING1F":"4060","MAPPING1N":"4060","MAPPING1H":"4060"},{"SYMBOLID":"O*O*U-----*****","DESCRIPTION":"Drug Operation","MAPPING1U":"4061","MAPPING1F":"4061","MAPPING1N":"4061","MAPPING1H":"4061"},{"SYMBOLID":"O*O*UT----*****","DESCRIPTION":"Drug Trafficking","MAPPING1U":"4506","MAPPING1F":"4506","MAPPING1N":"4506","MAPPING1H":"4506"},{"SYMBOLID":"O*O*N-----*****","DESCRIPTION":"Raid on a House","MAPPING1U":"4500","MAPPING1F":"4500","MAPPING1N":"4500","MAPPING1H":"4500"},{"SYMBOLID":"O*O*2-----*****","DESCRIPTION":"Burglary","MAPPING1U":"4502","MAPPING1F":"4502","MAPPING1N":"4502","MAPPING1H":"4502"},{"SYMBOLID":"O*O*V-----*****","DESCRIPTION":"Home Eviction","MAPPING1U":"4514","MAPPING1F":"4514","MAPPING1N":"4514","MAPPING1H":"4514"},{"SYMBOLID":"O*O*I-----*****","DESCRIPTION":"Black Marketing","MAPPING1U":"4516","MAPPING1F":"4516","MAPPING1N":"4516","MAPPING1H":"4516"},{"SYMBOLID":"O*O*J-----*****","DESCRIPTION":"Jail Break","MAPPING1U":"4518","MAPPING1F":"4518","MAPPING1N":"4518","MAPPING1H":"4518","MAPPING2":"4519","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"O*O*B-----*****","DESCRIPTION":"Robbery","MAPPING1U":"4524","MAPPING1F":"4524","MAPPING1N":"4524","MAPPING1H":"4524"},{"SYMBOLID":"O*O*G-----*****","DESCRIPTION":"Sabotage","MAPPING1U":"4526","MAPPING1F":"4526","MAPPING1N":"4526","MAPPING1H":"4526"},{"SYMBOLID":"O*O*X-----*****","DESCRIPTION":"Smuggling","MAPPING1U":"4527","MAPPING1F":"4527","MAPPING1N":"4527","MAPPING1H":"4527"},{"SYMBOLID":"O*O*W-----*****","DESCRIPTION":"Rock Throwing","MAPPING1U":"4525","MAPPING1F":"4525","MAPPING1N":"4525","MAPPING1H":"4525"},{"SYMBOLID":"O*O*Z-----*****","DESCRIPTION":"Suspicious Activity","MAPPING1U":"4529","MAPPING1F":"4529","MAPPING1N":"4529","MAPPING1H":"4529"},{"SYMBOLID":"O*O*T-----*****","DESCRIPTION":"Theft","MAPPING1U":"4531","MAPPING1F":"4531","MAPPING1N":"4531","MAPPING1H":"4531"},{"SYMBOLID":"O*O*TV----*****","DESCRIPTION":"Wheeled Vehicle Theft","MAPPING1U":"4533","MAPPING1F":"4533","MAPPING1N":"4533","MAPPING1H":"4533"},{"SYMBOLID":"O*O*Q-----*****","DESCRIPTION":"Warrant Served","MAPPING1U":"4532","MAPPING1F":"4532","MAPPING1N":"4532","MAPPING1H":"4532"},{"SYMBOLID":"O*I*------*****","DESCRIPTION":"Items"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Refugees","MAPPING1U":"4066","MAPPING1F":"4066","MAPPING1N":"4066","MAPPING1H":"4066"},{"SYMBOLID":"O*I*S-----*****","DESCRIPTION":"Safe House","MAPPING1U":"4067","MAPPING1F":"4067","MAPPING1N":"4067","MAPPING1H":"4067"},{"SYMBOLID":"O*I*G-----*****","DESCRIPTION":"Graffiti","MAPPING1U":"4068","MAPPING1F":"4068","MAPPING1N":"4068","MAPPING1H":"4068"},{"SYMBOLID":"O*I*V-----*****","DESCRIPTION":"Vandalism/Loot/Ransack/Plunder/Sack","MAPPING1U":"4069","MAPPING1F":"4069","MAPPING1N":"4069","MAPPING1H":"4069"},{"SYMBOLID":"O*I*I-----*****","DESCRIPTION":"Known Insurgent Vehicle","MAPPING1U":"4070","MAPPING1F":"4070","MAPPING1N":"4070","MAPPING1H":"4070"},{"SYMBOLID":"O*I*D-----*****","DESCRIPTION":"Drug Vehicle","MAPPING1U":"4071","MAPPING1F":"4071","MAPPING1N":"4071","MAPPING1H":"4071"},{"SYMBOLID":"O*I*F-----*****","DESCRIPTION":"Internal Security Force","MAPPING1U":"4072","MAPPING1F":"4072","MAPPING1N":"4072","MAPPING1H":"4072"},{"SYMBOLID":"O*I*M-----*****","DESCRIPTION":"Meeting","MAPPING1U":"4520","MAPPING1F":"4520","MAPPING1N":"4520","MAPPING1H":"4520"},{"SYMBOLID":"O*I*T-----*****","DESCRIPTION":"Tent","MAPPING1U":"4530","MAPPING1F":"4530","MAPPING1N":"4530","MAPPING1H":"4530"},{"SYMBOLID":"O*P*------*****","DESCRIPTION":"Individual","MAPPING1U":"4073","MAPPING1F":"4073","MAPPING1N":"4073","MAPPING1H":"4073"},{"SYMBOLID":"O*P*A-----*****","DESCRIPTION":"Leader","MAPPING1U":"4074","MAPPING1F":"4074","MAPPING1N":"4074","MAPPING1H":"4074"},{"SYMBOLID":"O*P*AR----*****","DESCRIPTION":"Religious Leader","MAPPING1U":"4523","MAPPING1F":"4523","MAPPING1N":"4523","MAPPING1H":"4523"},{"SYMBOLID":"O*P*B-----*****","DESCRIPTION":"Targeted Individual","MAPPING1U":"4075","MAPPING1F":"4075","MAPPING1N":"4075","MAPPING1H":"4075"},{"SYMBOLID":"O*P*C-----*****","DESCRIPTION":"Terrorist","MAPPING1U":"4076","MAPPING1F":"4076","MAPPING1N":"4076","MAPPING1H":"4076"},{"SYMBOLID":"O*P*D-----*****","DESCRIPTION":"Dead Body","MAPPING1U":"4504","MAPPING1F":"4504","MAPPING1N":"4504","MAPPING1H":"4504"},{"SYMBOLID":"O*P*E-----*****","DESCRIPTION":"Speaker","MAPPING1U":"4528","MAPPING1F":"4528","MAPPING1N":"4528","MAPPING1H":"4528"},{"SYMBOLID":"O*P*F-----*****","DESCRIPTION":"IED Suicide Bomber","MAPPING1U":"4501","MAPPING1F":"4501","MAPPING1N":"4501","MAPPING1H":"4501"},{"SYMBOLID":"O*P*G-----*****","DESCRIPTION":"Exfiltrating Individual","MAPPING1U":"4507","MAPPING1F":"4507","MAPPING1N":"4507","MAPPING1H":"4507"},{"SYMBOLID":"O*P*H-----*****","DESCRIPTION":"Infiltrating Individual","MAPPING1U":"4517","MAPPING1F":"4517","MAPPING1N":"4517","MAPPING1H":"4517"},{"SYMBOLID":"O*G*------*****","DESCRIPTION":"Non-Military Group or Organization","MAPPING1U":"4077","MAPPING1F":"4077","MAPPING1N":"4077","MAPPING1H":"4077"},{"SYMBOLID":"O*G*B-----*****","DESCRIPTION":"Non-Governmental Organizations (NGO)","MAPPING1U":"4079","MAPPING1F":"4079","MAPPING1N":"4079","MAPPING1H":"4079"},{"SYMBOLID":"O*G*C-----*****","DESCRIPTION":"Terrorist Organization","MAPPING1U":"4080","MAPPING1F":"4080","MAPPING1N":"4080","MAPPING1H":"4080"},{"SYMBOLID":"O*G*D-----*****","DESCRIPTION":"Religious Organization","MAPPING1U":"4081","MAPPING1F":"4081","MAPPING1N":"4081","MAPPING1H":"4081"},{"SYMBOLID":"O*G*E-----*****","DESCRIPTION":"Foreign Fighter","MAPPING1U":"4082","MAPPING1F":"4082","MAPPING1N":"4082","MAPPING1H":"4082"},{"SYMBOLID":"O*G*F-----*****","DESCRIPTION":"Gang","MAPPING1U":"4083","MAPPING1F":"4083","MAPPING1N":"4083","MAPPING1H":"4083"},{"SYMBOLID":"O*R*------*****","DESCRIPTION":"Rape","MAPPING1U":"4084","MAPPING1F":"4084","MAPPING1N":"4084","MAPPING1H":"4084"},{"SYMBOLID":"O*R*A-----*****","DESCRIPTION":"Attempted Rape","MAPPING1U":"4085","MAPPING1F":"4085","MAPPING1N":"4085","MAPPING1H":"4085"},{"SYMBOLID":"O*E*------*****","DESCRIPTION":"Events SASO"},{"SYMBOLID":"O*E*A-----*****","DESCRIPTION":"Elections SASO","MAPPING1U":"9004","MAPPING1F":"9004","MAPPING1N":"9004","MAPPING1H":"9004"},{"SYMBOLID":"O*E*B-----*****","DESCRIPTION":"Speech SASO","MAPPING1U":"9005","MAPPING1F":"9005","MAPPING1N":"9005","MAPPING1H":"9005"},{"SYMBOLID":"O*E*C-----*****","DESCRIPTION":"Sermon SASO","MAPPING1U":"9006","MAPPING1F":"9006","MAPPING1N":"9006","MAPPING1H":"9006"},{"SYMBOLID":"O*E*D-----*****","DESCRIPTION":"Meeting SASO","MAPPING1U":"9007","MAPPING1F":"9007","MAPPING1N":"9007","MAPPING1H":"9007"},{"SYMBOLID":"O*E*E-----*****","DESCRIPTION":"Demonstration(Events) SASO","MAPPING1U":"9008","MAPPING1F":"9008","MAPPING1N":"9008","MAPPING1H":"9008"},{"SYMBOLID":"O*E*F-----*****","DESCRIPTION":"Riot SASO","MAPPING1U":"9009","MAPPING1F":"9009","MAPPING1N":"9009","MAPPING1H":"9009"},{"SYMBOLID":"O*E*G-----*****","DESCRIPTION":"Gang Activity SASO","MAPPING1U":"9010","MAPPING1F":"9010","MAPPING1N":"9010","MAPPING1H":"9010"},{"SYMBOLID":"O*E*H-----*****","DESCRIPTION":"Jail Break/Escape Custody SASO","MAPPING1U":"9011","MAPPING1F":"9011","MAPPING1N":"9011","MAPPING1H":"9011"},{"SYMBOLID":"O*E*I-----*****","DESCRIPTION":"Rock Throwing SASO","MAPPING1U":"9012","MAPPING1F":"9012","MAPPING1N":"9012","MAPPING1H":"9012"},{"SYMBOLID":"O*E*J-----*****","DESCRIPTION":"Illegal Selling/Purchasing/Distributing/Black Market SASO","MAPPING1U":"9013","MAPPING1F":"9013","MAPPING1N":"9013","MAPPING1H":"9013"},{"SYMBOLID":"O*E*K-----*****","DESCRIPTION":"Surveillance SASO","MAPPING1U":"9014","MAPPING1F":"9014","MAPPING1N":"9014","MAPPING1H":"9014"},{"SYMBOLID":"O*E*L-----*****","DESCRIPTION":"Lights SASO","MAPPING1U":"9015","MAPPING1F":"9015","MAPPING1N":"9015","MAPPING1H":"9015"},{"SYMBOLID":"O*E*M-----*****","DESCRIPTION":"Border Crossing SASO","MAPPING1U":"9016","MAPPING1F":"9016","MAPPING1N":"9016","MAPPING1H":"9016"},{"SYMBOLID":"O*E*N-----*****","DESCRIPTION":"Border Activity SASO","MAPPING1U":"9017","MAPPING1F":"9017","MAPPING1N":"9017","MAPPING1H":"9017"},{"SYMBOLID":"O*E*O-----*****","DESCRIPTION":"Smuggling SASO","MAPPING1U":"9018","MAPPING1F":"9018","MAPPING1N":"9018","MAPPING1H":"9018"},{"SYMBOLID":"O*E*P-----*****","DESCRIPTION":"Exfiltration SASO","MAPPING1U":"9019","MAPPING1F":"9019","MAPPING1N":"9019","MAPPING1H":"9019"},{"SYMBOLID":"O*E*Q-----*****","DESCRIPTION":"Infiltration SASO","MAPPING1U":"9020","MAPPING1F":"9020","MAPPING1N":"9020","MAPPING1H":"9020"},{"SYMBOLID":"O*E*R-----*****","DESCRIPTION":"Auto Theft SASO","MAPPING1U":"9021","MAPPING1F":"9021","MAPPING1N":"9021","MAPPING1H":"9021"},{"SYMBOLID":"O*E*S-----*****","DESCRIPTION":"Auto Accident SASO","MAPPING1U":"9022","MAPPING1F":"9022","MAPPING1N":"9022","MAPPING1H":"9022"},{"SYMBOLID":"O*E*T-----*****","DESCRIPTION":"Looting SASO","MAPPING1U":"9023","MAPPING1F":"9023","MAPPING1N":"9023","MAPPING1H":"9023"},{"SYMBOLID":"O*E*U-----*****","DESCRIPTION":"Theft SASO","MAPPING1U":"9024","MAPPING1F":"9024","MAPPING1N":"9024","MAPPING1H":"9024"},{"SYMBOLID":"O*E*V-----*****","DESCRIPTION":"Robbery SASO","MAPPING1U":"9025","MAPPING1F":"9025","MAPPING1N":"9025","MAPPING1H":"9025"},{"SYMBOLID":"O*E*W-----*****","DESCRIPTION":"Home Eviction SASO","MAPPING1U":"9026","MAPPING1F":"9026","MAPPING1N":"9026","MAPPING1H":"9026"},{"SYMBOLID":"O*E*X-----*****","DESCRIPTION":"Shooting (Non Deadly) SASO","MAPPING1U":"9027","MAPPING1F":"9027","MAPPING1N":"9027","MAPPING1H":"9027"},{"SYMBOLID":"O*E*Y-----*****","DESCRIPTION":"Raid SASO","MAPPING1U":"9028","MAPPING1F":"9028","MAPPING1N":"9028","MAPPING1H":"9028"},{"SYMBOLID":"O*E*Z-----*****","DESCRIPTION":"Sabotage SASO","MAPPING1U":"9029","MAPPING1F":"9029","MAPPING1N":"9029","MAPPING1H":"9029"},{"SYMBOLID":"O*E*AA----*****","DESCRIPTION":"Warrant Served SASO","MAPPING1U":"9030","MAPPING1F":"9030","MAPPING1N":"9030","MAPPING1H":"9030"},{"SYMBOLID":"O*E*AB----*****","DESCRIPTION":"Rape SASO","MAPPING1U":"9031","MAPPING1F":"9031","MAPPING1N":"9031","MAPPING1H":"9031"},{"SYMBOLID":"O*E*AC----*****","DESCRIPTION":"Attempted Rape SASO","MAPPING1U":"9032","MAPPING1F":"9032","MAPPING1N":"9032","MAPPING1H":"9032"},{"SYMBOLID":"O*E*AD----*****","DESCRIPTION":"Attack(Events) SASO"},{"SYMBOLID":"O*E*ADA---*****","DESCRIPTION":"Attack on NGO SASO","MAPPING1U":"9033","MAPPING1F":"9033","MAPPING1N":"9033","MAPPING1H":"9033"},{"SYMBOLID":"O*E*ADB---*****","DESCRIPTION":"Terrorist Attack SASO","MAPPING1U":"9034","MAPPING1F":"9034","MAPPING1N":"9034","MAPPING1H":"9034"},{"SYMBOLID":"O*E*ADC---*****","DESCRIPTION":"Grenade Attack SASO","MAPPING1U":"9035","MAPPING1F":"9035","MAPPING1N":"9035","MAPPING1H":"9035"},{"SYMBOLID":"O*E*ADD---*****","DESCRIPTION":"Rocket Attack SASO","MAPPING1U":"9036","MAPPING1F":"9036","MAPPING1N":"9036","MAPPING1H":"9036"},{"SYMBOLID":"O*E*AE----*****","DESCRIPTION":"Explosions SASO"},{"SYMBOLID":"O*E*AEA---*****","DESCRIPTION":"Explosion (general) SASO","MAPPING1U":"9037","MAPPING1F":"9037","MAPPING1N":"9037","MAPPING1H":"9037"},{"SYMBOLID":"O*E*AEB---*****","DESCRIPTION":"Explosion, Mine SASO","MAPPING1U":"9038","MAPPING1F":"9038","MAPPING1N":"9038","MAPPING1H":"9038"},{"SYMBOLID":"O*E*AEC---*****","DESCRIPTION":"Explosion, Grenade SASO","MAPPING1U":"9039","MAPPING1F":"9039","MAPPING1N":"9039","MAPPING1H":"9039"},{"SYMBOLID":"O*E*AED---*****","DESCRIPTION":"Explosion, Bomb SASO","MAPPING1U":"9040","MAPPING1F":"9040","MAPPING1N":"9040","MAPPING1H":"9040"},{"SYMBOLID":"O*E*AEE---*****","DESCRIPTION":"Explosion, Mortar Fire SASO","MAPPING1U":"9041","MAPPING1F":"9041","MAPPING1N":"9041","MAPPING1H":"9041"},{"SYMBOLID":"O*E*AEF---*****","DESCRIPTION":"Explosion, Incendiary SASO","MAPPING1U":"9042","MAPPING1F":"9042","MAPPING1N":"9042","MAPPING1H":"9042"},{"SYMBOLID":"O*E*AEG---*****","DESCRIPTION":"Explosion, Rocket SASO","MAPPING1U":"9043","MAPPING1F":"9043","MAPPING1N":"9043","MAPPING1H":"9043"},{"SYMBOLID":"O*E*AEH---*****","DESCRIPTION":"Explosion, Improvised Explosive Device (IED) SASO","MAPPING1U":"9044","MAPPING1F":"9044","MAPPING1N":"9044","MAPPING1H":"9044"},{"SYMBOLID":"O*E*AEI---*****","DESCRIPTION":"Explosion, Car Bomb SASO","MAPPING1U":"9045","MAPPING1F":"9045","MAPPING1N":"9045","MAPPING1H":"9045"},{"SYMBOLID":"O*E*AEJ---*****","DESCRIPTION":"Suicide Bombing SASO","MAPPING1U":"9046","MAPPING1F":"9046","MAPPING1N":"9046","MAPPING1H":"9046"},{"SYMBOLID":"O*E*AF----*****","DESCRIPTION":"Fighting/Contact SASO"},{"SYMBOLID":"O*E*AFA---*****","DESCRIPTION":"Fighting (General) SASO","MAPPING1U":"9047","MAPPING1F":"9047","MAPPING1N":"9047","MAPPING1H":"9047"},{"SYMBOLID":"O*E*AFB---*****","DESCRIPTION":"Coalition vs. Enemy SASO","MAPPING1U":"9048","MAPPING1F":"9048","MAPPING1N":"9048","MAPPING1H":"9048"},{"SYMBOLID":"O*E*AFC---*****","DESCRIPTION":"Coalition vs. Coalition SASO","MAPPING1U":"9049","MAPPING1F":"9049","MAPPING1N":"9049","MAPPING1H":"9049"},{"SYMBOLID":"O*E*AG----*****","DESCRIPTION":"Drug Possession SASO","MAPPING1U":"9050","MAPPING1F":"9050","MAPPING1N":"9050","MAPPING1H":"9050"},{"SYMBOLID":"O*E*AH----*****","DESCRIPTION":"Drug Trafficking SASO","MAPPING1U":"9051","MAPPING1F":"9051","MAPPING1N":"9051","MAPPING1H":"9051"},{"SYMBOLID":"O*E*AI----*****","DESCRIPTION":"Suspicious Activity SASO","MAPPING1U":"9052","MAPPING1F":"9052","MAPPING1N":"9052","MAPPING1H":"9052"},{"SYMBOLID":"O*E*AJ----*****","DESCRIPTION":"Activity SASO","MAPPING1U":"9053","MAPPING1F":"9053","MAPPING1N":"9053","MAPPING1H":"9053"},{"SYMBOLID":"O*E*AK----*****","DESCRIPTION":"Threat SASO","MAPPING1U":"9054","MAPPING1F":"9054","MAPPING1N":"9054","MAPPING1H":"9054"},{"SYMBOLID":"O*E*AL----*****","DESCRIPTION":"Crater SASO","MAPPING1U":"9055","MAPPING1F":"9055","MAPPING1N":"9055","MAPPING1H":"9055"},{"SYMBOLID":"O*E*AM----*****","DESCRIPTION":"Pothole SASO","MAPPING1U":"9056","MAPPING1F":"9057","MAPPING1N":"9058","MAPPING1H":"9059"},{"SYMBOLID":"O*E*AN----*****","DESCRIPTION":"Escalation of Force SASO","MAPPING1U":"9060","MAPPING1F":"9061","MAPPING1N":"9062","MAPPING1H":"9063"},{"SYMBOLID":"O*E*AO----*****","DESCRIPTION":"Submunitions SASO","MAPPING1U":"9064","MAPPING1F":"9064","MAPPING1N":"9064","MAPPING1H":"9064"},{"SYMBOLID":"O*E*AP----*****","DESCRIPTION":"Confiscation SASO","MAPPING1U":"9065","MAPPING1F":"9066","MAPPING1N":"9067","MAPPING1H":"9068"},{"SYMBOLID":"O*E*AQ----*****","DESCRIPTION":"Counter Insurgency SASO","MAPPING1U":"9069","MAPPING1F":"9070","MAPPING1N":"9071","MAPPING1H":"9072"},{"SYMBOLID":"O*E*AR----*****","DESCRIPTION":"Counter Terrorism SASO","MAPPING1U":"9073","MAPPING1F":"9074","MAPPING1N":"9075","MAPPING1H":"9076"},{"SYMBOLID":"O*E*AS----*****","DESCRIPTION":"Humanitarian Assistance SASO","MAPPING1U":"9077","MAPPING1F":"9078","MAPPING1N":"9079","MAPPING1H":"9080"},{"SYMBOLID":"O*E*AT----*****","DESCRIPTION":"Tests of Security SASO","MAPPING1U":"9081","MAPPING1F":"9082","MAPPING1N":"9083","MAPPING1H":"9084"},{"SYMBOLID":"O*E*AU----*****","DESCRIPTION":"AWOL SASO","MAPPING1U":"9085","MAPPING1F":"9085","MAPPING1N":"9085","MAPPING1H":"9085"},{"SYMBOLID":"O*E*AV----*****","DESCRIPTION":"Curfew SASO","MAPPING1U":"9086","MAPPING1F":"9086","MAPPING1N":"9086","MAPPING1H":"9086"},{"SYMBOLID":"O*E*AW----*****","DESCRIPTION":"DUI SASO","MAPPING1U":"9087","MAPPING1F":"9087","MAPPING1N":"9087","MAPPING1H":"9087"},{"SYMBOLID":"O*E*AX----*****","DESCRIPTION":"Prostitution SASO","MAPPING1U":"9088","MAPPING1F":"9088","MAPPING1N":"9088","MAPPING1H":"9088"},{"SYMBOLID":"O*Y*------*****","DESCRIPTION":"Organization/Groups SASO"},{"SYMBOLID":"O*Y*A-----*****","DESCRIPTION":"Organization (General) SASO","MAPPING1U":"9089","MAPPING1F":"9089","MAPPING1N":"9089","MAPPING1H":"9089"},{"SYMBOLID":"O*Y*B-----*****","DESCRIPTION":"NGO Organization SASO","MAPPING1U":"9090","MAPPING1F":"9090","MAPPING1N":"9090","MAPPING1H":"9090"},{"SYMBOLID":"O*Y*C-----*****","DESCRIPTION":"Displaced Persons, Refugees SASO","MAPPING1U":"9091","MAPPING1F":"9091","MAPPING1N":"9091","MAPPING1H":"9091"},{"SYMBOLID":"O*Y*D-----*****","DESCRIPTION":"Terrorist Organization SASO","MAPPING1U":"9092","MAPPING1F":"9092","MAPPING1N":"9092","MAPPING1H":"9092"},{"SYMBOLID":"O*Y*E-----*****","DESCRIPTION":"Religious Organization SASO","MAPPING1U":"9093","MAPPING1F":"9093","MAPPING1N":"9093","MAPPING1H":"9093"},{"SYMBOLID":"O*Y*F-----*****","DESCRIPTION":"Group Tribe Cell SASO","MAPPING1U":"9094","MAPPING1F":"9094","MAPPING1N":"9094","MAPPING1H":"9094"},{"SYMBOLID":"O*Y*G-----*****","DESCRIPTION":"Foreign Fighters SASO","MAPPING1U":"9095","MAPPING1F":"9095","MAPPING1N":"9095","MAPPING1H":"9095"},{"SYMBOLID":"O*Y*R-----*****","DESCRIPTION":"Red Cross SASO"},{"SYMBOLID":"O*Y*SP----*****","DESCRIPTION":"State Police SASO"},{"SYMBOLID":"O*Y*LP----*****","DESCRIPTION":"Local Police SASO"},{"SYMBOLID":"O*Y*SH----*****","DESCRIPTION":"Shelter SASO"},{"SYMBOLID":"O*Y*FM----*****","DESCRIPTION":"FEMA SASO"},{"SYMBOLID":"O*Y*SA----*****","DESCRIPTION":"Staging Area SASO"},{"SYMBOLID":"O*Y*EP----*****","DESCRIPTION":"Evacuation Point SASO"},{"SYMBOLID":"O*Y*PD----*****","DESCRIPTION":"Person in Distress SASO"},{"SYMBOLID":"O*S*------*****","DESCRIPTION":"Structures SASO"},{"SYMBOLID":"O*S*A-----*****","DESCRIPTION":"Compound/Post/Fort SASO","MAPPING1U":"9103","MAPPING1F":"9103","MAPPING1N":"9103","MAPPING1H":"9103"},{"SYMBOLID":"O*S*B-----*****","DESCRIPTION":"House/Residence SASO","MAPPING1U":"9104","MAPPING1F":"9104","MAPPING1N":"9104","MAPPING1H":"9104"},{"SYMBOLID":"O*S*C-----*****","DESCRIPTION":"Safe House(Structures) SASO","MAPPING1U":"9105","MAPPING1F":"9105","MAPPING1N":"9105","MAPPING1H":"9105"},{"SYMBOLID":"O*S*D-----*****","DESCRIPTION":"Church SASO","MAPPING1U":"9106","MAPPING1F":"9106","MAPPING1N":"9106","MAPPING1H":"9106"},{"SYMBOLID":"O*S*E-----*****","DESCRIPTION":"Mosque SASO","MAPPING1U":"9107","MAPPING1F":"9107","MAPPING1N":"9107","MAPPING1H":"9107"},{"SYMBOLID":"O*S*F-----*****","DESCRIPTION":"Synagogue SASO","MAPPING1U":"9108","MAPPING1F":"9108","MAPPING1N":"9108","MAPPING1H":"9108"},{"SYMBOLID":"O*S*G-----*****","DESCRIPTION":"Warehouse/Storage Facility SASO","MAPPING1U":"9109","MAPPING1F":"9109","MAPPING1N":"9109","MAPPING1H":"9109"},{"SYMBOLID":"O*S*H-----*****","DESCRIPTION":"Bunker/Underground Facility SASO","MAPPING1U":"9110","MAPPING1F":"9110","MAPPING1N":"9110","MAPPING1H":"9110"},{"SYMBOLID":"O*S*I-----*****","DESCRIPTION":"Tents SASO","MAPPING1U":"9111","MAPPING1F":"9111","MAPPING1N":"9111","MAPPING1H":"9111"},{"SYMBOLID":"O*S*J-----*****","DESCRIPTION":"Cave SASO","MAPPING1U":"9112","MAPPING1F":"9112","MAPPING1N":"9112","MAPPING1H":"9112"},{"SYMBOLID":"O*S*K-----*****","DESCRIPTION":"Camps SASO"},{"SYMBOLID":"O*S*KA----*****","DESCRIPTION":"Camp (General) SASO","MAPPING1U":"9114","MAPPING1F":"9114","MAPPING1N":"9114","MAPPING1H":"9114"},{"SYMBOLID":"O*S*KB----*****","DESCRIPTION":"Displaced Persons/Refugees Camp SASO","MAPPING1U":"9115","MAPPING1F":"9115","MAPPING1N":"9115","MAPPING1H":"9115"},{"SYMBOLID":"O*S*KC----*****","DESCRIPTION":"Training Camp SASO","MAPPING1U":"9116","MAPPING1F":"9116","MAPPING1N":"9116","MAPPING1H":"9116"},{"SYMBOLID":"O*S*L-----*****","DESCRIPTION":"Prison/Detention Facility SASO","MAPPING1U":"9117","MAPPING1F":"9117","MAPPING1N":"9117","MAPPING1H":"9117"},{"SYMBOLID":"O*S*M-----*****","DESCRIPTION":"Police Station SASO","MAPPING1U":"9118","MAPPING1F":"9118","MAPPING1N":"9118","MAPPING1H":"9118"},{"SYMBOLID":"O*S*N-----*****","DESCRIPTION":"Palace/Presidential Residence SASO","MAPPING1U":"9119","MAPPING1F":"9119","MAPPING1N":"9119","MAPPING1H":"9119"},{"SYMBOLID":"O*Q*------*****","DESCRIPTION":"Equipment/Weapons SASO"},{"SYMBOLID":"O*Q*A-----*****","DESCRIPTION":"Weapons Found SASO","MAPPING1U":"9121","MAPPING1F":"9121","MAPPING1N":"9121","MAPPING1H":"9121"},{"SYMBOLID":"O*Q*B-----*****","DESCRIPTION":"Weapons Cache SASO","MAPPING1U":"9122","MAPPING1F":"9122","MAPPING1N":"9122","MAPPING1H":"9122"},{"SYMBOLID":"O*Q*C-----*****","DESCRIPTION":"Weapons Confiscated SASO","MAPPING1U":"9123","MAPPING1F":"9123","MAPPING1N":"9123","MAPPING1H":"9123"},{"SYMBOLID":"O*Q*D-----*****","DESCRIPTION":"Weapons Sale SASO","MAPPING1U":"9124","MAPPING1F":"9124","MAPPING1N":"9124","MAPPING1H":"9124"},{"SYMBOLID":"O*Q*E-----*****","DESCRIPTION":"Weapons Market SASO","MAPPING1U":"9125","MAPPING1F":"9125","MAPPING1N":"9125","MAPPING1H":"9125"},{"SYMBOLID":"O*Q*F-----*****","DESCRIPTION":"Chem/Bio Weapons Cache SASO","MAPPING1U":"9126","MAPPING1F":"9126","MAPPING1N":"9126","MAPPING1H":"9126"},{"SYMBOLID":"O*Q*G-----*****","DESCRIPTION":"Improvised Explosive Device (IED) SASO","MAPPING1U":"9127","MAPPING1F":"9127","MAPPING1N":"9127","MAPPING1H":"9127"},{"SYMBOLID":"O*Q*H-----*****","DESCRIPTION":"Unexploded Ordnance (UXO) SASO","MAPPING1U":"9128","MAPPING1F":"9128","MAPPING1N":"9128","MAPPING1H":"9128"},{"SYMBOLID":"O*Q*I-----*****","DESCRIPTION":"Horses SASO","MAPPING1U":"9129","MAPPING1F":"9129","MAPPING1N":"9129","MAPPING1H":"9129"},{"SYMBOLID":"O*Q*J-----*****","DESCRIPTION":"Camels SASO","MAPPING1U":"9130","MAPPING1F":"9130","MAPPING1N":"9130","MAPPING1H":"9130"},{"SYMBOLID":"O*Q*K-----*****","DESCRIPTION":"Donkeys SASO","MAPPING1U":"9131","MAPPING1F":"9131","MAPPING1N":"9131","MAPPING1H":"9131"},{"SYMBOLID":"E*-*------*****","DESCRIPTION":"Emergency Management Symbols"},{"SYMBOLID":"E*I*------*****","DESCRIPTION":"Incident"},{"SYMBOLID":"E*I*A-----*****","DESCRIPTION":"Civil Disturbance Incident","MAPPING1U":"5000","MAPPING1F":"5000","MAPPING1N":"5000","MAPPING1H":"5000"},{"SYMBOLID":"E*I*AC----*****","DESCRIPTION":"Civil Rioting","MAPPING1U":"5001","MAPPING1F":"5001","MAPPING1N":"5001","MAPPING1H":"5001"},{"SYMBOLID":"E*I*B-----*****","DESCRIPTION":"Criminal Activity Incident","MAPPING1U":"5002","MAPPING1F":"5002","MAPPING1N":"5002","MAPPING1H":"5002"},{"SYMBOLID":"E*I*BA----*****","DESCRIPTION":"Bomb Threat","MAPPING1U":"5003","MAPPING1F":"5003","MAPPING1N":"5003","MAPPING1H":"5003"},{"SYMBOLID":"E*I*BC----*****","DESCRIPTION":"Explosion (Bomb)","MAPPING1U":"5004","MAPPING1F":"5004","MAPPING1N":"5004","MAPPING1H":"5004"},{"SYMBOLID":"E*I*BD----*****","DESCRIPTION":"Looting","MAPPING1U":"5005","MAPPING1F":"5005","MAPPING1N":"5005","MAPPING1H":"5005"},{"SYMBOLID":"E*I*BF----*****","DESCRIPTION":"Shooting","MAPPING1U":"5006","MAPPING1F":"5006","MAPPING1N":"5006","MAPPING1H":"5006"},{"SYMBOLID":"E*I*C-----*****","DESCRIPTION":"Fire Incident","MAPPING1U":"5007","MAPPING1F":"5007","MAPPING1N":"5007","MAPPING1H":"5007"},{"SYMBOLID":"E*I*CA----*****","DESCRIPTION":"Hot Spot","MAPPING1U":"5008","MAPPING1F":"5008","MAPPING1N":"5008","MAPPING1H":"5008","MAPPING1COLOR":"000000","MAPPING2":"5009","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*CB----*****","DESCRIPTION":"Non-Residential Fire","MAPPING1U":"5010","MAPPING1F":"5010","MAPPING1N":"5010","MAPPING1H":"5010"},{"SYMBOLID":"E*I*CC----*****","DESCRIPTION":"Origin","MAPPING1U":"5011","MAPPING1F":"5011","MAPPING1N":"5011","MAPPING1H":"5011","MAPPING1COLOR":"000000","MAPPING2":"5012","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*CD----*****","DESCRIPTION":"Residential Fire","MAPPING1U":"5013","MAPPING1F":"5013","MAPPING1N":"5013","MAPPING1H":"5013"},{"SYMBOLID":"E*I*CE----*****","DESCRIPTION":"School Fire","MAPPING1U":"5014","MAPPING1F":"5014","MAPPING1N":"5014","MAPPING1H":"5014"},{"SYMBOLID":"E*I*CF----*****","DESCRIPTION":"Smoke","MAPPING1U":"5015","MAPPING1F":"5015","MAPPING1N":"5015","MAPPING1H":"5015"},{"SYMBOLID":"E*I*CG----*****","DESCRIPTION":"Special Needs Fire","MAPPING1U":"5016","MAPPING1F":"5016","MAPPING1N":"5016","MAPPING1H":"5016"},{"SYMBOLID":"E*I*CH----*****","DESCRIPTION":"Wild Fire","MAPPING1U":"5017","MAPPING1F":"5017","MAPPING1N":"5017","MAPPING1H":"5017"},{"SYMBOLID":"E*I*D-----*****","DESCRIPTION":"Hazardous Material Incident","MAPPING1U":"5018","MAPPING1F":"5018","MAPPING1N":"5018","MAPPING1H":"5018","MAPPING1COLOR":"000000","MAPPING2":"5019","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DA----*****","DESCRIPTION":"Chemical Agent","MAPPING1U":"5020","MAPPING1F":"5020","MAPPING1N":"5020","MAPPING1H":"5020","MAPPING1COLOR":"000000","MAPPING2":"5021","MAPPING2COLOR":"FFFF00"},{"SYMBOLID":"E*I*DB----*****","DESCRIPTION":"Corrosive Material","MAPPING1U":"5022","MAPPING1F":"5022","MAPPING1N":"5022","MAPPING1H":"5022"},{"SYMBOLID":"E*I*DC----*****","DESCRIPTION":"Hazardous When Wet","MAPPING1U":"5023","MAPPING1F":"5023","MAPPING1N":"5023","MAPPING1H":"5023","MAPPING1COLOR":"000000","MAPPING2":"5024","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DD----*****","DESCRIPTION":"Explosive","MAPPING1U":"5025","MAPPING1F":"5025","MAPPING1N":"5025","MAPPING1H":"5025","MAPPING1COLOR":"000000","MAPPING2":"5026","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DE----*****","DESCRIPTION":"Flammable Gas","MAPPING1U":"5027","MAPPING1F":"5027","MAPPING1N":"5027","MAPPING1H":"5027","MAPPING1COLOR":"000000","MAPPING2":"5028","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DF----*****","DESCRIPTION":"Flammable Liquid","MAPPING1U":"5029","MAPPING1F":"5029","MAPPING1N":"5029","MAPPING1H":"5029","MAPPING1COLOR":"000000","MAPPING2":"5030","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DG----*****","DESCRIPTION":"Flammable Solid","MAPPING1U":"5031","MAPPING1F":"5031","MAPPING1N":"5031","MAPPING1H":"5031","MAPPING1COLOR":"000000","MAPPING2":"5032","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DH----*****","DESCRIPTION":"Non-Flammable Gas","MAPPING1U":"5033","MAPPING1F":"5033","MAPPING1N":"5033","MAPPING1H":"5033","MAPPING1COLOR":"000000","MAPPING2":"5034","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DI----*****","DESCRIPTION":"Organic Peroxide","MAPPING1U":"5035","MAPPING1F":"5035","MAPPING1N":"5035","MAPPING1H":"5035","MAPPING1COLOR":"000000","MAPPING2":"5036","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DJ----*****","DESCRIPTION":"Oxidizer","MAPPING1U":"5037","MAPPING1F":"5037","MAPPING1N":"5037","MAPPING1H":"5037","MAPPING1COLOR":"000000","MAPPING2":"5038","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DK----*****","DESCRIPTION":"Radioactive Material","MAPPING1U":"5039","MAPPING1F":"5039","MAPPING1N":"5039","MAPPING1H":"5039"},{"SYMBOLID":"E*I*DL----*****","DESCRIPTION":"Spontaneously Combustible","MAPPING1U":"5040","MAPPING1F":"5040","MAPPING1N":"5040","MAPPING1H":"5040"},{"SYMBOLID":"E*I*DM----*****","DESCRIPTION":"Toxic Gas","MAPPING1U":"5041","MAPPING1F":"5041","MAPPING1N":"5041","MAPPING1H":"5041","MAPPING1COLOR":"000000","MAPPING2":"5042","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*DN----*****","DESCRIPTION":"Toxic and Infectious","MAPPING1U":"5043","MAPPING1F":"5043","MAPPING1N":"5043","MAPPING1H":"5043"},{"SYMBOLID":"E*I*DO----*****","DESCRIPTION":"Unexploded Ordinance","MAPPING1U":"5044","MAPPING1F":"5044","MAPPING1N":"5044","MAPPING1H":"5044"},{"SYMBOLID":"E*I*E-----*****","DESCRIPTION":"Air Incident","MAPPING1U":"5045","MAPPING1F":"5045","MAPPING1N":"5045","MAPPING1H":"5045","MAPPING1COLOR":"000000","MAPPING2":"5046","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*EA----*****","DESCRIPTION":"Air Accident","MAPPING1U":"5047","MAPPING1F":"5047","MAPPING1N":"5047","MAPPING1H":"5047","MAPPING1COLOR":"000000","MAPPING2":"5048","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*F-----*****","DESCRIPTION":"Marine Incident","MAPPING1U":"5051","MAPPING1F":"5051","MAPPING1N":"5051","MAPPING1H":"5051","MAPPING1COLOR":"000000","MAPPING2":"5052","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*FA----*****","DESCRIPTION":"Marine Accident","MAPPING1U":"5053","MAPPING1F":"5053","MAPPING1N":"5053","MAPPING1H":"5053","MAPPING1COLOR":"000000","MAPPING2":"5054","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*I*G-----*****","DESCRIPTION":"Rail Incident","MAPPING1U":"5057","MAPPING1F":"5057","MAPPING1N":"5057","MAPPING1H":"5057","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*I*GA----*****","DESCRIPTION":"Rail Accident","MAPPING1U":"5058","MAPPING1F":"5058","MAPPING1N":"5058","MAPPING1H":"5058","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*I*GB----*****","DESCRIPTION":"Rail Hijacking","MAPPING1U":"5059","MAPPING1F":"5059","MAPPING1N":"5059","MAPPING1H":"5059","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*I*H-----*****","DESCRIPTION":"Vehicle Incident","MAPPING1U":"5060","MAPPING1F":"5060","MAPPING1N":"5060","MAPPING1H":"5060","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*I*HA----*****","DESCRIPTION":"Vehicle Accident","MAPPING1U":"5061","MAPPING1F":"5061","MAPPING1N":"5061","MAPPING1H":"5061","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*N*------*****","DESCRIPTION":"Natural Events"},{"SYMBOLID":"E*O*------*****","DESCRIPTION":"Operations"},{"SYMBOLID":"E*O*A-----*****","DESCRIPTION":"Emergency Medical Operation","MAPPING1U":"5200","MAPPING1F":"5200","MAPPING1N":"5200","MAPPING1H":"5200"},{"SYMBOLID":"E*O*AA----*****","DESCRIPTION":"Emergency Medical Operation Unit","MAPPING1U":"5200","MAPPING1F":"5200","MAPPING1N":"5200","MAPPING1H":"5200"},{"SYMBOLID":"E*O*AB----*****","DESCRIPTION":"Emergency Medical Operation Equipment","MAPPING1U":"5200","MAPPING1F":"5200","MAPPING1N":"5200","MAPPING1H":"5200"},{"SYMBOLID":"E*O*AC----*****","DESCRIPTION":"Emergency Medical Operation Installation","MAPPING1U":"5200","MAPPING1F":"5200","MAPPING1N":"5200","MAPPING1H":"5200"},{"SYMBOLID":"E*O*AD----*****","DESCRIPTION":"EMT Station Location","MAPPING1U":"5200","MAPPING1F":"5200","MAPPING1N":"5200","MAPPING1H":"5200"},{"SYMBOLID":"E*O*AE----*****","DESCRIPTION":"Ambulance","MAPPING1U":"5201","MAPPING1F":"5201","MAPPING1N":"5201","MAPPING1H":"5201","MAPPING1COLOR":"000000","MAPPING2":"5202","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*AF----*****","DESCRIPTION":"Medical Evacuation Helicopter","MAPPING1U":"5203","MAPPING1F":"5203","MAPPING1N":"5203","MAPPING1H":"5203","MAPPING1COLOR":"000000","MAPPING2":"5204","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*AG----*****","DESCRIPTION":"Health Department Facility","MAPPING1U":"5205","MAPPING1F":"5205","MAPPING1N":"5205","MAPPING1H":"5205"},{"SYMBOLID":"E*O*AJ----*****","DESCRIPTION":"Medical Facilities Out Patient","MAPPING1U":"5206","MAPPING1F":"5206","MAPPING1N":"5206","MAPPING1H":"5206","MAPPING1COLOR":"000000","MAPPING2":"5207","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*AK----*****","DESCRIPTION":"Morgue","MAPPING1U":"5208","MAPPING1F":"5208","MAPPING1N":"5208","MAPPING1H":"5208","MAPPING1COLOR":"000000","MAPPING2":"5209","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*AL----*****","DESCRIPTION":"Pharmacy","MAPPING1U":"5210","MAPPING1F":"5210","MAPPING1N":"5210","MAPPING1H":"5210"},{"SYMBOLID":"E*O*AM----*****","DESCRIPTION":"Triage","MAPPING1U":"5211","MAPPING1F":"5211","MAPPING1N":"5211","MAPPING1H":"5211","MAPPING1COLOR":"000000","MAPPING2":"5212","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*B-----*****","DESCRIPTION":"Emergency Operation","MAPPING1U":"5213","MAPPING1F":"5213","MAPPING1N":"5213","MAPPING1H":"5213","MAPPING1COLOR":"000000","MAPPING2":"5214","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BA----*****","DESCRIPTION":"Emergency Operation Unit","MAPPING1U":"5213","MAPPING1F":"5213","MAPPING1N":"5213","MAPPING1H":"5213","MAPPING1COLOR":"000000","MAPPING2":"5214","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BB----*****","DESCRIPTION":"Emergency Operation Equipment","MAPPING1U":"5213","MAPPING1F":"5213","MAPPING1N":"5213","MAPPING1H":"5213","MAPPING1COLOR":"000000","MAPPING2":"5214","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BC----*****","DESCRIPTION":"Emergency Operation Installation","MAPPING1U":"5213","MAPPING1F":"5213","MAPPING1N":"5213","MAPPING1H":"5213","MAPPING1COLOR":"000000","MAPPING2":"5214","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BD----*****","DESCRIPTION":"Emergency Collection Evacuation Point","MAPPING1U":"5215","MAPPING1F":"5215","MAPPING1N":"5215","MAPPING1H":"5215","MAPPING1COLOR":"000000","MAPPING2":"5216","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BE----*****","DESCRIPTION":"Emergency Incident Command Center","MAPPING1U":"5217","MAPPING1F":"5217","MAPPING1N":"5217","MAPPING1H":"5217","MAPPING1COLOR":"000000","MAPPING2":"5218","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BF----*****","DESCRIPTION":"Emergency Operations Center","MAPPING1U":"5219","MAPPING1F":"5219","MAPPING1N":"5219","MAPPING1H":"5219","MAPPING1COLOR":"000000","MAPPING2":"5220","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BG----*****","DESCRIPTION":"Emergency Public Information Center","MAPPING1U":"5221","MAPPING1F":"5221","MAPPING1N":"5221","MAPPING1H":"5221","MAPPING1COLOR":"000000","MAPPING2":"5222","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BH----*****","DESCRIPTION":"Emergency Shelter","MAPPING1U":"5223","MAPPING1F":"5223","MAPPING1N":"5223","MAPPING1H":"5223","MAPPING1COLOR":"000000","MAPPING2":"5224","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BI----*****","DESCRIPTION":"Emergency Staging Area","MAPPING1U":"5225","MAPPING1F":"5225","MAPPING1N":"5225","MAPPING1H":"5225","MAPPING1COLOR":"000000","MAPPING2":"5226","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BJ----*****","DESCRIPTION":"Emergency Team","MAPPING1U":"5227","MAPPING1F":"5227","MAPPING1N":"5227","MAPPING1H":"5227","MAPPING1COLOR":"000000","MAPPING2":"5228","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*BK----*****","DESCRIPTION":"Emergency Water Distribution Center","MAPPING1U":"5229","MAPPING1F":"5230","MAPPING1N":"5231","MAPPING1H":"5232","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*O*BL----*****","DESCRIPTION":"Emergency Food Distribution Center","MAPPING1U":"5233","MAPPING1F":"5234","MAPPING1N":"5235","MAPPING1H":"5236","MAPPING1COLOR":"000000"},{"SYMBOLID":"E*O*C-----*****","DESCRIPTION":"Fire Fighting Operation","MAPPING1U":"5237","MAPPING1F":"5237","MAPPING1N":"5237","MAPPING1H":"5237"},{"SYMBOLID":"E*O*CA----*****","DESCRIPTION":"Fire Fighting Operation Unit","MAPPING1U":"5237","MAPPING1F":"5237","MAPPING1N":"5237","MAPPING1H":"5237"},{"SYMBOLID":"E*O*CB----*****","DESCRIPTION":"Fire Fighting Operation Equipment","MAPPING1U":"5237","MAPPING1F":"5237","MAPPING1N":"5237","MAPPING1H":"5237"},{"SYMBOLID":"E*O*CC----*****","DESCRIPTION":"Fire Hydrant","MAPPING1U":"5238","MAPPING1F":"5238","MAPPING1N":"5238","MAPPING1H":"5238","MAPPING1COLOR":"000000","MAPPING2":"5239","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*CD----*****","DESCRIPTION":"Other Water Supply Location","MAPPING1U":"5240","MAPPING1F":"5240","MAPPING1N":"5240","MAPPING1H":"5240","MAPPING1COLOR":"000000","MAPPING2":"5241","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*CE----*****","DESCRIPTION":"Fire Station","MAPPING1U":"5237","MAPPING1F":"5237","MAPPING1N":"5237","MAPPING1H":"5237"},{"SYMBOLID":"E*O*D-----*****","DESCRIPTION":"Law Enforcement Operation","MAPPING1U":"5242","MAPPING1F":"5242","MAPPING1N":"5242","MAPPING1H":"5242"},{"SYMBOLID":"E*O*DA----*****","DESCRIPTION":"Law Enforcement Operation Unit","MAPPING1U":"5242","MAPPING1F":"5242","MAPPING1N":"5242","MAPPING1H":"5242"},{"SYMBOLID":"E*O*DB----*****","DESCRIPTION":"Law Enforcement Operation Equipment","MAPPING1U":"5242","MAPPING1F":"5242","MAPPING1N":"5242","MAPPING1H":"5242"},{"SYMBOLID":"E*O*DC----*****","DESCRIPTION":"Law Enforcement Operation Installation","MAPPING1U":"5242","MAPPING1F":"5242","MAPPING1N":"5242","MAPPING1H":"5242"},{"SYMBOLID":"E*O*DD----*****","DESCRIPTION":"ATF","MAPPING1U":"5243","MAPPING1F":"5243","MAPPING1N":"5243","MAPPING1H":"5243"},{"SYMBOLID":"E*O*DDA---*****","DESCRIPTION":"ATF Unit","MAPPING1U":"5243","MAPPING1F":"5243","MAPPING1N":"5243","MAPPING1H":"5243"},{"SYMBOLID":"E*O*DDB---*****","DESCRIPTION":"ATF Equipment","MAPPING1U":"5243","MAPPING1F":"5243","MAPPING1N":"5243","MAPPING1H":"5243"},{"SYMBOLID":"E*O*DDC---*****","DESCRIPTION":"ATF Installation","MAPPING1U":"5243","MAPPING1F":"5243","MAPPING1N":"5243","MAPPING1H":"5243"},{"SYMBOLID":"E*O*DE----*****","DESCRIPTION":"Border Patrol","MAPPING1U":"5244","MAPPING1F":"5244","MAPPING1N":"5244","MAPPING1H":"5244","MAPPING1COLOR":"000000","MAPPING2":"5245","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DEA---*****","DESCRIPTION":"Border Patrol Unit","MAPPING1U":"5244","MAPPING1F":"5244","MAPPING1N":"5244","MAPPING1H":"5244","MAPPING1COLOR":"000000","MAPPING2":"5245","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DEB---*****","DESCRIPTION":"Border Patrol Equipment","MAPPING1U":"5244","MAPPING1F":"5244","MAPPING1N":"5244","MAPPING1H":"5244","MAPPING1COLOR":"000000","MAPPING2":"5245","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DEC---*****","DESCRIPTION":"Border Patrol Installation","MAPPING1U":"5244","MAPPING1F":"5244","MAPPING1N":"5244","MAPPING1H":"5244","MAPPING1COLOR":"000000","MAPPING2":"5245","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DF----*****","DESCRIPTION":"Customs Service","MAPPING1U":"5246","MAPPING1F":"5246","MAPPING1N":"5246","MAPPING1H":"5246","MAPPING1COLOR":"000000","MAPPING2":"5247","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DFA---*****","DESCRIPTION":"Customs Service Unit","MAPPING1U":"5246","MAPPING1F":"5246","MAPPING1N":"5246","MAPPING1H":"5246","MAPPING1COLOR":"000000","MAPPING2":"5247","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DFB---*****","DESCRIPTION":"Customs Service Equipment","MAPPING1U":"5246","MAPPING1F":"5246","MAPPING1N":"5246","MAPPING1H":"5246","MAPPING1COLOR":"000000","MAPPING2":"5247","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DFC---*****","DESCRIPTION":"Customs Service Installation","MAPPING1U":"5246","MAPPING1F":"5246","MAPPING1N":"5246","MAPPING1H":"5246","MAPPING1COLOR":"000000","MAPPING2":"5247","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DG----*****","DESCRIPTION":"DEA","MAPPING1U":"5248","MAPPING1F":"5248","MAPPING1N":"5248","MAPPING1H":"5248"},{"SYMBOLID":"E*O*DGA---*****","DESCRIPTION":"DEA Unit","MAPPING1U":"5248","MAPPING1F":"5248","MAPPING1N":"5248","MAPPING1H":"5248"},{"SYMBOLID":"E*O*DGB---*****","DESCRIPTION":"DEA Equipment","MAPPING1U":"5248","MAPPING1F":"5248","MAPPING1N":"5248","MAPPING1H":"5248"},{"SYMBOLID":"E*O*DGC---*****","DESCRIPTION":"DEA Installation","MAPPING1U":"5248","MAPPING1F":"5248","MAPPING1N":"5248","MAPPING1H":"5248"},{"SYMBOLID":"E*O*DH----*****","DESCRIPTION":"DOJ","MAPPING1U":"5249","MAPPING1F":"5249","MAPPING1N":"5249","MAPPING1H":"5249"},{"SYMBOLID":"E*O*DHA---*****","DESCRIPTION":"DOJ Unit","MAPPING1U":"5249","MAPPING1F":"5249","MAPPING1N":"5249","MAPPING1H":"5249"},{"SYMBOLID":"E*O*DHB---*****","DESCRIPTION":"DOJ Equipment","MAPPING1U":"5249","MAPPING1F":"5249","MAPPING1N":"5249","MAPPING1H":"5249"},{"SYMBOLID":"E*O*DHC---*****","DESCRIPTION":"DOJ Installation","MAPPING1U":"5249","MAPPING1F":"5249","MAPPING1N":"5249","MAPPING1H":"5249"},{"SYMBOLID":"E*O*DI----*****","DESCRIPTION":"FBI","MAPPING1U":"5250","MAPPING1F":"5250","MAPPING1N":"5250","MAPPING1H":"5250"},{"SYMBOLID":"E*O*DIA---*****","DESCRIPTION":"FBI Unit","MAPPING1U":"5250","MAPPING1F":"5250","MAPPING1N":"5250","MAPPING1H":"5250"},{"SYMBOLID":"E*O*DIB---*****","DESCRIPTION":"FBI Equipment","MAPPING1U":"5250","MAPPING1F":"5250","MAPPING1N":"5250","MAPPING1H":"5250"},{"SYMBOLID":"E*O*DIC---*****","DESCRIPTION":"FBI Installation","MAPPING1U":"5250","MAPPING1F":"5250","MAPPING1N":"5250","MAPPING1H":"5250"},{"SYMBOLID":"E*O*DJ----*****","DESCRIPTION":"Police","MAPPING1U":"5251","MAPPING1F":"5251","MAPPING1N":"5251","MAPPING1H":"5251"},{"SYMBOLID":"E*O*DJB---*****","DESCRIPTION":"Police Equipment","MAPPING1U":"5251","MAPPING1F":"5251","MAPPING1N":"5251","MAPPING1H":"5251"},{"SYMBOLID":"E*O*DJC---*****","DESCRIPTION":"Police Installation","MAPPING1U":"5251","MAPPING1F":"5251","MAPPING1N":"5251","MAPPING1H":"5251"},{"SYMBOLID":"E*O*DK----*****","DESCRIPTION":"Prison","MAPPING1U":"5252","MAPPING1F":"5252","MAPPING1N":"5252","MAPPING1H":"5252","MAPPING1COLOR":"000000","MAPPING2":"5253","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DL----*****","DESCRIPTION":"Secret Service","MAPPING1U":"5254","MAPPING1F":"5254","MAPPING1N":"5254","MAPPING1H":"5254"},{"SYMBOLID":"E*O*DLA---*****","DESCRIPTION":"Secret Service Unit","MAPPING1U":"5254","MAPPING1F":"5254","MAPPING1N":"5254","MAPPING1H":"5254"},{"SYMBOLID":"E*O*DLB---*****","DESCRIPTION":"Secret Service Equipment","MAPPING1U":"5254","MAPPING1F":"5254","MAPPING1N":"5254","MAPPING1H":"5254"},{"SYMBOLID":"E*O*DLC---*****","DESCRIPTION":"Secret Service Installation","MAPPING1U":"5254","MAPPING1F":"5254","MAPPING1N":"5254","MAPPING1H":"5254"},{"SYMBOLID":"E*O*DM----*****","DESCRIPTION":"TSA","MAPPING1U":"5255","MAPPING1F":"5255","MAPPING1N":"5255","MAPPING1H":"5255"},{"SYMBOLID":"E*O*DMA---*****","DESCRIPTION":"TSA Unit","MAPPING1U":"5255","MAPPING1F":"5255","MAPPING1N":"5255","MAPPING1H":"5255"},{"SYMBOLID":"E*O*DMB---*****","DESCRIPTION":"TSA Equipment","MAPPING1U":"5255","MAPPING1F":"5255","MAPPING1N":"5255","MAPPING1H":"5255"},{"SYMBOLID":"E*O*DMC---*****","DESCRIPTION":"TSA Installation","MAPPING1U":"5255","MAPPING1F":"5255","MAPPING1N":"5255","MAPPING1H":"5255"},{"SYMBOLID":"E*O*DN----*****","DESCRIPTION":"Coast Guard","MAPPING1U":"2007","MAPPING1F":"2007","MAPPING1N":"2007","MAPPING1H":"2007","MAPPING1COLOR":"000000","MAPPING2":"2008","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DNA---*****","DESCRIPTION":"Coast Guard Unit","MAPPING1U":"2007","MAPPING1F":"2007","MAPPING1N":"2007","MAPPING1H":"2007","MAPPING1COLOR":"000000","MAPPING2":"2008","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DNC---*****","DESCRIPTION":"Coast Guard Installation","MAPPING1U":"2007","MAPPING1F":"2007","MAPPING1N":"2007","MAPPING1H":"2007","MAPPING1COLOR":"000000","MAPPING2":"2008","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DO----*****","DESCRIPTION":"US Marshals Service","MAPPING1U":"5257","MAPPING1F":"5257","MAPPING1N":"5257","MAPPING1H":"5257","MAPPING1COLOR":"000000","MAPPING2":"5258","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DOA---*****","DESCRIPTION":"US Marshals Service Unit","MAPPING1U":"5257","MAPPING1F":"5257","MAPPING1N":"5257","MAPPING1H":"5257","MAPPING1COLOR":"000000","MAPPING2":"5258","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DOB---*****","DESCRIPTION":"US Marshals Service Equipment","MAPPING1U":"5257","MAPPING1F":"5257","MAPPING1N":"5257","MAPPING1H":"5257","MAPPING1COLOR":"000000","MAPPING2":"5258","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*DOC---*****","DESCRIPTION":"US Marshals Service Installation","MAPPING1U":"5257","MAPPING1F":"5257","MAPPING1N":"5257","MAPPING1H":"5257","MAPPING1COLOR":"000000","MAPPING2":"5258","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*O*EA----*****","DESCRIPTION":"Biological Sensor","MAPPING1U":"5260","MAPPING1F":"5260","MAPPING1N":"5260","MAPPING1H":"5260"},{"SYMBOLID":"E*O*EB----*****","DESCRIPTION":"Chemical Sensor","MAPPING1U":"5261","MAPPING1F":"5261","MAPPING1N":"5261","MAPPING1H":"5261"},{"SYMBOLID":"E*O*EC----*****","DESCRIPTION":"Intrusion Sensor","MAPPING1U":"5262","MAPPING1F":"5262","MAPPING1N":"5262","MAPPING1H":"5262"},{"SYMBOLID":"E*O*ED----*****","DESCRIPTION":"Nuclear Sensor","MAPPING1U":"5263","MAPPING1F":"5263","MAPPING1N":"5263","MAPPING1H":"5263"},{"SYMBOLID":"E*O*EE----*****","DESCRIPTION":"Radiological Sensor","MAPPING1U":"5264","MAPPING1F":"5264","MAPPING1N":"5264","MAPPING1H":"5264"},{"SYMBOLID":"E*F*------*****","DESCRIPTION":"Infrastructure"},{"SYMBOLID":"E*F*A-----*****","DESCRIPTION":"Agriculture and Food Infrastructure","MAPPING1U":"5265","MAPPING1F":"5265","MAPPING1N":"5265","MAPPING1H":"5265","MAPPING1COLOR":"000000","MAPPING2":"5266","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*AA----*****","DESCRIPTION":"Agricultural Laboratory","MAPPING1U":"5267","MAPPING1F":"5267","MAPPING1N":"5267","MAPPING1H":"5267","MAPPING1COLOR":"000000","MAPPING2":"5268","MAPPING2COLOR":"808080"},{"SYMBOLID":"E*F*AB----*****","DESCRIPTION":"Animal Feedlot","MAPPING1U":"5269","MAPPING1F":"5269","MAPPING1N":"5269","MAPPING1H":"5269","MAPPING1COLOR":"000000","MAPPING2":"5270","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*AC----*****","DESCRIPTION":"Commercial Food Distribution Center","MAPPING1U":"5271","MAPPING1F":"5272","MAPPING1N":"5273","MAPPING1H":"5274"},{"SYMBOLID":"E*F*AD----*****","DESCRIPTION":"Farm/Ranch","MAPPING1U":"5275","MAPPING1F":"5275","MAPPING1N":"5275","MAPPING1H":"5275","MAPPING1COLOR":"000000","MAPPING2":"5276","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*AE----*****","DESCRIPTION":"Food Production Center","MAPPING1U":"5277","MAPPING1F":"5278","MAPPING1N":"5279","MAPPING1H":"5280"},{"SYMBOLID":"E*F*AF----*****","DESCRIPTION":"Food Retail","MAPPING1U":"5281","MAPPING1F":"5282","MAPPING1N":"5283","MAPPING1H":"5284"},{"SYMBOLID":"E*F*AH----*****","DESCRIPTION":"Grain Storage","MAPPING1U":"5285","MAPPING1F":"5285","MAPPING1N":"5285","MAPPING1H":"5285","MAPPING2":"5286","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*B-----*****","DESCRIPTION":"Banking Finance and Insurance Infrastructure","MAPPING1U":"5287","MAPPING1F":"5287","MAPPING1N":"5287","MAPPING1H":"5287"},{"SYMBOLID":"E*F*BA----*****","DESCRIPTION":"ATM","MAPPING1U":"5288","MAPPING1F":"5288","MAPPING1N":"5288","MAPPING1H":"5288","MAPPING2":"5289","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*BB----*****","DESCRIPTION":"Bank","MAPPING1U":"5290","MAPPING1F":"5290","MAPPING1N":"5290","MAPPING1H":"5290","MAPPING2":"5291","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*BC----*****","DESCRIPTION":"Bullion Storage","MAPPING1U":"5292","MAPPING1F":"5292","MAPPING1N":"5292","MAPPING1H":"5292","MAPPING2":"5293","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*BD----*****","DESCRIPTION":"Federal Reserve Bank","MAPPING1U":"5294","MAPPING1F":"5294","MAPPING1N":"5294","MAPPING1H":"5294","MAPPING2":"5295","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*BE----*****","DESCRIPTION":"Financial Exchange","MAPPING1U":"5296","MAPPING1F":"5296","MAPPING1N":"5296","MAPPING1H":"5296"},{"SYMBOLID":"E*F*BF----*****","DESCRIPTION":"Financial Services Other","MAPPING1U":"5297","MAPPING1F":"5297","MAPPING1N":"5297","MAPPING1H":"5297"},{"SYMBOLID":"E*F*C-----*****","DESCRIPTION":"Commercial Infrastructure","MAPPING1U":"5298","MAPPING1F":"5298","MAPPING1N":"5298","MAPPING1H":"5298","MAPPING2":"5299","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CA----*****","DESCRIPTION":"Chemical Plant","MAPPING1U":"5300","MAPPING1F":"5300","MAPPING1N":"5300","MAPPING1H":"5300","MAPPING2":"5299","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CB----*****","DESCRIPTION":"Firearms Manufacturer","MAPPING1U":"5301","MAPPING1F":"5301","MAPPING1N":"5301","MAPPING1H":"5301","MAPPING2":"5299","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CC----*****","DESCRIPTION":"Firearms Retailer","MAPPING1U":"5302","MAPPING1F":"5302","MAPPING1N":"5302","MAPPING1H":"5302","MAPPING2":"5303","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CD----*****","DESCRIPTION":"Hazardous Material Production","MAPPING1U":"5304","MAPPING1F":"5304","MAPPING1N":"5304","MAPPING1H":"5304","MAPPING2":"5299","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CE----*****","DESCRIPTION":"Hazardous Material Storage","MAPPING1U":"5306","MAPPING1F":"5306","MAPPING1N":"5306","MAPPING1H":"5306","MAPPING2":"5307","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CF----*****","DESCRIPTION":"Industrial Site","MAPPING1U":"5308","MAPPING1F":"5308","MAPPING1N":"5308","MAPPING1H":"5308","MAPPING2":"5299","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CG----*****","DESCRIPTION":"Landfill","MAPPING1U":"5310","MAPPING1F":"5310","MAPPING1N":"5310","MAPPING1H":"5310","MAPPING2":"5311","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CH----*****","DESCRIPTION":"Pharmaceutical Manufacturer","MAPPING1U":"5312","MAPPING1F":"5312","MAPPING1N":"5312","MAPPING1H":"5312","MAPPING2":"5313","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CI----*****","DESCRIPTION":"Contaminated Hazardous Waste Site","MAPPING1U":"5314","MAPPING1F":"5314","MAPPING1N":"5314","MAPPING1H":"5314","MAPPING2":"5315","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*CJ----*****","DESCRIPTION":"Toxic Release Inventory","MAPPING1U":"5316","MAPPING1F":"5316","MAPPING1N":"5316","MAPPING1H":"5316","MAPPING2":"5317","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*D-----*****","DESCRIPTION":"Educational Facilties Infrastructure","MAPPING1U":"5318","MAPPING1F":"5318","MAPPING1N":"5318","MAPPING1H":"5318"},{"SYMBOLID":"E*F*DA----*****","DESCRIPTION":"College University","MAPPING1U":"5319","MAPPING1F":"5319","MAPPING1N":"5319","MAPPING1H":"5319"},{"SYMBOLID":"E*F*DB----*****","DESCRIPTION":"School","MAPPING1U":"5320","MAPPING1F":"5320","MAPPING1N":"5320","MAPPING1H":"5320"},{"SYMBOLID":"E*F*EA----*****","DESCRIPTION":"Generation Station","MAPPING1U":"5323","MAPPING1F":"5323","MAPPING1N":"5323","MAPPING1H":"5323"},{"SYMBOLID":"E*F*EB----*****","DESCRIPTION":"Natural Gas Facility","MAPPING1U":"5325","MAPPING1F":"5325","MAPPING1N":"5325","MAPPING1H":"5325"},{"SYMBOLID":"E*F*EE----*****","DESCRIPTION":"Propane Facility","MAPPING1U":"5330","MAPPING1F":"5330","MAPPING1N":"5330","MAPPING1H":"5330","MAPPING2":"5331","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*F-----*****","DESCRIPTION":"Government Site Infrastructure","MAPPING1U":"5332","MAPPING1F":"5332","MAPPING1N":"5332","MAPPING1H":"5332","MAPPING2":"5333","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*G-----*****","DESCRIPTION":"Military Infrastructure","MAPPING1U":"5334","MAPPING1F":"5334","MAPPING1N":"5334","MAPPING1H":"5334","MAPPING2":"5335","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*GA----*****","DESCRIPTION":"Military Armory","MAPPING1U":"5336","MAPPING1F":"5336","MAPPING1N":"5336","MAPPING1H":"5336"},{"SYMBOLID":"E*F*H-----*****","DESCRIPTION":"Postal Service Infrastructure","MAPPING1U":"5338","MAPPING1F":"5338","MAPPING1N":"5338","MAPPING1H":"5338","MAPPING2":"5339","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*HA----*****","DESCRIPTION":"Postal Distribution Center","MAPPING1U":"5340","MAPPING1F":"5340","MAPPING1N":"5340","MAPPING1H":"5340","MAPPING2":"5341","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*HB----*****","DESCRIPTION":"Post Office","MAPPING1U":"5342","MAPPING1F":"5342","MAPPING1N":"5342","MAPPING1H":"5342","MAPPING2":"5343","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*I-----*****","DESCRIPTION":"Public Venues Infrastructure","MAPPING1U":"5344","MAPPING1F":"5344","MAPPING1N":"5344","MAPPING1H":"5344"},{"SYMBOLID":"E*F*IA----*****","DESCRIPTION":"Enclosed Facility","MAPPING1U":"5345","MAPPING1F":"5345","MAPPING1N":"5345","MAPPING1H":"5345","MAPPING2":"5346","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*IB----*****","DESCRIPTION":"Open Facility","MAPPING1U":"5347","MAPPING1F":"5347","MAPPING1N":"5347","MAPPING1H":"5347"},{"SYMBOLID":"E*F*IC----*****","DESCRIPTION":"Recreational Area","MAPPING1U":"5348","MAPPING1F":"5348","MAPPING1N":"5348","MAPPING1H":"5348"},{"SYMBOLID":"E*F*ID----*****","DESCRIPTION":"Religious Institution","MAPPING1U":"5349","MAPPING1F":"5349","MAPPING1N":"5349","MAPPING1H":"5349","MAPPING2":"5350","MAPPING2COLOR":"#FFFFFF"},{"SYMBOLID":"E*F*J-----*****","DESCRIPTION":"Special Needs Infrastructure","MAPPING1U":"5351","MAPPING1F":"5351","MAPPING1N":"5351","MAPPING1H":"5351"},{"SYMBOLID":"E*F*JA----*****","DESCRIPTION":"Adult Day Care","MAPPING1U":"5352","MAPPING1F":"5352","MAPPING1N":"5352","MAPPING1H":"5352"},{"SYMBOLID":"E*F*JB----*****","DESCRIPTION":"Child Day Care","MAPPING1U":"5353","MAPPING1F":"5353","MAPPING1N":"5353","MAPPING1H":"5353","MAPPING2":"5354","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*JC----*****","DESCRIPTION":"Elder Care","MAPPING1U":"5355","MAPPING1F":"5355","MAPPING1N":"5355","MAPPING1H":"5355"},{"SYMBOLID":"E*F*K-----*****","DESCRIPTION":"Telecommunications Infrastructure","MAPPING1U":"5356","MAPPING1F":"5356","MAPPING1N":"5356","MAPPING1H":"5356"},{"SYMBOLID":"E*F*KB----*****","DESCRIPTION":"Telecommunications Tower","MAPPING1U":"5358","MAPPING1F":"5358","MAPPING1N":"5358","MAPPING1H":"5358"},{"SYMBOLID":"E*F*LA----*****","DESCRIPTION":"Air Traffic Control Facility","MAPPING1U":"5360","MAPPING1F":"5360","MAPPING1N":"5360","MAPPING1H":"5360"},{"SYMBOLID":"E*F*LD----*****","DESCRIPTION":"Bus Station","MAPPING1U":"5363","MAPPING1F":"5363","MAPPING1N":"5363","MAPPING1H":"5363","MAPPING2":"5364","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*LE----*****","DESCRIPTION":"Ferry Terminal","MAPPING1U":"5365","MAPPING1F":"5365","MAPPING1N":"5365","MAPPING1H":"5365","MAPPING2":"5366","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*LF----*****","DESCRIPTION":"Helicopter Landing Site","MAPPING1U":"5367","MAPPING1F":"5367","MAPPING1N":"5367","MAPPING1H":"5367","MAPPING2":"5368","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*LH----*****","DESCRIPTION":"Maintenance Facility","MAPPING1U":"5370","MAPPING1F":"5370","MAPPING1N":"5370","MAPPING1H":"5370"},{"SYMBOLID":"E*F*LJ----*****","DESCRIPTION":"Rail Station","MAPPING1U":"5372","MAPPING1F":"5372","MAPPING1N":"5372","MAPPING1H":"5372"},{"SYMBOLID":"E*F*LK----*****","DESCRIPTION":"Rest Stop","MAPPING1U":"5373","MAPPING1F":"5373","MAPPING1N":"5373","MAPPING1H":"5373"},{"SYMBOLID":"E*F*LM----*****","DESCRIPTION":"Toll Facility","MAPPING1U":"5375","MAPPING1F":"5375","MAPPING1N":"5375","MAPPING1H":"5375","MAPPING2":"5376","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*LO----*****","DESCRIPTION":"Traffic Inspection Facility","MAPPING1U":"5378","MAPPING1F":"5378","MAPPING1N":"5378","MAPPING1H":"5378","MAPPING2":"5379","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*LP----*****","DESCRIPTION":"Tunnel","MAPPING1U":"5380","MAPPING1F":"5380","MAPPING1N":"5380","MAPPING1H":"5380","MAPPING2":"5381","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*MA----*****","DESCRIPTION":"Control Valve","MAPPING1U":"5383","MAPPING1F":"5383","MAPPING1N":"5383","MAPPING1H":"5383"},{"SYMBOLID":"E*F*MB----*****","DESCRIPTION":"Dam","MAPPING1U":"5384","MAPPING1F":"5384","MAPPING1N":"5384","MAPPING1H":"5384"},{"SYMBOLID":"E*F*MC----*****","DESCRIPTION":"Discharge Outfall","MAPPING1U":"5385","MAPPING1F":"5385","MAPPING1N":"5385","MAPPING1H":"5385"},{"SYMBOLID":"E*F*MD----*****","DESCRIPTION":"Ground Water Well","MAPPING1U":"5386","MAPPING1F":"5386","MAPPING1N":"5386","MAPPING1H":"5386"},{"SYMBOLID":"E*F*ME----*****","DESCRIPTION":"Pumping Station","MAPPING1U":"5387","MAPPING1F":"5387","MAPPING1N":"5387","MAPPING1H":"5387","MAPPING2":"5388","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*MF----*****","DESCRIPTION":"Reservoir","MAPPING1U":"5389","MAPPING1F":"5389","MAPPING1N":"5389","MAPPING1H":"5389","MAPPING2":"5390","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*MG----*****","DESCRIPTION":"Storage Tower","MAPPING1U":"5391","MAPPING1F":"5391","MAPPING1N":"5391","MAPPING1H":"5391","MAPPING2":"5392","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*MH----*****","DESCRIPTION":"Surface Water Intake","MAPPING1U":"5393","MAPPING1F":"5393","MAPPING1N":"5393","MAPPING1H":"5393","MAPPING2":"5394","MAPPING2COLOR":"FFFFFF"},{"SYMBOLID":"E*F*MI----*****","DESCRIPTION":"Wastewater Treatment Facility","MAPPING1U":"5395","MAPPING1F":"5395","MAPPING1N":"5395","MAPPING1H":"5395","MAPPING2":"5396","MAPPING2COLOR":"FFFFFF"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitConstantsC={"UNITCONSTANTS":{"SYMBOL":[{"SYMBOLID":"S***------*****","DESCRIPTION":"Warfighting Symbology","DRAWCATEGORY":"0","HIERARCHY":"1.X","ALPHAHIERARCHY":"WAR"},{"SYMBOLID":"S*P*------*****","DESCRIPTION":"Space Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.1","ALPHAHIERARCHY":"WAR.SPC","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*P*S-----*****","DESCRIPTION":"Satellite","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.1","ALPHAHIERARCHY":"WAR.SPC.SAT","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*V-----*****","DESCRIPTION":"Crewed Space Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.2","ALPHAHIERARCHY":"WAR.SPC.CSV","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*T-----*****","DESCRIPTION":"Space Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.3","ALPHAHIERARCHY":"WAR.SPC.SST","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*P*L-----*****","DESCRIPTION":"Space Launch Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.1.4","ALPHAHIERARCHY":"WAR.SPC.SLV","PATH":"Warfighting Symbology/Space Track"},{"SYMBOLID":"S*A*------*****","DESCRIPTION":"Air Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.2","ALPHAHIERARCHY":"WAR.AIRTRK","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*A*M-----*****","DESCRIPTION":"Military","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*MF----*****","DESCRIPTION":"Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*MFB---*****","DESCRIPTION":"Fixed Wing Bomber","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.BMB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFF---*****","DESCRIPTION":"Fixed Wing Fighter","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.FTR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFFI--*****","DESCRIPTION":"Fixed Wing Interceptor","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.FTR.INCR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Fighter"},{"SYMBOLID":"S*A*MFT---*****","DESCRIPTION":"Fixed Wing Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNE","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFA---*****","DESCRIPTION":"Attack/Strike","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ATK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFL---*****","DESCRIPTION":"Fixed Wing VSTOL","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.VSTOL","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFK---*****","DESCRIPTION":"Fixed Wing Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFKB--*****","DESCRIPTION":"Fixed Wing Tanker Boom-Only","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK.BOOM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Tanker"},{"SYMBOLID":"S*A*MFKD--*****","DESCRIPTION":"Fixed Wing Tanker Drouge-Only","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.6.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.TNK.DROG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Tanker"},{"SYMBOLID":"S*A*MFC---*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Transport)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFCL--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.LIT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFCM--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.MDM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFCH--*****","DESCRIPTION":"Fixed Wing Cargo Airlift (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.7.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CGOALT.HVY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Cargo Airlift (Transport)"},{"SYMBOLID":"S*A*MFJ---*****","DESCRIPTION":"Fixed Wing ECM/Jammer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFO---*****","DESCRIPTION":"Fixed Wing MEDEVAC","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFR---*****","DESCRIPTION":"Fixed Wing Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFRW--*****","DESCRIPTION":"Fixed Wing Airborne Early Warning (AEW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.ABNEW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFRZ--*****","DESCRIPTION":"Fixed Wing Electronic Surveillance Measures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.ESM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFRX--*****","DESCRIPTION":"Fixed Wing Photographic","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.10.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.RECON.PHG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Reconnaissance"},{"SYMBOLID":"S*A*MFP---*****","DESCRIPTION":"Fixed Wing Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFPN--*****","DESCRIPTION":"Patrol Antisurface Warfare (ASUW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT.ASUW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Patrol"},{"SYMBOLID":"S*A*MFPM--*****","DESCRIPTION":"Fixed Wing Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.11.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.PAT.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Patrol"},{"SYMBOLID":"S*A*MFU---*****","DESCRIPTION":"Fixed Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFUL--*****","DESCRIPTION":"Fixed Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.LIT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFUM--*****","DESCRIPTION":"Fixed Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.MDM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFUH--*****","DESCRIPTION":"Fixed Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.12.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.UTY.HVY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Fixed Wing Utility"},{"SYMBOLID":"S*A*MFY---*****","DESCRIPTION":"Fixed Wing Communications (C3I)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.COMM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFH---*****","DESCRIPTION":"Fixed Wing Combat Search and Rescue (CSAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFD---*****","DESCRIPTION":"Fixed Wing Airborne Command Post (C2)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.15","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFQ---*****","DESCRIPTION":"Drone (RPV/UAV) Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFQA--*****","DESCRIPTION":"Drone Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ATK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQB--*****","DESCRIPTION":"Drone Bomber","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.BMB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQC--*****","DESCRIPTION":"Drone Cargo","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.CGO","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQD--*****","DESCRIPTION":"Drone (RPV/UAV) Airborne Command Post","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQF--*****","DESCRIPTION":"Drone Fighter","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.FTR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQH--*****","DESCRIPTION":"Search & Rescue (CSAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQJ--*****","DESCRIPTION":"Drone Electronic Countermeasures (Jammer)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQK--*****","DESCRIPTION":"Drone Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.TNK","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQL--*****","DESCRIPTION":"Drone Vstol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.VSTOL","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQM--*****","DESCRIPTION":"Drone Special Operations Forces (SOF)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.SOF","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQI--*****","DESCRIPTION":"Drone Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQN--*****","DESCRIPTION":"Drone Anti-Surface Warfare (ASUW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ASUW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQP--*****","DESCRIPTION":"Drone Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.PAT","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQR--*****","DESCRIPTION":"Drone Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQRW-*****","DESCRIPTION":"Drone Airborne Early Warning (AEW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.ABNEW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQRZ-*****","DESCRIPTION":"Drone Electronic Surveillance Measures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.ESM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQRX-*****","DESCRIPTION":"Drone Photographic","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.14.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.RECON.PHG","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing/Drone Reconnaissance"},{"SYMBOLID":"S*A*MFQS--*****","DESCRIPTION":"Drone Anti-Submarine Warfare (ASW)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.15","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.ASBW","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQT--*****","DESCRIPTION":"Drone Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.16","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.TNE","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQU--*****","DESCRIPTION":"Drone Utility Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.17","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.UTY","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQY--*****","DESCRIPTION":"Drone Communications (C3I)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.18","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.COMM","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFQO--*****","DESCRIPTION":"Drone Medevac","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.16.19","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.DRN.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing/Drone (RPV-UAV) Fixed Wing"},{"SYMBOLID":"S*A*MFS---*****","DESCRIPTION":"Antisubmarine Warfare (ASW) Carrier Based","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.17","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.ASBWCB","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MFM---*****","DESCRIPTION":"Fixed Wing Special Operations Forces (SOF)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.1.18","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.FIXD.SOF","PATH":"Warfighting Symbology/Air Track/Military/Fixed Wing"},{"SYMBOLID":"S*A*MH----*****","DESCRIPTION":"Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*MHA---*****","DESCRIPTION":"Rotary Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ATK","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHS---*****","DESCRIPTION":"Antisubmarine Warfare/MPA ROTARY WING","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ASBW","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHU---*****","DESCRIPTION":"Rotary Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHUL--*****","DESCRIPTION":"Rotary Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.LIT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHUM--*****","DESCRIPTION":"Rotary Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.MDM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHUH--*****","DESCRIPTION":"Rotary Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.3.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.UTY.HVY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Utility"},{"SYMBOLID":"S*A*MHI---*****","DESCRIPTION":"Rotary Wing Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.MNECM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHH---*****","DESCRIPTION":"Rotary Wing Combat Search and Rescue(Military)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CSAR","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHR---*****","DESCRIPTION":"Rotary Wing Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.6","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.RECON","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHQ---*****","DESCRIPTION":"Drone (RPV/UAV) Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.7","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.DRN","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHC---*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Transport)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHCL--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.1","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.LIT","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHCM--*****","DESCRIPTION":"Rotary Wing Cargo AirLift (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.2","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.MDM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHCH--*****","DESCRIPTION":"Rotary Wing Cargo Airlift (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.8.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.CGOALT.HVY","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing/Rotary Wing Cargo AirLift (Transport)"},{"SYMBOLID":"S*A*MHT---*****","DESCRIPTION":"Rotary Wing Trainer","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.9","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.TNE","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHO---*****","DESCRIPTION":"Rotary Wing MEDEVAC","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.10","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.MEDV","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHM---*****","DESCRIPTION":"Rotary Wing Special Operations Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.11","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.SOF","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHD---*****","DESCRIPTION":"Rotary Wing Airborne Command Post","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.12","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ABNCP","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHK---*****","DESCRIPTION":"Rotary Wing Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.13","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.TNK","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*MHJ---*****","DESCRIPTION":"Rotary Wing ECM/Jammer(TANKER)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.2.14","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ROT.ECM","PATH":"Warfighting Symbology/Air Track/Military/Rotary Wing"},{"SYMBOLID":"S*A*ML----*****","DESCRIPTION":"Military Aircraft Lighter Than Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.LTA","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*MV----*****","DESCRIPTION":"VIP","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.VIP","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*ME----*****","DESCRIPTION":"Escort","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.1.5","ALPHAHIERARCHY":"WAR.AIRTRK.MIL.ESCORT","PATH":"Warfighting Symbology/Air Track/Military"},{"SYMBOLID":"S*A*W-----*****","DESCRIPTION":"Air Track Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*WM----*****","DESCRIPTION":"Missile In Flight","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF","PATH":"Warfighting Symbology/Air Track/Air Track Weapon"},{"SYMBOLID":"S*A*WMS---*****","DESCRIPTION":"Surface Launched Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMSS--*****","DESCRIPTION":"Surface to Surface Missile (SSM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SSM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSA--*****","DESCRIPTION":"Surface To Air Missile (SAM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SAM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSU--*****","DESCRIPTION":"Surface to Subsurface Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.SSUM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMSB--*****","DESCRIPTION":"Anti-Ballistic Missile (ABM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SLM.ABM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Surface Launched Missile"},{"SYMBOLID":"S*A*WMA---*****","DESCRIPTION":"Air Launched Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMAS--*****","DESCRIPTION":"Air To Surface Missile (ASM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.1","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.ASM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMAA--*****","DESCRIPTION":"Air To Air Missile (AAM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.AAM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMAP--*****","DESCRIPTION":"Air to Space Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.ALM.ASPC","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight/Air Launched Missile"},{"SYMBOLID":"S*A*WMU---*****","DESCRIPTION":"Subsurface To Surface Missile (S/SSM)","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.SBSM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMCM--*****","DESCRIPTION":"Cruise Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.4","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.CM","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WMB---*****","DESCRIPTION":"Ballistic Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.1.5","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.MSLIF.BLST","PATH":"Warfighting Symbology/Air Track/Air Track Weapon/Missile In Flight"},{"SYMBOLID":"S*A*WD----*****","DESCRIPTION":"Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.2","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.DCY","PATH":"Warfighting Symbology/Air Track/Weapon"},{"SYMBOLID":"S*A*WB----*****","DESCRIPTION":"Bomb","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.WPN.BM","PATH":"Warfighting Symbology/Air Track/Weapon"},{"SYMBOLID":"S*A*C-----*****","DESCRIPTION":"Civil Aircraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3","ALPHAHIERARCHY":"WAR.AIRTRK.CVL","PATH":"Warfighting Symbology/Air Track"},{"SYMBOLID":"S*A*CF----*****","DESCRIPTION":"Civil Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.1","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.FIXD","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*A*CH----*****","DESCRIPTION":"Civil Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.2","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.ROT","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*A*CL----*****","DESCRIPTION":"Civil Aircraft Lighter Than Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.2.3.3","ALPHAHIERARCHY":"WAR.AIRTRK.CVL.LTA","PATH":"Warfighting Symbology/Air Track/Civil Aircraft"},{"SYMBOLID":"S*G*------*****","DESCRIPTION":"Ground Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.3","ALPHAHIERARCHY":"WAR.GRDTRK","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*G*U-----*****","DESCRIPTION":"Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*UC----*****","DESCRIPTION":"Combat","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*UCD---*****","DESCRIPTION":"Air Defense","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCDS--*****","DESCRIPTION":"Short Range","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDSC-*****","DESCRIPTION":"Chaparral","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.CPL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDSS-*****","DESCRIPTION":"Stinger","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.STG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDSV-*****","DESCRIPTION":"Vulcan","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.SHTR.VUL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Short Range"},{"SYMBOLID":"S*G*UCDM--*****","DESCRIPTION":"Air Defense Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDML-*****","DESCRIPTION":"Air Defense Missile Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDMLA*****","DESCRIPTION":"Air Defense Missile Motorized (Avenger)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.LIT.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/Air Defense Missile Light"},{"SYMBOLID":"S*G*UCDMM-*****","DESCRIPTION":"Air Defense Missile Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDMH-*****","DESCRIPTION":"Air Defense Missile Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDH--*****","DESCRIPTION":"H/MAD","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile"},{"SYMBOLID":"S*G*UCDHH-*****","DESCRIPTION":"Hawk","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.HWK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/H and MAD"},{"SYMBOLID":"S*G*UCDHP-*****","DESCRIPTION":"Patriot","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.MSL.HMAD.PATT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense/Air Defense Missile/H and MAD"},{"SYMBOLID":"S*G*UCDG--*****","DESCRIPTION":"Gun Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.GUNUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDC--*****","DESCRIPTION":"Air Defense Composite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.CMPS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDT--*****","DESCRIPTION":"Targeting Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.TGTGUT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCDO--*****","DESCRIPTION":"Theater Missile Defense Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ADF.TMDU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Air Defense"},{"SYMBOLID":"S*G*UCA---*****","DESCRIPTION":"Armor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCAT--*****","DESCRIPTION":"Armor Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor"},{"SYMBOLID":"S*G*UCATA-*****","DESCRIPTION":"Armor Track Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATW-*****","DESCRIPTION":"Armor Track Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATWR*****","DESCRIPTION":"Armor Track Amphibious Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.AMP.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track/Armor Track Amphibious"},{"SYMBOLID":"S*G*UCATL-*****","DESCRIPTION":"Armor Track, Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATM-*****","DESCRIPTION":"Armor Track, Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATH-*****","DESCRIPTION":"Armor Track, Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCATR-*****","DESCRIPTION":"Armor Track, Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.TRK.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor Track"},{"SYMBOLID":"S*G*UCAW--*****","DESCRIPTION":"Armor, Wheeled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor"},{"SYMBOLID":"S*G*UCAWS-*****","DESCRIPTION":"Armor, Wheeled Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWA-*****","DESCRIPTION":"Armor, Wheeled Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWW-*****","DESCRIPTION":"Armor, Wheeled Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWWR*****","DESCRIPTION":"Armor, Wheeled Amphibious Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.AMP.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled/Armor, Wheeled Amphibious"},{"SYMBOLID":"S*G*UCAWL-*****","DESCRIPTION":"Armor, Wheeled Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWM-*****","DESCRIPTION":"Armor, Wheeled Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWH-*****","DESCRIPTION":"Armor, Wheeled Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAWR-*****","DESCRIPTION":"Armor, Wheeled Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ARM.WHD.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Armor/Armor, Wheeled"},{"SYMBOLID":"S*G*UCAA--*****","DESCRIPTION":"Anti Armor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCAAD-*****","DESCRIPTION":"Anti Armor Dismounted","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAL-*****","DESCRIPTION":"Anti Armor Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAM-*****","DESCRIPTION":"Anti Armor Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAS-*****","DESCRIPTION":"Anti Armor Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAU-*****","DESCRIPTION":"Anti Armor Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAC-*****","DESCRIPTION":"Anti Armor Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAA-*****","DESCRIPTION":"Anti Armor Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAAT*****","DESCRIPTION":"Anti Armor Armored Tracked","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.TKD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAAW*****","DESCRIPTION":"Anti Armor Armored Wheeled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.WHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAAS*****","DESCRIPTION":"Anti Armor Armored Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.ARMD.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Armored"},{"SYMBOLID":"S*G*UCAAO-*****","DESCRIPTION":"Anti Armor Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor"},{"SYMBOLID":"S*G*UCAAOS*****","DESCRIPTION":"Anti Armor Motorized Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.3.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AARM.MOT.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Anti Armor/Anti Armor Motorized"},{"SYMBOLID":"S*G*UCV---*****","DESCRIPTION":"Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCVF--*****","DESCRIPTION":"Aviation Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVFU-*****","DESCRIPTION":"Utility Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.UTY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVFA-*****","DESCRIPTION":"Fixed Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.ATK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVFR-*****","DESCRIPTION":"Recon Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.FIXD.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Fixed Wing"},{"SYMBOLID":"S*G*UCVR--*****","DESCRIPTION":"Aviation Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVRA-*****","DESCRIPTION":"Attack Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.ATK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRS-*****","DESCRIPTION":"Scout Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.SCUT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRW-*****","DESCRIPTION":"Antisubmarine Warfare Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.ASBW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRU-*****","DESCRIPTION":"Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRUL*****","DESCRIPTION":"Light Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUM*****","DESCRIPTION":"Medium Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUH*****","DESCRIPTION":"Heavy Utility Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.UTY.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing/Utility Rotary Wing"},{"SYMBOLID":"S*G*UCVRUC*****","DESCRIPTION":"C2 Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.C2","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRUE*****","DESCRIPTION":"Medevac Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.MEDV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVRM-*****","DESCRIPTION":"Mine Countermeasure Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.ROT.MNECM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Aviation Rotary Wing"},{"SYMBOLID":"S*G*UCVS--*****","DESCRIPTION":"Search and Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.SAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVC--*****","DESCRIPTION":"Aviation Composite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.CMPS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVV--*****","DESCRIPTION":"Vertical/Short Takeoff And Landing (V/Stol)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.VSTOL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVU--*****","DESCRIPTION":"Unmanned Aerial Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation"},{"SYMBOLID":"S*G*UCVUF-*****","DESCRIPTION":"Unmanned Aerial Vehicle Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV.FIXD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Unmanned Aerial Vehicle"},{"SYMBOLID":"S*G*UCVUR-*****","DESCRIPTION":"Unmanned Aerial Vehicle Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.AVN.UAV.ROT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Aviation/Unmanned Aerial Vehicle"},{"SYMBOLID":"S*G*UCI---*****","DESCRIPTION":"Infantry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCIL--*****","DESCRIPTION":"Infantry Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIM--*****","DESCRIPTION":"Infantry Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIO--*****","DESCRIPTION":"Infantry Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIA--*****","DESCRIPTION":"Infantry Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIS--*****","DESCRIPTION":"Infantry Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIZ--*****","DESCRIPTION":"Infantry Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIN--*****","DESCRIPTION":"Infantry Naval","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.NAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCII--*****","DESCRIPTION":"Infantry Fighting Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.INFFV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCIC--*****","DESCRIPTION":"Infantry Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.5.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.INF.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Infantry"},{"SYMBOLID":"S*G*UCE---*****","DESCRIPTION":"Engineer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCEC--*****","DESCRIPTION":"Engineer Combat","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer"},{"SYMBOLID":"S*G*UCECS-*****","DESCRIPTION":"Engineer Combat Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECA-*****","DESCRIPTION":"Engineer Combat Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECC-*****","DESCRIPTION":"Engineer Combat Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECL-*****","DESCRIPTION":"Engineer Combat Light (Sapper)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECM-*****","DESCRIPTION":"Engineer Combat Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECH-*****","DESCRIPTION":"Engineer Combat Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECT-*****","DESCRIPTION":"Engineer Combat Mechanized (Track)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECW-*****","DESCRIPTION":"Engineer Combat Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECO-*****","DESCRIPTION":"Engineer Combat Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCECR-*****","DESCRIPTION":"Engineer Combat Recon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CBT.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Combat"},{"SYMBOLID":"S*G*UCEN--*****","DESCRIPTION":"Engineer Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CSN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer"},{"SYMBOLID":"S*G*UCENN-*****","DESCRIPTION":"Engineer Naval Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.6.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ENG.CSN.NAV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Engineer/Engineer Construction"},{"SYMBOLID":"S*G*UCF---*****","DESCRIPTION":"Field Artillery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCFH--*****","DESCRIPTION":"Howitzer/Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFHE-*****","DESCRIPTION":"Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.SPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHS-*****","DESCRIPTION":"Howitzer/Gun Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHA-*****","DESCRIPTION":"Howitzer/Gun Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHC-*****","DESCRIPTION":"Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHO-*****","DESCRIPTION":"Howitzer/Gun Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHL-*****","DESCRIPTION":"Howitzer/Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHM-*****","DESCRIPTION":"Howitzer/Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.MDM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHH-*****","DESCRIPTION":"Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFHX-*****","DESCRIPTION":"Amphibious","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.HOW.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Howitzer and Gun"},{"SYMBOLID":"S*G*UCFR--*****","DESCRIPTION":"Rocket","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFRS-*****","DESCRIPTION":"Rocket Single Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket"},{"SYMBOLID":"S*G*UCFRSS*****","DESCRIPTION":"Single Rocket Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRSPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRSR*****","DESCRIPTION":"Single Rocket Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRST*****","DESCRIPTION":"Single Rocket Towed","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.SRL.SRTOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Rocket Single Rocket Launcher"},{"SYMBOLID":"S*G*UCFRM-*****","DESCRIPTION":"Multi Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket"},{"SYMBOLID":"S*G*UCFRMS*****","DESCRIPTION":"Multi Rocket Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRSPD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFRMR*****","DESCRIPTION":"Multi Rocket Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFRMT*****","DESCRIPTION":"Multi Rocket Towed","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ROC.MRL.MRTOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Rocket/Multi Rocket Launcher"},{"SYMBOLID":"S*G*UCFT--*****","DESCRIPTION":"Target Acquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFTR-*****","DESCRIPTION":"Target Acquisition Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.RAD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTS-*****","DESCRIPTION":"Sound","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.SND","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTF-*****","DESCRIPTION":"Flash (Optical)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.FLH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTC-*****","DESCRIPTION":"Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFTCD*****","DESCRIPTION":"Dismounted Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition/Colt and Fist"},{"SYMBOLID":"S*G*UCFTCM*****","DESCRIPTION":"Tracked Colt/Fist","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.CLT.TKD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition/Colt and Fist"},{"SYMBOLID":"S*G*UCFTA-*****","DESCRIPTION":"Anglico","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.TGTAQ.ANG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Target Acquisition"},{"SYMBOLID":"S*G*UCFM--*****","DESCRIPTION":"Field Artillery Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFMS-*****","DESCRIPTION":"Self-Propelled (SP) Tracked Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDTRK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMW-*****","DESCRIPTION":"SP Wheeled Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.SPDWHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMT-*****","DESCRIPTION":"Towed Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFMTA*****","DESCRIPTION":"Towed Airborne Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTS*****","DESCRIPTION":"Towed Air Assault Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTC*****","DESCRIPTION":"Towed Arctic Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFMTO*****","DESCRIPTION":"Towed Mountain Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.TOW.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar/Towed Mortar"},{"SYMBOLID":"S*G*UCFML-*****","DESCRIPTION":"Amphibious Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.MORT.AMP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Mortar"},{"SYMBOLID":"S*G*UCFS--*****","DESCRIPTION":"Artillery Survey","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFSS-*****","DESCRIPTION":"Artillery Survey Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSA-*****","DESCRIPTION":"Artillery Survey Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSL-*****","DESCRIPTION":"Artillery Survey Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFSO-*****","DESCRIPTION":"Artillery Survey Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.ARTSVY.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Artillery Survey"},{"SYMBOLID":"S*G*UCFO--*****","DESCRIPTION":"Field Artillery Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery"},{"SYMBOLID":"S*G*UCFOS-*****","DESCRIPTION":"Air Assault Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorologicall"},{"SYMBOLID":"S*G*UCFOA-*****","DESCRIPTION":"Airborne Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCFOL-*****","DESCRIPTION":"Light Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCFOO-*****","DESCRIPTION":"Mountain Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.7.6.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.FLDART.METO.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Field Artillery/Field Artillery Meteorological"},{"SYMBOLID":"S*G*UCR---*****","DESCRIPTION":"Combat Reconnaissance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCRH--*****","DESCRIPTION":"Reconnaissance Horse","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.HRE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRV--*****","DESCRIPTION":"Reconnaissance Cavalry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRVA-*****","DESCRIPTION":"Reconnaissance Cavalry Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.ARMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVM-*****","DESCRIPTION":"Reconnaissance Cavalry Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVG-*****","DESCRIPTION":"Reconnaissance Cavalry Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.GRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRVO-*****","DESCRIPTION":"Reconnaissance Cavalry Air","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.CVY.AIR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Cavalry"},{"SYMBOLID":"S*G*UCRC--*****","DESCRIPTION":"Reconnaissance Arctic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.ARC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRS--*****","DESCRIPTION":"Reconnaissance Air Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.AAST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRA--*****","DESCRIPTION":"Reconnaissance Airborne","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.ABN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRO--*****","DESCRIPTION":"Reconnaissance Mountain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRL--*****","DESCRIPTION":"Reconnaissance Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.LIT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRR--*****","DESCRIPTION":"Reconnaissance Marine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCRRD-*****","DESCRIPTION":"Reconnaissance Marine Division","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.DIV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRRF-*****","DESCRIPTION":"Reconnaissance Marine Force","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.FOR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRRL-*****","DESCRIPTION":"Reconnaissance Marine Light Armored (LAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.MAR.LAR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance/Reconnaissance Marine"},{"SYMBOLID":"S*G*UCRX--*****","DESCRIPTION":"Reconnaissance Long Range Surveillance (LRS)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.8.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.RECON.LRS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Combat Reconnaissance"},{"SYMBOLID":"S*G*UCM---*****","DESCRIPTION":"Missile (Surf-Surf)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCMT--*****","DESCRIPTION":"Missile (Surf-Surf) Tactical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL.TAC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Missile (Surf-Surf)"},{"SYMBOLID":"S*G*UCMS--*****","DESCRIPTION":"Missile (Surf-Surf) Strategic","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.MSL.STGC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Missile (Surf-Surf)"},{"SYMBOLID":"S*G*UCS---*****","DESCRIPTION":"Internal Security Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UCSW--*****","DESCRIPTION":"Internal Security Forces Riverine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.RIV","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSG--*****","DESCRIPTION":"Internal Security Forces Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSGD-*****","DESCRIPTION":"Internal Security Forces Dismounted","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.DMD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSGM-*****","DESCRIPTION":"Internal Security Forces Motorized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSGA-*****","DESCRIPTION":"Internal Security Forces Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.GRD.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces/Internal Security Forces Ground"},{"SYMBOLID":"S*G*UCSM--*****","DESCRIPTION":"Internal Security Forces Wheeled Mechanized","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.WHMECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSR--*****","DESCRIPTION":"Internal Security Forces Railroad","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.RALRD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCSA--*****","DESCRIPTION":"Internal Security Forces Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.10.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.ISF.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat/Internal Security Forces"},{"SYMBOLID":"S*G*UCL---*****","DESCRIPTION":"Surveillance Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CBT.SVL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat"},{"SYMBOLID":"S*G*UU----*****","DESCRIPTION":"Combat Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*UUA---*****","DESCRIPTION":"Combat Support NBC","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUAC--*****","DESCRIPTION":"Combat Support Chemical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUACC-*****","DESCRIPTION":"Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACCK*****","DESCRIPTION":"Mechanized Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MECH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke and Decon"},{"SYMBOLID":"S*G*UUACCM*****","DESCRIPTION":"Motorized Smoke/Decon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMKDEC.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke and Decon"},{"SYMBOLID":"S*G*UUACS-*****","DESCRIPTION":"Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACSM*****","DESCRIPTION":"Motorized Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK.MOT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke"},{"SYMBOLID":"S*G*UUACSA*****","DESCRIPTION":"Armor Smoke","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.SMK.ARM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Smoke"},{"SYMBOLID":"S*G*UUACR-*****","DESCRIPTION":"Chemical Recon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical"},{"SYMBOLID":"S*G*UUACRW*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WARMVH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Chemical Recon"},{"SYMBOLID":"S*G*UUACRS*****","DESCRIPTION":"Chemical Wheeled Armored Vehicle Reconnaissance Surveillance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.CML.RECON.WAVS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support Chemical/Chemical Recon"},{"SYMBOLID":"S*G*UUAN--*****","DESCRIPTION":"Combat Support NBC Nuclear","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.NUC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUAB--*****","DESCRIPTION":"Combat Support NBC Biological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.BIO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUABR-*****","DESCRIPTION":"Recon Equipped","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.BIO.RECEQP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC/Combat Support NBC Biological"},{"SYMBOLID":"S*G*UUAD--*****","DESCRIPTION":"NBC Decontamination","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.NBC.DECON","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Combat Support NBC"},{"SYMBOLID":"S*G*UUM---*****","DESCRIPTION":"Military Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUMA--*****","DESCRIPTION":"Aerial Exploitation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.AEREXP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMS--*****","DESCRIPTION":"Signal Intelligence (SIGINT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMSE-*****","DESCRIPTION":"Electronic Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)"},{"SYMBOLID":"S*G*UUMSEA*****","DESCRIPTION":"Armored Wheeled Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.ARMWVH","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSED*****","DESCRIPTION":"Direction Finding","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.DFN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEI*****","DESCRIPTION":"Intercept","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.INC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEJ*****","DESCRIPTION":"Jamming","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.JMG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSET*****","DESCRIPTION":"Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMSEC*****","DESCRIPTION":"Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SIGINT.ECW.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Signal Intelligence (SIGINT)/Electronic Warfare"},{"SYMBOLID":"S*G*UUMC--*****","DESCRIPTION":"Counter Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.CINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMR--*****","DESCRIPTION":"Counter Intelligence Surveillance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMRG-*****","DESCRIPTION":"Ground Surveillance Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMRS-*****","DESCRIPTION":"Surveillance Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMRSS*****","DESCRIPTION":"Sensor SCM","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.SNS.SCM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance/Surveillance Sensor"},{"SYMBOLID":"S*G*UUMRX-*****","DESCRIPTION":"Ground Station Module","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.GRDSM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMMO-*****","DESCRIPTION":"Surveillance Meteorological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.SVL.METO","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence/Counter Intelligence Surveillance"},{"SYMBOLID":"S*G*UUMO--*****","DESCRIPTION":"Military Intelligence Operations","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.OPN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMT--*****","DESCRIPTION":"Tactical Exploit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.TACEXP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMQ--*****","DESCRIPTION":"Interrogation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.INTGN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUMJ--*****","DESCRIPTION":"Joint Intelligence Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.2.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.MILINT.JINTCT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Military Intelligence"},{"SYMBOLID":"S*G*UUL---*****","DESCRIPTION":"Law Enforcement Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UULS--*****","DESCRIPTION":"Shore Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.SHRPAT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULM--*****","DESCRIPTION":"Military Police","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.MILP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULC--*****","DESCRIPTION":"Civilian Law Enforcement","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.CLE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULF--*****","DESCRIPTION":"Security Police (Air)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.SECPOL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UULD--*****","DESCRIPTION":"Central Intelligence Division (CID)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LAWENU.CID","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Law Enforcement Unit"},{"SYMBOLID":"S*G*UUS---*****","DESCRIPTION":"Signal Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUSA--*****","DESCRIPTION":"Area","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.ARA","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSC--*****","DESCRIPTION":"Communication Configured Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.COMCP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSCL-*****","DESCRIPTION":"Large Communication Configured Package (LCCP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.COMCP.LCCP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Communication Configured Package"},{"SYMBOLID":"S*G*UUSO--*****","DESCRIPTION":"Command Operations","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.CMDOPN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSF--*****","DESCRIPTION":"Forward Communications","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.FWDCOM","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSM--*****","DESCRIPTION":"Multiple Subscriber Element","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSMS-*****","DESCRIPTION":"Small Extension Node","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.SEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSML-*****","DESCRIPTION":"Large Extension Node","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.LEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSMN-*****","DESCRIPTION":"Node Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.MSE.NODCTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Multiple Subscriber Element"},{"SYMBOLID":"S*G*UUSR--*****","DESCRIPTION":"Radio Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSRS-*****","DESCRIPTION":"Tactical Satellite","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TACSAT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSRT-*****","DESCRIPTION":"Teletype Center","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.TTYCTR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSRW-*****","DESCRIPTION":"Relay","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.RDOUNT.RLY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit/Radio Unit"},{"SYMBOLID":"S*G*UUSS--*****","DESCRIPTION":"Signal Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.SIGSUP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSW--*****","DESCRIPTION":"Telephone Switch","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.PHOSWT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUSX--*****","DESCRIPTION":"Electronic Ranging","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.4.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.SIGUNT.ECRG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support/Signal Unit"},{"SYMBOLID":"S*G*UUI---*****","DESCRIPTION":"Information Warfare Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.IWU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUP---*****","DESCRIPTION":"Landing Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.LNDSUP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*UUE---*****","DESCRIPTION":"Explosive Ordnance Disposal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CS.EOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Support"},{"SYMBOLID":"S*G*US----*****","DESCRIPTION":"Combat Service Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*USA---*****","DESCRIPTION":"Administrative (ADMIN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USAT--*****","DESCRIPTION":"Admin Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAC--*****","DESCRIPTION":"Admin Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAJ--*****","DESCRIPTION":"Judge Advocate General (JAG)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAJT-*****","DESCRIPTION":"JAG Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Judge Advocate General (JAG)"},{"SYMBOLID":"S*G*USAJC-*****","DESCRIPTION":"JAG Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.JAG.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Judge Advocate General (JAG)"},{"SYMBOLID":"S*G*USAO--*****","DESCRIPTION":"Postal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAOT-*****","DESCRIPTION":"Postal Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Postal"},{"SYMBOLID":"S*G*USAOC-*****","DESCRIPTION":"Postal Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PST.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Postal"},{"SYMBOLID":"S*G*USAF--*****","DESCRIPTION":"Finance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAFT-*****","DESCRIPTION":"Finance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Finance"},{"SYMBOLID":"S*G*USAFC-*****","DESCRIPTION":"Finance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.FIN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Finance"},{"SYMBOLID":"S*G*USAS--*****","DESCRIPTION":"Personnel Services","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAST-*****","DESCRIPTION":"Personnel Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Personnel Services"},{"SYMBOLID":"S*G*USASC-*****","DESCRIPTION":"Personnel Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PERSVC.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Personnel Services"},{"SYMBOLID":"S*G*USAM--*****","DESCRIPTION":"Mortuary/Graves Registry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAMT-*****","DESCRIPTION":"Mortuary/Graves Registry Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Mortuary and Graves Registry"},{"SYMBOLID":"S*G*USAMC-*****","DESCRIPTION":"Mortuary/Graves Registry Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MTRY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Mortuary and Graves Registry"},{"SYMBOLID":"S*G*USAR--*****","DESCRIPTION":"Religious/Chaplain","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USART-*****","DESCRIPTION":"Religious/Chaplain Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Religious and Chaplain"},{"SYMBOLID":"S*G*USARC-*****","DESCRIPTION":"Religious/Chaplain Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RELG.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Religious and Chaplain"},{"SYMBOLID":"S*G*USAP--*****","DESCRIPTION":"Public Affairs","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAPT-*****","DESCRIPTION":"Public Affairs Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPC-*****","DESCRIPTION":"Public Affairs Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPB-*****","DESCRIPTION":"Public Affairs Broadcast","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPBT*****","DESCRIPTION":"Public Affairs Broadcast Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Broadcast"},{"SYMBOLID":"S*G*USAPBC*****","DESCRIPTION":"Public Affairs Broadcast Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.BRCT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Broadcast"},{"SYMBOLID":"S*G*USAPM-*****","DESCRIPTION":"Public Affairs Joint Information Bureau (JIB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs"},{"SYMBOLID":"S*G*USAPMT*****","DESCRIPTION":"Public Affairs JIB Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Joint Information Bureau (JIB)"},{"SYMBOLID":"S*G*USAPMC*****","DESCRIPTION":"Public Affairs JIB Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.9.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.PUBAFF.JIB.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Public Affairs/Public Affairs Joint Information Bureau (JIB)"},{"SYMBOLID":"S*G*USAX--*****","DESCRIPTION":"Replacement Holding Unit (RHU)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAXT-*****","DESCRIPTION":"RHU Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Replacement Holding Unit (RHU)"},{"SYMBOLID":"S*G*USAXC-*****","DESCRIPTION":"RHU Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.RHU.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Replacement Holding Unit (RHU)"},{"SYMBOLID":"S*G*USAL--*****","DESCRIPTION":"Labor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USALT-*****","DESCRIPTION":"Labor Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Labor"},{"SYMBOLID":"S*G*USALC-*****","DESCRIPTION":"Labor Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.LBR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Labor"},{"SYMBOLID":"S*G*USAW--*****","DESCRIPTION":"Morale, Welfare, Recreation (MWR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAWT-*****","DESCRIPTION":"MWR Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Morale, Welfare, Recreation (MWR)"},{"SYMBOLID":"S*G*USAWC-*****","DESCRIPTION":"MWR Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.12.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.MWR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Morale, Welfare, Recreation (MWR)"},{"SYMBOLID":"S*G*USAQ--*****","DESCRIPTION":"Quartermaster (Supply)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)"},{"SYMBOLID":"S*G*USAQT-*****","DESCRIPTION":"Quartermaster (Supply) Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Quartermaster (Supply)"},{"SYMBOLID":"S*G*USAQC-*****","DESCRIPTION":"Quartermaster (Supply) Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.1.13.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.ADMIN.SUPPLY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Administrative (ADMIN)/Quartermaster (Supply)"},{"SYMBOLID":"S*G*USM---*****","DESCRIPTION":"Medical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USMT--*****","DESCRIPTION":"Medical Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMC--*****","DESCRIPTION":"Medical Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMM--*****","DESCRIPTION":"Medical Treatment Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMMT-*****","DESCRIPTION":"Medical Treatment Facility Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Treatment Facility"},{"SYMBOLID":"S*G*USMMC-*****","DESCRIPTION":"Medical Treatment Facility Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.MEDTF.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Treatment Facility"},{"SYMBOLID":"S*G*USMV--*****","DESCRIPTION":"Medical Veterinary","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMVT-*****","DESCRIPTION":"Medical Veterinary Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Veterinary"},{"SYMBOLID":"S*G*USMVC-*****","DESCRIPTION":"Medical Veterinary Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.VNY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Veterinary"},{"SYMBOLID":"S*G*USMD--*****","DESCRIPTION":"Medical Dental","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMDT-*****","DESCRIPTION":"Medical Dental Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Dental"},{"SYMBOLID":"S*G*USMDC-*****","DESCRIPTION":"Medical Dental Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.DEN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Dental"},{"SYMBOLID":"S*G*USMP--*****","DESCRIPTION":"Medical Psychological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical"},{"SYMBOLID":"S*G*USMPT-*****","DESCRIPTION":"Medical Psychological Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Psychological"},{"SYMBOLID":"S*G*USMPC-*****","DESCRIPTION":"Medical Psychological Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MED.PSY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Medical/Medical Psychological"},{"SYMBOLID":"S*G*USS---*****","DESCRIPTION":"Supply","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USST--*****","DESCRIPTION":"Supply Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSC--*****","DESCRIPTION":"Supply Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS1--*****","DESCRIPTION":"Supply Class I","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS1T-*****","DESCRIPTION":"Supply Class I Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class I"},{"SYMBOLID":"S*G*USS1C-*****","DESCRIPTION":"Supply Class I Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS1.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class I"},{"SYMBOLID":"S*G*USS2--*****","DESCRIPTION":"Supply Class II","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS2T-*****","DESCRIPTION":"Supply Class II Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class II"},{"SYMBOLID":"S*G*USS2C-*****","DESCRIPTION":"Supply Class II Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS2.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class II"},{"SYMBOLID":"S*G*USS3--*****","DESCRIPTION":"Supply Class III","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS3T-*****","DESCRIPTION":"Supply Class III Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3C-*****","DESCRIPTION":"Supply Class III Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3A-*****","DESCRIPTION":"Supply Class III Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III"},{"SYMBOLID":"S*G*USS3AT*****","DESCRIPTION":"Supply Class III Aviation Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III/Supply Class III Aviation"},{"SYMBOLID":"S*G*USS3AC*****","DESCRIPTION":"Supply Class III Aviation Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS3.AVN.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class III/Supply Class III Aviation"},{"SYMBOLID":"S*G*USS4--*****","DESCRIPTION":"Supply Class IV","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS4T-*****","DESCRIPTION":"Supply Class IV Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IV"},{"SYMBOLID":"S*G*USS4C-*****","DESCRIPTION":"Supply Class IV Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS4.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IV"},{"SYMBOLID":"S*G*USS5--*****","DESCRIPTION":"Supply Class V","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS5T-*****","DESCRIPTION":"Supply Class V Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class V"},{"SYMBOLID":"S*G*USS5C-*****","DESCRIPTION":"Supply Class V Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS5.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class V"},{"SYMBOLID":"S*G*USS6--*****","DESCRIPTION":"Supply Class VI","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS6T-*****","DESCRIPTION":"Supply Class VI Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VI"},{"SYMBOLID":"S*G*USS6C-*****","DESCRIPTION":"Supply Class VI Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS6.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VI"},{"SYMBOLID":"S*G*USS7--*****","DESCRIPTION":"Supply Class VII","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS7T-*****","DESCRIPTION":"Supply Class VII Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VII"},{"SYMBOLID":"S*G*USS7C-*****","DESCRIPTION":"Supply Class VII Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS7.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VII"},{"SYMBOLID":"S*G*USS8--*****","DESCRIPTION":"Supply Class VIII","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS8T-*****","DESCRIPTION":"Supply Class VIII Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VIII"},{"SYMBOLID":"S*G*USS8C-*****","DESCRIPTION":"Supply Class VIII Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS8.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class VIII"},{"SYMBOLID":"S*G*USS9--*****","DESCRIPTION":"Supply Class IX","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USS9T-*****","DESCRIPTION":"Supply Class IX Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IX"},{"SYMBOLID":"S*G*USS9C-*****","DESCRIPTION":"Supply Class IX Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS9.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class IX"},{"SYMBOLID":"S*G*USSX--*****","DESCRIPTION":"Supply Class X","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSXT-*****","DESCRIPTION":"Supply Class X Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class X"},{"SYMBOLID":"S*G*USSXC-*****","DESCRIPTION":"Supply Class X Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.12.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.CLS10.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Class X"},{"SYMBOLID":"S*G*USSL--*****","DESCRIPTION":"Supply Laundry/Bath","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSLT-*****","DESCRIPTION":"Supply Laundry/Bath Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Laundry and Bath"},{"SYMBOLID":"S*G*USSLC-*****","DESCRIPTION":"Supply Laundry/Bath Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.13.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.LDY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Laundry and Bath"},{"SYMBOLID":"S*G*USSW--*****","DESCRIPTION":"Supply Water","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply"},{"SYMBOLID":"S*G*USSWT-*****","DESCRIPTION":"Supply Water Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWC-*****","DESCRIPTION":"Supply Water Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWP-*****","DESCRIPTION":"Supply Water Purification","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water"},{"SYMBOLID":"S*G*USSWPT*****","DESCRIPTION":"Supply Water Purification Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water/Supply Water Purification"},{"SYMBOLID":"S*G*USSWPC*****","DESCRIPTION":"Supply Water Purification Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.3.14.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.SLP.H2O.PUR.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Supply/Supply Water/Supply Water Purification"},{"SYMBOLID":"S*G*UST---*****","DESCRIPTION":"Transportation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USTT--*****","DESCRIPTION":"Transportation Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTC--*****","DESCRIPTION":"Transportation Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTM--*****","DESCRIPTION":"Movement Control Center (MCC)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTMT-*****","DESCRIPTION":"MCC Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Movement Control Center (MCC)"},{"SYMBOLID":"S*G*USTMC-*****","DESCRIPTION":"MCC Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MCC.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Movement Control Center (MCC)"},{"SYMBOLID":"S*G*USTR--*****","DESCRIPTION":"Railhead","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTRT-*****","DESCRIPTION":"Railhead Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Railhead"},{"SYMBOLID":"S*G*USTRC-*****","DESCRIPTION":"Railhead Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.RHD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Railhead"},{"SYMBOLID":"S*G*USTS--*****","DESCRIPTION":"SPOD/SPOE","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTST-*****","DESCRIPTION":"SPOD/SPOE Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/SPOD and SPOE"},{"SYMBOLID":"S*G*USTSC-*****","DESCRIPTION":"SPOD/SPOE Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.SPOD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/SPOD and SPOE"},{"SYMBOLID":"S*G*USTA--*****","DESCRIPTION":"APOD/APOE","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTAT-*****","DESCRIPTION":"APOD/APOE Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/APOD and APOE"},{"SYMBOLID":"S*G*USTAC-*****","DESCRIPTION":"APOD/APOE Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.APOD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/APOD and APOE"},{"SYMBOLID":"S*G*USTI--*****","DESCRIPTION":"Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation"},{"SYMBOLID":"S*G*USTIT-*****","DESCRIPTION":"Missile Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Missile"},{"SYMBOLID":"S*G*USTIC-*****","DESCRIPTION":"Missile Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.4.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.TPT.MSL.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Transportation/Missile"},{"SYMBOLID":"S*G*USX---*****","DESCRIPTION":"Maintenance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support"},{"SYMBOLID":"S*G*USXT--*****","DESCRIPTION":"Maintenance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXC--*****","DESCRIPTION":"Maintenance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXH--*****","DESCRIPTION":"Maintenance Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXHT-*****","DESCRIPTION":"Maintenance Heavy Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Heavy"},{"SYMBOLID":"S*G*USXHC-*****","DESCRIPTION":"Maintenance Heavy Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.HVY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Heavy"},{"SYMBOLID":"S*G*USXR--*****","DESCRIPTION":"Maintenance Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXRT-*****","DESCRIPTION":"Maintenance Recovery Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Recovery"},{"SYMBOLID":"S*G*USXRC-*****","DESCRIPTION":"Maintenance Recovery Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.RCY.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Maintenance Recovery"},{"SYMBOLID":"S*G*USXO--*****","DESCRIPTION":"Ordnance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXOT-*****","DESCRIPTION":"Ordnance Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOC-*****","DESCRIPTION":"Ordnance Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOM-*****","DESCRIPTION":"Ordnance Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance"},{"SYMBOLID":"S*G*USXOMT*****","DESCRIPTION":"Ordnance Missile Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance/Ordnance Missile"},{"SYMBOLID":"S*G*USXOMC*****","DESCRIPTION":"Ordnance Missile Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.ORD.MSL.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Ordnance/Ordnance Missile"},{"SYMBOLID":"S*G*USXE--*****","DESCRIPTION":"Electro-Optical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance"},{"SYMBOLID":"S*G*USXET-*****","DESCRIPTION":"Electro-Optical Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP.THT","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Electro-Optical"},{"SYMBOLID":"S*G*USXEC-*****","DESCRIPTION":"Electro-Optical Corps","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.3.5.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.CSS.MAINT.EOP.CRP","PATH":"Warfighting Symbology/Ground Track/Unit/Combat Service Support/Maintenance/Electro-Optical"},{"SYMBOLID":"S*G*UH----*****","DESCRIPTION":"Special C2 Headquarters Component","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.UNT.C2HQ","PATH":"Warfighting Symbology/Ground Track/Unit"},{"SYMBOLID":"S*G*E-----*****","DESCRIPTION":"Ground Track Equipment","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*EW----*****","DESCRIPTION":"Weapon","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EWM---*****","DESCRIPTION":"Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWMA--*****","DESCRIPTION":"Air Defense (AD) Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMAS-*****","DESCRIPTION":"Short Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMASR*****","DESCRIPTION":"Short Range Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/ShortRange"},{"SYMBOLID":"S*G*EWMASE*****","DESCRIPTION":"Short Range Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.SHTR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/ShortRange"},{"SYMBOLID":"S*G*EWMAI-*****","DESCRIPTION":"Intermediate Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMAIR*****","DESCRIPTION":"Intermediate Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Intermediate Range"},{"SYMBOLID":"S*G*EWMAIE*****","DESCRIPTION":"Intermediate Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.INTMR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Intermediate Range"},{"SYMBOLID":"S*G*EWMAL-*****","DESCRIPTION":"Long Range AD Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMALR*****","DESCRIPTION":"Long Range Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Long Range"},{"SYMBOLID":"S*G*EWMALE*****","DESCRIPTION":"Long Range Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.LNGR.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Long Range"},{"SYMBOLID":"S*G*EWMAT-*****","DESCRIPTION":"AD Missile Launcher Theater","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher"},{"SYMBOLID":"S*G*EWMATR*****","DESCRIPTION":"Theater Transporter Launcher and Radar (TLAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TLAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Theater"},{"SYMBOLID":"S*G*EWMATE*****","DESCRIPTION":"Theater Transporter Erector Launcher and Radar (TELAR)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.ADFAD.THT.TELAR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Air Defense (AD) Missile Launcher/Theater"},{"SYMBOLID":"S*G*EWMS--*****","DESCRIPTION":"Surf-Surf (SS) Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMSS-*****","DESCRIPTION":"Short Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.SHTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMSI-*****","DESCRIPTION":"Intermediate Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.INTMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMSL-*****","DESCRIPTION":"Long Range SS Missile Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.SUF.LNGR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Surf-Surf (SS) Missile Launcher"},{"SYMBOLID":"S*G*EWMT--*****","DESCRIPTION":"Missile Launcher Antitank (AT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher"},{"SYMBOLID":"S*G*EWMTL-*****","DESCRIPTION":"Missile Launcher AT Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWMTM-*****","DESCRIPTION":"Missile Launcher AT Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWMTH-*****","DESCRIPTION":"Missile Launcher AT Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MSLL.AT.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Missile Launcher/Missile Launcher Antitank (AT)"},{"SYMBOLID":"S*G*EWS---*****","DESCRIPTION":"Weapon Single Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWSL--*****","DESCRIPTION":"Single Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWSM--*****","DESCRIPTION":"Single Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWSH--*****","DESCRIPTION":"Single Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.SRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Single Rocket Launcher"},{"SYMBOLID":"S*G*EWX---*****","DESCRIPTION":"Multiple Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWXL--*****","DESCRIPTION":"Multiple Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWXM--*****","DESCRIPTION":"Multiple Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWXH--*****","DESCRIPTION":"Multiple Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Multiple Rocket Launcher"},{"SYMBOLID":"S*G*EWT---*****","DESCRIPTION":"Anti-Tank Rocket Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWTL--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.1","ALPHAHIERARCHY":"211SYMBOL UNKNOWN FRIEND NEUTRAL HOSTILEWAR.GRDTRK.EQT.WPN.MRL.HVYWARFIGHTING SYMBOLSGROUND TRACKEQUIPMENTWEAPONMULTIPLE ROCKET LAUNCHERHEAVYHierarchy: 1.X.3.2.1.3.3Framed: FOSUGPEWXH--*****SFGPEWXH--*****SNGPEWXH--*****SHGPEWXH--*****SUGPEWXH--*****SFGPEWXH--*****SNGPEWXH--*****SHGPEWXH--*****WAR.GRDTRK.EQT.WPN.ATRLWARFIGHTING SYMBOLSGROUND TRACKEQUIPMENTWEAPONANTITANK ROCKET LAUNCHERHierarchy: 1.X.3.2.1.4Framed: FOSUGPEWT---*****SFGPEWT---*****SNGPEWT---*****SHGPEWT---*****SUGPEWT---*****SFGPEWT---*****SNGPEWT---*****SHGPEWT---*****WAR.GRDTRK.EQT.WPN.ATRL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWTM--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWTH--*****","DESCRIPTION":"Anti-Tank Rocket Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATRL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Rocket Launcher"},{"SYMBOLID":"S*G*EWR---*****","DESCRIPTION":"Rifle/Automatic Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Rifle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Cache","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.CACHE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Confiscated","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.CONF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Found","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.FND","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Market","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.MKT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRR--*****","DESCRIPTION":"Weapons Sale","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.RIF.SALE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon/Rifle"},{"SYMBOLID":"S*G*EWRL--*****","DESCRIPTION":"Light Machine Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.LMG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWRH--*****","DESCRIPTION":"Heavy Machine Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.RIFWPN.HMG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Rifle and Automatic Weapon"},{"SYMBOLID":"S*G*EWZ---*****","DESCRIPTION":"Grenade Launcher","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWZL--*****","DESCRIPTION":"Grenade Launcher Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWZM--*****","DESCRIPTION":"Grenade Launcher Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWZH--*****","DESCRIPTION":"Grenade Launcher Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.GREL.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Grenade Launcher"},{"SYMBOLID":"S*G*EWO---*****","DESCRIPTION":"Weapon Mortar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWOL--*****","DESCRIPTION":"Mortar Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWOM--*****","DESCRIPTION":"Mortar Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWOH--*****","DESCRIPTION":"Mortar Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.MORT.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Weapon Mortar"},{"SYMBOLID":"S*G*EWH---*****","DESCRIPTION":"Howitzer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWHL--*****","DESCRIPTION":"Howitzer Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHLS-*****","DESCRIPTION":"Howitzer Light Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.LIT.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Light"},{"SYMBOLID":"S*G*EWHM--*****","DESCRIPTION":"Howitzer Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHMS-*****","DESCRIPTION":"Howitzer Medium Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.MDM.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Medium"},{"SYMBOLID":"S*G*EWHH--*****","DESCRIPTION":"Howitzer Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer"},{"SYMBOLID":"S*G*EWHHS-*****","DESCRIPTION":"Howitzer Heavy Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.8.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.HOW.HVY.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Howitzer/Howitzer Heavy"},{"SYMBOLID":"S*G*EWG---*****","DESCRIPTION":"Anti-Tank Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWGL--*****","DESCRIPTION":"Anti-Tank Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGM--*****","DESCRIPTION":"Anti-Tank Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGH--*****","DESCRIPTION":"Anti-Tank Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWGR--*****","DESCRIPTION":"Anti-Tank Gun Recoilless","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.9.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ATG.RECL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Anti-Tank Gun"},{"SYMBOLID":"S*G*EWD---*****","DESCRIPTION":"Direct Fire Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWDL--*****","DESCRIPTION":"Direct Fire Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDLS-*****","DESCRIPTION":"Direct Fire Gun Light Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.LIT.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Light"},{"SYMBOLID":"S*G*EWDM--*****","DESCRIPTION":"Direct Fire Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDMS-*****","DESCRIPTION":"Direct Fire Gun Medium Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.MDM.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Medium"},{"SYMBOLID":"S*G*EWDH--*****","DESCRIPTION":"Direct Fire Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun"},{"SYMBOLID":"S*G*EWDHS-*****","DESCRIPTION":"Direct Fire Gun Heavy Self-Propelled","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.10.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.DFG.HVY.SPD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Direct Fire Gun/Direct Fire Gun Heavy"},{"SYMBOLID":"S*G*EWA---*****","DESCRIPTION":"Air Defense Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon"},{"SYMBOLID":"S*G*EWAL--*****","DESCRIPTION":"Air Defense Gun Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EWAM--*****","DESCRIPTION":"Air Defense Gun Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EWAH--*****","DESCRIPTION":"Air Defense Gun Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.1.11.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.WPN.ADFG.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Weapon/Air Defense Gun"},{"SYMBOLID":"S*G*EV----*****","DESCRIPTION":"Ground Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EVA---*****","DESCRIPTION":"Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVAT--*****","DESCRIPTION":"Tank","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVATL-*****","DESCRIPTION":"Tank Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATLR*****","DESCRIPTION":"Tank Light Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.LIT.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Light"},{"SYMBOLID":"S*G*EVATM-*****","DESCRIPTION":"Tank Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATMR*****","DESCRIPTION":"Tank Medium Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.MDM.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Medium"},{"SYMBOLID":"S*G*EVATH-*****","DESCRIPTION":"Tank Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank"},{"SYMBOLID":"S*G*EVATHR*****","DESCRIPTION":"Tank Heavy Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.TANK.HVY.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Tank/Tank Heavy"},{"SYMBOLID":"S*G*EVAA--*****","DESCRIPTION":"Armored Personnel Carrier","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAAR-*****","DESCRIPTION":"Armored Personnel Carrier Recovery","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMPC.RCY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle/Armored Personnel Carrier"},{"SYMBOLID":"S*G*EVAI--*****","DESCRIPTION":"Armored Infantry","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.ARMINF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAC--*****","DESCRIPTION":"C2V/ACV","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.C2V","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAS--*****","DESCRIPTION":"Combat Service Support Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.CSSVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVAL--*****","DESCRIPTION":"Light Armored Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.1.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ARMD.LARMVH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Armored Vehicle"},{"SYMBOLID":"S*G*EVU---*****","DESCRIPTION":"Utility Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVUB--*****","DESCRIPTION":"Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.BUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUS--*****","DESCRIPTION":"Semi","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUSL-*****","DESCRIPTION":"Semi Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUSM-*****","DESCRIPTION":"Semi Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUSH-*****","DESCRIPTION":"Semi Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.SEMI.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Semi"},{"SYMBOLID":"S*G*EVUL--*****","DESCRIPTION":"Limited Cross-Country Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.LCCTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUX--*****","DESCRIPTION":"Cross-Country Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.CCTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUR--*****","DESCRIPTION":"Water Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.H2OCRT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUT--*****","DESCRIPTION":"Tow Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUTL-*****","DESCRIPTION":"Tow Truck Light","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.LIT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Tow Truck"},{"SYMBOLID":"S*G*EVUTH-*****","DESCRIPTION":"Tow Truck Heavy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.TOWTRK.HVY","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Tow Truck"},{"SYMBOLID":"S*G*EVUA--*****","DESCRIPTION":"Ambulance","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVUAA-*****","DESCRIPTION":"Ambulance Armored","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.2.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.UTYVEH.AMBLNC.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Utility Vehicle/Ambulance"},{"SYMBOLID":"S*G*EVE---*****","DESCRIPTION":"Engineer Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVEB--*****","DESCRIPTION":"Engineer Vehicle Bridge","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEE--*****","DESCRIPTION":"Earthmover","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ERHMR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEC--*****","DESCRIPTION":"Construction Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.CSNVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEM--*****","DESCRIPTION":"Mine Laying Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEMV-*****","DESCRIPTION":"Armored Carrier with Volcano","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.ARMCV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Laying Vehicle"},{"SYMBOLID":"S*G*EVEML-*****","DESCRIPTION":"Truck Mounted with Volcano","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MLVEH.TRKMV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Laying Vehicle"},{"SYMBOLID":"S*G*EVEA--*****","DESCRIPTION":"Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEAA-*****","DESCRIPTION":"Armored Mounted Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.ARMVM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Clearing Vehicle"},{"SYMBOLID":"S*G*EVEAT-*****","DESCRIPTION":"Trailer Mounted Mine Clearing Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.MCVEH.TM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle/Mine Clearing Vehicle"},{"SYMBOLID":"S*G*EVED--*****","DESCRIPTION":"Dozer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEDA-*****","DESCRIPTION":"Armored Dozer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.DZR.ARMD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVES--*****","DESCRIPTION":"Armored Assault","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.AST","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVER--*****","DESCRIPTION":"Armored Engineer Recon Vehicle (AERV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.ARMERV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEH--*****","DESCRIPTION":"Backhoe","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.BH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Engineer Vehicle"},{"SYMBOLID":"S*G*EVEF--*****","DESCRIPTION":"Ferry Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.ENGVEH.FRYTSP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVT---*****","DESCRIPTION":"Train Locomotive","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.TRNLCO","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVC---*****","DESCRIPTION":"Civilian Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVCA--*****","DESCRIPTION":"Civilian Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCAL-*****","DESCRIPTION":"Civilian Compact Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.CPCT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCAM-*****","DESCRIPTION":"Civilian Midsize Automobile","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.MDSZ","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCAH-*****","DESCRIPTION":"Civilian Automobile Sedan","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.AUT.SDN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Automobile"},{"SYMBOLID":"S*G*EVCO--*****","DESCRIPTION":"Civilian Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCOL-*****","DESCRIPTION":"Civilian Pickup Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.PU","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCOM-*****","DESCRIPTION":"Civilian Small Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCOH-*****","DESCRIPTION":"Civilian Large Open-Bed Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.OBTRK.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Open-Bed Truck"},{"SYMBOLID":"S*G*EVCM--*****","DESCRIPTION":"Civilian Multi-Passenger Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCML-*****","DESCRIPTION":"Civilian Multi-Passenger Van","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.VAN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCMM-*****","DESCRIPTION":"Civilian Small Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.SBUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCMH-*****","DESCRIPTION":"Civilian Large Bus","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.MPV.LBUS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Multi-Passenger Vehicle"},{"SYMBOLID":"S*G*EVCU--*****","DESCRIPTION":"Civilian Utility Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCUL-*****","DESCRIPTION":"Civilian Sport Utility Vehicle (SUV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SUV","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCUM-*****","DESCRIPTION":"Civilian Utility Small Box Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.SBOX","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCUH-*****","DESCRIPTION":"Civilian Utility Large Box Truck","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.UTYVEH.LBOX","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Utility Vehicle"},{"SYMBOLID":"S*G*EVCJ--*****","DESCRIPTION":"Civilian Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCJL-*****","DESCRIPTION":"Civilian Small/Light Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCJM-*****","DESCRIPTION":"Civilian Medium Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCJH-*****","DESCRIPTION":"Civilian Large/Heavy Jeep Type Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.JP.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Jeep Type Vehicle"},{"SYMBOLID":"S*G*EVCT--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCTL-*****","DESCRIPTION":"Civilian Small/Light Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCTM-*****","DESCRIPTION":"Civilian Medium Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCTH-*****","DESCRIPTION":"Civilian Large/Heavy Box Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRL.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Box Trailer"},{"SYMBOLID":"S*G*EVCF--*****","DESCRIPTION":"Civilian Tractor Trailer Truck With Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle"},{"SYMBOLID":"S*G*EVCFL-*****","DESCRIPTION":"Civilian Small/Light Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.SMAL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVCFM-*****","DESCRIPTION":"Civilian Medium Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.MDM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVCFH-*****","DESCRIPTION":"Civilian Large/Heavy Flatbed Trailer","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.5.7.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.CVLVEH.TRTRLF.LRG","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Civilian Vehicle/Civilian Tractor Trailer Truck With Flatbed Trailer"},{"SYMBOLID":"S*G*EVS---*****","DESCRIPTION":"Missile Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*EVST--*****","DESCRIPTION":"Transloader","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TLDR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSR--*****","DESCRIPTION":"Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.TPTR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSC--*****","DESCRIPTION":"Crane/Loading Device","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.CRN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSP--*****","DESCRIPTION":"Propellant Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.PLNT","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVSW--*****","DESCRIPTION":"Warhead Transporter","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.6.5","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.MSLSPT.WH","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle/Missile Support"},{"SYMBOLID":"S*G*EVM---*****","DESCRIPTION":"Pack Animal(s)","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.2.7","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.GRDVEH.PKAN","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Ground Vehicle"},{"SYMBOLID":"S*G*ES----*****","DESCRIPTION":"Equipment Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*ESR---*****","DESCRIPTION":"Sensor Radar","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS.RAD","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Sensor"},{"SYMBOLID":"S*G*ESE---*****","DESCRIPTION":"Emplaced Sensor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SNS.EMP","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Sensor"},{"SYMBOLID":"S*G*EX----*****","DESCRIPTION":"Special","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.2.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment"},{"SYMBOLID":"S*G*EXL---*****","DESCRIPTION":"Laser","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LSR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXN---*****","DESCRIPTION":"NBC Equipment","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.NBCEQ","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXF---*****","DESCRIPTION":"Flame Thrower","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.FLMTHR","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXM---*****","DESCRIPTION":"Land Mines","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXMC--*****","DESCRIPTION":"Claymore","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE.CLM","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Land Mines"},{"SYMBOLID":"S*G*EXML--*****","DESCRIPTION":"Less Than Lethal","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.EQT.SPL.LNDMNE.LTL","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Land Mines"},{"SYMBOLID":"S*G*EXI---*****","DESCRIPTION":"IED","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.5","ALPHAHIERARCHY":"WAR.GRNTRK.EQT.SPL.IED","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special"},{"SYMBOLID":"S*G*EXI---MO***","DESCRIPTION":"VBIED","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.2.4.5.1","ALPHAHIERARCHY":"WAR.GRNTRK.EQT.SPL.IED.VBIED","PATH":"Warfighting Symbology/Ground Track/Ground Track Equipment/Special/Improvised Explosive Device (IED)"},{"SYMBOLID":"S*G*I-----H****","DESCRIPTION":"Installation","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS","PATH":"Warfighting Symbology/Ground Track"},{"SYMBOLID":"S*G*IR----H****","DESCRIPTION":"Raw Material Production/Storage","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IRM---H****","DESCRIPTION":"Raw Material Production/Storage Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.MNE","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRP---H****","DESCRIPTION":"Petroleum/Gas/Oil","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.PGO","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRN---H****","DESCRIPTION":"NBC","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage"},{"SYMBOLID":"S*G*IRNB--H****","DESCRIPTION":"Production/Storage NBC Biological","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.BIO","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IRNC--H****","DESCRIPTION":"Production/Storage NBC Chemical","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.CML","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IRNN--H****","DESCRIPTION":"Production/Storage NBC Nuclear","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.1.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.RMP.CBRN.NUC","PATH":"Warfighting Symbology/Ground Track/Installation/Raw Material Production and Storage/NBC"},{"SYMBOLID":"S*G*IP----H****","DESCRIPTION":"Processing Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.PF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IPD---H****","DESCRIPTION":"Processing Facility Decontamination","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.PF.DECON","PATH":"Warfighting Symbology/Ground Track/Installation/Processing Facility"},{"SYMBOLID":"S*G*IE----H****","DESCRIPTION":"Equipment Manufacture","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.EQTMNF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IU----H****","DESCRIPTION":"Service, Reasearch, Utility Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IUR---H****","DESCRIPTION":"Technological Research Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.TRF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUT---H****","DESCRIPTION":"Telecommunications Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.TCF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUE---H****","DESCRIPTION":"Electric Power Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IUEN--H****","DESCRIPTION":"Nuclear Plant","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.NPT","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUED--H****","DESCRIPTION":"Dam","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.DAM","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUEF--H****","DESCRIPTION":"Fossil Fuel","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.3.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.EPF.FOSF","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility/Electric Power Facility"},{"SYMBOLID":"S*G*IUP---H****","DESCRIPTION":"Public Water Services","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.4.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.SRUF.PWS","PATH":"Warfighting Symbology/Ground Track/Installation/Service, Reasearch, Utility Facility"},{"SYMBOLID":"S*G*IM----H****","DESCRIPTION":"Military Materiel Facility","DRAWCATEGORY":"0","HIERARCHY":"1.X.3.3.5","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IMF---H****","DESCRIPTION":"Nuclear Energy","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMFA--H****","DESCRIPTION":"Atomic Energy Reactor","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.ATMER","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMFP--H****","DESCRIPTION":"Nuclear Material Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMFPW-H****","DESCRIPTION":"Weapons Grade","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.2.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMP.WPNGR","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy/Nuclear Material Production"},{"SYMBOLID":"S*G*IMFS--H****","DESCRIPTION":"Nuclear Material Storage","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.1.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.NENY.NMS","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Nuclear Energy"},{"SYMBOLID":"S*G*IMA---H****","DESCRIPTION":"Aircraft Production & Assembly","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.APA","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IME---H****","DESCRIPTION":"Ammunition And Explosives Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.3","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.AMEP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMG---H****","DESCRIPTION":"Armament Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.4","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.AMTP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMV---H****","DESCRIPTION":"Military Vehicle Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.5","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.MILVP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMN---H****","DESCRIPTION":"Engineering Equipment Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.6","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.ENGEP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMNB--H****","DESCRIPTION":"Engineering Equipment Production Bridge","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.6.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.ENGEP.BRG","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility/Engineering Equipment Production"},{"SYMBOLID":"S*G*IMC---H****","DESCRIPTION":"Chemical & Biological Warfare Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.7","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.CBWP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMS---H****","DESCRIPTION":"Ship Construction","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.8","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.SHPCSN","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IMM---H****","DESCRIPTION":"Missile & Space System Production","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.5.9","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MMF.MSSP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Materiel Facility"},{"SYMBOLID":"S*G*IG----H****","DESCRIPTION":"Government Leadership","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.6","ALPHAHIERARCHY":"WAR.GRDTRK.INS.GOVLDR","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IB----H****","DESCRIPTION":"Military Base/Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IBA---H****","DESCRIPTION":"Airport/Airbase","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF.AB","PATH":"Warfighting Symbology/Ground Track/Installation/Military Base and Facility"},{"SYMBOLID":"S*G*IBN---H****","DESCRIPTION":"Seaport/Naval Base","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.7.2","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MILBF.SP","PATH":"Warfighting Symbology/Ground Track/Installation/Military Base and Facility"},{"SYMBOLID":"S*G*IT----H****","DESCRIPTION":"Transport Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.8","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TSPF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IX----H****","DESCRIPTION":"Medical Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.9","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MEDF","PATH":"Warfighting Symbology/Ground Track/Installation"},{"SYMBOLID":"S*G*IXH---H****","DESCRIPTION":"Hospital","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.9.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.MEDF.HSP","PATH":"Warfighting Symbology/Ground Track/Installation/Medical Facility"},{"SYMBOLID":"S*G*IC----H****","DESCRIPTION":"Tented Camp","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TNTCMP","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION"},{"SYMBOLID":"S*G*ICD---H****","DESCRIPTION":"Tented Camp, Displaced Persons/Refugees","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10.1","ALPHAHIERARCHY":"WAR.GRDTRK.INS.TNTCMP.DPRE","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION/Tented Camp"},{"SYMBOLID":"S*G*ICT---H****","DESCRIPTION":"Tented Training Camp","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.10.2","ALPHAHIERARCHY":"WAR.GRDTRK.INK.INS.TNTCMP.TNG","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION/TENTED CAMP"},{"SYMBOLID":"S*G*IW----H****","DESCRIPTION":"Warehouse/Storage Facility","DRAWCATEGORY":"8","HIERARCHY":"1.X.3.3.11","ALPHAHIERARCHY":"WAR.GRDTRK.INS.WAREHS","PATH":"WARFIGHTING SYMBOLS/GROUND TRACK/INSTALLATION"},{"SYMBOLID":"S*S*------*****","DESCRIPTION":"Sea Surface Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.4","ALPHAHIERARCHY":"WAR.SSUF","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*S*C-----*****","DESCRIPTION":"Sea Surface Track Combatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*CL----*****","DESCRIPTION":"Line","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CLCV--*****","DESCRIPTION":"Carrier","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.CRR","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLBB--*****","DESCRIPTION":"Battleship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.BBS","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLCC--*****","DESCRIPTION":"Cruiser","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.CRU","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLDD--*****","DESCRIPTION":"Destroyer","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.DD","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLFF--*****","DESCRIPTION":"Frigate/Corvette","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.5","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.FFR","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLLL--*****","DESCRIPTION":"Littoral Combatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line"},{"SYMBOLID":"S*S*CLLLAS*****","DESCRIPTION":"Antisubmarine Warfare Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CLLLMI*****","DESCRIPTION":"Mine Warfare Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.MNEW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CLLLSU*****","DESCRIPTION":"Surface Warfare (SUW) Mission Package","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.1.6.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.LNE.LL.SUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Line/Littoral Combatant"},{"SYMBOLID":"S*S*CA----*****","DESCRIPTION":"Amphibious Warfare Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CALA--*****","DESCRIPTION":"Assault Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.ASTVES","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CALS--*****","DESCRIPTION":"Landing Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CALSM-*****","DESCRIPTION":"Landing Ship Medium","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP.MDM","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship/Landing Ship"},{"SYMBOLID":"S*S*CALST-*****","DESCRIPTION":"Landing Ship Tank","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDSHP.TANK","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship/Landing Ship"},{"SYMBOLID":"S*S*CALC--*****","DESCRIPTION":"Landing Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.2.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.AMPWS.LNDCRT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Amphibious Warfare Ship"},{"SYMBOLID":"S*S*CM----*****","DESCRIPTION":"Mine Warfare Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CMML--*****","DESCRIPTION":"Minelayer","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNELYR","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMS--*****","DESCRIPTION":"Minesweeper","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNESWE","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMH--*****","DESCRIPTION":"Minehunter","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MNEHNT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CMMA--*****","DESCRIPTION":"MCM Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.3.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.MNEWV.MCMSUP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Mine Warfare Vessel"},{"SYMBOLID":"S*S*CP----*****","DESCRIPTION":"Sea Surface Combatant Patrol","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CPSB--*****","DESCRIPTION":"Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Sea Surface Combatant Patrol"},{"SYMBOLID":"S*S*CPSU--*****","DESCRIPTION":"Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Sea Surface Combatant Patrol"},{"SYMBOLID":"S*S*CPSUM-*****","DESCRIPTION":"Anti-Ship Missile","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.ASMSL","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CPSUT-*****","DESCRIPTION":"Torpedo(Antisurface Warfare)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.TPD","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CPSUG-*****","DESCRIPTION":"Antisurface Warfare Gun","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.4.2.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.PAT.ASUW.GUN","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Patrol/Antisurface Warfare"},{"SYMBOLID":"S*S*CH----*****","DESCRIPTION":"Combatant Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.5","ALPHAHIERARCHY":"WAR.SSUF.CBTT.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*S-----*****","DESCRIPTION":"Sea Surface Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*SP----*****","DESCRIPTION":"Picket","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN.PKT","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Station"},{"SYMBOLID":"S*S*SA----*****","DESCRIPTION":"ASW Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.6.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.STN.ASWSHP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Station"},{"SYMBOLID":"S*S*G-----*****","DESCRIPTION":"Navy Group","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*GT----*****","DESCRIPTION":"Navy Task Force","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTF","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GG----*****","DESCRIPTION":"Navy Task Group","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTG","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GU----*****","DESCRIPTION":"Navy Task Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.NAVTU","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*GC----*****","DESCRIPTION":"Convoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.7.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.NAVGRP.CNY","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Navy Group"},{"SYMBOLID":"S*S*CD----*****","DESCRIPTION":"Surface Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.8","ALPHAHIERARCHY":"WAR.SSUF.CBTT.SUFDCY","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant"},{"SYMBOLID":"S*S*CU----*****","DESCRIPTION":"Unmanned Surface Vehicle (USV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/"},{"SYMBOLID":"S*S*CUM---*****","DESCRIPTION":"USV Mine Countermeasures","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.1","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.MNECM","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUS---*****","DESCRIPTION":"USV Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.2","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.ASBW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUN---*****","DESCRIPTION":"USV Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.3","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.ASUW","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*CUR---*****","DESCRIPTION":"USV Remote Multimission Vehicle","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.1.9.4","ALPHAHIERARCHY":"WAR.SSUF.CBTT.USV.RMV","PATH":"Warfighting Symbology/Sea Surface Track/Sea Surface Track Combatant/Unmanned Surface Vehicle (USV)"},{"SYMBOLID":"S*S*N-----*****","DESCRIPTION":"Noncombatant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2","ALPHAHIERARCHY":"WAR.SSUF.NCBTT","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*NR----*****","DESCRIPTION":"Underway Replenishment","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.1","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.UWRPM","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NF----*****","DESCRIPTION":"Fleet Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.2","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.FLTSUP","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NI----*****","DESCRIPTION":"Intelligence","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.3","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.INT","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NS----*****","DESCRIPTION":"Service & Support Harbor","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.4","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.SSH","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NM----*****","DESCRIPTION":"Hospital Ship","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.5","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.HSPSHP","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NH----*****","DESCRIPTION":"Noncombatant Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.6","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NN----*****","DESCRIPTION":"Noncombatant Station","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.7","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.STN","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant"},{"SYMBOLID":"S*S*NNR---*****","DESCRIPTION":"Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.2.7.1","ALPHAHIERARCHY":"WAR.SSUF.NCBTT.STN.RSC","PATH":"Warfighting Symbology/Sea Surface Track/Noncombatant/Station"},{"SYMBOLID":"S*S*X-----*****","DESCRIPTION":"Non-Military","DRAWCATEGORY":"0","HIERARCHY":"1.X.4.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*S*XM----*****","DESCRIPTION":"Merchant","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XMC---*****","DESCRIPTION":"Subsurface Non-military Cargo","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.CGO","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMR---*****","DESCRIPTION":"Roll On/Roll Off","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.RORO","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMO---*****","DESCRIPTION":"Oiler/Tanker","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.OLR","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMTU--*****","DESCRIPTION":"Tug","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.4","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.TUG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMF---*****","DESCRIPTION":"Ferry","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.5","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.FRY","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMP---*****","DESCRIPTION":"Passenger","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.6","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.PSG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMH---*****","DESCRIPTION":"Hazardous Materials (HAZMAT)","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.7","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.HAZMAT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XMTO--*****","DESCRIPTION":"Towing Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.1.8","ALPHAHIERARCHY":"WAR.SSUF.NMIL.MCT.TOWVES","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Merchant"},{"SYMBOLID":"S*S*XF----*****","DESCRIPTION":"Fishing","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XFDF--*****","DESCRIPTION":"Drifter","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.1","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.DRFT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XFDR--*****","DESCRIPTION":"Dredge","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.2","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.DRG","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XFTR--*****","DESCRIPTION":"Trawler","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.2.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.FSG.TRW","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military/Fishing"},{"SYMBOLID":"S*S*XR----*****","DESCRIPTION":"Leisure Craft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.3","ALPHAHIERARCHY":"WAR.SSUF.NMIL.LESCRT","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XL----*****","DESCRIPTION":"Law Enforcement Vessel","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.4","ALPHAHIERARCHY":"WAR.SSUF.NMIL.LAWENV","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*XH----*****","DESCRIPTION":"Non-military Hovercraft","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.3.5","ALPHAHIERARCHY":"WAR.SSUF.NMIL.HOV","PATH":"Warfighting Symbology/Sea Surface Track/Non-Military"},{"SYMBOLID":"S*S*O-----*****","DESCRIPTION":"Own Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.4.4","ALPHAHIERARCHY":"WAR.SSUF.OWN","PATH":"Warfighting Symbology/Sea Surface Track"},{"SYMBOLID":"S*U*------*****","DESCRIPTION":"Subsurface Track","DRAWCATEGORY":"8","HIERARCHY":"1.X.5","ALPHAHIERARCHY":"WAR.SBSUF","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*U*S-----*****","DESCRIPTION":"Submarine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*SN----*****","DESCRIPTION":"Nuclear Propulsion","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SNF---*****","DESCRIPTION":"Submarine Nuclear Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNA---*****","DESCRIPTION":"Submarine Nuclear Attack (SSN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.ATK","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNM---*****","DESCRIPTION":"Submarine Nuclear Missile Type Unknown","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.MSL","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNG---*****","DESCRIPTION":"Submarine Nuclear Guided Missile (SSGN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.4","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.GDD","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SNB---*****","DESCRIPTION":"Ballistic Missile Submarine (SSB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.1.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NPRN.BLST","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Nuclear Propulsion"},{"SYMBOLID":"S*U*SC----*****","DESCRIPTION":"Conventional Propulsion","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SCF---*****","DESCRIPTION":"Conventional Propulsion Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCA---*****","DESCRIPTION":"Attack Submarine (SS)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.ATK","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCM---*****","DESCRIPTION":"Conventional Propulsion Missile Submarine (TYPE UNKNOWN)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.MSL","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCG---*****","DESCRIPTION":"Guided Missile Submarine (SSG)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.4","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.GDD","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SCB---*****","DESCRIPTION":"Conventional Propulsion Ballistic Missile (SSB)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.2.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CNVPRN.BLST","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Conventional Propulsion"},{"SYMBOLID":"S*U*SO----*****","DESCRIPTION":"Other Submersible","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.OTH","PATH":"Warfighting Symbology/Subsurface Track/Submarine"},{"SYMBOLID":"S*U*SOF---*****","DESCRIPTION":"Other Submersible Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.0","ALPHAHIERARCHY":"WAR.SBSUF.SUB.OTH.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible"},{"SYMBOLID":"S*U*SU----*****","DESCRIPTION":"Unmanned Underwater Vehicle (UUV)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible"},{"SYMBOLID":"S*U*SUM---*****","DESCRIPTION":"UUV Mine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.1","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.MNEW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SUS---*****","DESCRIPTION":"UUV Antisubmarine Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.2","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.ASBW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SUN---*****","DESCRIPTION":"UUV Antisurface Warfare","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.3.1.3","ALPHAHIERARCHY":"WAR.SBSUF.SUB.UUV.ASUW","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Other Submersible/Unmanned Underwater Vehicle (UUV)"},{"SYMBOLID":"S*U*SF----*****","DESCRIPTION":"Submarine Surfaced","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.5","ALPHAHIERARCHY":"WAR.SBSUF.SUB.SURF","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*SB----*****","DESCRIPTION":"Submarine Bottomed","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.6","ALPHAHIERARCHY":"WAR.SBSUF.SUB.BOTTMD","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*SR----*****","DESCRIPTION":"Submarine Certsub","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.7","ALPHAHIERARCHY":"WAR.SBSUF.SUB.CRT","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*SX----*****","DESCRIPTION":"Non Submarine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.8","ALPHAHIERARCHY":"WAR.SBSUF.SUB.NONSUB","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*S1----*****","DESCRIPTION":"Possub-1","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.9","ALPHAHIERARCHY":"WAR.SBSUF.SUB.POSS1","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*S2----*****","DESCRIPTION":"Possub-2","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.10","ALPHAHIERARCHY":"WAR.SBSUF.SUB.POSS2","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*S3----*****","DESCRIPTION":"Possub-3","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.11","ALPHAHIERARCHY":"WAR.SBSUF.SUB.POSS3","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*S4----*****","DESCRIPTION":"Possub-4","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.12","ALPHAHIERARCHY":"WAR.SBSUF.SUB.POSS4","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*SL----*****","DESCRIPTION":"ProbSub","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.13","ALPHAHIERARCHY":"WAR.SBSUF.SUB.PRBSUB","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*SK----*****","DESCRIPTION":"Snorkeling","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.1.14","ALPHAHIERARCHY":"WAR.SBSUF.SUB.SNORKL","PATH":"Warfighting Symbology/Subsurface Track/Submarine/Station"},{"SYMBOLID":"S*U*W-----*****","DESCRIPTION":"Underwater Weapon","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*WT----*****","DESCRIPTION":"Torpedo","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.TPD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon"},{"SYMBOLID":"S*U*WM----*****","DESCRIPTION":"Sea Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon"},{"SYMBOLID":"S*U*WMD---*****","DESCRIPTION":"Sea Mine Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMG---*****","DESCRIPTION":"Sea Mine (Ground)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMGD--*****","DESCRIPTION":"Sea Mine (Ground) Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMGX--*****","DESCRIPTION":"Ground (Bottom) Excercise Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.EXER","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMGE--*****","DESCRIPTION":"Ground (Bottom) MILEC","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.MILEC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMGC--*****","DESCRIPTION":"Ground (Bottom) MILCO","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.4","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.MILCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMGR--*****","DESCRIPTION":"Ground (Bottom) Negative Reacquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.5","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.NGREAC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMGO--*****","DESCRIPTION":"Ground (Bottom) Non-Mine Mike-Like Contact","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.2.6","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMG.NMMLCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Ground)"},{"SYMBOLID":"S*U*WMM---*****","DESCRIPTION":"Sea Mine (Moored)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMMD--*****","DESCRIPTION":"Sea Mine (Moored) Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMMX--*****","DESCRIPTION":"Moored Exercise Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.EXER","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMME--*****","DESCRIPTION":"Moored MILEC","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.MILEC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMMC--*****","DESCRIPTION":"Moored MILCO","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.4","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.MILCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMMR--*****","DESCRIPTION":"Moored Negative Reacquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.5","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.NGREAC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMMO--*****","DESCRIPTION":"Moored Non-Mine Mine-Like Object","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.3.6","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMM.NMMLCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Moored)"},{"SYMBOLID":"S*U*WMF---*****","DESCRIPTION":"Sea Mine (Floating)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMFD--*****","DESCRIPTION":"Sea Mine (Floating) Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.DLT","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMFX--*****","DESCRIPTION":"Floating Exercise Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.EXER","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMFE--*****","DESCRIPTION":"Floating MILEC","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.MILEC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMFC--*****","DESCRIPTION":"Floating MILCO","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.4","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.MILCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMFR--*****","DESCRIPTION":"Floating Negative Reacquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.5","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.NGREAC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMFO--*****","DESCRIPTION":"Floating Non-Mine Mine-Like Contact","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.4.6","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMF.NMMLCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (Floating)"},{"SYMBOLID":"S*U*WMO---*****","DESCRIPTION":"Sea Mine (Other Position)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.5","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMOP","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMOD--*****","DESCRIPTION":"Sea Mine (Other Position) Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.5.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.SMOP.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Sea Mine (In Other Position)"},{"SYMBOLID":"S*U*WMX---*****","DESCRIPTION":"General Exercise Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.6","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.EXER","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WME---*****","DESCRIPTION":"General MILEC","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.7","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.MILEC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMA---*****","DESCRIPTION":"General Mine Anchor","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.8","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.ANCHOR","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMC---*****","DESCRIPTION":"General MILCO","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.9","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.MILCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMR---*****","DESCRIPTION":"General Negative Reacquisition","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.10","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.NGREAC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMB---*****","DESCRIPTION":"General Obstructor","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.11","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.OBSTRC","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMBD--*****","DESCRIPTION":"General Obstructor Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.11.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.OBSTRC.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/General Obstructor"},{"SYMBOLID":"S*U*WMN---*****","DESCRIPTION":"General Non-Mine Mine-Like Object","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.12","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.NMMLCO","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMS---*****","DESCRIPTION":"Rising Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.13","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.RISING","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine"},{"SYMBOLID":"S*U*WMSX--*****","DESCRIPTION":"Rising Exercise Mine","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.13.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.RISING.EXER","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Rising Mine"},{"SYMBOLID":"S*U*WMSD--*****","DESCRIPTION":"Rising Mine Neutralized","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.2.2.13.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2WPN.SMNE.RISING.NTRLZD","PATH":"Warfighting Symbology/Subsurface Track/Underwater Weapon/Sea Mine/Rising Mine"},{"SYMBOLID":"S*U*WD----*****","DESCRIPTION":"Underwater Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*WDM---*****","DESCRIPTION":"Sea Mine Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY.SMDCY","PATH":"Warfighting Symbology/Subsurface Track/Underwater Decoy"},{"SYMBOLID":"S*U*WDMG--*****","DESCRIPTION":"Ground (Bottom) Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3.1.1","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY.SMDCY.GRND","PATH":"Warfighting Symbology/Subsurface Track/Underwater Decoy/Sea Mine Decoy"},{"SYMBOLID":"S*U*WDMM--*****","DESCRIPTION":"Moored Decoy","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.3.1.2","ALPHAHIERARCHY":"WAR.SBSUF.UH2DCY.SMDCY.MOORED","PATH":"Warfighting Symbology/Subsurface Track/Underwater Decoy/Sea Mine Decoy"},{"SYMBOLID":"S*U*N-----*****","DESCRIPTION":"Non-Submarine","DRAWCATEGORY":"0","HIERARCHY":"1.X.5.4","ALPHAHIERARCHY":"WAR.SBSUF.NSUB","PATH":"Warfighting Symbology/Subsurface Track"},{"SYMBOLID":"S*U*ND----*****","DESCRIPTION":"Diver","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.4.1","ALPHAHIERARCHY":"WAR.SBSUF.NSUB.DVR","PATH":"Warfighting Symbology/Subsurface Track/Non-Submarine"},{"SYMBOLID":"S*U*E-----*****","DESCRIPTION":"Environmental Report Location","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.5","ALPHAHIERARCHY":"WAR.SBSUF.ERL","PATH":"WARFIGHTING SYMBOLS/SUBSURFACE TRACK"},{"SYMBOLID":"S*U*V-----*****","DESCRIPTION":"Dive Report Location","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.6","ALPHAHIERARCHY":"WAR.SBSUF.DRL","PATH":"WARFIGHTING SYMBOLS/SUBSURFACE TRACK"},{"SYMBOLID":"S*U*X-----*****","DESCRIPTION":"Unexploded Ordnance Area (Subsurface)","DRAWCATEGORY":"8","HIERARCHY":"1.X.5.7","ALPHAHIERARCHY":"WAR.SBSUF.UXO","PATH":"WARFIGHTING SYMBOLS/SUBSURFACE TRACK"},{"SYMBOLID":"S*F*------*****","DESCRIPTION":"Special Operations Forces (SOF) Unit","DRAWCATEGORY":"8","HIERARCHY":"1.X.6","ALPHAHIERARCHY":"WAR.SOFUNT","PATH":"Warfighting Symbology"},{"SYMBOLID":"S*F*A-----*****","DESCRIPTION":"SOF Unit Aviation","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*AF----*****","DESCRIPTION":"SOF Unit Fixed Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AFA---*****","DESCRIPTION":"SOF Unit Fixed Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.ATK","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFK---*****","DESCRIPTION":"SOF Unit Refuel","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.RFE","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFU---*****","DESCRIPTION":"SOF Unit Fixed Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing"},{"SYMBOLID":"S*F*AFUL--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.LIT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AFUM--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.MDM","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AFUH--*****","DESCRIPTION":"SOF Unit Fixed Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.1.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.FIXD.UTY.HVY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Fixed Wing/SOF Unit Fixed Wing Utility"},{"SYMBOLID":"S*F*AV----*****","DESCRIPTION":"SOF Unit V/STOL","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.VSTOL","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AH----*****","DESCRIPTION":"SOF Unit Rotary Wing","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation"},{"SYMBOLID":"S*F*AHH---*****","DESCRIPTION":"SOF Unit Rotary Wing Combat Search & Rescue","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.CSAR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHA---*****","DESCRIPTION":"SOF Unit Rotary Wing Attack","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.ATK","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHU---*****","DESCRIPTION":"SOF Unit Rotary Wing Utility","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing"},{"SYMBOLID":"S*F*AHUL--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Light)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.LIT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*AHUM--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Medium)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.MDM","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*AHUH--*****","DESCRIPTION":"SOF Unit Rotary Wing Utility (Heavy)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.1.3.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.AVN.ROT.UTY.HVY","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Aviation/SOF Unit Rotary Wing/SOF Unit Rotary Wing Utility"},{"SYMBOLID":"S*F*N-----*****","DESCRIPTION":"SOF Unit SOF Unit Naval","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2","ALPHAHIERARCHY":"WAR.SOFUNT.NAV","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*NS----*****","DESCRIPTION":"SOF Unit Seal","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.1","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SEAL","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NU----*****","DESCRIPTION":"SOF Unit Underwater Demolition Team","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.2","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.UH2DML","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NB----*****","DESCRIPTION":"SOF Unit Special Boat","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.3","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SBT","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*NN----*****","DESCRIPTION":"SOF Unit Special SSNR","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.2.4","ALPHAHIERARCHY":"WAR.SOFUNT.NAV.SSSNR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit SOF Unit Naval"},{"SYMBOLID":"S*F*G-----*****","DESCRIPTION":"SOF Unit Ground","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3","ALPHAHIERARCHY":"WAR.SOFUNT.GRD","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*F*GS----*****","DESCRIPTION":"SOF Unit Special Forces","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.SOF","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GR----*****","DESCRIPTION":"SOF Unit Ranger","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.2","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.RGR","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GP----*****","DESCRIPTION":"SOF Unit Psychological Operations (PSYOP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.3","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.PSYOP","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*GPA---*****","DESCRIPTION":"SOF Unit Fixed Wing Aviation (PSYOP)","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.3.1","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.PSYOP.FIXAVN","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground/SOF Unit Psychological Operations (PSYOP)"},{"SYMBOLID":"S*F*GC----*****","DESCRIPTION":"SOF Unit Civil Affairs","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.3.4","ALPHAHIERARCHY":"WAR.SOFUNT.GRD.CVLAFF","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit/SOF Unit Ground"},{"SYMBOLID":"S*F*B-----*****","DESCRIPTION":"SOF Unit Support","DRAWCATEGORY":"8","HIERARCHY":"1.X.6.4","ALPHAHIERARCHY":"WAR.SOFUNT.SUP","PATH":"Warfighting Symbology/Special Operations Forces (SOF) Unit"},{"SYMBOLID":"S*Z*------*****","DESCRIPTION":"Unknown Battle Dimension","DRAWCATEGORY":"8","HIERARCHY":"1.X.7","ALPHAHIERARCHY":"UNK","PATH":"Warfighting Symbology"},{"SYMBOLID":"I*-*--------***","DESCRIPTION":"Signals Intelligence","DRAWCATEGORY":"0","HIERARCHY":"4.X","ALPHAHIERARCHY":"SIGINT"},{"SYMBOLID":"I*P*--------***","DESCRIPTION":"Space Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.1","ALPHAHIERARCHY":"SIGINT.SPC","PATH":"Signals Intelligence"},{"SYMBOLID":"I*P*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC","PATH":"Signals Intelligence/Space Track"},{"SYMBOLID":"I*P*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.COMM","PATH":"Signals Intelligence/Space Track/Signal Intercept"},{"SYMBOLID":"I*P*SCD-----***","DESCRIPTION":"Satellite Down-Link","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.1.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.COMM.SATDL","PATH":"Signals Intelligence/Space Track/Signal Intercept/Communications"},{"SYMBOLID":"I*P*SR------***","DESCRIPTION":"Radar(Signal Intercept)","DRAWCATEGORY":"0","HIERARCHY":"4.X.1.1.2","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD","PATH":"Signals Intelligence/Space Track/Signal Intercept"},{"SYMBOLID":"I*P*SRD-----***","DESCRIPTION":"Data Transmission(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.1","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRE-----***","DESCRIPTION":"Earth Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.2","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.ERHSVL","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRI-----***","DESCRIPTION":"IFF (Transponder)(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.3","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.IFF","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRM-----***","DESCRIPTION":"Multi-function(SPACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.4","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRT-----***","DESCRIPTION":"Target Acquisition(Space Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.5","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRS-----***","DESCRIPTION":"Space","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.6","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.SPC","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*P*SRU-----***","DESCRIPTION":"Unknown(Space Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.1.1.2.7","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Space Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*--------***","DESCRIPTION":"Air Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.2","ALPHAHIERARCHY":"SIGINT.AIRTRK","PATH":"Signals Intelligence"},{"SYMBOLID":"I*A*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC","PATH":"Signals Intelligence/Air Track"},{"SYMBOLID":"I*A*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM","PATH":"Signals Intelligence/Air Track/Signal Intercept"},{"SYMBOLID":"I*A*SCC-----***","DESCRIPTION":"Cellular/Mobile(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.2","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.3","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SCS-----***","DESCRIPTION":"Satellite Up-Link(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.1.4","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Communications"},{"SYMBOLID":"I*A*SR------***","DESCRIPTION":"Radar","DRAWCATEGORY":"0","HIERARCHY":"4.X.2.1.2","ALPHAHIERARCHY":"SIGINT.SPC.SIGINC.RAD","PATH":"Signals Intelligence/Air Track/Signal Intercept"},{"SYMBOLID":"I*A*SRAI----***","DESCRIPTION":"Airborne Intercept","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.1","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.ABNINC","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRAS----***","DESCRIPTION":"Airborne Search and Bombing","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.2","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.ABNSB","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRC-----***","DESCRIPTION":"Controlled Intercept(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.3","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.CTDINC","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRD-----***","DESCRIPTION":"Data Transmission(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.4","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRE-----***","DESCRIPTION":"Early Warning(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.5","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.EW","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRF-----***","DESCRIPTION":"Fire Control(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.6","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRI-----***","DESCRIPTION":"IFF (Transponder)(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.7","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.IFF","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMA----***","DESCRIPTION":"Missile Acquisition(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.8","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMD----***","DESCRIPTION":"Missile Downlink","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.9","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLDL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMG----***","DESCRIPTION":"Missile Guidance(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.10","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMT----***","DESCRIPTION":"Missile Tracking(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.11","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRMF----***","DESCRIPTION":"Multi-Function(AIR TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.12","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTI----***","DESCRIPTION":"Target Illuminator(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.13","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTA----***","DESCRIPTION":"Target Acquisition(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.14","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRTT----***","DESCRIPTION":"Target Tracking(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.15","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*A*SRU-----***","DESCRIPTION":"Unknown(Air Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.2.1.2.16","ALPHAHIERARCHY":"SIGINT.AIRTRK.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Air Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*--------***","DESCRIPTION":"Ground Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.3","ALPHAHIERARCHY":"SIGINT.GRDTRK","PATH":"Signals Intelligence"},{"SYMBOLID":"I*G*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC","PATH":"Signals Intelligence/Ground Track"},{"SYMBOLID":"I*G*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM","PATH":"Signals Intelligence/Ground Track/Signal Intercept"},{"SYMBOLID":"I*G*SCC-----***","DESCRIPTION":"Cellular/Mobile(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.2","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.3","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCS-----***","DESCRIPTION":"Satellite Up-Link(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.4","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SCT-----***","DESCRIPTION":"Tropospheric Scatter","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.1.5","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.COMM.TPSSCT","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Communications"},{"SYMBOLID":"I*G*SR------***","DESCRIPTION":"Radar(Signals Intelligence)","DRAWCATEGORY":"0","HIERARCHY":"4.X.3.1.2","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD","PATH":"Signals Intelligence/Ground Track/Signal Intercept"},{"SYMBOLID":"I*G*SRAT----***","DESCRIPTION":"Air Traffic Control(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.1","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.ATCTL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRAA----***","DESCRIPTION":"Anti-Aircraft(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.2","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.AAC","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRB-----***","DESCRIPTION":"Battlefield Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.3","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.BTFSVL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRCS----***","DESCRIPTION":"Coastal Surveillance","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.4","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.CSTSVL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRCA----***","DESCRIPTION":"Controlled Approach(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.5","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.CTDAPP","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRD-----***","DESCRIPTION":"Data Transmission(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.6","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRE-----***","DESCRIPTION":"Early Warning(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.7","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.EW","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRF-----***","DESCRIPTION":"Fire Control(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.8","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRH-----***","DESCRIPTION":"Height Finding(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.9","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.HGTFDG","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRI-----***","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.10","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.IDFF","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMM----***","DESCRIPTION":"Meteorological (Military)(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.11","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.METO","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMA----***","DESCRIPTION":"Missile Acquisition(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.12","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMG----***","DESCRIPTION":"Missile Guidance(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.13","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMT----***","DESCRIPTION":"Missile Tracking(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.14","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRMF----***","DESCRIPTION":"Multi-Function(GROUND TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.15","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRS-----***","DESCRIPTION":"Shell Tracking","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.16","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.SHETKG","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTA----***","DESCRIPTION":"Target Acquisition(Radar)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.17","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTI----***","DESCRIPTION":"Target Illuminator(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.18","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRTT----***","DESCRIPTION":"Target Tracking(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.19","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*G*SRU-----***","DESCRIPTION":"Unknown(Ground Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.3.1.2.20","ALPHAHIERARCHY":"SIGINT.GRDTRK.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Ground Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*--------***","DESCRIPTION":"Sea Surface Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.4","ALPHAHIERARCHY":"SIGINT.SSUF","PATH":"Signals Intelligence"},{"SYMBOLID":"I*S*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC","PATH":"Signals Intelligence/Sea Surface Track"},{"SYMBOLID":"I*S*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept"},{"SYMBOLID":"I*S*SCC-----***","DESCRIPTION":"Cellular/Mobile(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.CELL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.2","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.3","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SCS-----***","DESCRIPTION":"Satellite Up-Link(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.1.4","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*S*SR------***","DESCRIPTION":"Radar(Sea Surface Track)","DRAWCATEGORY":"0","HIERARCHY":"4.X.4.1.2","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept"},{"SYMBOLID":"I*S*SRAT----***","DESCRIPTION":"Air Traffic Control(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.1","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.ATCTL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRAA----***","DESCRIPTION":"Anti-Aircraft(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.2","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.AAC","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRCA----***","DESCRIPTION":"Controlled Approach(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.3","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.CTDAPP","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRCI----***","DESCRIPTION":"Controlled Intercept(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.4","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.CTDINC","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRD-----***","DESCRIPTION":"Data Transmission(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.5","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRE-----***","DESCRIPTION":"Early Warning(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.6","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.EW","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRF-----***","DESCRIPTION":"Fire Control(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.7","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.FIRCTL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRH-----***","DESCRIPTION":"Height Finding(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.8","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.HGTFDG","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRI-----***","DESCRIPTION":"Indentification Friend/Foe (Interrogator)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.9","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.IDFF","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMM----***","DESCRIPTION":"Meteorological (Military)(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.10","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.METO","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMA----***","DESCRIPTION":"Missile Acquisition(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.11","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLAQ","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMG----***","DESCRIPTION":"Missile Guidance(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.12","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLGDN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMT----***","DESCRIPTION":"Missile Tracking(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.13","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MSLTRK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRMF----***","DESCRIPTION":"Multi-Function(SEA SURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.14","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRS-----***","DESCRIPTION":"Surface Search(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.15","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.SUFSRH","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTA----***","DESCRIPTION":"Target Acquisition(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.16","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTI----***","DESCRIPTION":"Target Illuminator(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.17","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTILL","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRTT----***","DESCRIPTION":"Target Tracking(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.18","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.TGTTRK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*S*SRU-----***","DESCRIPTION":"Unknown(Sea Surface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.4.1.2.19","ALPHAHIERARCHY":"SIGINT.SSUF.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Sea Surface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*--------***","DESCRIPTION":"Subsurface Track","DRAWCATEGORY":"0","HIERARCHY":"4.X.5","ALPHAHIERARCHY":"SIGINT.SBSUF","PATH":"Signals Intelligence"},{"SYMBOLID":"I*U*S-------***","DESCRIPTION":"Signal Intercept","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC","PATH":"Signals Intelligence/Subsurface Track"},{"SYMBOLID":"I*U*SC------***","DESCRIPTION":"Communications","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept"},{"SYMBOLID":"I*U*SCO-----***","DESCRIPTION":"Omni-Line-Of-Sight (LOS)(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.OLOS","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SCP-----***","DESCRIPTION":"Point-To-Point Line-Of-Sight (LOS)(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.2","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.PTPLOS","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SCS-----***","DESCRIPTION":"Satellite Up-Link(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.1.3","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.COMM.SATUL","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Communications"},{"SYMBOLID":"I*U*SR------***","DESCRIPTION":"Radar(Subsurface Track)","DRAWCATEGORY":"0","HIERARCHY":"4.X.5.1.2","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept"},{"SYMBOLID":"I*U*SRD-----***","DESCRIPTION":"Data Transmission(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.1","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.DATTMN","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRE-----***","DESCRIPTION":"Early Warning(SUBSURFACE TRACK)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.2","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.EW","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRM-----***","DESCRIPTION":"Multi-Function(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.3","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.MFN","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRS-----***","DESCRIPTION":"Surface Search(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.4","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.SUFSRH","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRT-----***","DESCRIPTION":"Target Acquisition(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.5","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.TGTAQ","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"I*U*SRU-----***","DESCRIPTION":"Unknown(Subsurface Track)","DRAWCATEGORY":"8","HIERARCHY":"4.X.5.1.2.6","ALPHAHIERARCHY":"SIGINT.SBSUF.SIGINC.RAD.UNK","PATH":"Signals Intelligence/Subsurface Track/Signal Intercept/Radar"},{"SYMBOLID":"O*-*------*****","DESCRIPTION":"Stability Operations","DRAWCATEGORY":"0","HIERARCHY":"5.X","ALPHAHIERARCHY":"STBOPS"},{"SYMBOLID":"O*V*------*****","DESCRIPTION":"Violent Activities","DRAWCATEGORY":"0","HIERARCHY":"5.X.1","ALPHAHIERARCHY":"STBOPS.VIOATY","PATH":"Stability Operations"},{"SYMBOLID":"O*V*A-----*****","DESCRIPTION":"Arson/Fire","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.1","ALPHAHIERARCHY":"STBOPS.VIOATY.ASN","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*M-----*****","DESCRIPTION":"Killing (General)","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*MA----*****","DESCRIPTION":"Murder","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.1","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.MDR","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*MB----*****","DESCRIPTION":"Execution","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.2","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.EX","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*MC----*****","DESCRIPTION":"Assassination","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.2.3","ALPHAHIERARCHY":"STBOPS.VIOATY.KILL.ASS","PATH":"Stability Operations/Violent Activities/Killing (General)"},{"SYMBOLID":"O*V*B-----*****","DESCRIPTION":"Bomb/Bombing","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.3","ALPHAHIERARCHY":"STBOPS.VIOATY.BM","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*Y-----*****","DESCRIPTION":"Booby Trap","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.4","ALPHAHIERARCHY":"STBOPS.VIOATY.BBY","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*D-----*****","DESCRIPTION":"Drive-By Shooting","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.5","ALPHAHIERARCHY":"STBOPS.VIOATY.DBS","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*S-----*****","DESCRIPTION":"Sniping","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.6","ALPHAHIERARCHY":"STBOPS.VIOATY.SPG","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*P-----*****","DESCRIPTION":"Poisoning","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.7","ALPHAHIERARCHY":"STBOPS.VIOATY.PSNG","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*E-----*****","DESCRIPTION":"Explosion","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities"},{"SYMBOLID":"O*V*EI----*****","DESCRIPTION":"IED Explosion","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.1","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EG----*****","DESCRIPTION":"Explosion, Grenade","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.2","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EN----*****","DESCRIPTION":"Explosion, Incendiary","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.3","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EM----*****","DESCRIPTION":"Explosion, Mine","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.4","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EO----*****","DESCRIPTION":"Explosion, Mortar Fire","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.5","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*ER----*****","DESCRIPTION":"Explosion, Rocket","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.6","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*V*EV----*****","DESCRIPTION":"Explosion, Wheeled Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.1.8.7","ALPHAHIERARCHY":"STBOPS.VIOATY.EXPLSN.VEH","PATH":"Stability Operations/Violent Activities/Explosion"},{"SYMBOLID":"O*L*------*****","DESCRIPTION":"Locations","DRAWCATEGORY":"0","HIERARCHY":"5.X.2","ALPHAHIERARCHY":"STBOPS.LOCAT","PATH":"Stability Operations"},{"SYMBOLID":"O*L*B-----*****","DESCRIPTION":"Black List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.1","ALPHAHIERARCHY":"STBOPS.LOCAT.BLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*G-----*****","DESCRIPTION":"Gray List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.2","ALPHAHIERARCHY":"STBOPS.LOCAT.GLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*W-----*****","DESCRIPTION":"White List Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.3","ALPHAHIERARCHY":"STBOPS.LOCAT.WLST","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*M-----*****","DESCRIPTION":"Mass Grave Location","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.4","ALPHAHIERARCHY":"STBOPS.LOCAT.MASS","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*E-----H****","DESCRIPTION":"Drug Lab","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.6","ALPHAHIERARCHY":"STBOPS.LOCAT.DGLAB","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*H-----H****","DESCRIPTION":"House/Residence","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.7","ALPHAHIERARCHY":"STBOPS.LOCAT.HOUSE","PATH":"Stability Operations/LOCATIONS"},{"SYMBOLID":"O*L*N-----H****","DESCRIPTION":"Cave Entrance","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.8","ALPHAHIERARCHY":"STBOPS.LOCAT.CAVENT","PATH":"Stability Operations/Locations"},{"SYMBOLID":"O*L*H-----H****","DESCRIPTION":"Palace/Presidential Residence","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.9","ALPHAHIERARCHY":"STBOPS.LOCAT.HOUSE","PATH":"Stability Operations/lOCATIONS"},{"SYMBOLID":"O*L*F-----H****","DESCRIPTION":"Polling Place","DRAWCATEGORY":"8","HIERARCHY":"5.X.2.10","ALPHAHIERARCHY":"STBOPS.LOCAT.POLLPL","PATH":"Stability Operations/LOCATIONS"},{"SYMBOLID":"O*O*------*****","DESCRIPTION":"Operations","DRAWCATEGORY":"0","HIERARCHY":"5.X.3","ALPHAHIERARCHY":"STBOPS.OPN","PATH":"Stability Operations"},{"SYMBOLID":"O*O*P-----*****","DESCRIPTION":"Patrolling","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.1","ALPHAHIERARCHY":"STBOPS.OPN.PATG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*R-----*****","DESCRIPTION":"Recruitment","DRAWCATEGORY":"0","HIERARCHY":"5.X.3.2","ALPHAHIERARCHY":"STBOPS.OPN.RCMT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*RW----*****","DESCRIPTION":"Recruitment (Willing)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.2.1","ALPHAHIERARCHY":"STBOPS.OPN.RCMT.WLG","PATH":"Stability Operations/Operations/Recruitment"},{"SYMBOLID":"O*O*RC----*****","DESCRIPTION":"Recruitment (Coerced/Impressed)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.2.2","ALPHAHIERARCHY":"STBOPS.OPN.RCMT.CRCD","PATH":"Stability Operations/Operations/Recruitment"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Demonstration","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.3","ALPHAHIERARCHY":"STBOPS.OPN.DEMO","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*M-----*****","DESCRIPTION":"Mine Laying","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.4","ALPHAHIERARCHY":"STBOPS.OPN.ML","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*Y-----*****","DESCRIPTION":"Psychological Operations (Psyop)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*YT----*****","DESCRIPTION":"Psyop (TV and Radio Propaganda)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.1","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.TARP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*YW----*****","DESCRIPTION":"Psyop (Written Propaganda)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.2","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.WP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*YH----*****","DESCRIPTION":"House-to-House Propaganda","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.5.3","ALPHAHIERARCHY":"STBOPS.OPN.PSYOP.HTHP","PATH":"Stability Operations/Operations/Psychological Operations (Psyop)"},{"SYMBOLID":"O*O*F-----*****","DESCRIPTION":"Foraging/Searching","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.6","ALPHAHIERARCHY":"STBOPS.OPN.FRGSRH","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*S-----*****","DESCRIPTION":"Spy","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.7","ALPHAHIERARCHY":"STBOPS.OPN.SPY","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*O-----*****","DESCRIPTION":"Food Distribution","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.8","ALPHAHIERARCHY":"STBOPS.OPN.FDDIST","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*E-----*****","DESCRIPTION":"Extortion","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.9","ALPHAHIERARCHY":"STBOPS.OPN.EXTN","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*H-----*****","DESCRIPTION":"Hijacking","DRAWCATEGORY":"0","HIERARCHY":"5.X.3.10","ALPHAHIERARCHY":"STBOPS.OPN.HJKG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*HT----*****","DESCRIPTION":"Hijacking (Vehicle)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.1","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.VEH","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*HA----*****","DESCRIPTION":"Hijacking (Airplane)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.2","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.APL","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*HV----*****","DESCRIPTION":"Hijacking (Boat)","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.10.3","ALPHAHIERARCHY":"STBOPS.OPN.HJKG.BOAT","PATH":"Stability Operations/Operations/Hijacking"},{"SYMBOLID":"O*O*K-----*****","DESCRIPTION":"Kidnapping","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.11","ALPHAHIERARCHY":"STBOPS.OPN.KDNG","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*KA----*****","DESCRIPTION":"Attempted Kidnapping","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.11.1","ALPHAHIERARCHY":"STBOPS.OPN.KDNG.ATEMPT","PATH":"Stability Operations/Operations/Kidnapping"},{"SYMBOLID":"O*O*A-----*****","DESCRIPTION":"Arrest","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.12","ALPHAHIERARCHY":"STBOPS.OPN.ARR","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*U-----*****","DESCRIPTION":"Drug Operation","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.13","ALPHAHIERARCHY":"STBOPS.OPN.DGOPN","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*UT----*****","DESCRIPTION":"Drug Trafficking","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.13.1","ALPHAHIERARCHY":"STBOPS.OPN.DGOPN.DGTRFC","PATH":"Stability Operations/OPERATIONS/DRUG OPERATION"},{"SYMBOLID":"O*O*N-----*****","DESCRIPTION":"Raid on a House","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.14","ALPHAHIERARCHY":"STBOPS.OPN.HSRAID","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*2-----*****","DESCRIPTION":"Burglary","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.15","ALPHAHIERARCHY":"STBOPS.OPN.BRGLRY","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*V-----*****","DESCRIPTION":"Home Eviction","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.16","ALPHAHIERARCHY":"STBOPS.OPN.HSEVCT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*I-----*****","DESCRIPTION":"Black Marketing","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.17","ALPHAHIERARCHY":"STBOPS.OPM.BLKMKT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*J-----*****","DESCRIPTION":"Jail Break","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.18","ALPHAHIERARCHY":"STBOPS.OPN.JAILBREAK","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*B-----*****","DESCRIPTION":"Robbery","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.19","ALPHAHIERARCHY":"STBOPS.OPN.ROB","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*G-----*****","DESCRIPTION":"Sabotage","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.21","ALPHAHIERARCHY":"STBOPS.OPN.SABOTG","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*X-----*****","DESCRIPTION":"Smuggling","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.22","ALPHAHIERARCHY":"STBOPS.OPN.SMGLNG","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*O*W-----*****","DESCRIPTION":"Rock Throwing","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.23","ALPHAHIERARCHY":"STBOPS.OPN.RCKTHR","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*Z-----*****","DESCRIPTION":"Suspicious Activity","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.24","ALPHAHIERARCHY":"STBOPS.OPN.SUSACT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*T-----*****","DESCRIPTION":"Theft","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.25","ALPHAHIERARCHY":"STBOPS.OPN.THEFT","PATH":"Stability Operations/Operations"},{"SYMBOLID":"O*O*TV----*****","DESCRIPTION":"Wheeled Vehicle Theft","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.25.1","ALPHAHIERARCHY":"STBOPS.OPN.THEFT.VEH","PATH":"Stability Operations/OPERATIONS/THEFT"},{"SYMBOLID":"O*O*Q-----*****","DESCRIPTION":"Warrant Served","DRAWCATEGORY":"8","HIERARCHY":"5.X.3.26","ALPHAHIERARCHY":"STBOPS.OPN.WARRENT","PATH":"Stability Operations/OPERATIONS"},{"SYMBOLID":"O*I*------*****","DESCRIPTION":"Items","DRAWCATEGORY":"0","HIERARCHY":"5.X.4","ALPHAHIERARCHY":"STBOPS.ITM","PATH":"Stability Operations"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Refugees","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.1","ALPHAHIERARCHY":"STBOPS.ITM.RFG","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*S-----*****","DESCRIPTION":"Safe House","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.2","ALPHAHIERARCHY":"STBOPS.ITM.SAFHSE","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*G-----*****","DESCRIPTION":"Graffiti","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.3","ALPHAHIERARCHY":"STBOPS.ITM.GRF","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*V-----*****","DESCRIPTION":"Vandalism/Loot/Ransack/Plunder/Sack","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.4","ALPHAHIERARCHY":"STBOPS.ITM.VRLRPS","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*I-----*****","DESCRIPTION":"Known Insurgent Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.5","ALPHAHIERARCHY":"STBOPS.ITM.KNIVEH","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*D-----*****","DESCRIPTION":"Drug Vehicle","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.6","ALPHAHIERARCHY":"STBOPS.ITM.DGVEH","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*F-----*****","DESCRIPTION":"Internal Security Force","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.7","ALPHAHIERARCHY":"STBOPS.ITM.ISF","PATH":"Stability Operations/Items"},{"SYMBOLID":"O*I*M-----*****","DESCRIPTION":"Meeting","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.8","ALPHAHIERARCHY":"STBOPS.ITM.MEETING","PATH":"Stability Operations/ITEMS"},{"SYMBOLID":"O*I*T-----*****","DESCRIPTION":"Tent","DRAWCATEGORY":"8","HIERARCHY":"5.X.4.9","ALPHAHIERARCHY":"STBOPS.ITM.TENT","PATH":"Stability Operations/ITEMS"},{"SYMBOLID":"O*P*------*****","DESCRIPTION":"Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5","ALPHAHIERARCHY":"STBOPS.INDIV","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*A-----*****","DESCRIPTION":"Leader","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.1","ALPHAHIERARCHY":"STBOPS.INDIV.LEADER","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*AR----*****","DESCRIPTION":"Religious Leader","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.1.1","ALPHAHIERARCHY":"STBOPS.INDIV.LEADER.RELIGS","PATH":"Stability Operations/INDIVIDUAL/LEADER"},{"SYMBOLID":"O*P*B-----*****","DESCRIPTION":"Targeted Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.2","ALPHAHIERARCHY":"STBOPS.INDIV.TRGTD","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*C-----*****","DESCRIPTION":"Terrorist","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.3","ALPHAHIERARCHY":"STBOPS.INDIV.TERRST","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*P*D-----*****","DESCRIPTION":"Dead Body","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.4","ALPHAHIERARCHY":"STBOPS.INDIV.DDBODY","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*E-----*****","DESCRIPTION":"Speaker","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.5","ALPHAHIERARCHY":"STBOPS.INDIV.SPKR","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*P*F-----*****","DESCRIPTION":"IED Suicide Bomber","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.6","ALPHAHIERARCHY":"STBOPS.INDIV.SUICBM","PATH":"Stability Operations/Individual"},{"SYMBOLID":"O*P*G-----*****","DESCRIPTION":"Exfiltrating Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.7","ALPHAHIERARCHY":"STBOPS.INDIV.EXFLT","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*P*H-----*****","DESCRIPTION":"Infiltrating Individual","DRAWCATEGORY":"8","HIERARCHY":"5.X.5.8","ALPHAHIERARCHY":"STBOPS.INDIV.INFLT","PATH":"Stability Operations/INDIVIDUAL"},{"SYMBOLID":"O*G*------*****","DESCRIPTION":"Non-Military Group or Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6","ALPHAHIERARCHY":"STBOPS.GRPORG","PATH":"Stability Operations"},{"SYMBOLID":"O*G*B-----*****","DESCRIPTION":"Non-Governmental Organizations (NGO)","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.2","ALPHAHIERARCHY":"STBOPS.GRPORG.NGO","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*C-----*****","DESCRIPTION":"Terrorist Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.3","ALPHAHIERARCHY":"STBOPS.GRPORG.TERRST","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*D-----*****","DESCRIPTION":"Religious Organization","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.4","ALPHAHIERARCHY":"STBOPS.GRPORG.RELIGS","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*E-----*****","DESCRIPTION":"Foreign Fighter","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.5","ALPHAHIERARCHY":"STBOPS.GRPORG.FNFGHT","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*G*F-----*****","DESCRIPTION":"Gang","DRAWCATEGORY":"8","HIERARCHY":"5.X.6.6","ALPHAHIERARCHY":"STBOPS.GRPORG.GANG","PATH":"Stability Operations/NONMILITARY GROUP OR ORGANIZATION"},{"SYMBOLID":"O*R*------*****","DESCRIPTION":"Rape","DRAWCATEGORY":"8","HIERARCHY":"5.X.7","ALPHAHIERARCHY":"STBOPS.RAPE","PATH":"Stability Operations/RAPE"},{"SYMBOLID":"O*R*A-----*****","DESCRIPTION":"Attempted Rape","DRAWCATEGORY":"8","HIERARCHY":"5.X.7.1","ALPHAHIERARCHY":"STBOPS.RAPE.ATEMPT","PATH":"Stability Operations/Rape"},{"SYMBOLID":"O*E*------*****","DESCRIPTION":"Events SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10","ALPHAHIERARCHY":"STBOPS.SASO","PATH":"Stability Operations"},{"SYMBOLID":"O*E*A-----*****","DESCRIPTION":"Elections SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.1","ALPHAHIERARCHY":"STBOPS.SASO.ELCT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*B-----*****","DESCRIPTION":"Speech SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.2","ALPHAHIERARCHY":"STBOPS.SASO.SPH","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*C-----*****","DESCRIPTION":"Sermon SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.3","ALPHAHIERARCHY":"STBOPS.SASO.SRMN","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*D-----*****","DESCRIPTION":"Meeting SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.4","ALPHAHIERARCHY":"STBOPS.SASO.MTG","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*E-----*****","DESCRIPTION":"Demonstration(Events) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.5","ALPHAHIERARCHY":"STBOPS.SASO.DEMO","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*F-----*****","DESCRIPTION":"Riot SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.6","ALPHAHIERARCHY":"STBOPS.SASO.RIOT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*G-----*****","DESCRIPTION":"Gang Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.7","ALPHAHIERARCHY":"STBOPS.SASO.GANG","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*H-----*****","DESCRIPTION":"Jail Break/Escape Custody SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.8","ALPHAHIERARCHY":"STBOPS.SASO.JAIL.BK","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*I-----*****","DESCRIPTION":"Rock Throwing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.9","ALPHAHIERARCHY":"STBOPS.SASO.RCKTHR","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*J-----*****","DESCRIPTION":"Illegal Selling/Purchasing/Distributing/Black Market SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.10","ALPHAHIERARCHY":"STBOPS.SASO.BLKMKT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*K-----*****","DESCRIPTION":"Surveillance SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.11","ALPHAHIERARCHY":"STBOPS.SASO.SRVLLNCE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*L-----*****","DESCRIPTION":"Lights SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.12","ALPHAHIERARCHY":"STBOPS.SASO.LIT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*M-----*****","DESCRIPTION":"Border Crossing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.13","ALPHAHIERARCHY":"STBOPS.SASO.BRDCSG","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*N-----*****","DESCRIPTION":"Border Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.14","ALPHAHIERARCHY":"STBOPS.SASO.BRDACT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*O-----*****","DESCRIPTION":"Smuggling SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.15","ALPHAHIERARCHY":"STBOPS.SASO.SMGL","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*P-----*****","DESCRIPTION":"Exfiltration SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.16","ALPHAHIERARCHY":"STBOPS.SASO.EXFNLE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Q-----*****","DESCRIPTION":"Infiltration SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.17","ALPHAHIERARCHY":"STBOPS.SASO.INFNLE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*R-----*****","DESCRIPTION":"Auto Theft SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.18","ALPHAHIERARCHY":"STBOPS.SASO.AUTOTHEFT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*S-----*****","DESCRIPTION":"Auto Accident SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.19","ALPHAHIERARCHY":"STBOPS.SASO.AUTOACDNT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*T-----*****","DESCRIPTION":"Looting SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.20","ALPHAHIERARCHY":"STBOPS.SASO.LOOT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*U-----*****","DESCRIPTION":"Theft SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.21","ALPHAHIERARCHY":"STBOPS.SASO.THEFT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*V-----*****","DESCRIPTION":"Robbery SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.22","ALPHAHIERARCHY":"STBOPS.SASO.ROB","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*W-----*****","DESCRIPTION":"Home Eviction SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.23","ALPHAHIERARCHY":"STBOPS.SASO.HSEVCT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*X-----*****","DESCRIPTION":"Shooting (Non Deadly) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.24","ALPHAHIERARCHY":"STBOPS.SASO.SHTGND","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Y-----*****","DESCRIPTION":"Raid SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.25","ALPHAHIERARCHY":"STBOPS.SASO.RAID","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*Z-----*****","DESCRIPTION":"Sabotage SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.26","ALPHAHIERARCHY":"STBOPS.SASO.SABOTG","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AA----*****","DESCRIPTION":"Warrant Served SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.27","ALPHAHIERARCHY":"STBOPS.SASO.WARRNT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AB----*****","DESCRIPTION":"Rape SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.28","ALPHAHIERARCHY":"STBOPS.SASO.RAPE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AC----*****","DESCRIPTION":"Attempted Rape SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.29","ALPHAHIERARCHY":"STBOPS.SASO.RAPEATEMPT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AD----*****","DESCRIPTION":"Attack(Events) SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.30","ALPHAHIERARCHY":"STBOPS.SASO.ATK","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*ADA---*****","DESCRIPTION":"Attack on NGO SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.1","ALPHAHIERARCHY":"STBOPS.SASO.ATK.NGO","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADB---*****","DESCRIPTION":"Terrorist Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.2","ALPHAHIERARCHY":"STBOPS.SASO.ATK.TER","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADC---*****","DESCRIPTION":"Grenade Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.3","ALPHAHIERARCHY":"STBOPS.SASO.ATK.GREN","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*ADD---*****","DESCRIPTION":"Rocket Attack SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.30.4","ALPHAHIERARCHY":"STBOPS.SASO.ATK.ROCKET","PATH":"Stability Operations/Events/Attack"},{"SYMBOLID":"O*E*AE----*****","DESCRIPTION":"Explosions SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.31","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AEA---*****","DESCRIPTION":"Explosion (general) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.1","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.GEN","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEB---*****","DESCRIPTION":"Explosion, Mine SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.2","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.MINE","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEC---*****","DESCRIPTION":"Explosion, Grenade SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.3","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.GREN","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AED---*****","DESCRIPTION":"Explosion, Bomb SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.4","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.BOMB","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEE---*****","DESCRIPTION":"Explosion, Mortar Fire SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.5","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.MTRFR","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEF---*****","DESCRIPTION":"Explosion, Incendiary SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.6","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.INCEND","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEG---*****","DESCRIPTION":"Explosion, Rocket SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.7","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.ROCKET","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEH---*****","DESCRIPTION":"Explosion, Improvised Explosive Device (IED) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.8","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.IED","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEI---*****","DESCRIPTION":"Explosion, Car Bomb SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.9","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AEJ---*****","DESCRIPTION":"Suicide Bombing SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.31.10","ALPHAHIERARCHY":"STBOPS.SASO.EXPLSN.SUICBM","PATH":"Stability Operations/Events/Explosions"},{"SYMBOLID":"O*E*AF----*****","DESCRIPTION":"Fighting/Contact SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.10.32","ALPHAHIERARCHY":"STBOPS.SASO.FT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AFA---*****","DESCRIPTION":"Fighting (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.1","ALPHAHIERARCHY":"STBOPS.SASO.FT.GEN","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AFB---*****","DESCRIPTION":"Coalition vs. Enemy SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.2","ALPHAHIERARCHY":"STBOPS.SASO.FT.CLTNVENMY","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AFC---*****","DESCRIPTION":"Coalition vs. Coalition SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.32.3","ALPHAHIERARCHY":"STBOPS.SASO.FT.CLTNVCLTN","PATH":"Stability Operations/Events/Fighting and Contact"},{"SYMBOLID":"O*E*AG----*****","DESCRIPTION":"Drug Possession SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.33","ALPHAHIERARCHY":"STBOPS.SASO.DGPOS","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AH----*****","DESCRIPTION":"Drug Trafficking SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.34","ALPHAHIERARCHY":"STBOPS.SASO.DGTRFC","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AI----*****","DESCRIPTION":"Suspicious Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.35","ALPHAHIERARCHY":"STBOPS.SASO.SUSACT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AJ----*****","DESCRIPTION":"Activity SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.36","ALPHAHIERARCHY":"STBOPS.SASO.ACT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AK----*****","DESCRIPTION":"Threat SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.37","ALPHAHIERARCHY":"STBOPS.SASO.THT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AL----*****","DESCRIPTION":"Crater SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.38","ALPHAHIERARCHY":"STBOPS.SASO.CRTR","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AM----*****","DESCRIPTION":"Pothole SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.39","ALPHAHIERARCHY":"STBOPS.SASO.POTHOLE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AN----*****","DESCRIPTION":"Escalation of Force SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.40","ALPHAHIERARCHY":"STBOPS.SASO.ESCLTNFRCE","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AO----*****","DESCRIPTION":"Submunitions SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.41","ALPHAHIERARCHY":"STBOPS.SASO.SUBMNTN","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AP----*****","DESCRIPTION":"Confiscation SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.42","ALPHAHIERARCHY":"STBOPS.SASO.CONF","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AQ----*****","DESCRIPTION":"Counter Insurgency SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.43","ALPHAHIERARCHY":"STBOPS.SASO.CI","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AR----*****","DESCRIPTION":"Counter Terrorism SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.44","ALPHAHIERARCHY":"STBOPS.SASO.CT","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AS----*****","DESCRIPTION":"Humanitarian Assistance SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.45","ALPHAHIERARCHY":"STBOPS.SASO.HA","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AT----*****","DESCRIPTION":"Tests of Security SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.46","ALPHAHIERARCHY":"STBOPS.SASO.TOS","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AU----*****","DESCRIPTION":"AWOL SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.47","ALPHAHIERARCHY":"STBOPS.SASO.AWOL","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AV----*****","DESCRIPTION":"Curfew SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.48","ALPHAHIERARCHY":"STBOPS.SASO.CURFEW","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AW----*****","DESCRIPTION":"DUI SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.49","ALPHAHIERARCHY":"STBOPS.SASO.DUI","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*E*AX----*****","DESCRIPTION":"Prostitution SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.10.50","ALPHAHIERARCHY":"STBOPS.SASO.PROS","PATH":"Stability Operations/Events"},{"SYMBOLID":"O*Y*------*****","DESCRIPTION":"Organization/Groups SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.11","ALPHAHIERARCHY":"STBOPS.SASO.ORG","PATH":"Stability Operations"},{"SYMBOLID":"O*Y*A-----*****","DESCRIPTION":"Organization (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.1","ALPHAHIERARCHY":"STBOPS.SASO.ORG.GEN","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*B-----*****","DESCRIPTION":"NGO Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.2","ALPHAHIERARCHY":"STBOPS.SASO.ORG.NGO","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*C-----*****","DESCRIPTION":"Displaced Persons, Refugees SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.3","ALPHAHIERARCHY":"STBOPS.SASO.ORG.DPR","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*D-----*****","DESCRIPTION":"Terrorist Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.4","ALPHAHIERARCHY":"STBOPS.SASO.ORG.TERRST","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*E-----*****","DESCRIPTION":"Religious Organization SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.5","ALPHAHIERARCHY":"STBOPS.SASO.ORG.REL","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*F-----*****","DESCRIPTION":"Group Tribe Cell SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.6","ALPHAHIERARCHY":"STBOPS.SASO.ORG.GTC","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*G-----*****","DESCRIPTION":"Foreign Fighters SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.7","ALPHAHIERARCHY":"STBOPS.SASO.ORG.FNFGHT","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*R-----*****","DESCRIPTION":"Red Cross SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.8","ALPHAHIERARCHY":"STBOPS.SASO.ORG.RDCRSS","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SP----*****","DESCRIPTION":"State Police SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.9","ALPHAHIERARCHY":"STBOPS.SASO.ORG.STPOL","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*LP----*****","DESCRIPTION":"Local Police SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.10","ALPHAHIERARCHY":"STBOPS.SASO.ORG.LCPOL","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SH----*****","DESCRIPTION":"Shelter SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.11","ALPHAHIERARCHY":"STBOPS.SASO.ORG.SHL","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*FM----*****","DESCRIPTION":"FEMA SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.12","ALPHAHIERARCHY":"STBOPS.SASO.ORG.FEMA","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*SA----*****","DESCRIPTION":"Staging Area SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.13","ALPHAHIERARCHY":"STBOPS.SASO.","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*EP----*****","DESCRIPTION":"Evacuation Point SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.14","ALPHAHIERARCHY":"STBOPS.SASO.ORG.EVAC","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*Y*PD----*****","DESCRIPTION":"Person in Distress SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.11.15","ALPHAHIERARCHY":"STBOPS.SASO.ORG.PID","PATH":"Stability Operations/Organization and Groups"},{"SYMBOLID":"O*S*------*****","DESCRIPTION":"Structures SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.13","ALPHAHIERARCHY":"STBOPS.SASO.STRT","PATH":"Stability Operations"},{"SYMBOLID":"O*S*A-----*****","DESCRIPTION":"Compound/Post/Fort SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.1","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CPD","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*B-----*****","DESCRIPTION":"House/Residence SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.2","ALPHAHIERARCHY":"STBOPS.SASO.STRT.HSE","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*C-----*****","DESCRIPTION":"Safe House(Structures) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.3","ALPHAHIERARCHY":"STBOPS.SASO.STRT.SAFHSE","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*D-----*****","DESCRIPTION":"Church SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.4","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CHRCH","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*E-----*****","DESCRIPTION":"Mosque SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.5","ALPHAHIERARCHY":"STBOPS.SASO.STRT.MOS","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*F-----*****","DESCRIPTION":"Synagogue SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.6","ALPHAHIERARCHY":"STBOPS.SASO.STRT.SYN","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*G-----*****","DESCRIPTION":"Warehouse/Storage Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.7","ALPHAHIERARCHY":"STBOPS.SASO.STRT.WAREHS","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*H-----*****","DESCRIPTION":"Bunker/Underground Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.8","ALPHAHIERARCHY":"STBOPS.SASO.STRT.BKR","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*I-----*****","DESCRIPTION":"Tents SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.9","ALPHAHIERARCHY":"STBOPS.SASO.STRT.TENT","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*J-----*****","DESCRIPTION":"Cave SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.10","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CAVE","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*K-----*****","DESCRIPTION":"Camps SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.13.11","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CMP","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*KA----*****","DESCRIPTION":"Camp (General) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.1","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CMP.GEN","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*KB----*****","DESCRIPTION":"Displaced Persons/Refugees Camp SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.2","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CMP.DPRC","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*KC----*****","DESCRIPTION":"Training Camp SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.11.3","ALPHAHIERARCHY":"STBOPS.SASO.STRT.CMP.TRG","PATH":"Stability Operations/Structures/Camps"},{"SYMBOLID":"O*S*L-----*****","DESCRIPTION":"Prison/Detention Facility SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.12","ALPHAHIERARCHY":"STBOPS.SASO.STRT.PRSN","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*M-----*****","DESCRIPTION":"Police Station SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.13","ALPHAHIERARCHY":"STBOPS.SASO.STRT.POL","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*S*N-----*****","DESCRIPTION":"Palace/Presidential Residence SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.13.14","ALPHAHIERARCHY":"STBOPS.SASO.PAL","PATH":"Stability Operations/Structures"},{"SYMBOLID":"O*Q*------*****","DESCRIPTION":"Equipment/Weapons SASO","DRAWCATEGORY":"0","HIERARCHY":"5.X.14","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN","PATH":"Stability Operations"},{"SYMBOLID":"O*Q*A-----*****","DESCRIPTION":"Weapons Found SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.1","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.FIND","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*B-----*****","DESCRIPTION":"Weapons Cache SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.2","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.CACHE","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*C-----*****","DESCRIPTION":"Weapons Confiscated SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.3","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.CONF","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*D-----*****","DESCRIPTION":"Weapons Sale SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.4","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.SALE","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*E-----*****","DESCRIPTION":"Weapons Market SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.5","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.MKT","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*F-----*****","DESCRIPTION":"Chem/Bio Weapons Cache SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.6","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.BIO","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*G-----*****","DESCRIPTION":"Improvised Explosive Device (IED) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.7","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.IED","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*H-----*****","DESCRIPTION":"Unexploded Ordnance (UXO) SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.8","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.UXO","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*I-----*****","DESCRIPTION":"Horses SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.9","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.HRE","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*J-----*****","DESCRIPTION":"Camels SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.10","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.CML","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"O*Q*K-----*****","DESCRIPTION":"Donkeys SASO","DRAWCATEGORY":"8","HIERARCHY":"5.X.14.11","ALPHAHIERARCHY":"STBOPS.SASO.EQTWPN.DKY","PATH":"Stability Operations/Equipment and Weapons"},{"SYMBOLID":"E*-*------*****","DESCRIPTION":"Emergency Management Symbols","DRAWCATEGORY":"0","HIERARCHY":"6.X","ALPHAHIERARCHY":"EMS"},{"SYMBOLID":"E*I*------*****","DESCRIPTION":"Incident","DRAWCATEGORY":"0","HIERARCHY":"6.X.1","ALPHAHIERARCHY":"EMS.INCDNT","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*I*A-----*****","DESCRIPTION":"Civil Disturbance Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.1","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"O*O*D-----*****","DESCRIPTION":"Civil Demonstration","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.1.1","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.DEMO","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"O*I*R-----*****","DESCRIPTION":"Civil Displaced Population","DRAWCATEGORY":"0","HIERARCHY":"6.X.1.1.2","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.DISPOP","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"E*I*AC----*****","DESCRIPTION":"Civil Rioting","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.1.3","ALPHAHIERARCHY":"EMS.INCDNT.CVDIS.CVRIOT","PATH":"Emergency Management Symbols/Incident/Civil Disturbance Incident"},{"SYMBOLID":"E*I*B-----*****","DESCRIPTION":"Criminal Activity Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*BA----*****","DESCRIPTION":"Bomb Threat","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.1","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.BMTHT","PATH":"Emergency Management Symbols/Incident/Criminal Activity Incident"},{"SYMBOLID":"O*V*B-----*****","DESCRIPTION":"Bomb","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.2","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.BM","PATH":"Emergency Management Symbols/Incident/Criminal Activity Incident"},{"SYMBOLID":"E*I*BC----*****","DESCRIPTION":"Explosion (Bomb)","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.3","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.EXPLN","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"E*I*BD----*****","DESCRIPTION":"Looting","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.4","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.LOOT","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"O*V*P-----*****","DESCRIPTION":"Poisoning","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.5","ALPHAHIERARCHY":"EMS.INCDNT.CRMACT.PSNG","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"E*I*BF----*****","DESCRIPTION":"Shooting","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.2.6","ALPHAHIERARCHY":"EMS..INCDNT.CRMACT.SHTG","PATH":"EMERGENCY MANAGEMENT SYMBOLS/INCIDENT/CRIMINAL ACTIVITY INCIDENT"},{"SYMBOLID":"E*I*C-----*****","DESCRIPTION":"Fire Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3","ALPHAHIERARCHY":"EMS.INCDNT.FIRE","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*CA----*****","DESCRIPTION":"Hot Spot","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.1","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.HTSPT","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CB----*****","DESCRIPTION":"Non-Residential Fire","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.2","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.NRES","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CC----*****","DESCRIPTION":"Origin","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.3","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.ORGN","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CD----*****","DESCRIPTION":"Residential Fire","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.4","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.RES","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CE----*****","DESCRIPTION":"School Fire","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.5","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.SCH","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CF----*****","DESCRIPTION":"Smoke","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.6","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.SMK","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CG----*****","DESCRIPTION":"Special Needs Fire","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.7","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.SN","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*CH----*****","DESCRIPTION":"Wild Fire","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.3.8","ALPHAHIERARCHY":"EMS.INCDNT.FIRE.WLD","PATH":"Emergency Management Symbols/Incident/Fire Incident"},{"SYMBOLID":"E*I*D-----*****","DESCRIPTION":"Hazardous Material Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*DA----*****","DESCRIPTION":"Chemical Agent","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.1","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.CHMAGT","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DB----*****","DESCRIPTION":"Corrosive Material","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.2","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.CORMTL","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DC----*****","DESCRIPTION":"Hazardous When Wet","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.3","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.WHWET","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DD----*****","DESCRIPTION":"Explosive","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.4","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.EXPLV","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DE----*****","DESCRIPTION":"Flammable Gas","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.5","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.FLGAS","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DF----*****","DESCRIPTION":"Flammable Liquid","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.6","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.FLLIQ","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DG----*****","DESCRIPTION":"Flammable Solid","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.7","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.FLSLD","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DH----*****","DESCRIPTION":"Non-Flammable Gas","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.8","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.NFLGAS","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DI----*****","DESCRIPTION":"Organic Peroxide","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.9","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.ORGPER","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DJ----*****","DESCRIPTION":"Oxidizer","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.10","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.OXDZR","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DK----*****","DESCRIPTION":"Radioactive Material","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.11","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.RADMTL","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DL----*****","DESCRIPTION":"Spontaneously Combustible","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.12","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.SPCMB","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DM----*****","DESCRIPTION":"Toxic Gas","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.13","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.TXGAS","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DN----*****","DESCRIPTION":"Toxic and Infectious","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.14","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.TXINF","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*DO----*****","DESCRIPTION":"Unexploded Ordinance","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.4.15","ALPHAHIERARCHY":"EMS.INCDNT.HAZMAT.UNXORD","PATH":"Emergency Management Symbols/Incident/Hazardous Material Incident"},{"SYMBOLID":"E*I*E-----*****","DESCRIPTION":"Air Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.5","ALPHAHIERARCHY":"EMS.INCDNT.AIR","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*EA----*****","DESCRIPTION":"Air Accident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.5.1","ALPHAHIERARCHY":"EMS.INCDNT.AIR.ACDNT","PATH":"Emergency Management Symbols/Incident/Air Incident"},{"SYMBOLID":"O*O*HA----*****","DESCRIPTION":"Air Hijacking","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.5.2","ALPHAHIERARCHY":"EMS.INCDNT.AIR.HJKG.APL","PATH":"Emergency Management Symbols/Incident/Air Incident"},{"SYMBOLID":"E*I*F-----*****","DESCRIPTION":"Marine Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.6","ALPHAHIERARCHY":"EMS.INCDNT.MRN","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*FA----*****","DESCRIPTION":"Marine Accident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.6.1","ALPHAHIERARCHY":"EMS.INCDNT.MRN.ACDNT","PATH":"Emergency Management Symbols/Incident/Marine Incident"},{"SYMBOLID":"O*O*HV----*****","DESCRIPTION":"Marine Hijacking","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.6.2","ALPHAHIERARCHY":"EMS.INCDNT.MRN.HJKG","PATH":"Emergency Management Symbols/Incident/Marine Incident"},{"SYMBOLID":"E*I*G-----*****","DESCRIPTION":"Rail Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.7","ALPHAHIERARCHY":"EMS.INCDNT.RAIL","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*GA----*****","DESCRIPTION":"Rail Accident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.7.1","ALPHAHIERARCHY":"EMS.INCDNT.RAIL.ACDNT","PATH":"Emergency Management Symbols/Incident/Rail Incident"},{"SYMBOLID":"E*I*GB----*****","DESCRIPTION":"Rail Hijacking","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.7.2","ALPHAHIERARCHY":"EMS.INCDNT.RAIL.HJCK","PATH":"Emergency Management Symbols/Incident/Rail Incident"},{"SYMBOLID":"E*I*H-----*****","DESCRIPTION":"Vehicle Incident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.8","ALPHAHIERARCHY":"EMS.INCDNT.VEH","PATH":"Emergency Management Symbols/Incident"},{"SYMBOLID":"E*I*HA----*****","DESCRIPTION":"Vehicle Accident","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.8.1","ALPHAHIERARCHY":"EMS.INCDNT.VEH.ACDNT","PATH":"Emergency Management Symbols/Incident/Vehicle Incident"},{"SYMBOLID":"O*O*HT----*****","DESCRIPTION":"Vehicle Hijacking","DRAWCATEGORY":"8","HIERARCHY":"6.X.1.8.2","ALPHAHIERARCHY":"EMS.INCDNT.VEH.HJKG","PATH":"Emergency Management Symbols/Incident/Vehicle Incident"},{"SYMBOLID":"E*N*------*****","DESCRIPTION":"Natural Events","DRAWCATEGORY":"0","HIERARCHY":"6.X.2","ALPHAHIERARCHY":"EMS.NATEVT","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*O*------*****","DESCRIPTION":"Operations","DRAWCATEGORY":"0","HIERARCHY":"6.X.3","ALPHAHIERARCHY":"EMS.OPN","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*O*A-----*****","DESCRIPTION":"Emergency Medical Operation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1","ALPHAHIERARCHY":"EMS.OPN.EMMED","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*AA----*****","DESCRIPTION":"Emergency Medical Operation Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.1","ALPHAHIERARCHY":"EMS.OPN.EMMED.UNT","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AB----*****","DESCRIPTION":"Emergency Medical Operation Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.2","ALPHAHIERARCHY":"EMS.OPN.EMMED.EQPT","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AC----H****","DESCRIPTION":"Emergency Medical Operation Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.3","ALPHAHIERARCHY":"EMS.OPN.EMMED.INS","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AD----H****","DESCRIPTION":"EMT Station Location","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.4","ALPHAHIERARCHY":"EMS.OPN.EMMED.EMTLOC","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AE----*****","DESCRIPTION":"Ambulance","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.5","ALPHAHIERARCHY":"EMS.OPN.EMMED.AMBLNC","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AF----*****","DESCRIPTION":"Medical Evacuation Helicopter","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.6","ALPHAHIERARCHY":"EMS.OPN.EMMED.MEH","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AG----H****","DESCRIPTION":"Health Department Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.7","ALPHAHIERARCHY":"EMS.OPN.EMMED.HDF","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"S*G*IXH---H****","DESCRIPTION":"Hospital","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.8","ALPHAHIERARCHY":"EMS.OPN.EMMED.HSP","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"S*S*NM----*****","DESCRIPTION":"Hospital Ship","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.9","ALPHAHIERARCHY":"EMS.OPN.EMMED.HSPSHP","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AJ----H****","DESCRIPTION":"Medical Facilities Out Patient","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.10","ALPHAHIERARCHY":"EMS.OPN.EMMED.MFOP","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AK----H****","DESCRIPTION":"Morgue","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.11","ALPHAHIERARCHY":"EMS.OPN.EMMED.MRG","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AL----H****","DESCRIPTION":"Pharmacy","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.12","ALPHAHIERARCHY":"EMS.OPN.EMMED.RX","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*AM----H****","DESCRIPTION":"Triage","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.1.13","ALPHAHIERARCHY":"EMS.OPN.EMMED.TRIAGE","PATH":"Emergency Management Symbols/Operations/Emergency Medical Operation"},{"SYMBOLID":"E*O*B-----*****","DESCRIPTION":"Emergency Operation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2","ALPHAHIERARCHY":"EMS.OPN.EMOPN","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*BA----*****","DESCRIPTION":"Emergency Operation Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.1","ALPHAHIERARCHY":"EMS.OPN.EMOPN.UNT","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BB----*****","DESCRIPTION":"Emergency Operation Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.2","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EQPT","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BC----H****","DESCRIPTION":"Emergency Operation Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.3","ALPHAHIERARCHY":"EMS.OPN.EMOPN.INS","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BD----*****","DESCRIPTION":"Emergency Collection Evacuation Point","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.4","ALPHAHIERARCHY":"EMS.OPN.EMOPN.ECEP","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BE----H****","DESCRIPTION":"Emergency Incident Command Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.5","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EICC","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BF----H****","DESCRIPTION":"Emergency Operations Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.6","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EOC","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BG----H****","DESCRIPTION":"Emergency Public Information Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.7","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EPIC","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BH----H****","DESCRIPTION":"Emergency Shelter","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.8","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EMSHLT","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BI----H****","DESCRIPTION":"Emergency Staging Area","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.9","ALPHAHIERARCHY":"EMS.OPN.EMOPN.ESA","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BJ----*****","DESCRIPTION":"Emergency Team","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.10","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EMTM","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BK----H****","DESCRIPTION":"Emergency Water Distribution Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.11","ALPHAHIERARCHY":"EMS.OPN.EMOPN.EWDC","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*BL----H****","DESCRIPTION":"Emergency Food Distribution Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.2.12","ALPHAHIERARCHY":"EMS.OPN.EMOPN.FDDIST","PATH":"Emergency Management Symbols/Operations/Emergency Operation"},{"SYMBOLID":"E*O*C-----*****","DESCRIPTION":"Fire Fighting Operation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3","ALPHAHIERARCHY":"EMS.OPN.FIRFT","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*CA----*****","DESCRIPTION":"Fire Fighting Operation Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3.1","ALPHAHIERARCHY":"EMS.OPN.FIRFT.FIRFTU","PATH":"Emergency Management Symbols/Operations/Fire Fighting Operation"},{"SYMBOLID":"E*O*CB----*****","DESCRIPTION":"Fire Fighting Operation Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3.2","ALPHAHIERARCHY":"EMS.OPN.FIRFT.FIRFTE","PATH":"Emergency Management Symbols/Operations/Fire Fighting Operation"},{"SYMBOLID":"E*O*CC----*****","DESCRIPTION":"Fire Hydrant","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3.3","ALPHAHIERARCHY":"EMS.OPN.FIRFT.FIRHYD","PATH":"Emergency Management Symbols/Operations/Fire Fighting Operation"},{"SYMBOLID":"E*O*CD----H****","DESCRIPTION":"Other Water Supply Location","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3.4","ALPHAHIERARCHY":"EMS.OPN.FIRFT.OTHH2O","PATH":"Emergency Management Symbols/Operations/Fire Fighting Operation"},{"SYMBOLID":"E*O*CE----H****","DESCRIPTION":"Fire Station","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.3.5","ALPHAHIERARCHY":"EMS.OPN.FIRFT.FIRSTN","PATH":"Emergency Management Symbols/Operations/Fire Fighting Operation"},{"SYMBOLID":"E*O*D-----*****","DESCRIPTION":"Law Enforcement Operation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4","ALPHAHIERARCHY":"EMS.OPN.LAWENF","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*DA----*****","DESCRIPTION":"Law Enforcement Operation Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.LAWENU","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DB----*****","DESCRIPTION":"Law Enforcement Operation Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.LAWENE","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DC----H****","DESCRIPTION":"Law Enforcement Operation Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.LAWENI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DD----*****","DESCRIPTION":"ATF","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.4","ALPHAHIERARCHY":"EMS.OPN.LAWENF.ATF","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DDA---*****","DESCRIPTION":"ATF Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.4.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.ATF.ATFUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/ATF"},{"SYMBOLID":"E*O*DDB---*****","DESCRIPTION":"ATF Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.4.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.ATF.ATFEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/ATF"},{"SYMBOLID":"E*O*DDC---H****","DESCRIPTION":"ATF Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.4.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.ATF.ATFINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/ATF"},{"SYMBOLID":"E*O*DE----*****","DESCRIPTION":"Border Patrol","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.5","ALPHAHIERARCHY":"EMS.OPN.LAWENF.BDRPT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DEA---*****","DESCRIPTION":"Border Patrol Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.5.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.BDRPT.BDRPTU","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Border Patrol"},{"SYMBOLID":"E*O*DEB---*****","DESCRIPTION":"Border Patrol Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.5.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.BDRPT.BDRPTE","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Border Patrol"},{"SYMBOLID":"E*O*DEC---H****","DESCRIPTION":"Border Patrol Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.5.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.BDRPT.BDRPTI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Border Patrol"},{"SYMBOLID":"E*O*DF----*****","DESCRIPTION":"Customs Service","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.6","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTM","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DFA---*****","DESCRIPTION":"Customs Service Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.6.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTM.CSTMUN","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Customs Service"},{"SYMBOLID":"E*O*DFB---*****","DESCRIPTION":"Customs Service Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.6.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTM.CSTMEQ","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Customs Service"},{"SYMBOLID":"E*O*DFC---H****","DESCRIPTION":"Customs Service Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.6.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTM.CSTMIN","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Customs Service"},{"SYMBOLID":"E*O*DG----*****","DESCRIPTION":"DEA","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.7","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DEA","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DGA---*****","DESCRIPTION":"DEA Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.7.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DEA.DEAUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DEA"},{"SYMBOLID":"E*O*DGB---*****","DESCRIPTION":"DEA Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.7.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DEA.DEAEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DEA"},{"SYMBOLID":"E*O*DGC---H****","DESCRIPTION":"DEA Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.7.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DEA.DEAINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DEA"},{"SYMBOLID":"E*O*DH----*****","DESCRIPTION":"DOJ","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.8","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DOJ","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DHA---*****","DESCRIPTION":"DOJ Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.8.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DOJ.DOJUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DOJ"},{"SYMBOLID":"E*O*DHB---*****","DESCRIPTION":"DOJ Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.8.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DOJ.DOJEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DOJ"},{"SYMBOLID":"E*O*DHC---H****","DESCRIPTION":"DOJ Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.8.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.DOJ.DOJINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/DOJ"},{"SYMBOLID":"E*O*DI----*****","DESCRIPTION":"FBI","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.9","ALPHAHIERARCHY":"EMS.OPN.LAWENF.FBI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DIA---*****","DESCRIPTION":"FBI Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.9.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.FBI.FBIUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/FBI"},{"SYMBOLID":"E*O*DIB---*****","DESCRIPTION":"FBI Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.9.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.FBI.FBIEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/FBI"},{"SYMBOLID":"E*O*DIC---H****","DESCRIPTION":"FBI Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.9.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.FBI.FBIINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/FBI"},{"SYMBOLID":"E*O*DJ----*****","DESCRIPTION":"Police","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.10","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"S*G*UULC--*****","DESCRIPTION":"Police Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.10.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL.POLUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Police"},{"SYMBOLID":"E*O*DJB---*****","DESCRIPTION":"Police Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.10.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL.POLEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Police"},{"SYMBOLID":"E*O*DJC---H****","DESCRIPTION":"Police Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.10.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.POL.POLINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Police"},{"SYMBOLID":"E*O*DK----H****","DESCRIPTION":"Prison","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.11","ALPHAHIERARCHY":"EMS.OPN.LAWENF.PRSN","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DL----*****","DESCRIPTION":"Secret Service","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.12","ALPHAHIERARCHY":"EMS.OPN.LAWENF.SECSR","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DLA---*****","DESCRIPTION":"Secret Service Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.12.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.SECSR.SECSRU","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Secret Service"},{"SYMBOLID":"E*O*DLB---*****","DESCRIPTION":"Secret Service Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.12.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.SECSR.SECSRE","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Secret Service"},{"SYMBOLID":"E*O*DLC---H****","DESCRIPTION":"Secret Service Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.12.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.SECSR.SECSRI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Secret Service"},{"SYMBOLID":"E*O*DM----*****","DESCRIPTION":"TSA","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.13","ALPHAHIERARCHY":"EMS.OPN.LAWENF.TSA","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DMA---*****","DESCRIPTION":"TSA Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.13.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.TSA.TSAUNT","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/TSA"},{"SYMBOLID":"E*O*DMB---*****","DESCRIPTION":"TSA Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.13.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.TSA.TSAEQP","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/TSA"},{"SYMBOLID":"E*O*DMC---H****","DESCRIPTION":"TSA Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.13.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.TSA.TSAINS","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/TSA"},{"SYMBOLID":"E*O*DN----*****","DESCRIPTION":"Coast Guard","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.14","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTGD","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DNA---*****","DESCRIPTION":"Coast Guard Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.14.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTGD.CSTGDU","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Coast Guard"},{"SYMBOLID":"S*S*XL----*****","DESCRIPTION":"Coast Guard Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.14.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTGD.CSTGDE","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Coast Guard"},{"SYMBOLID":"E*O*DNC---H****","DESCRIPTION":"Coast Guard Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.14.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.CSTGD.CSTGDI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/Coast Guard"},{"SYMBOLID":"E*O*DO----*****","DESCRIPTION":"US Marshals Service","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.15","ALPHAHIERARCHY":"EMS.OPN.LAWENF.USMAR","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation"},{"SYMBOLID":"E*O*DOA---*****","DESCRIPTION":"US Marshals Service Unit","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.15.1","ALPHAHIERARCHY":"EMS.OPN.LAWENF.USMAR.USMARU","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/US Marshals Service"},{"SYMBOLID":"E*O*DOB---*****","DESCRIPTION":"US Marshals Service Equipment","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.15.2","ALPHAHIERARCHY":"EMS.OPN.LAWENF.USMAR.USMARE","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/US Marshals Service"},{"SYMBOLID":"E*O*DOC---H****","DESCRIPTION":"US Marshals Service Installation","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.4.15.3","ALPHAHIERARCHY":"EMS.OPN.LAWENF.USMAR.USMARI","PATH":"Emergency Management Symbols/Operations/Law Enforcement Operation/US Marshals Service"},{"SYMBOLID":"S*G*ES----*****","DESCRIPTION":"Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5","ALPHAHIERARCHY":"EMS.OPN.SNS","PATH":"Emergency Management Symbols/Operations"},{"SYMBOLID":"E*O*EA----*****","DESCRIPTION":"Biological Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5.1","ALPHAHIERARCHY":"EMS.OPN.SNS.BIO","PATH":"Emergency Management Symbols/Operations/Sensor"},{"SYMBOLID":"E*O*EB----*****","DESCRIPTION":"Chemical Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5.2","ALPHAHIERARCHY":"EMS.OPN.SNS.CML","PATH":"Emergency Management Symbols/Operations/Sensor"},{"SYMBOLID":"E*O*EC----*****","DESCRIPTION":"Intrusion Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5.3","ALPHAHIERARCHY":"EMS.OPN.SNS.INT","PATH":"Emergency Management Symbols/Operations/Sensor"},{"SYMBOLID":"E*O*ED----*****","DESCRIPTION":"Nuclear Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5.4","ALPHAHIERARCHY":"EMS.OPN.SNS.NUC","PATH":"Emergency Management Symbols/Operations/Sensor"},{"SYMBOLID":"E*O*EE----*****","DESCRIPTION":"Radiological Sensor","DRAWCATEGORY":"8","HIERARCHY":"6.X.3.5.5","ALPHAHIERARCHY":"EMS.OPN.SNS.RAD","PATH":"Emergency Management Symbols/Operations/Sensor"},{"SYMBOLID":"E*F*------H****","DESCRIPTION":"Infrastructure","DRAWCATEGORY":"0","HIERARCHY":"6.X.4","ALPHAHIERARCHY":"EMS.INFSTR","PATH":"Emergency Management Symbols"},{"SYMBOLID":"E*F*A-----H****","DESCRIPTION":"Agriculture and Food Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1","ALPHAHIERARCHY":"EMS.INFSTR.AGFD","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*AA----H****","DESCRIPTION":"Agricultural Laboratory","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.1","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.AGLAB","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AB----H****","DESCRIPTION":"Animal Feedlot","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.2","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.AFL","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AC----H****","DESCRIPTION":"Commercial Food Distribution Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.3","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.CFDC","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AD----H****","DESCRIPTION":"Farm/Ranch","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.4","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.FRMRNC","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AE----H****","DESCRIPTION":"Food Production Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.5","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.FPC","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AF----H****","DESCRIPTION":"Food Retail","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.6","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.FDRTL","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*AH----H****","DESCRIPTION":"Grain Storage","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.1.7","ALPHAHIERARCHY":"EMS.INFSTR.AGFD.GRSTR","PATH":"Emergency Management Symbols/Infrastructure/Agriculture and Food Infrastructure"},{"SYMBOLID":"E*F*B-----H****","DESCRIPTION":"Banking Finance and Insurance Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2","ALPHAHIERARCHY":"EMS.INFSTR.BFI","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*BA----*****","DESCRIPTION":"ATM","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.1","ALPHAHIERARCHY":"EMS.INFSTR.BFI.ATM","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*BB----H****","DESCRIPTION":"Bank","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.2","ALPHAHIERARCHY":"EMS.INFSTR.BFI.BANK","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*BC----H****","DESCRIPTION":"Bullion Storage","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.3","ALPHAHIERARCHY":"EMS.INFSTR.BFI.BLSTR","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*BD----H****","DESCRIPTION":"Federal Reserve Bank","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.4","ALPHAHIERARCHY":"EMS.INFSTR.BFI.FRB","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*BE----H****","DESCRIPTION":"Financial Exchange","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.5","ALPHAHIERARCHY":"EMS.INFSTR.BFI.FINEX","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*BF----H****","DESCRIPTION":"Financial Services Other","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.2.6","ALPHAHIERARCHY":"EMS.INFSTR.BFI.FSO","PATH":"Emergency Management Symbols/Infrastructure/Banking Finance and Insurance Infrastructure"},{"SYMBOLID":"E*F*C-----H****","DESCRIPTION":"Commercial Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3","ALPHAHIERARCHY":"EMS.INFSTR.CMCL","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*CA----H****","DESCRIPTION":"Chemical Plant","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.1","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.CMLPLN","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CB----H****","DESCRIPTION":"Firearms Manufacturer","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.2","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.FIRMAN","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CC----H****","DESCRIPTION":"Firearms Retailer","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.3","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.FIRRET","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CD----H****","DESCRIPTION":"Hazardous Material Production","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.4","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.HZMTPR","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CE----H****","DESCRIPTION":"Hazardous Material Storage","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.5","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.HZMTST","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CF----H****","DESCRIPTION":"Industrial Site","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.6","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.INDSTE","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CG----*****","DESCRIPTION":"Landfill","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.7","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.LNDFL","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CH----H****","DESCRIPTION":"Pharmaceutical Manufacturer","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.8","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.RXMFG","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CI----H****","DESCRIPTION":"Contaminated Hazardous Waste Site","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.9","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.CHWS","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*CJ----H****","DESCRIPTION":"Toxic Release Inventory","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.3.10","ALPHAHIERARCHY":"EMS.INFSTR.CMCL.TXRLIN","PATH":"Emergency Management Symbols/Infrastructure/Commercial Infrastructure"},{"SYMBOLID":"E*F*D-----H****","DESCRIPTION":"Educational Facilties Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.4","ALPHAHIERARCHY":"EMS.INFSTR.EDFAC","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*DA----H****","DESCRIPTION":"College University","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.4.1","ALPHAHIERARCHY":"EMS.INFSTR.EDFAC.COLUNI","PATH":"Emergency Management Symbols/Infrastructure/Educational Facilties Infrastructure"},{"SYMBOLID":"E*F*DB----H****","DESCRIPTION":"School","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.4.2","ALPHAHIERARCHY":"EMS.INFSTR.EDFAC.SCHOOL","PATH":"Emergency Management Symbols/Infrastructure/Educational Facilties Infrastructure"},{"SYMBOLID":"S*G*IUE---H****","DESCRIPTION":"Energy Facilities Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*EA----H****","DESCRIPTION":"Generation Station","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5.1","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC.GENSTA","PATH":"Emergency Management Symbols/Infrastructure/Energy Facilities Infrastructure"},{"SYMBOLID":"E*F*EB----H****","DESCRIPTION":"Natural Gas Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5.2","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC.NTLGAS","PATH":"Emergency Management Symbols/Infrastructure/Energy Facilities Infrastructure"},{"SYMBOLID":"S*G*IUEN--H****","DESCRIPTION":"Nuclear Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5.3","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC.NUCFAC","PATH":"Emergency Management Symbols/Infrastructure/Energy Facilities Infrastructure"},{"SYMBOLID":"S*G*IRP---*****","DESCRIPTION":"Petrolium Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5.4","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC.PETFAC","PATH":"Emergency Management Symbols/Infrastructure/Energy Facilities Infrastructure"},{"SYMBOLID":"E*F*EE----H****","DESCRIPTION":"Propane Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.5.5","ALPHAHIERARCHY":"EMS.INFSTR.ENGFAC.PROPNE","PATH":"Emergency Management Symbols/Infrastructure/Energy Facilities Infrastructure"},{"SYMBOLID":"E*F*F-----H****","DESCRIPTION":"Government Site Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.6","ALPHAHIERARCHY":"EMS.INFSTR.GVTSTE","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*G-----H****","DESCRIPTION":"Military Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.7","ALPHAHIERARCHY":"EMS.INFSTR.MIL","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*GA----H****","DESCRIPTION":"Military Armory","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.7.1","ALPHAHIERARCHY":"EMS.INFSTR.MIL.ARMORY","PATH":"Emergency Management Symbols/Infrastructure/Military Infrastructure"},{"SYMBOLID":"S*G*IB----H****","DESCRIPTION":"Military Base","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.7.2","ALPHAHIERARCHY":"EMS.INFSTR.MIL.MILBF","PATH":"Emergency Management Symbols/Infrastructure/Military Infrastructure"},{"SYMBOLID":"E*F*H-----H****","DESCRIPTION":"Postal Service Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.8","ALPHAHIERARCHY":"EMS.INFSTR.PSTSRV","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*HA----H****","DESCRIPTION":"Postal Distribution Center","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.8.1","ALPHAHIERARCHY":"EMS.INFSTR.PSTSRV.PDC","PATH":"Emergency Management Symbols/Infrastructure/Postal Service Infrastructure"},{"SYMBOLID":"E*F*HB----H****","DESCRIPTION":"Post Office","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.8.2","ALPHAHIERARCHY":"EMS.INFSTR.PSTSRV.PO","PATH":"Emergency Management Symbols/Infrastructure/Postal Service Infrastructure"},{"SYMBOLID":"E*F*I-----H****","DESCRIPTION":"Public Venues Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.9","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*IA----H****","DESCRIPTION":"Enclosed Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.9.1","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN.ENCFAC","PATH":"Emergency Management Symbols/Infrastructure/Public Venues Infrastructure"},{"SYMBOLID":"E*F*IB----H****","DESCRIPTION":"Open Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.9.2","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN.OPNFAC","PATH":"Emergency Management Symbols/Infrastructure/Public Venues Infrastructure"},{"SYMBOLID":"E*F*IC----H****","DESCRIPTION":"Recreational Area","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.9.3","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN.RECARE","PATH":"Emergency Management Symbols/Infrastructure/Public Venues Infrastructure"},{"SYMBOLID":"E*F*ID----H****","DESCRIPTION":"Religious Institution","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.9.4","ALPHAHIERARCHY":"EMS.INFSTR.PUBVEN.RELIG","PATH":"Emergency Management Symbols/Infrastructure/Public Venues Infrastructure"},{"SYMBOLID":"E*F*J-----H****","DESCRIPTION":"Special Needs Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.10","ALPHAHIERARCHY":"EMS.INFSTR.SPCNDS","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*JA----H****","DESCRIPTION":"Adult Day Care","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.10.1","ALPHAHIERARCHY":"EMS.INFSTR.SPCNDS.ADLTDC","PATH":"Emergency Management Symbols/Infrastructure/Special Needs Infrastructure"},{"SYMBOLID":"E*F*JB----H****","DESCRIPTION":"Child Day Care","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.10.2","ALPHAHIERARCHY":"EMS.INFSTR.SPCNDS.CHLDC","PATH":"Emergency Management Symbols/Infrastructure/Special Needs Infrastructure"},{"SYMBOLID":"E*F*JC----H****","DESCRIPTION":"Elder Care","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.10.3","ALPHAHIERARCHY":"EMS.INFSTR.SPCNDS.ELDERC","PATH":"Emergency Management Symbols/Infrastructure/Special Needs Infrastructure"},{"SYMBOLID":"E*F*K-----H****","DESCRIPTION":"Telecommunications Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.11","ALPHAHIERARCHY":"EMS.INFSTR.TELCOM","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"S*G*IUT---H****","DESCRIPTION":"Telecommunications Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.11.1","ALPHAHIERARCHY":"EMS.INFSTR.TELCOM.TCF","PATH":"Emergency Management Symbols/Infrastructure/Telecommunications Infrastructure"},{"SYMBOLID":"E*F*KB----H****","DESCRIPTION":"Telecommunications Tower","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.11.2","ALPHAHIERARCHY":"EMS.INFSTR.TELCOM.TCTWR","PATH":"Emergency Management Symbols/Infrastructure/Telecommunications Infrastructure"},{"SYMBOLID":"S*G*IT----H****","DESCRIPTION":"Transportation Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12","ALPHAHIERARCHY":"EMS.INFSTR.TSP","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*LA----H****","DESCRIPTION":"Air Traffic Control Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.1","ALPHAHIERARCHY":"EMS.INFSTR.TSP.ATCF","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"S*G*IBA---H****","DESCRIPTION":"Airport","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.2","ALPHAHIERARCHY":"EMS.INFSTR.TSP.AIRPT","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"G*M*BCB---****X","DESCRIPTION":"Bridge","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.3","ALPHAHIERARCHY":"EMS.INFSTR.TSP.BRG","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LD----H****","DESCRIPTION":"Bus Station","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.4","ALPHAHIERARCHY":"EMS.INFSTR.TSP.BSTN","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LE----H****","DESCRIPTION":"Ferry Terminal","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.5","ALPHAHIERARCHY":"EMS.INFSTR.TSP.FRYTRM","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LF----H****","DESCRIPTION":"Helicopter Landing Site","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.6","ALPHAHIERARCHY":"EMS.INFSTR.TSP.HLS","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"WOS-ML----P----","DESCRIPTION":"Lock","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.7","ALPHAHIERARCHY":"EMS.INFSTR.TSP.LCK","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LH----H****","DESCRIPTION":"Maintenance Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.8","ALPHAHIERARCHY":"EMS.INFSTR.TSP.MAINTF","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"S*G*IBN---H****","DESCRIPTION":"Port","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.9","ALPHAHIERARCHY":"EMS.INFSTR.TSP.SP","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LJ----H****","DESCRIPTION":"Rail Station","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.10","ALPHAHIERARCHY":"EMS.INFSTR.TSP.RLSTN","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LK----H****","DESCRIPTION":"Rest Stop","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.11","ALPHAHIERARCHY":"EMS.INFSTR.TSP.RSTSTP","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"WOS-HPBA--P----","DESCRIPTION":"Ship Anchorage","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.12","ALPHAHIERARCHY":"EMS.INFSTR.TSP.ANCRG","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LM----H****","DESCRIPTION":"Toll Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.13","ALPHAHIERARCHY":"EMS.INFSTR.TSP.TOLLF","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"G*S*PO----****X","DESCRIPTION":"Traffic Control Point","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.14","ALPHAHIERARCHY":"EMS.INFSTR.TSP.TCP","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LO----H****","DESCRIPTION":"Traffic Inspection Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.15","ALPHAHIERARCHY":"EMS.INFSTR.TSP.TIF","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"E*F*LP----H****","DESCRIPTION":"Tunnel","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.12.16","ALPHAHIERARCHY":"EMS.INFSTR.TSP.TML","PATH":"Emergency Management Symbols/Infrastructure/Transportation Infrastructure"},{"SYMBOLID":"S*G*IUP---H****","DESCRIPTION":"Water Supply Infrastructure","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13","ALPHAHIERARCHY":"EMS.INFSTR.WS","PATH":"Emergency Management Symbols/Infrastructure"},{"SYMBOLID":"E*F*MA----H****","DESCRIPTION":"Control Valve","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.1","ALPHAHIERARCHY":"EMS.INFSTR.WS.CV","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MB----H****","DESCRIPTION":"Dam","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.2","ALPHAHIERARCHY":"EMS.INFSTR.WS.DAM","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MC----H****","DESCRIPTION":"Discharge Outfall","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.3","ALPHAHIERARCHY":"EMS.INFSTR.WS.DO","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MD----H****","DESCRIPTION":"Ground Water Well","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.4","ALPHAHIERARCHY":"EMS.INFSTR.WS.GWWELL","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*ME----H****","DESCRIPTION":"Pumping Station","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.5","ALPHAHIERARCHY":"EMS.INFSTR.WS.PMPSTN","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MF----H****","DESCRIPTION":"Reservoir","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.6","ALPHAHIERARCHY":"EMS.INFSTR.WS.RSVR","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MG----H****","DESCRIPTION":"Storage Tower","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.7","ALPHAHIERARCHY":"EMS.INFSTR.WS.STRTWR","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MH----H****","DESCRIPTION":"Surface Water Intake","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.8","ALPHAHIERARCHY":"EMS.INFSTR.WS.SWI","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"},{"SYMBOLID":"E*F*MI----H****","DESCRIPTION":"Wastewater Treatment Facility","DRAWCATEGORY":"8","HIERARCHY":"6.X.4.13.9","ALPHAHIERARCHY":"EMS.INFSTR.WS.WH20TF","PATH":"Emergency Management Symbols/Infrastructure/Water Supply Infrastructure"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.ShapeTypes={};armyc2.c2sd.renderer.so.ShapeTypes.RECTANGLE="RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.POINT="POINT";armyc2.c2sd.renderer.so.ShapeTypes.ELLIPSE="ELLIPSE";armyc2.c2sd.renderer.so.ShapeTypes.ROUNDED_RECTANGLE="ROUNDED_RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.LINE="LINE";armyc2.c2sd.renderer.so.ShapeTypes.BCURVE="BCURVE";armyc2.c2sd.renderer.so.ShapeTypes.ARC="ARC";armyc2.c2sd.renderer.so.ShapeTypes.PATH="PATH";armyc2.c2sd.renderer.so.ActionTypes={};armyc2.c2sd.renderer.so.ActionTypes.ACTION_MOVE_TO=0;armyc2.c2sd.renderer.so.ActionTypes.ACTION_LINE_TO=1;armyc2.c2sd.renderer.so.ActionTypes.ACTION_CURVE_TO=2;armyc2.c2sd.renderer.so.ActionTypes.ACTION_QUAD_TO=3;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC_TO=4;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC=5;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.utilities=armyc2.c2sd.renderer.so.utilities||{};armyc2.c2sd.renderer.so.utilities.relativeCCW=function(x1,y1,x2,y2,px,py) -{x2-=x1;y2-=y1;px-=x1;py-=y1;var ccw=px*y2-py*x2;if(ccw===0.0){ccw=px*x2+py*y2;if(ccw>0.0){px-=x2;py-=y2;ccw=px*x2+py*y2;if(ccw<0.0){ccw=0.0;}}} -return(ccw<0.0)?-1:((ccw>0.0)?1:0);};armyc2.c2sd.renderer.so.utilities.linesIntersect=function(x1,y1,x2,y2,x3,y3,x4,y4) -{var rCCW1=this.relativeCCW(x1,y1,x2,y2,x3,y3),rCCW2=this.relativeCCW(x1,y1,x2,y2,x4,y4),rCCW3=this.relativeCCW(x3,y3,x4,y4,x1,y1),rCCW4=this.relativeCCW(x3,y3,x4,y4,x2,y2);return(((rCCW1*rCCW2)<=0)&&((rCCW3*rCCW4)<=0));};armyc2.c2sd.renderer.so.utilities.intersectRects=function(src1,src2) -{var x1=Math.max(src1.getMinX(),src2.getMinX()),y1=Math.max(src1.getMinY(),src2.getMinY()),x2=Math.min(src1.getMaxX(),src2.getMaxX()),y2=Math.min(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2-x1,y2-y1);};armyc2.c2sd.renderer.so.utilities.unionRects=function(src1,src2) -{var x1=Math.min(src1.getMinX(),src2.getMinX()),y1=Math.min(src1.getMinY(),src2.getMinY()),x2=Math.max(src1.getMaxX(),src2.getMaxX()),y2=Math.max(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2,y2);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Point=function(x,y){this.x=x,this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.getShapeType=function(){return"POINT";};armyc2.c2sd.renderer.so.Point.prototype.getX=function(){return this.x;};armyc2.c2sd.renderer.so.Point.prototype.getY=function(){return this.y;};armyc2.c2sd.renderer.so.Point.prototype.setLocation=function(x,y){this.x=x;this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.shift=function(x,y){this.x+=x;this.y+=y;};armyc2.c2sd.renderer.so.Point.prototype.toStringFormatted=function(){return"{x:"+this.x+", y:"+this.y+"}";};armyc2.c2sd.renderer.so.Point.prototype.clone=function(){return new armyc2.c2sd.renderer.so.Point(this.x,this.y);};armyc2.c2sd.renderer.so.Point.prototype.setPath=function(context){var x=this.x,y=this.y;context.moveTo(x,y);context.lineTo(x+1,y);context.lineTo(x+1,y+1);context.lineTo(x,y+1);context.closePath();};armyc2.c2sd.renderer.so.Point.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.Point.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Rect={};armyc2.c2sd.renderer.so.Rectangle=function(x,y,width,height){this.x=x,this.y=y,this.width=width,this.height=height,this.bottom=y+height,this.right=x+width;};armyc2.c2sd.renderer.so.Rectangle.prototype.getShapeType=function(){return"RECTANGLE";};armyc2.c2sd.renderer.so.Rectangle.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.x-1,this.y-1,this.width+2,this.height+2);};armyc2.c2sd.renderer.so.Rectangle.prototype.getX=function(){return this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.getY=function(){return this.y;};armyc2.c2sd.renderer.so.Rectangle.prototype.getWidth=function(){return this.width;};armyc2.c2sd.renderer.so.Rectangle.prototype.getHeight=function(){return this.height;};armyc2.c2sd.renderer.so.Rectangle.prototype.getBottom=function(){return this.bottom;};armyc2.c2sd.renderer.so.Rectangle.prototype.getRight=function(){return this.right;};armyc2.c2sd.renderer.so.Rectangle.prototype.getCenterX=function(){return this.x+(this.width/2);};armyc2.c2sd.renderer.so.Rectangle.prototype.getCenterY=function(){return this.y+(this.height/2);};armyc2.c2sd.renderer.so.Rectangle.prototype.setLocation=function(x,y){this.x=x;this.y=y;this.bottom=y+this.height;this.right=x+this.width;};armyc2.c2sd.renderer.so.Rectangle.prototype.isEmpty=function() -{return(this.width<=0.0)||(this.height<=0.0);};armyc2.c2sd.renderer.so.Rectangle.prototype.shift=function(x,y){this.x+=x;this.y+=y;this.right+=x;this.bottom+=y;};armyc2.c2sd.renderer.so.Rectangle.prototype.shiftTL=function(x,y){this.x+=x;this.y+=y;this.height=this.bottom-this.y;this.width=this.right-this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.shiftBR=function(x,y){this.right+=x;this.bottom+=y;this.height=this.bottom-this.y;this.width=this.right-this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.grow=function(pixel){this.shiftTL(-pixel,-pixel);this.shiftBR(pixel,pixel);};armyc2.c2sd.renderer.so.Rectangle.prototype.union=function(rect){if(rect) -{if(rect.ythis.bottom) -this.bottom=rect.bottom;if(rect.right>this.right) -this.right=rect.right;this.width=this.right-this.x;this.height=this.bottom-this.y;}};armyc2.c2sd.renderer.so.Rectangle.prototype.unionPoint=function(point){if(point) -{if(point.ythis.bottom) -this.bottom=point.y;if(point.x>this.right) -this.right=point.x;this.width=this.right-this.x;this.height=this.bottom-this.y;}};armyc2.c2sd.renderer.so.Rectangle.prototype.contains=function(x,y,w,h) -{if(x&&y&&w&&h) -{if(isEmpty()||w<=0||h<=0){return false;} -var x0=this.getX(),y0=this.getY();return(x>=x0&&y>=y0&&(x+w)<=x0+this.getWidth()&&(y+h)<=y0+this.getHeight());} -else if(x&&y) -{var x0=this.getX(),y0=this.getY();return(x>=x0&&y>=y0&&xthis.x+this.width){out|=this.OUT_RIGHT;} -if(this.height<=0){out|=this.OUT_TOP|this.OUT_BOTTOM;}else if(ythis.y+this.height){out|=this.OUT_BOTTOM;} -return out;};armyc2.c2sd.renderer.so.Rectangle.prototype.intersectsLine=function(x1,y1,x2,y2) -{var out1,out2;if((out2=outcode(x2,y2))===0){return true;} -while((out1=outcode(x1,y1))!==0){if((out1&out2)!==0){return false;} -if((out1&(this.OUT_LEFT|this.OUT_RIGHT))!==0){var x=this.getX();if((out1&this.OUT_RIGHT)!==0){x+=getWidth();} -y1=y1+(x-x1)*(y2-y1)/(x2-x1);x1=x;}else{var y=this.getY();if((out1&this.OUT_BOTTOM)!==0){y+=getHeight();} -x1=x1+(y-y1)*(x2-x1)/(y2-y1);y1=y;}} -return true;};armyc2.c2sd.renderer.so.Rectangle.prototype.setPath=function(context){var x=this.getX(),y=this.getY(),w=this.getWidth(),h=this.getHeight();context.moveTo(x,y);context.lineTo(x+w,y);context.lineTo(x+w,y+h);context.lineTo(x,y+h);context.closePath();};armyc2.c2sd.renderer.so.Rectangle.prototype.stroke=function(context){context.strokeRect(this.getX(),this.getY(),this.getWidth(),this.getHeight());};armyc2.c2sd.renderer.so.Rectangle.prototype.fill=function(context){context.fillRect(this.getX(),this.getY(),this.getWidth(),this.getHeight());};armyc2.c2sd.renderer.so.Rectangle.prototype.clone=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.x,this.y,this.width,this.height);};armyc2.c2sd.renderer.so.Rectangle.prototype.intersects=function(r){var tw=this.width;var th=this.height;var rw=r.width;var rh=r.height;if(rw<=0||rh<=0||tw<=0||th<=0){return false;} -var tx=this.x;var ty=this.y;var rx=r.x;var ry=r.y;rw+=rx;rh+=ry;tw+=tx;th+=ty;return((rwtx)&&(rhty)&&(twrx)&&(thry));};armyc2.c2sd.renderer.so.Rectangle.prototype.OUT_LEFT=1;armyc2.c2sd.renderer.so.Rectangle.prototype.OUT_TOP=2;armyc2.c2sd.renderer.so.Rectangle.prototype.OUT_RIGHT=4;armyc2.c2sd.renderer.so.Rectangle.prototype.OUT_BOTTOM=8;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.RoundedRectangle=function(x,y,w,h,radius){this.radius=radius;this.rectangle=new armyc2.c2sd.renderer.so.Rectangle(x,y,w,h);};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.getShapeType=function(){return"ROUNDED_RECTANGLE";};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.rectangle.getX()-1,this.rectangle.getY()-1,this.rectangle.getWidth()+2,this.rectangle.getHeight()+2);};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.shift=function(x,y){this.rectangle.shift(x,y);};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.setPath=function(context){var x=this.rectangle.getX(),y=this.rectangle.getY(),w=this.rectangle.getWidth(),h=this.rectangle.getHeight();if(w<(2*this.radius)) -this.radius=w/2;if(h<(2*this.radius)) -this.radius=h/2;var r=this.radius;context.moveTo(x+r,y);context.lineTo(x+w-r,y);context.arcTo(x+w,y,x+w,y+r,r);context.lineTo(x+w,y+h-r);context.arcTo(x+w,y+h,x+w-r,y+h,r);context.lineTo(x+r,y+h);context.arcTo(x,y+h,x,y+h-r,r);context.lineTo(x,y+r);context.arcTo(x,y,x+r,y,r);};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.RoundedRectangle.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Ellipse=function(x,y,w,h){this.rectangle=new armyc2.c2sd.renderer.so.Rectangle(x,y,w,h);};armyc2.c2sd.renderer.so.Ellipse.prototype.getShapeType=function(){return"ELLIPSE";};armyc2.c2sd.renderer.so.Ellipse.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.rectangle.getX()-1,this.rectangle.getY()-1,this.rectangle.getWidth()+2,this.rectangle.getHeight()+2);};armyc2.c2sd.renderer.so.Ellipse.prototype.shift=function(x,y){this.rectangle.shift(x,y);};armyc2.c2sd.renderer.so.Ellipse.prototype.setPath=function(context){var x=this.rectangle.getX(),y=this.rectangle.getY(),w=this.rectangle.getWidth(),h=this.rectangle.getHeight();var kappa=0.5522848,ox=(w/2)*kappa,oy=(h/2)*kappa,xe=x+w,ye=y+h,xm=x+w/2,ym=y+h/2;context.moveTo(x,ym);context.bezierCurveTo(x,ym-oy,xm-ox,y,xm,y);context.bezierCurveTo(xm+ox,y,xe,ym-oy,xe,ym);context.bezierCurveTo(xe,ym+oy,xm+ox,ye,xm,ye);context.bezierCurveTo(xm-ox,ye,x,ym+oy,x,ym);context.closePath();};armyc2.c2sd.renderer.so.Ellipse.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.Ellipse.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Arc=function(x,y,r,sa,ea){this.x=x,this.y=y,this.r=r,this.sa=sa*(Math.PI/180),this.ea=ea*(Math.PI/180);this.rectangle=new armyc2.c2sd.renderer.so.Rectangle(x-r,y-r,r*2,r*2);};armyc2.c2sd.renderer.so.Arc.prototype.getShapeType=function(){return"ARC";};armyc2.c2sd.renderer.so.Arc.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.rectangle.getX(),this.rectangle.getY(),this.rectangle.getWidth(),this.rectangle.getHeight());};armyc2.c2sd.renderer.so.Arc.prototype.shift=function(x,y){this.x+=x;this.y+=y;this.rectangle.shift(x,y);};armyc2.c2sd.renderer.so.Arc.prototype.setPath=function(context){context.arc(this.x,this.y,this.r,this.sa,this.ea,false);};armyc2.c2sd.renderer.so.Arc.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.Arc.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.BCurve=function(x1,y1,x2,y2,x3,y3,x4,y4){var so=armyc2.c2sd.renderer.so;this.x1=x1,this.y1=y1,this.x2=x2,this.y2=y2,this.x3=x3,this.y3=y3,this.x4=x4,this.y4=y4;this.rectangle=new so.Rectangle(x1,y1,1,1);this.rectangle.unionPoint(new so.Point(x2,y2));this.rectangle.unionPoint(new so.Point(x3,y3));this.rectangle.unionPoint(new so.Point(x4,y4));};armyc2.c2sd.renderer.so.BCurve.prototype.getShapeType=function(){return"BCURVE";};armyc2.c2sd.renderer.so.BCurve.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.rectangle.getX()-1,this.rectangle.getY()-1,this.rectangle.getWidth()+2,this.rectangle.getHeight()+2);};armyc2.c2sd.renderer.so.BCurve.prototype.shift=function(x,y){this.x1+=x;this.y1+=y;this.x2+=x;this.y2+=y;this.x3+=x;this.y3+=y;this.x4+=x;this.y4+=y;this.rectangle.shift(x,y);};armyc2.c2sd.renderer.so.BCurve.prototype.setPath=function(context){context.moveTo(this.x1,this.y1);context.bezierCurveTo(this.x2,this.y2,this.x3,this.y3,this.x4,this.y4);};armyc2.c2sd.renderer.so.BCurve.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.BCurve.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Line=function(x1,y1,x2,y2){var so=armyc2.c2sd.renderer.so;this.pt1=new so.Point(x1,y1);this.pt2=new so.Point(x2,y2);this.rectangle=new so.Rectangle(x1,y1,1,1);this.rectangle.unionPoint(new so.Point(x2,y2));};armyc2.c2sd.renderer.so.Line.prototype.getShapeType=function(){return"LINE";};armyc2.c2sd.renderer.so.Line.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.rectangle.getX(),this.rectangle.getY(),this.rectangle.getWidth(),this.rectangle.getHeight());};armyc2.c2sd.renderer.so.Line.prototype.getP1=function() -{return this.pt1;};armyc2.c2sd.renderer.so.Line.prototype.getP2=function() -{return this.pt2;};armyc2.c2sd.renderer.so.Line.prototype.shift=function(x,y){this.rectangle.shift(x,y);this.pt1.shift(x,y);this.pt2.shift(x,y);};armyc2.c2sd.renderer.so.Line.prototype.intersectsLine=function(line) -{return armyc2.c2sd.renderer.so.utilities.linesIntersect(this.getP1().getX(),this.getP1().getY(),this.getP2().getX(),this.getP2().getY(),line.getP1().getX(),line.getP1().getY(),line.getP2().getX(),line.getP2().getY());};armyc2.c2sd.renderer.so.Line.prototype.setPath=function(context){context.moveTo(this.pt1.getX(),this.pt1.getY());context.lineTo(this.pt2.getX(),this.pt2.getY());};armyc2.c2sd.renderer.so.Line.prototype.stroke=function(context){context.beginPath();context.moveTo(this.pt1.getX(),this.pt1.getY());context.lineTo(this.pt2.getX(),this.pt2.getY());context.stroke();};armyc2.c2sd.renderer.so.Line.prototype.fill=function(context){context.beginPath();context.moveTo(this.pt1.getX(),this.pt1.getY());context.lineTo(this.pt2.getX(),this.pt2.getY());context.fill();};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Path=function(){this._actions=[],this._startPoint=null,this._endPoint=null,this._lastMoveTo=null,this._rectangle=null;};armyc2.c2sd.renderer.so.Path.prototype.getShapeType=function(){return armyc2.c2sd.renderer.so.ShapeTypes.PATH;};armyc2.c2sd.renderer.so.Path.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this._rectangle.getX(),this._rectangle.getY(),this._rectangle.getWidth(),this._rectangle.getHeight());};armyc2.c2sd.renderer.so.Path.prototype.shift=function(x,y){var size=this._actions.length;var temp=null;this._rectangle.shift(x,y);for(var i=0;i0) -{var lastPt=this.pts.get(this.pts.size()-1);if(lastPt.x===x&&lastPt.y===y) -return;} -this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};android.graphics.Path.prototype.moveTo=function(x,y){if(this.pts.size()>0) -{var lastPt=this.pts.get(this.pts.size()-1);if(lastPt.x===x&&lastPt.y===y) -return;} -this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};android.graphics.Path.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3));};android.graphics.Path.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3));};android.graphics.Path.prototype.quadTo=function(x1,y1,x2,y2){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));};android.graphics.Path.prototype.addPath=function(path){this.pts.addAll(path.getPts());return;};android.graphics.Path.prototype.computeBounds=function(rect,exact){var j=0;var left=this.pts.get(0).x;var right=this.pts.get(0).x;var top=this.pts.get(0).y;var bottom=this.pts.get(0).y;var pt=null;for(j=1;jright) -right=pt.x;if(pt.ybottom) -bottom=pt.y;} -rect.left=left;rect.top=top;rect.right=right;rect.bottom=bottom;return;};android.graphics.Path.prototype.close=function(){};android.graphics.Path.prototype.getPts=function(){return pts;};var android=android||{};android.graphics=android.graphics||{};android.graphics.PointF=function() -{this.x=0;this.y=0;if(arguments.length===2) -{this.x=arguments[0];this.y=arguments[1];}};var android=android||{};android.graphics=android.graphics||{};android.graphics.Rect=function() -{this.left=0;this.top=0;this.width=function(){return 0;};this.height=function(){return 0;};};var android=android||{};android.graphics=android.graphics||{};android.graphics.RectF=function(){this.top=0;this.left=0;this.bottom=0;this.right=0;if(arguments.length===4) -{this.left=arguments[0];this.top=arguments[1];this.right=arguments[2];this.bottom=arguments[3];} -this.intersects=function(a,b){if(a.contains(b.left,b.top)) -return true;else if(a.contains(b.left,b.bottom)) -return true;else if(a.contains(b.right,b.top)) -return true;else if(a.contains(b.right,b.bottom)) -return true;return false;};this.width=function(){return this.right-this.left;};this.height=function(){return this.bottom-this.top;};this.contains=function(x,y){if(this.left=sourceCount){return(targetCount===0?sourceCount:-1);} -if(fromIndex<0){fromIndex=0;} -if(targetCount===0){return fromIndex;} -var first=target[targetOffset];var i=sourceOffset+fromIndex;var max=sourceOffset+(sourceCount-targetCount);startSearchForFirstChar:while(true){while(i<=max&&source[i]!==first){i++;} -if(i>max){return-1;} -var j=i+1;var end=j+targetCount-1;var k=targetOffset+1;while(jthis.length-pc)){return false;} -while(--pc>=0){if(this.charAt(to++)!==prefix.charAt(po++)){return false;}} -return true;};String.prototype.startsWith=function(prefix){if(arguments.length===1){return this.startsWith_string_number(arguments[0],0);}else if(arguments.length===2){return this.startsWith_string_number(arguments[0],arguments[1]);}else{return false;}};String.prototype.matches=function(exp){if(exp!==null){exp="^("+exp+")$";} -var regExp=new RegExp(exp,"gm");var m=this.match(regExp);return m!==null&&m.length!==0;};String.prototype.$plit=function(regex,limit){if(limit!==null&&limit>0){if(limit===1){return this;} -var regExp=new RegExp("("+regex+")","gm");var count=1;var s=this.replace(regExp,function($0,$1){count++;if(count===limit){return"@@_@@";}else if(count>limit){return $0;}else{return $0;}});regExp=new RegExp(regex,"gm");var arr=this.split(regExp);if(arr.length>limit){arr[limit-1]=s.substring(s.indexOf("@@_@@")+5);arr.length=limit;} -return arr;}else{var regExp=new RegExp(regex,"gm");return this.split(regExp);}};String.prototype.doubleValue=function() -{return this.valueOf();};Math.toRadians=function(v) -{return v*Math.PI/180.0;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.AffineTransform=function(){this.getScaleInstance=function(x,y){return null;};this.transform=function(){return;};this.setToIdentity=function(){return;};this.rotate=function(theta,x,y){return;};this.translate=function(x,y){return;};this.scale=function(x,y){return;};this.createTransformedShape=function(temp){return temp;};};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Area=function() -{this._path=null;this._pathIterator=null;if(arguments.length===1) -{var obj=arguments[0];var poly=null;var shape=null;var pt=null;var j=0;if(obj instanceof armyc2.c2sd.graphics2d.Polygon) -{poly=obj;this._path=new android.graphics.Path();this._pathIterator=new armyc2.c2sd.graphics2d.PathIterator(null);for(j=0;j0){for(j=0;jright)right=polygon.get(j).x;if(polygon.get(j).ybottom)bottom=polygon.get(j).y;} -return new armyc2.c2sd.graphics2d.Rectangle2D(left,top,right-left,bottom-top);};armyc2.c2sd.graphics2d.Area.isVertical=function(edge){if(edge.getX1()===edge.getX2())return true;else return false;};armyc2.c2sd.graphics2d.Area.adjustVerticalLine=function(line){var linePt0=line.getP1();var linePt1=line.getP2();if(armyc2.c2sd.graphics2d.Area.isVertical(line)) -{var x=line.getX2()+1;var y=line.getY2();linePt1.setLocation(x,y);line.setLine(linePt0,linePt1);}};armyc2.c2sd.graphics2d.Area.getLineIntersectPoints=function(polygon,hatchLine){var pts=null;try{var j=0;var k=0;var segment=null;var pt0=null;var pt1=null;var pt2=null;armyc2.c2sd.graphics2d.Area.adjustVerticalLine(hatchLine);var ptsPath=new java.util.ArrayList();var x=0;var y=0;var m1=0;var m2=0;var b1=0;var b2=0;for(j=0;j0) -this.width=arguments[0];if(arguments.length>1) -this.cap=arguments[1];if(arguments.length>2) -this.join=arguments[2];if(arguments.length>3) -this.miterlimit=arguments[3];if(arguments.length>4) -{this.dash=arguments[4];} -if(arguments.length>5) -this.dash_phase=arguments[5];};armyc2.c2sd.graphics2d.BasicStroke.prototype.createStrokedShape=function() -{var poly=null;if(arguments.length>0) -poly=arguments[0];else -return null;var pts=poly.getPathIterator(null).getPoints();var j=0;var gp=new armyc2.c2sd.graphics2d.GeneralPath();var pt=null;var ptsx=new Array(pts.size());for(j=0;j0){_text=arguments[0];_type=arguments[1];_size=arguments[2];} -this.getSize=function() -{return _size;};};armyc2.c2sd.graphics2d.Font.PLAIN=0;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FontMetrics=function(font){var _fontRenderContext=null;var _font=null;if(font) -_font=font;else -_font=armyc2.c2sd.renderer.utilities.RendererSettings.getModifierFont();var textInfoBuffer=document.createElement('canvas');textInfoBuffer.width=1;textInfoBuffer.height=1;this.textInfoContext=textInfoBuffer.getContext('2d');this.textInfoContext.font=_font;this.stringWidth=function(str) -{var location=new armyc2.c2sd.renderer.so.Point(0,0);var bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.getTextBounds(this.textInfoContext,str,location);var stringWidth=bounds.width;return stringWidth;};this.stringHeight=function(str) -{var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;var fontName="Arial";var fontStyle="normal";var fontSize=16;var height=armyc2.c2sd.renderer.utilities.RendererUtilities.measureTextHeight(fontName,fontSize,fontStyle).fullHeight;stringHeight=height;return stringHeight;};this.getTextBounds=function(str) -{var location=new armyc2.c2sd.renderer.so.Point(0,0);var bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.getTextBounds(this.textInfoContext,str,location,undefined);return bounds;};this.getFontRenderContext=function(){return _fontRenderContext;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FontRenderContext=function(){};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.GeneralPath=function(){this._path=new android.graphics.Path();this._pathIterator=new armyc2.c2sd.graphics2d.PathIterator(null);this.getBounds=function(){var rect=this._pathIterator.getBounds();return new armyc2.c2sd.graphics2d.Rectangle(Math.floor(rect.x),Math.floor(rect.y),Math.floor(rect.width),Math.floor(rect.height));};};armyc2.c2sd.graphics2d.GeneralPath.prototype.lineTo=function(x,y){this._path.lineTo(x,y);this._pathIterator.lineTo(x,y);};armyc2.c2sd.graphics2d.GeneralPath.prototype.moveTo=function(x,y){this._path.moveTo(x,y);this._pathIterator.moveTo(x,y);};armyc2.c2sd.graphics2d.GeneralPath.prototype.quadTo=function(x1,y1,x2,y2){this._path.quadTo(x1,y1,x2,y2);this._pathIterator.quadTo(x1,y1,x2,y2);};armyc2.c2sd.graphics2d.GeneralPath.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this._path.cubicTo(x1,y1,x2,y2,x3,y3);this._pathIterator.cubicTo(x1,y1,x2,y2,x3,y3);};armyc2.c2sd.graphics2d.GeneralPath.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this._path.cubicTo(x1,y1,x2,y2,x3,y3);this._pathIterator.cubicTo(x1,y1,x2,y2,x3,y3);};armyc2.c2sd.graphics2d.GeneralPath.prototype.computeBounds=function(rect){var rectf=new android.graphics.RectF();this._path.computeBounds(rectf,true);rect.x=rectf.left;rect.y=rectf.top;rect.width=rectf.bottom-rectf.top;rect.setRect(rectf.left,rectf.top,rectf.width(),rectf.height());};armyc2.c2sd.graphics2d.GeneralPath.prototype.closePath=function(){if(this._path!==null) -this._path.close();};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsPt2=function(x,y){return false;};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsPt=function(pt){return false;};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsRect2=function(x,y,width,height){var rect2=this.getBounds();return rect2.containsRect2(x,y,width,height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsRect=function(r){var rect=new armyc2.c2sd.graphics2d.Rectangle(Math.floor(r.x),Math.floor(r.y),Math.floor(r.width),Math.floor(r.height));var rect2=this.getBounds();return rect2.containsRect2(rect.x,rect.y,rect.width,rect.height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.getBounds2D=function(){return this._pathIterator.getBounds();};armyc2.c2sd.graphics2d.GeneralPath.prototype.intersectsRect2=function(x,y,w,h){return this.getBounds().intersectsRect2(x,y,w,h);};armyc2.c2sd.graphics2d.GeneralPath.prototype.intersectsRect=function(rect){return this.getBounds().intersectsRect2(rect.x,rect.y,rect.width,rect.height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.append=function(shape,connect){var gp=shape;var pi=gp.getPathIterator(null);var pts=pi.getPoints();var j=0;var pt=null;var pt1=null;var pt2=null;for(j=0;jthis.x2&&edgex2>this.x2) -return false;} -else -{if(edgex1this.x1&&edgex2>this.x1) -return false;} -if(this.y1<=this.y2) -{if(edgey1this.y2&&edgey2>this.y2) -return false;} -else -{if(edgey1this.y1&&edgey2>this.y1) -return false;} -var slope=(this.y2-this.y1)/(this.x2-this.x1);var b1=this.y2-slope*this.x2;var edgeSlope=(edgey2-edgey1)/(edgex2-edgex1);var b2=edgey2-edgeSlope*edgex2;var rect=new armyc2.c2sd.graphics2d.Rectangle2D(this.x1,this.y1,this.x2,this.y2);var x0=edgex1;var width=Math.abs(edgex1-edgex2);var y0=edgey1;var height=Math.abs(edgey1-edgey2);var rect2=new armyc2.c2sd.graphics2d.Rectangle2D(x0,y0,width,height);if(slope===edgeSlope){if(b1===b2&&rect.intersectsRect(rect2)===true) -return true;else -return false;}else{var x=(b2-b1)/(slope-edgeSlope);var y=(slope*x+b1);if(this.x1this.x2) -return false;}else if(this.x2this.x1) -return false;} -if(this.y1this.y2) -return false;}else if(this.y2this.y1) -return false;} -if(edgex1edgex2) -return false;}else if(edgex2edgex1) -return false;} -if(edgey1edgey2) -return false;}else if(edgey2edgey1) -return false;}} -return true;};armyc2.c2sd.graphics2d.Line2D.prototype.setLine=function() -{if(arguments.length===1) -{var line1=arguments[0];this.x1=line1.x1;this.y1=line1.y1;this.x2=line1.x2;this.y2=line1.y2;} -else if(arguments.length===2) -{var pt1=arguments[0];var pt2=arguments[1];this.x1=pt1.x;this.y1=pt1.y;this.x2=pt2.x;this.y2=pt2.y;} -else if(arguments.length===4) -{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;}};armyc2.c2sd.graphics2d.Line2D.ptSegDistSq=function(x1,y1,x2,y2,px,py){x2-=x1;y2-=y1;px-=x1;py-=y1;var dotprod=px*x2+py*y2;var projlenSq;if(dotprod<=0.0){projlenSq=0.0;}else{px=x2-px;py=y2-py;dotprod=px*x2+py*y2;if(dotprod<=0.0){projlenSq=0.0;}else{projlenSq=dotprod*dotprod/(x2*x2+y2*y2);}} -var lenSq=px*px+py*py-projlenSq;if(lenSq<0){lenSq=0;} -return lenSq;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.PathIterator=function(){this._currentSeg=0;this._pts=new java.util.ArrayList();this.reset=function(){this._currentSeg=0;};this.setPathIterator=function(pts){this._currentSeg=0;this._pts=pts;};};armyc2.c2sd.graphics2d.PathIterator.prototype.getPoints=function(){return this._pts;};armyc2.c2sd.graphics2d.PathIterator.prototype.currentSegment=function(coords){coords[0]=this._pts.get(this._currentSeg).x;coords[1]=this._pts.get(this._currentSeg).y;return this._pts.get(this._currentSeg).style;};armyc2.c2sd.graphics2d.PathIterator.prototype.getWindingRule=function(){return 1;};armyc2.c2sd.graphics2d.PathIterator.prototype.isDone=function(){if(this._currentSeg===this._pts.size()) -return true;return false;};armyc2.c2sd.graphics2d.PathIterator.prototype.next=function(){this._currentSeg++;};armyc2.c2sd.graphics2d.PathIterator.prototype.moveTo=function(x,y){if(this._pts.size()>0) -{var lastPt=this._pts.get(this._pts.size()-1);if(lastPt.x===x&&lastPt.y===y) -return;} -this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y,0));};armyc2.c2sd.graphics2d.PathIterator.prototype.lineTo=function(x,y){if(this._pts.size()>0) -{var lastPt=this._pts.get(this._pts.size()-1);if(lastPt.x===x&&lastPt.y===y) -return;} -this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y,1));};armyc2.c2sd.graphics2d.PathIterator.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3,3));};armyc2.c2sd.graphics2d.PathIterator.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3,3));};armyc2.c2sd.graphics2d.PathIterator.prototype.quadTo=function(x1,y1,x2,y2){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,2));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,2));};armyc2.c2sd.graphics2d.PathIterator.prototype.getBounds=function(){var j=0;var left=this._pts.get(0).x;var right=this._pts.get(0).x;var top=this._pts.get(0).y;var bottom=this._pts.get(0).y;for(j=1;jright) -right=this._pts.get(j).x;if(this._pts.get(j).ybottom) -bottom=this._pts.get(j).y;} -var rect=new armyc2.c2sd.graphics2d.Rectangle2D(left,top,right-left,bottom-top);return rect;};armyc2.c2sd.graphics2d.PathIterator.SEG_CLOSE=4;armyc2.c2sd.graphics2d.PathIterator.SEG_CUBICTO=3;armyc2.c2sd.graphics2d.PathIterator.SEG_LINETO=1;armyc2.c2sd.graphics2d.PathIterator.SEG_MOVETO=0;armyc2.c2sd.graphics2d.PathIterator.SEG_QUADTO=2;armyc2.c2sd.graphics2d.PathIterator.WIND_EVEN_ODD=0;armyc2.c2sd.graphics2d.PathIterator.WIND_NON_ZERO=1;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Point=function(){this.x=0;this.y=0;if(arguments.length===2) -{this.x=Number(arguments[0]);this.y=Number(arguments[1]);}};armyc2.c2sd.graphics2d.Point.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Point.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Point.prototype.setLocation=function(x1,y1){this.x=Number(x1);this.y=Number(y1);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Point2D=function(){this.x=0;this.y=0;if(arguments.length===2) -{this.x=Number(arguments[0]);this.y=Number(arguments[1]);} -if(arguments.length===1) -{this.x=Number(arguments[0].x);this.y=Number(arguments[0].y);}};armyc2.c2sd.graphics2d.Point2D.prototype.distance=function(x1,y1) -{var dist=Math.sqrt((this.x-x1)*(this.x-x1)+(this.y-y1)*(this.y-y1));return dist;};armyc2.c2sd.graphics2d.Point2D.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Point2D.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Point2D.prototype.setLocation=function(x1,y1){this.x=Number(x1);this.y=Number(y1);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Polygon=function(){this.bounds=null;this.pts=new java.util.ArrayList();this.contains=function(x,y){if(this.pts.size()<3) -return false;if((this.pts.get(0).x!==this.pts.get(this.pts.size()-1).x)||(this.pts.get(0).y!==this.pts.get(this.pts.size()-1).y)){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(this.pts.get(0)));} -var lowVal=-100;var pt0=new armyc2.c2sd.JavaLineArray.POINT2(lowVal,y);var pt1=new armyc2.c2sd.JavaLineArray.POINT2(x,y);var edge=null;var ray=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);var j=0;var intersectCounter=0;for(j=0;jright) -right=pt.x;if(pt.ybottom) -bottom=pt.y;} -rect.left=left;rect.top=top;rect.right=right;rect.bottom=bottom;return;};};armyc2.c2sd.graphics2d.Polygon.prototype.size=function() -{if(this.pts!==null) -return this.pts.size();else -return 0;};armyc2.c2sd.graphics2d.Polygon.prototype.addPoint=function(x,y) -{this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};armyc2.c2sd.graphics2d.Polygon.prototype.containsPt2=function(x,y) -{if(this.pts.size()<3) -return false;if((this.pts.get(0).x!==this.pts.get(this.pts.size()-1).x)||(this.pts.get(0).y!==this.pts.get(this.pts.size()-1).y)){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(this.pts.get(0)));} -var lowVal=-100;var pt0=new armyc2.c2sd.JavaLineArray.POINT2(lowVal,y);var pt1=new armyc2.c2sd.JavaLineArray.POINT2(x,y);var edge=null;var ray=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);var j=0;var intersectCounter=0;for(j=0;j0){pi.moveTo(this.pts.get(0).x,this.pts.get(0).y);for(j=1;jrect.x+rect.width) -return false;if(this.y+this.heightrect.y+rect.height) -return false;return true;};armyc2.c2sd.graphics2d.Rectangle.prototype.intersectsRect2=function(x1,y1,width1,height1){if(this.x+this.widthx1+width1) -return false;if(this.y+this.heighty1+height1) -return false;return true;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsRect=function(rect){var x1=Math.floor(rect.getX());var y1=Math.floor(rect.getY());if(this.containsPt2(x1,y1)){x1+=rect.getWidth();y1+=rect.getHeight();if(this.containsPt2(x1,y1)) -return true;} -return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsRect2=function(x1,y1,width1,height1){if(this.containsPt2(x1,y1)&&this.containsPt2(x1+width1,y1+height1)) -return true;else -return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsPt=function(pt){if(this.x<=pt.getX()&&pt.getX()<=this.x+this.width&&this.y<=pt.getY()&&pt.getY()<=this.y+this.height) -return true;else -return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.getBounds2D=function(){return new armyc2.c2sd.graphics2d.Rectangle2D(this.x,this.y,this.width,this.height);};armyc2.c2sd.graphics2d.Rectangle.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Rectangle.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMinX=function(){return this.x;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMinY=function(){return this.y;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMaxX=function(){return this.x+this.width;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMaxY=function(){return this.y+this.height;};armyc2.c2sd.graphics2d.Rectangle.prototype.getHeight=function(){return this.height;};armyc2.c2sd.graphics2d.Rectangle.prototype.getWidth=function(){return this.width;};armyc2.c2sd.graphics2d.Rectangle.prototype.grow=function(h,v){return;};armyc2.c2sd.graphics2d.Rectangle.prototype.setRect=function(rect){this.x=rect.x;this.y=rect.y;this.width=rect.width;this.height=rect.height;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Rectangle2D=function(){this.x=0;this.y=0;this.width=0;this.height=0;if(arguments.length===4) -{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];} -this.containsPt2=function(x1,y1){if(this.x<=x1&&x1<=this.x+this.width&&this.y<=y1&&y1<=this.y+this.width) -return true;else -return false;};this.add=function(x1,y1){if(x1this.x+this.width) -this.width+=(x1-this.x);if(y1>this.y+this.height) -this.height+=(y1-this.y);};};armyc2.c2sd.graphics2d.Rectangle2D.prototype.createIntersection=function(r){if(r.x>this.x+this.width) -return null;if(r.x+r.widththis.y+this.height) -return null;if(r.y+r.heightrect.x+rect.width) -return false;if(this.y+this.heightrect.y+rect.height) -return false;return true;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.intersectsRect2=function(x1,y1,width1,height1){if(this.x+this.widthx1+width1) -return false;if(this.y+this.heighty1+height1) -return false;return true;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsRect=function(rect){var x1=rect.getX();var y1=rect.getY();if(this.containsPt2(x1,y1)){x1+=rect.getWidth();y1+=rect.getHeight();if(this.containsPt2(x1,y1)) -return true;} -return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsPt=function(pt){if(this.x<=pt.getX()&&pt.getX()<=this.x+this.width) -if(this.y<=pt.getY()&&pt.getY()<=this.x+this.height) -return true;return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.intersectsLine=function(line){var pt0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x,this.y);var pt1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x+this.width,this.y);var edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0,pt1);if(line.intersectsLine(edge)) -return true;var pt2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x+this.width,this.y+this.height);edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt1,pt2);if(line.intersectsLine(edge)) -return true;var pt3=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x,this.y+this.height);edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt2,pt3);if(line.intersectsLine(edge)) -return true;edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt3,pt0);if(line.intersectsLine(edge)) -return true;return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsRect2=function(x,y,width,height){var x1=x;var y1=y;if(this.containsPt2(x1,y1)){x1+=width;y1+=height;if(this.containsPt2(x1,y1)) -return true;} -return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.isEmpty=function(){if(this.width===0&&this.height===0) -return true;else -return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.setRect=function() -{if(arguments.length===4) -{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];} -else if(arguments.length===1) -{this.x=arguments[0].getX();this.y=arguments[0].getY();this.width=arguments[0].getWidth();this.height=arguments[0].getHeight();}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Shape={};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Stroke={};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.TextLayout=function(){var _font=null;var _str="";if(arguments.length>1) -{_str=arguments[0];_font=arguments[1];} -this.getOutline=function(tx){return new armyc2.c2sd.graphics2d.GeneralPath();};this.getPixelBounds=function(frc,x,y){return null;};this.getBounds=function(){var width=Math.floor(_font.getSize()/2)*_str.length;var height=_font.getSize();var rect=new armyc2.c2sd.graphics2d.Rectangle(0,0,width,height);return rect;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.TexturePaint=function(){var _rect=null;var _g2d=null;var _bi=null;if(arguments.length===2) -{_bi=arguments[0];_rect=arguments[1];}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Arc2D=function() -{this.x=0;this.y=0;this.width=0;this.height=0;this.start=0;this.extent=0;this.type=0;if(arguments.length===1) -{var t=arguments[0];this.setArcType(t);} -else if(arguments.length===7) -{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];this.start=arguments[4];this.extent=arguments[5];armyc2.c2sd.graphics2d.Arc2D.setArcType(this,arguments[6]);} -else if(arguments.length===4) -{var ellipseBounds=arguments[0];var start=arguments[1];var extent=arguments[2];var type=arguments[3];armyc2.c2sd.graphics2d.Arc2D.setArcType(this,type);this.x=ellipseBounds.getX();this.y=ellipseBounds.getY();this.width=ellipseBounds.getWidth();this.height=ellipseBounds.getHeight();this.start=start;this.extent=extent;} -this.getX=function(){return this.x;};this.getY=function(){return this.y;};this.getWidth=function(){return this.width;};this.getHeight=function(){return this.height;};this.getAngleStart=function(){return this.start;};this.getAngleExtent=function(){return this.extent;};this.isEmpty=function(){return(this.width<=0.0||this.height<=0.0);};this.setArc=function(x,y,w,h,angSt,angExt,closure){this.setArcType(closure);this.x=x;this.y=y;this.width=w;this.height=h;this.start=angSt;this.extent=angExt;};this.setAngleStart=function(angSt){this.start=angSt;};this.setAngleExtent=function(angExt){this.extent=angExt;};this.getArcType=function(){return this.type;};this.getStartPoint=function(){var angle=Math.toRadians(-this.getAngleStart());var x=this.getX()+(Math.cos(angle)*0.5+0.5)*this.getWidth();var y=this.getY()+(Math.sin(angle)*0.5+0.5)*this.getHeight();return new armyc2.c2sd.graphics2d.Point2D(x,y);};this.getEndPoint=function(){var angle=Math.toRadians(-this.getAngleStart()-this.getAngleExtent());var x=this.getX()+(Math.cos(angle)*0.5+0.5)*this.getWidth();var y=this.getY()+(Math.sin(angle)*0.5+0.5)*this.getHeight();return new armyc2.c2sd.graphics2d.Point2D(x,y);};this.setArc2=function(rect,angSt,angExt,closure){this.setArc(rect.getX(),rect.getY(),rect.getWidth(),rect.getHeight(),angSt,angExt,closure);};this.setArc3=function(a){this.setArc(a.getX(),a.getY(),a.getWidth(),a.getHeight(),a.getAngleStart(),a.getAngleExtent(),a.type);};this.setArcByCenter=function(x,y,radius,angSt,angExt,closure){this.setArc(x-radius,y-radius,radius*2.0,radius*2.0,angSt,angExt,closure);};this.setArcByTangent=function(p1,p2,p3,radius){var ang1=Math.atan2(p1.getY()-p2.getY(),p1.getX()-p2.getX());var ang2=Math.atan2(p3.getY()-p2.getY(),p3.getX()-p2.getX());var diff=ang2-ang1;if(diff>3.141592653589793){ang2-=6.283185307179586;}else if(diff<-3.141592653589793){ang2+=6.283185307179586;} -var bisect=(ang1+ang2)/2.0;var theta=Math.abs(ang2-bisect);var dist=radius/Math.sin(theta);var x=p2.getX()+dist*Math.cos(bisect);var y=p2.getY()+dist*Math.sin(bisect);if(ang12){throw new IllegalArgumentException("invalid type for Arc: "+type);} -this.type=type;};this.setFrame=function(x,y,w,h){this.setArc(x,y,w,h,this.getAngleStart(),this.getAngleExtent(),this.type);};this.getBounds2D=function(){if(this.isEmpty()){return this.makeBounds(this.getX(),this.getY(),this.getWidth(),this.getHeight());} -var x1;var y1;var x2;var y2;if(this.getArcType()===2){x1=y1=x2=y2=0.0;}else{x1=y1=1.0;x2=y2=-1.0;} -var angle=0.0;for(var i=0;i<6;i++){if(i<4){angle+=90.0;if(!this.containsAngle(angle)){continue;}}else if(i===4){angle=this.getAngleStart();}else{angle+=this.getAngleExtent();} -var rads=Math.toRadians(-angle);var xe=Math.cos(rads);var ye=Math.sin(rads);x1=Math.min(x1,xe);y1=Math.min(y1,ye);x2=Math.max(x2,xe);y2=Math.max(y2,ye);} -var w=this.getWidth();var h=this.getHeight();x2=(x2-x1)*0.5*w;y2=(y2-y1)*0.5*h;x1=this.getX()+(x1*0.5+0.5)*w;y1=this.getY()+(y1*0.5+0.5)*h;return this.makeBounds(x1,y1,x2,y2);};this.makeBounds=function(x,y,w,h){return null;};this.containsAngle=function(angle){var angExt=this.getAngleExtent();var backwards=(angExt<0.0);if(backwards){angExt=-angExt;} -if(angExt>=360.0){return true;} -angle=armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees(angle)-armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees(this.getAngleStart());if(backwards){angle=-angle;} -if(angle<0.0){angle+=360.0;} -return(angle>=0.0)&&(angle=0.25){return false;} -var angExt=Math.abs(this.getAngleExtent());if(angExt>=360.0){return true;} -var inarc=this.containsAngle(-Math.toDegrees(Math.atan2(normy,normx)));if(this.type===2){return inarc;} -if(inarc){if(angExt>=180.0){return true;}}else{if(angExt<=180.0){return false;}} -var angle=Math.toRadians(-this.getAngleStart());var x1=Math.cos(angle);var y1=Math.sin(angle);angle+=Math.toRadians(-this.getAngleExtent());var x2=Math.cos(angle);var y2=Math.sin(angle);var inside=(armyc2.c2sd.graphics2d.Line2D.relativeCCW(x1,y1,x2,y2,2*normx,2*normy)*armyc2.c2sd.graphics2d.Line2D.relativeCCW(x1,y1,x2,y2,0,0)>=0);return inarc?!inside:inside;};this.getPathIterator=function(at){return new armyc2.c2sd.graphics2d.ArcIterator(this,at);};this.hashCode=function(){var bits=java.lang.Double.doubleToLongBits(this.getX());bits+=java.lang.Double.doubleToLongBits(this.getY())*37;bits+=java.lang.Double.doubleToLongBits(this.getWidth())*43;bits+=java.lang.Double.doubleToLongBits(this.getHeight())*47;bits+=java.lang.Double.doubleToLongBits(this.getAngleStart())*53;bits+=java.lang.Double.doubleToLongBits(this.getAngleExtent())*59;bits+=this.getArcType()*61;return((bits)^((bits>>32)));};this.equals=function(obj){if(obj===this){return true;} -if(Clazz.instanceOf(obj,armyc2.c2sd.graphics2d.Arc2D)){var a2d=obj;return((this.getX()===a2d.getX())&&(this.getY()===a2d.getY())&&(this.getWidth()===a2d.getWidth())&&(this.getHeight()===a2d.getHeight())&&(this.getAngleStart()===a2d.getAngleStart())&&(this.getAngleExtent()===a2d.getAngleExtent())&&(this.getArcType()===a2d.getArcType()));} -return false;};};armyc2.c2sd.graphics2d.Arc2D.setArcType=function(that,type) -{if(type<0||type>2){throw new IllegalArgumentException("invalid type for Arc: "+type);} -that.type=type;};armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees=function(angle){if(angle>180.0){if(angle<=(540.0)){angle=angle-360.0;}else{angle=Math.IEEEremainder(angle,360.0);if(angle===-180.0){angle=180.0;}}}else if(angle<=-180.0){if(angle>(-540.0)){angle=angle+360.0;}else{angle=Math.IEEEremainder(angle,360.0);if(angle===-180.0){angle=180.0;}}} -return angle;};armyc2.c2sd.graphics2d.Arc2D.OPEN=0;armyc2.c2sd.graphics2d.Arc2D.CHORD=1;armyc2.c2sd.graphics2d.Arc2D.PIE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.ArcIterator=function() -{this.x=0;this.y=0;this.w=0;this.h=0;this.angStRad=0;this.increment=0;this.cv=0;this.affine=null;this.index=0;this.arcSegs=0;this.lineSegs=0;var a=arguments[0];var at=arguments[1];this.w=a.getWidth()/2;this.h=a.getHeight()/2;this.x=a.getX()+this.w;this.y=a.getY()+this.h;this.angStRad=-Math.toRadians(a.getAngleStart());this.affine=at;var ext=-a.getAngleExtent();if(ext>=360.0||ext<=-360){this.arcSegs=4;this.increment=1.5707963267948966;this.cv=0.5522847498307933;if(ext<0){this.increment=-this.increment;this.cv=-this.cv;}}else{this.arcSegs=Math.floor(Math.ceil(Math.abs(ext)/90.0));this.increment=Math.toRadians(ext/this.arcSegs);this.cv=armyc2.c2sd.graphics2d.ArcIterator.btan(this.increment);if(this.cv===0){this.arcSegs=0;}} -switch(a.getArcType()){case 0:this.lineSegs=0;break;case 1:this.lineSegs=1;break;case 2:this.lineSegs=2;break;} -if(this.w<0||this.h<0){this.arcSegs=this.lineSegs=-1;} -this.getWindingRule=function(){return 1;};this.isDone=function(){return this.index>this.arcSegs+this.lineSegs;};this.next=function(){this.index++;};this.currentSegmentFlt=function(coords){if(this.isDone()){System.out.println("arc iterator out of bounds");return-1;} -var angle=this.angStRad;if(this.index===0){coords[0]=(this.x+Math.cos(angle)*this.w);coords[1]=(this.y+Math.sin(angle)*this.h);if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} -return 0;} -if(this.index>this.arcSegs){if(this.index===this.arcSegs+this.lineSegs){return 4;} -coords[0]=this.x;coords[1]=this.y;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} -return 1;} -angle+=this.increment*(this.index-1);var relx=Math.cos(angle);var rely=Math.sin(angle);coords[0]=(this.x+(relx-this.cv*rely)*this.w);coords[1]=(this.y+(rely+this.cv*relx)*this.h);angle+=this.increment;relx=Math.cos(angle);rely=Math.sin(angle);coords[2]=(this.x+(relx+this.cv*rely)*this.w);coords[3]=(this.y+(rely-this.cv*relx)*this.h);coords[4]=(this.x+relx*this.w);coords[5]=(this.y+rely*this.h);if(this.affine!==null){this.affine.transform(coords,0,coords,0,3);} -return 3;};this.currentSegment=function(coords){if(this.isDone()){} -var angle=this.angStRad;if(this.index===0){coords[0]=this.x+Math.cos(angle)*this.w;coords[1]=this.y+Math.sin(angle)*this.h;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} -return 0;} -if(this.index>this.arcSegs){if(this.index===this.arcSegs+this.lineSegs){return 4;} -coords[0]=this.x;coords[1]=this.y;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} -return 1;} -angle+=this.increment*(this.index-1);var relx=Math.cos(angle);var rely=Math.sin(angle);coords[0]=this.x+(relx-this.cv*rely)*this.w;coords[1]=this.y+(rely+this.cv*relx)*this.h;angle+=this.increment;relx=Math.cos(angle);rely=Math.sin(angle);coords[2]=this.x+(relx+this.cv*rely)*this.w;coords[3]=this.y+(rely-this.cv*relx)*this.h;coords[4]=this.x+relx*this.w;coords[5]=this.y+rely*this.h;if(this.affine!==null){this.affine.transform(coords,0,coords,0,3);} -return 3;};};armyc2.c2sd.graphics2d.ArcIterator.btan=function(increment){increment/=2.0;return 1.3333333333333333*Math.sin(increment)/(1.0+Math.cos(increment));};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.QuadCurve2D=function(){} -armyc2.c2sd.graphics2d.QuadCurve2D.getFlatnessSq2=function(x1,y1,ctrlx,ctrly,x2,y2){return armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx,ctrly);};armyc2.c2sd.graphics2d.QuadCurve2D.getFlatnessSq=function(coords,offset){return armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(coords[offset+0],coords[offset+1],coords[offset+4],coords[offset+5],coords[offset+2],coords[offset+3]);};armyc2.c2sd.graphics2d.QuadCurve2D.subdivide=function(src,srcoff,left,leftoff,right,rightoff){var x1=src[srcoff+0];var y1=src[srcoff+1];var ctrlx=src[srcoff+2];var ctrly=src[srcoff+3];var x2=src[srcoff+4];var y2=src[srcoff+5];if(left!==null){left[leftoff+0]=x1;left[leftoff+1]=y1;} -if(right!==null){right[rightoff+4]=x2;right[rightoff+5]=y2;} -x1=(x1+ctrlx)/2.0;y1=(y1+ctrly)/2.0;x2=(x2+ctrlx)/2.0;y2=(y2+ctrly)/2.0;ctrlx=(x1+x2)/2.0;ctrly=(y1+y2)/2.0;if(left!==null){left[leftoff+2]=x1;left[leftoff+3]=y1;left[leftoff+4]=ctrlx;left[leftoff+5]=ctrly;} -if(right!==null){right[rightoff+0]=ctrlx;right[rightoff+1]=ctrly;right[rightoff+2]=x2;right[rightoff+3]=y2;}};armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic=function(eqn){return armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2(eqn,eqn);};armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2=function(eqn,res){var a=eqn[2];var b=eqn[1];var c=eqn[0];var roots=0;if(a===0.0){if(b===0.0){return-1;} -res[roots++]=-c/b;}else{var d=b*b-4.0*a*c;if(d<0.0){return 0;} -d=Math.sqrt(d);if(b<0.0){d=-d;} -var q=(b+d)/-2.0;res[roots++]=q/a;if(q!==0.0){res[roots++]=c/q;}} -return roots;};armyc2.c2sd.graphics2d.QuadCurve2D.BELOW=-2;armyc2.c2sd.graphics2d.QuadCurve2D.LOWEDGE=-1;armyc2.c2sd.graphics2d.QuadCurve2D.INSIDE=0;armyc2.c2sd.graphics2d.QuadCurve2D.HIGHEDGE=1;armyc2.c2sd.graphics2d.QuadCurve2D.ABOVE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.CubicCurve2D=function() -{} -armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2=function(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2){return Math.max(armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx1,ctrly1),armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx2,ctrly2));};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness=function(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2){return Math.sqrt(armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2));};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq=function(coords,offset){return armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2(coords[offset+0],coords[offset+1],coords[offset+2],coords[offset+3],coords[offset+4],coords[offset+5],coords[offset+6],coords[offset+7]);};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness2=function(coords,offset){return armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness(coords[offset+0],coords[offset+1],coords[offset+2],coords[offset+3],coords[offset+4],coords[offset+5],coords[offset+6],coords[offset+7]);};armyc2.c2sd.graphics2d.CubicCurve2D.subdivide=function(src,srcoff,left,leftoff,right,rightoff){var x1=src[srcoff+0];var y1=src[srcoff+1];var ctrlx1=src[srcoff+2];var ctrly1=src[srcoff+3];var ctrlx2=src[srcoff+4];var ctrly2=src[srcoff+5];var x2=src[srcoff+6];var y2=src[srcoff+7];if(left!==null){left[leftoff+0]=x1;left[leftoff+1]=y1;} -if(right!==null){right[rightoff+6]=x2;right[rightoff+7]=y2;} -x1=(x1+ctrlx1)/2.0;y1=(y1+ctrly1)/2.0;x2=(x2+ctrlx2)/2.0;y2=(y2+ctrly2)/2.0;var centerx=(ctrlx1+ctrlx2)/2.0;var centery=(ctrly1+ctrly2)/2.0;ctrlx1=(x1+centerx)/2.0;ctrly1=(y1+centery)/2.0;ctrlx2=(x2+centerx)/2.0;ctrly2=(y2+centery)/2.0;centerx=(ctrlx1+ctrlx2)/2.0;centery=(ctrly1+ctrly2)/2.0;if(left!==null){left[leftoff+2]=x1;left[leftoff+3]=y1;left[leftoff+4]=ctrlx1;left[leftoff+5]=ctrly1;left[leftoff+6]=centerx;left[leftoff+7]=centery;} -if(right!==null){right[rightoff+0]=centerx;right[rightoff+1]=centery;right[rightoff+2]=ctrlx2;right[rightoff+3]=ctrly2;right[rightoff+4]=x2;right[rightoff+5]=y2;}};armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic=function(eqn){return armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic2(eqn,eqn);};armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic2=function(eqn,res){var d=eqn[3];if(d===0.0){return armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2(eqn,res);} -var a=eqn[2]/d;var b=eqn[1]/d;var c=eqn[0]/d;var roots=0;var Q=(a*a-3.0*b)/9.0;var R=(2.0*a*a*a-9.0*a*b+27.0*c)/54.0;var R2=R*R;var Q3=Q*Q*Q;a=a/3.0;if(R2=0){v=v*t+eqn[order];} -return v;};armyc2.c2sd.graphics2d.CubicCurve2D.findZero=function(t,target,eqn){var slopeqn=[eqn[1],2*eqn[2],3*eqn[3]];var slope;var origdelta=0;var origt=t;while(true){slope=armyc2.c2sd.graphics2d.CubicCurve2D.solveEqn(slopeqn,2,t);if(slope===0){return t;} -var y=armyc2.c2sd.graphics2d.CubicCurve2D.solveEqn(eqn,3,t);if(y===0){return t;} -var delta=-(y/slope);if(origdelta===0){origdelta=delta;} -if(ttarget){if(delta>0) -return t;}else{return(delta>0?(target+4.9E-324):(target-4.9E-324));} -var newt=t+delta;if(t===newt){return t;} -if(delta*origdelta<0){var tag=(origt=high){return(coord>high?2:1);} -return 0;};armyc2.c2sd.graphics2d.CubicCurve2D.BELOW=-2;armyc2.c2sd.graphics2d.CubicCurve2D.LOWEDGE=-1;armyc2.c2sd.graphics2d.CubicCurve2D.INSIDE=0;armyc2.c2sd.graphics2d.CubicCurve2D.HIGHEDGE=1;armyc2.c2sd.graphics2d.CubicCurve2D.ABOVE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FlatteningPathIterator=function(){this.src=null;this.squareflat=0;this.limit=0;this.hold=null;this.curx=0;this.cury=0;this.movx=0;this.movy=0;this.holdType=0;this.holdEnd=0;this.holdIndex=0;this.levels=null;this.levelIndex=0;this.done=false;var limit;var src=arguments[0];var flatness=arguments[1];if(arguments.length===2) -limit=10;if(arguments.length>2) -limit=arguments[2];if(flatness<0.0){throw new IllegalArgumentException("flatness must be >= 0");} -if(limit<0){throw new IllegalArgumentException("limit must be >= 0");} -this.src=src;this.squareflat=flatness*flatness;this.limit=limit;this.levels=Clazz.newArray(limit+1,0);this.hold=Clazz.newArray(14,0);armyc2.c2sd.graphics2d.FlatteningPathIterator.next2(this,false);this.getFlatness=function(){return Math.sqrt(this.squareflat);};this.getRecursionLimit=function(){return this.limit;};this.getWindingRule=function(){return this.src.getWindingRule();};this.isDone=function(){return this.done;};this.ensureHoldCapacity=function(want){if(this.holdIndex-want<0){var have=this.hold.length-this.holdIndex;var newsize=this.hold.length+24;var newhold=Clazz.newArray(newsize,0);System.arraycopy(this.hold,this.holdIndex,newhold,this.holdIndex+24,have);this.hold=newhold;this.holdIndex+=24;this.holdEnd+=24;}};this.next=function(){this.next2(true);};this.next2=function(doNext){var level;if(this.holdIndex>=this.holdEnd){if(doNext){this.src.next();} -if(this.src.isDone()){this.done=true;return;} -this.holdType=this.src.currentSegment(this.hold);this.levelIndex=0;this.levels[0]=0;} -switch(this.holdType){case 0:case 1:this.curx=this.hold[0];this.cury=this.hold[1];if(this.holdType===0){this.movx=this.curx;this.movy=this.cury;} -this.holdIndex=0;this.holdEnd=0;break;case 4:this.curx=this.movx;this.cury=this.movy;this.holdIndex=0;this.holdEnd=0;break;case 2:if(this.holdIndex>=this.holdEnd){this.holdIndex=this.hold.length-6;this.holdEnd=this.hold.length-2;this.hold[this.holdIndex+0]=this.curx;this.hold[this.holdIndex+1]=this.cury;this.hold[this.holdIndex+2]=this.hold[0];this.hold[this.holdIndex+3]=this.hold[1];this.hold[this.holdIndex+4]=this.curx=this.hold[2];this.hold[this.holdIndex+5]=this.cury=this.hold[3];} -level=this.levels[this.levelIndex];while(level=this.holdEnd){this.holdIndex=this.hold.length-8;this.holdEnd=this.hold.length-2;this.hold[this.holdIndex+0]=this.curx;this.hold[this.holdIndex+1]=this.cury;this.hold[this.holdIndex+2]=this.hold[0];this.hold[this.holdIndex+3]=this.hold[1];this.hold[this.holdIndex+4]=this.hold[2];this.hold[this.holdIndex+5]=this.hold[3];this.hold[this.holdIndex+6]=this.curx=this.hold[4];this.hold[this.holdIndex+7]=this.cury=this.hold[5];} -level=this.levels[this.levelIndex];while(level=that.holdEnd){if(doNext){that.src.next();} -if(that.src.isDone()){that.done=true;return;} -that.holdType=that.src.currentSegment(that.hold);that.levelIndex=0;that.levels[0]=0;} -switch(that.holdType){case 0:case 1:that.curx=that.hold[0];that.cury=that.hold[1];if(that.holdType===0){that.movx=that.curx;that.movy=that.cury;} -that.holdIndex=0;that.holdEnd=0;break;case 4:that.curx=that.movx;that.cury=that.movy;that.holdIndex=0;that.holdEnd=0;break;case 2:if(that.holdIndex>=that.holdEnd){that.holdIndex=that.hold.length-6;that.holdEnd=that.hold.length-2;that.hold[that.holdIndex+0]=that.curx;that.hold[that.holdIndex+1]=that.cury;that.hold[that.holdIndex+2]=that.hold[0];that.hold[that.holdIndex+3]=that.hold[1];that.hold[that.holdIndex+4]=that.curx=that.hold[2];that.hold[that.holdIndex+5]=that.cury=that.hold[3];} -level=that.levels[that.levelIndex];while(level=that.holdEnd){that.holdIndex=that.hold.length-8;that.holdEnd=that.hold.length-2;that.hold[that.holdIndex+0]=that.curx;that.hold[that.holdIndex+1]=that.cury;that.hold[that.holdIndex+2]=that.hold[0];that.hold[that.holdIndex+3]=that.hold[1];that.hold[that.holdIndex+4]=that.hold[2];that.hold[that.holdIndex+5]=that.hold[3];that.hold[that.holdIndex+6]=that.curx=that.hold[4];that.hold[that.holdIndex+7]=that.cury=that.hold[5];} -level=that.levels[that.levelIndex];while(level0) -nLast=6;if(nDiff1Y<0) -nLast=4;} -if(nDiff1Y===0){if(nDiff1X>0) -nLast=0;if(nDiff1X<0) -nLast=2;} -if(nDiff1X<0&&nDiff1Y>0) -nLast=3;if(nDiff1X>0&&nDiff1Y>0) -nLast=0;if(nDiff1X<0&&nDiff1Y<0) -nLast=3;if(nDiff1X>0&&nDiff1Y<0) -nLast=0;ResultChannelPoint=armyc2.c2sd.JavaLineArray.Channels.GetTrueEndPointDouble(nWidth,pLinePoints[0],pLinePoints[1],nLast);pResultChannelPoints[0]=new armyc2.c2sd.JavaLineArray.CChannelPoints2(ResultChannelPoint);for(nPointCounter=1;nPointCounter0&&nDiff2X>0){switch(nLast){case 0:case 3:case 4:case 7:lOrient=0;break;case 1:case 2:case 5:case 6:lOrient=3;break;default:break;}} -if(nDiff1X>0&&nDiff2X===0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff2Y>0) -lOrient=1;if(nDiff2Y<0) -lOrient=0;break;case 1:case 2:case 5:case 6:if(nDiff2Y>0) -lOrient=2;if(nDiff2Y<0) -lOrient=3;break;default:break;}} -if(nDiff1X<0&&nDiff2X===0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff2Y>0) -lOrient=3;if(nDiff2Y<0) -lOrient=2;break;case 1:case 2:case 5:case 6:if(nDiff2Y>0) -lOrient=0;if(nDiff2Y<0) -lOrient=1;break;default:break;}} -if(nDiff1X===0&&nDiff2X>0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff1Y>0) -lOrient=2;if(nDiff1Y<0) -lOrient=0;break;case 1:case 2:case 5:case 6:if(nDiff1Y>0) -lOrient=1;if(nDiff1Y<0) -lOrient=3;break;default:break;}} -if(nDiff1X===0&&nDiff2X<0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff1Y>0) -lOrient=3;if(nDiff1Y<0) -lOrient=1;break;case 1:case 2:case 5:case 6:if(nDiff1Y>0) -lOrient=0;if(nDiff1Y<0) -lOrient=2;break;default:break;}} -if(nDiff1X<0&&nDiff2X<0){switch(nLast){case 0:case 3:case 4:case 7:lOrient=3;break;case 1:case 2:case 5:case 6:lOrient=0;break;default:break;}} -if(new Boolean(nDiff1X>0&nDiff2X<0).valueOf()){switch(nLast){case 0:case 3:case 4:case 7:lOrient=1;break;case 1:case 2:case 5:case 6:lOrient=2;break;default:break;}} -if(new Boolean(nDiff1X<0&nDiff2X>0).valueOf()){switch(nLast){case 0:case 3:case 4:case 7:lOrient=2;break;case 1:case 2:case 5:case 6:lOrient=1;break;default:break;}} -if(nDiff1X===0&&nDiff2X===0){switch(nLast){case 4:if(nDiff2Y<0) -lOrient=0;break;case 6:if(nDiff2Y>0) -lOrient=0;break;case 5:if(nDiff2Y<0) -lOrient=3;break;case 7:if(nDiff2Y>0) -lOrient=3;break;default:break;}} -pResultChannelPoints[nPointCounter]=armyc2.c2sd.JavaLineArray.Channels.ConnectTrueDouble2(nWidth,LinePoint1,LinePoint2,LinePoint3,lOrient);if(nDiff2X===0){switch(lOrient){case 0:if(nDiff2Y>0){nLast=6;} -if(nDiff2Y<0){nLast=4;} -break;case 1:if(nDiff2Y>0){nLast=7;} -if(nDiff2Y<0){nLast=5;} -break;case 2:if(nDiff2Y>0){nLast=6;} -if(nDiff2Y<0){nLast=4;} -break;case 3:if(nDiff2Y>0){nLast=7;} -if(nDiff2Y<0){nLast=5;} -break;default:break;}} -if(nDiff2X>0){switch(lOrient){case 0:nLast=0;break;case 1:nLast=1;break;case 2:nLast=0;break;case 3:nLast=1;break;default:break;}} -if(nDiff2X<0){switch(lOrient){case 0:nLast=2;break;case 1:nLast=3;break;case 2:nLast=2;break;case 3:nLast=3;break;default:break;}}} -ResultChannelPoint=armyc2.c2sd.JavaLineArray.Channels.GetTrueEndPointDouble(nWidth,pLinePoints[nCounter],pLinePoints[nCounter-1],nLast);pResultChannelPoints[nCounter]=new armyc2.c2sd.JavaLineArray.CChannelPoints2(ResultChannelPoint);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"ConnectArrayTrueDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ConnectArrayTrueDouble",exc));}else{throw exc;}} -return pResultChannelPoints;},GetChannel2Double:function(nChannelWidth,vblCounter,pLinePoints,pResultChannelPoints){try{pResultChannelPoints=armyc2.c2sd.JavaLineArray.Channels.ConnectArrayTrueDouble(Math.floor(nChannelWidth/2),vblCounter-1,pLinePoints,pResultChannelPoints);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetChannel2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetChannel2Double",exc));}else{throw exc;}} -return pResultChannelPoints;},GetLowerChannelLineDouble:function(pChannelPoints,vblCounter,pResultLinePoints){try{var j=0;for(j=0;j45){var midPt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pLowerLinePoints[lLowerCounter-2],pUpperLinePoints[lUpperCounter-2],0);ArrowLinePoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(ArrowLinePoint,midPt,45);pLowerLinePoints[lLowerCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pLowerLinePoints[lLowerCounter-1],pLowerLinePoints[lLowerCounter-2],45);pUpperLinePoints[lUpperCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pUpperLinePoints[lUpperCounter-1],pUpperLinePoints[lUpperCounter-2],45);}} -for(j=0;j45){pUpperLinePoints[lUpperCounter-1].x=ptUpper0.x;pUpperLinePoints[lUpperCounter-1].y=ptUpper0.y;pLowerLinePoints[lLowerCounter-1].x=ptLower0.x;pLowerLinePoints[lLowerCounter-1].y=ptLower0.y;ArrowLinePoint.x=origArrowPt.x;ArrowLinePoint.y=origArrowPt.y;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetAXADDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetAXADDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} -return;},GetChannelArray2Double:function(nPrinter,pLinePoints,nUpperLower,vblCounter,vbiDrawThis,vblChannelWidth){try{switch(vbiDrawThis){case 231117301:case 231117201:case 231117101:case 22123001:case 22123000:case 22521200:case 22521300:case 22521100:case 21700000:case 21710000:case 22521410:case 22521411:case 22320000:case 22320001:case 22521420:case 22521421:case 23111000:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231114000:case 231111000:case 231112000:case 231113000:case 231113001:case 231113002:case 231113003:case 15000000:pLinePoints=armyc2.c2sd.JavaLineArray.Channels.CoordIL2Double(nPrinter,pLinePoints,nUpperLower,vblCounter,vbiDrawThis,vblChannelWidth);break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetChannelArray2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetChannelArray2Double "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} -return pLinePoints;},GetTrueEndPointDouble:function(nWidth,EndLinePoint,NextLinePoint,lLast){var cAnswers=new armyc2.c2sd.JavaLineArray.CChannelPoints2();try{var LinePoint1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var LinePoint2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var m=0;var b=0;var bPerpendicular=0;var Upperb=0;var Lowerb=0;var dWidth=nWidth;var bolVertical=0;var pdResult=new armyc2.c2sd.JavaLineArray.ref();bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,EndLinePoint,NextLinePoint,pdResult);m=pdResult.value[0];b=pdResult.value[1];Upperb=pdResult.value[3];Lowerb=pdResult.value[5];if(bolVertical===0){switch(lLast){case 4:case 6:cAnswers.m_Line1.x=EndLinePoint.x-dWidth;cAnswers.m_Line1.y=EndLinePoint.y;cAnswers.m_Line2.x=EndLinePoint.x+dWidth;cAnswers.m_Line2.y=EndLinePoint.y;break;case 5:case 7:cAnswers.m_Line1.x=EndLinePoint.x+dWidth;cAnswers.m_Line1.y=EndLinePoint.y;cAnswers.m_Line2.x=EndLinePoint.x-dWidth;cAnswers.m_Line2.y=EndLinePoint.y;break;default:break;}} -if(m===0){switch(lLast){case 0:case 2:cAnswers.m_Line1.x=EndLinePoint.x;cAnswers.m_Line1.y=EndLinePoint.y-dWidth;cAnswers.m_Line2.x=EndLinePoint.x;cAnswers.m_Line2.y=EndLinePoint.y+dWidth;break;case 1:case 3:cAnswers.m_Line1.x=EndLinePoint.x;cAnswers.m_Line1.y=EndLinePoint.y+dWidth;cAnswers.m_Line2.x=EndLinePoint.x;cAnswers.m_Line2.y=EndLinePoint.y-dWidth;break;default:break;}} -if(bolVertical!==0&&m!==0){bPerpendicular=EndLinePoint.y+EndLinePoint.x/m;LinePoint1=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m,Upperb,-1/m,bPerpendicular,1,1,0,0);LinePoint2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m,Lowerb,-1/m,bPerpendicular,1,1,0,0);switch(lLast){case 0:case 2:if(LinePoint1.yLinePoint2.y){cAnswers.m_Line1=LinePoint1;cAnswers.m_Line2=LinePoint2;}else{cAnswers.m_Line1=LinePoint2;cAnswers.m_Line2=LinePoint1;} -break;default:break;}} -pdResult=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetTrueEndPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetTrueEndPointDouble",exc));}else{throw exc;}} -return cAnswers;},ConnectTrueDouble2:function(nWidth,LinePoint1,LinePoint2,LinePoint3,lOrient){var pAnswerLinePoints=new armyc2.c2sd.JavaLineArray.CChannelPoints2();try{var m1=0;var b1=0;var m2=0;var b2=0;var Lowerb1=0;var Upperb1=0;var Lowerb2=0;var Upperb2=0;var dWidth=nWidth;var pdResult=new armyc2.c2sd.JavaLineArray.ref();var bolVerticalSlope1=0;var bolVerticalSlope2=0;var x=new armyc2.c2sd.JavaLineArray.ref();var y=new armyc2.c2sd.JavaLineArray.ref();bolVerticalSlope1=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,LinePoint1,LinePoint2,pdResult);if(bolVerticalSlope1!==0){m1=pdResult.value[0];b1=pdResult.value[1];Upperb1=pdResult.value[5];Lowerb1=pdResult.value[3];} -bolVerticalSlope2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,LinePoint2,LinePoint3,pdResult);if(bolVerticalSlope2!==0){m2=pdResult.value[0];b2=pdResult.value[1];Upperb2=pdResult.value[5];Lowerb2=pdResult.value[3];} -switch(lOrient){case 0:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 1:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 2:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 3:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;default:break;} -pdResult=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"ConnectTrueDouble2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ConnectTrueDouble2",exc));}else{throw exc;}} -return pAnswerLinePoints;},shiftCATKBYFIREControlPoint:function(linetype,pLinePoints,shift){try{if(linetype!==21710000) -return;var controlPtIndex=pLinePoints.size()-1;var pt0=pLinePoints.get(0);var pt1=pLinePoints.get(1);var dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints.get(0),pLinePoints.get(1));if(dist<=45) -return;var controlPt=pLinePoints.get(controlPtIndex);var pt3=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(pt0,pt1,pt0,controlPt);var pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt3,controlPt,shift);pLinePoints.set(controlPtIndex,pt4);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"shiftCATKBYFIREControlPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside shiftCATKBYFIREControlPoint",exc));}else{throw exc;}}},GetChannel1Double:function(lpsaUpperVBPoints,lpsaLowerVBPoints,resultVBPoints,vblUpperCounter,vblLowerCounter,vbiDrawThis,vblChannelWidth,useptr,shapes,rev){var lResult=-1;try{var k=0;var vblCounter=0;var nPrinter=1;var nArrowSize=40*nPrinter;var max=0;var dist=0;var remainder=0;var vblUpperCounter2=vblUpperCounter;var vblLowerCounter2=vblLowerCounter;var nReverseUpper=0;var lUpperFlotCount=0;var lLowerFlotCount=0;var nLowerCounter=0;var lUpperCounter=0;var lResultCounter=0;var XCounter=0;var j=0;var lHowManyThisSegment=0;var l=0;var t=0;var pi=3.141592653589793;var dAngle=0;var d=0;var a=13;var b=6;var dFactor=0;var lEllipseCounter=0;var arrowOffsetFactor=Math.floor(vblChannelWidth/4);var pLowerLinePoints=new Array(vblLowerCounter);var pUpperLinePoints=new Array(vblUpperCounter);var pArrowLinePoints=new Array(1);var pLinePoints=null;var pUpperFlotPoints=null;var pLowerFlotPoints=null;var pOriginalLinePoints=null;var pOriginalLinePoints2=null;armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLowerLinePoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pUpperLinePoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArrowLinePoints);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt4=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var arrowPts=new Array(3);var XPoints=new Array(4);var pEllipsePoints2=new Array(37);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(XPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pEllipsePoints2);var temp1LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLowerLinePoints[0]);var temp2LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var lastPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var nextToLastPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();if(vblChannelWidth<5&&vbiDrawThis!==15000000){vblChannelWidth=5;} -if(vblLowerCounter<2||vblUpperCounter<2){return-1;} -for(k=0;kpUpperLinePoints[1].x)&&(pUpperLinePoints[0].y!==pUpperLinePoints[1].y)){nReverseUpper=1;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLowerLinePoints,vblLowerCounter);}else if((pUpperLinePoints[0].x>pUpperLinePoints[1].x)&&(pUpperLinePoints[0].y===pUpperLinePoints[1].y)){nReverseUpper=0;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pUpperLinePoints,vblUpperCounter);}else if(pUpperLinePoints[0].xpUpperLinePoints[1].y)&&(pUpperLinePoints[0].x===pUpperLinePoints[1].x)){nReverseUpper=1;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLowerLinePoints,vblLowerCounter);}else if((pUpperLinePoints[0].ypOriginalLinePoints[1].x){pLinePoints[k].style=26;} -if(pOriginalLinePoints[0].x>pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y===pOriginalLinePoints[1].y){pLinePoints[k].style=25;}} -if(pOriginalLinePoints[0].x===pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].ypOriginalLinePoints[1].x){pLinePoints[vblUpperCounter+k].style=25;} -if(pOriginalLinePoints[0].x>pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y===pOriginalLinePoints[1].y){pLinePoints[vblUpperCounter+k].style=26;}} -if(pOriginalLinePoints[0].x===pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y0){pLinePoints[lUpperFlotCount-1].style=5;} -for(k=0;k0){pLinePoints[lUpperFlotCount+lLowerFlotCount-1].style=5;}} -if(nReverseUpper===0){for(k=0;k0) -pLinePoints[lUpperFlotCount-1].style=5;for(k=0;k0) -pLinePoints[lUpperFlotCount+lLowerFlotCount-1].style=5;} -break;case 231117301:case 231117201:case 231117101:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231111000:case 231114000:case 231112000:case 231113000:case 231113001:case 231113002:case 231113003:pLinePoints=new Array(vblCounter);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);for(j=0;jlEllipseCounter){pLinePoints[lEllipseCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pOriginalLinePoints[j]);lEllipseCounter++;pLinePoints[lEllipseCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pOriginalLinePoints[j+1]);pLinePoints[lEllipseCounter].style=5;lEllipseCounter++;}}} -pLinePoints=armyc2.c2sd.JavaLineArray.lineutility.ResizeArray(pLinePoints,lEllipseCounter);vblCounter=pLinePoints.length;} -if(armyc2.c2sd.JavaLineArray.Channels.FenceType(vbiDrawThis)===1){if(lEllipseCounter<=vblLowerCounter+vblUpperCounter){for(k=0;karmyc2.c2sd.JavaLineArray.Channels.maxLength){d=armyc2.c2sd.JavaLineArray.Channels.maxLength;} -if(d45) -dist-=45;if(dist2>20){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],5+dist);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],5+dist);}else{pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],-50);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],-50);} -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt2,pt1,10+Math.abs(dist/2),18);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt2,10+Math.abs(dist/2),5);midPt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,pt2,17);pLinePoints[vblCounter-9]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[vblCounter-6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);if(dist2>20){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],15+dist);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],15+dist);}else{pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],-50);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],-50);} -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt2,pt1,Math.abs(dist/2),18);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt2,Math.abs(dist/2),18);midPt2=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,pt2,18);pLinePoints[vblCounter-8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[vblCounter-7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);pLinePoints[vblCounter-5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPt2);if(midPt1.x===midPt2.x&&midPt1.y===midPt2.y){if(armyc2.c2sd.JavaLineArray.Channels._client.startsWith("cpof")) -dFeature=30;else -dFeature=15;midPt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],10,17);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt1,midPt1,dFeature,18);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt1,midPt1,-dFeature,5);pLinePoints[vblCounter-9]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[vblCounter-6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);if(armyc2.c2sd.JavaLineArray.Channels._client.startsWith("cpof")) -midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],20,17);else{if(dist2>30) -midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],20,17);else -midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],dFeature,17);} -dFeature-=10;pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt2,midPt2,dFeature,18);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt2,midPt2,-dFeature,18);pLinePoints[vblCounter-8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[vblCounter-7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[vblCounter-5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPt2);} -if(armyc2.c2sd.JavaLineArray.Channels._client.startsWith("cpof")) -dFeature=30;else{if(dist2>30) -dFeature=30;else if(dist2>20) -dFeature=10;else -dFeature=10;} -pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(midPt1,midPt2,dFeature,Math.floor(dFeature));pLinePoints[vblCounter-4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(midPt2,pt1,Math.floor(Math.floor(dFeature)/2),Math.floor(Math.floor(dFeature)/2),arrowPts,18);for(k=0;k<3;k++){pLinePoints[vblCounter-k-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arrowPts[k]);pLinePoints[vblCounter-k-1].style=18;}} -break;case 22320000:case 22320001:vblCounter=vblLowerCounter+vblUpperCounter+8;pLinePoints=new Array(vblCounter);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);for(j=0;j0) -if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5) -shape.lineTo(pLinePoints[k]);if(k===0) -shape.set_Style(pLinePoints[k].style);shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} -if(k===vblCounter-1){shapes.add(shape);}} -for(k=0;k0){if(pLinePoints[k].style===5){shape.lineTo(pLinePoints[k]);if(shape!==null&&shape.getShape()!==null){shapes.add(shape);} -beginPath=true;}else{shape.lineTo(pLinePoints[k]);}}else{shape.moveTo(pLinePoints[k]);}}else{shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pLinePoints[k]);shape.set_Style(pLinePoints[k].style);if(pLinePoints[k].style===25) -shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);beginPath=false;} -break;case 21700000:case 21710000:case 22521300:case 22521420:case 22521421:case 22521200:case 22521100:if(beginLine){if(k>0){if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5&&k!==vblCounter-1) -continue;} -shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} -if(k===vblCounter-1){if(shape!==null&&shape.getShape()!==null){shapes.add(shape);}} -break;case 231111000:case 231112000:case 231113000:case 231115000:case 231116000:if(k===0){shape.moveTo(pLinePoints[k]);if(pLinePoints[k].style===5){continue;}} -if(k>0&&k0) -shapes.addAll(0,fillShapes);if(vbiDrawThis===15000000) -{shapes.remove(1);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pOriginalLinePoints[0]);for(j=1;j=Math.floor(n/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-19)/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-17)/2);j--){newPts.add(pLinePoints[j]);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j250) -result=3;else -result=2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetTGFontSize",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetTGFontSize",exc));}else{throw exc;}} -return result;},ArcApproximationDouble:function(left,top,right,bottom,startx,starty,endx,endy,lpoints){try{var dstartx=startx;var dstarty=starty;var dendx=endx;var dendy=endy;var a=0;var b=0;var ctrX=0;var ctrY=0;var x1;var y1;var x2;var y2;var startAngle;var endAngle;var angleIncrement=0;var t=0;var i=0;if(left>right){var temp=left;left=right;right=temp;} -if(top>bottom){temp=top;top=bottom;bottom=temp;} -a=(right-left)/2.0;b=(bottom-top)/2.0;ctrX=left+a;ctrY=top+b;x1=dstartx-ctrX;x2=dendx-ctrX;y1=ctrY-dstarty;y2=ctrY-dendy;if(y1===0){if(x1>0) -startAngle=0;else -startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;}else if(x1===0){if(y1>0) -startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*0.5;else -startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*-0.5;}else -startAngle=Math.atan2(y1,x1);if(y2===0){if(x2>0) -endAngle=0;else -endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;}else if(x2===0){if(y2>0) -endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*0.5;else -endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*-0.5;}else -endAngle=Math.atan2(y2,x2);if(endAngle<=startAngle) -endAngle+=2*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;angleIncrement=(endAngle-startAngle)/16.0;for(t=startAngle;i<17;t+=angleIncrement,i++){lpoints[i].x=ctrX+a*Math.cos(t);lpoints[i].y=ctrY-b*Math.sin(t);} -return;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"ArcApproximationDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ArcApproximationDouble",exc));}else{throw exc;}}},DrawOpenRectangleDouble:function(points,pointsCorner,resultpts){try{var point_mid=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;point_mid.x=(points[0].x+points[1].x)/2;point_mid.y=(points[0].y+points[1].y)/2;pointsCorner[0].x=points[0].x-point_mid.x+points[2].x;pointsCorner[0].y=points[0].y-point_mid.y+points[2].y;pointsCorner[1].x=points[1].x-point_mid.x+points[2].x;pointsCorner[1].y=points[1].y-point_mid.y+points[2].y;resultpts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[1]);resultpts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pointsCorner[1]);resultpts[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pointsCorner[0]);resultpts[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[0]);for(j=0;j<4;j++){resultpts[j].style=0;} -resultpts[3].style=5;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"DrawOpenRectangleDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DrawOpenRectangleDouble",exc));}else{throw exc;}} -return;},DetermineDirectionDouble:function(points){var result=0;try{var dP0P1M=0;var iP0P1B=0;if(points[0].x===points[1].x){if(points[2].xpoints[2].x){return 1;}else{return 0;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"DetermineDirectionDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DetermineDirectionDouble",exc));}else{throw exc;}} -return result;},CalcEndpieceDeltasDouble:function(points,piDeltaX,piDeltaY,dAngleDelta){try{var pntMid=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var iDiagEOL_length=0;var dAngle1=0;pntMid.x=(points[0].x+points[1].x)/2;pntMid.y=(points[0].y+points[1].y)/2;iDiagEOL_length=((Math.sqrt((points[1].x-points[0].x)*(points[1].x-points[0].x)+(points[1].y-points[0].y)*(points[1].y-points[0].y))+Math.sqrt((points[2].x-pntMid.x)*(points[2].x-pntMid.x)+(points[2].y-pntMid.y)*(points[2].y-pntMid.y)))/20);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengthpt2.x&&quadrant===2) -sign=-1;else if(pt1.x>pt2.x&&quadrant===3) -sign=-1;else if(pt1.xiLengthPt0Pt2){iLengthPt0Pt1=iLengthPt0Pt2;} -iFontSize=armyc2.c2sd.JavaLineArray.DISMSupport.GetTGFontSize(iLengthPt0Pt1);if(iFontSize>0){iDelta=iLengthPt0Pt1/15;if(iDelta>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDelta=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDeltapt2.x&&quadrant===2) -sign=-1;else if(pt1.x>pt2.x&&quadrant===3) -sign=-1;else if(pt1.xiLengthPt0Pt2){iLengthPt0Pt1=iLengthPt0Pt2;} -iFontSize=armyc2.c2sd.JavaLineArray.DISMSupport.GetTGFontSize(iLengthPt0Pt1);if(iFontSize>0){iDelta=iLengthPt0Pt1/15;if(iDelta>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDelta=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDeltaarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengthsavepoints[1].y){if(ptRelative.x>ptCenter.x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[0],savepoints[1]);}} -if(savepoints[0].yptCenter.y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[0],savepoints[1]);}} -if(savepoints[0].x>savepoints[1].x){if(ptRelative.yarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);pts[1].x=(pts[0].x+ptCenter.x)/2;pts[1].y=(pts[0].y+ptCenter.y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-(ptPerp.x-ptCenter.x)*iRadius/iPerpLength;pts[0].y=ptCenter.y-(ptPerp.y-ptCenter.y)*iRadius/iPerpLength;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dDeltaX1=Math.cos(dAngle2+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY1=Math.sin(dAngle2+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaX2=Math.cos(dAngle2-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY2=Math.sin(dAngle2-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dDeltaX1=Math.cos(dAngle2+3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY1=Math.sin(dAngle2+3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaX2=Math.cos(dAngle2-3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY2=Math.sin(dAngle2-3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts=null;savepoints=null;arcpoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMContainDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMContainDouble",exc));}else{throw exc;}} -return counter;},GetDISMFixDouble:function(points,linetype,clipBounds){var counter=0;try{var pts=new Array(3);var savepoints=new Array(2);var dAngle1=0;var dLength=0;var dJaggyHalfAmp=0;var dJaggyHalfPeriod=0;var dDeltaXOut=0;var dDeltaYOut=0;var dDeltaXAlong=0;var dDeltaYAlong=0;var iNumJaggies=0;var i=0;var j=0;for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -var drawJaggies=new Boolean(true);if(clipBounds!==null){var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMinX(),clipBounds.getMinY());var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMaxX(),clipBounds.getMaxY());savepoints=armyc2.c2sd.JavaLineArray.lineutility.BoundOneSegment(savepoints[0],savepoints[1],ul,lr);} -if(savepoints===null){savepoints=new Array(2);for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -drawJaggies=new Boolean(false);} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);dAngle1=Math.atan2(savepoints[0].y-savepoints[1].y,savepoints[0].x-savepoints[1].x);dLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dJaggyHalfAmp=dLength/15;if(dJaggyHalfAmp>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(dJaggyHalfAmpd){return true;}else{return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"IsSeizeArcReversed",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside IsSeizeArcReversed",exc));}else{throw exc;}} -return false;},GetDISMSeizeDouble:function(points,linetype,radius){var counter=0;try{var ptArcCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptArcStart=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var savepoints=new Array(3);var scale=0.9;var iCircleRadius=(25*scale);var arcpoints=new Array(17);var pts=new Array(3);var dAngle1=0;var dDeltaX1=0;var dDeltaY1=0;var dDeltaX2=0;var dDeltaY2=0;var dChordLength=0;var dArcRadius=0;var j=0;var dDeltaX3=0;var dDeltaY3=0;var iDiagEOL_length=0;var factor=1;if(radius>0) -iCircleRadius=radius;for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -var client=armyc2.c2sd.JavaLineArray.CELineArray.getClient();if(!client.startsWith("cpof")&&radius===0){dArcRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],savepoints[1]);if(iCircleRadius>dArcRadius/2) -iCircleRadius=dArcRadius/2;} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(arcpoints);armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble(savepoints[0].x-iCircleRadius,savepoints[0].y-iCircleRadius,savepoints[0].x+iCircleRadius,savepoints[0].y+iCircleRadius,savepoints[0].x,savepoints[0].y,savepoints[0].x,savepoints[0].y,arcpoints);for(j=0;j<17;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);points[counter].style=0;counter++;} -points[counter-1].style=5;dAngle1=Math.atan2(savepoints[0].y-savepoints[1].y,savepoints[0].x-savepoints[1].x);dDeltaX1=Math.cos(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaY1=Math.sin(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaX2=Math.cos(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaY2=Math.sin(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);var isArcReversed=armyc2.c2sd.JavaLineArray.DISMSupport.IsSeizeArcReversed(savepoints);if(isArcReversed===false){ptArcStart.x=savepoints[0].x-dDeltaX2*iCircleRadius;ptArcStart.y=savepoints[0].y-dDeltaY2*iCircleRadius;dChordLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dArcRadius=dChordLength/1.414213562373;ptArcCenter.x=savepoints[0].x-dDeltaX1*dArcRadius;ptArcCenter.y=savepoints[0].y-dDeltaY1*dArcRadius;armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptArcCenter.x-dArcRadius),(ptArcCenter.y-dArcRadius),(ptArcCenter.x+dArcRadius),(ptArcCenter.y+dArcRadius),savepoints[1].x,savepoints[1].y,ptArcStart.x,ptArcStart.y,arcpoints);}else{ptArcStart.x=savepoints[0].x-dDeltaX1*iCircleRadius;ptArcStart.y=savepoints[0].y-dDeltaY1*iCircleRadius;dChordLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dArcRadius=dChordLength/1.414213562373;ptArcCenter.x=savepoints[0].x-dDeltaX2*dArcRadius;ptArcCenter.y=savepoints[0].y-dDeltaY2*dArcRadius;armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptArcCenter.x-dArcRadius),(ptArcCenter.y-dArcRadius),(ptArcCenter.x+dArcRadius),(ptArcCenter.y+dArcRadius),ptArcStart.x,ptArcStart.y,savepoints[1].x,savepoints[1].y,arcpoints);} -for(j=0;j<17;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);points[counter].style=0;counter++;} -points[counter-1].style=5;if(dChordLength/8>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){factor=dChordLength/(8*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} -if(factor===0){factor=1;} -if(isArcReversed===false){pts[0].x=savepoints[1].x-(savepoints[1].x-savepoints[0].x)/(8*factor);pts[0].y=savepoints[1].y-(savepoints[1].y-savepoints[0].y)/(8*factor);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);dDeltaX3=Math.cos(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);dDeltaY3=Math.sin(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);iDiagEOL_length=(dChordLength/8);pts[2].x=savepoints[1].x+dDeltaX3*iDiagEOL_length/factor;pts[2].y=savepoints[1].y+dDeltaY3*iDiagEOL_length/factor;}else{pts[0].x=savepoints[1].x-(savepoints[1].x-savepoints[0].x)/(8*factor);pts[0].y=savepoints[1].y-(savepoints[1].y-savepoints[0].y)/(8*factor);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);dDeltaX3=Math.cos(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);dDeltaY3=Math.sin(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);iDiagEOL_length=(dChordLength/8);pts[2].x=savepoints[1].x+dDeltaX3*iDiagEOL_length/factor;pts[2].y=savepoints[1].y+dDeltaY3*iDiagEOL_length/factor;} -for(j=0;j<3;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[j]);points[counter].style=0;counter++;} -points[counter-1].style=5;savepoints=null;arcpoints=null;pts=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMSeizeDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMSeizeDouble",exc));}else{throw exc;}} -return counter;},side:function(x1,y1,x2,y2,px,py){var dx1;var dx2;var dy1;var dy2;try{var o;dx1=x2-x1;dy1=y2-y1;dx2=px-x1;dy2=py-y1;o=(dx1*dy2)-(dy1*dx2);if(o>0.0){return(armyc2.c2sd.JavaLineArray.DISMSupport.LEFT_SIDE);} -if(o<0.0){return(armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"side",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside side",exc));}else{throw exc;}} -return(armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR);},GetDISMRIPDouble:function(points,linetype){var counter=0;try{var pts=new Array(2);var savepoints=new Array(4);var j=0;var iLengthPt0Pt1=0;var iDiagEOL_length=0;var dAngle1=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;var iLengthPt2Pt3=0;var iRadius=0;var deltapoints=new Array(4);var arcpoints=new Array(17);var ptArcCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var clockwise=false;var side01=armyc2.c2sd.JavaLineArray.DISMSupport.side(points[0].x,points[0].y,points[1].x,points[1].y,points[2].x,points[2].y);var side12=armyc2.c2sd.JavaLineArray.DISMSupport.side(points[1].x,points[1].y,points[2].x,points[2].y,points[3].x,points[3].y);if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE) -clockwise=true;else if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR) -clockwise=true;else if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE) -clockwise=true;for(j=0;j<4;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(arcpoints);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[3]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);iLengthPt0Pt1=Math.sqrt((pts[1].x-pts[0].x)*(pts[1].x-pts[0].x)+(pts[1].y-pts[0].y)*(pts[1].y-pts[0].y));iDiagEOL_length=iLengthPt0Pt1/8;if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(dJaggyHalfAmparmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(d/5600) -d=600;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(points[2],points[3],Math.floor(Math.floor(d)/20),Math.floor(Math.floor(d)/20),arrowpts,0);for(j=0;j<3;j++){points[4+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arrowpts[j]);} -arrowpts=null;savepoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMPenetrateDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMPenetrateDouble",exc));}else{throw exc;}} -return;},GetDISMByImpDouble:function(points,linetype){var counter=0;try{var j=0;var pointsCorner=new Array(2);var rectpts=new Array(4);var savepoints=new Array(3);var deltapoints1=new Array(4);var deltapoints2=new Array(4);var midpt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pts=new Array(6);var ptRelative=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var iDeltaX=new armyc2.c2sd.JavaLineArray.ref();var iDeltaY=new armyc2.c2sd.JavaLineArray.ref();var bPointsRight=0;var dMBR=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(points,3);if(dMBR>40*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=40*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(dMBR<5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength){dMBR=5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength;} -if(dMBR>250) -dMBR=250;for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(rectpts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints1);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints2);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pointsCorner);armyc2.c2sd.JavaLineArray.DISMSupport.DrawOpenRectangleDouble(savepoints,pointsCorner,rectpts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[1]);points[counter].style=0;counter++;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(rectpts[1],rectpts[2],0);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(rectpts[1],midpt,-5,5);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(rectpts[1],midpt,5,5);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=5;counter++;ptRelative=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(rectpts[0],rectpts[1],pts[0]);pts[2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[0],-dMBR/40);pts[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[0],dMBR/40);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[2]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[3]);points[counter].style=5;counter++;ptRelative=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(rectpts[2],rectpts[3],pts[1]);pts[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[1],-dMBR/40);pts[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[1],dMBR/40);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[4]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[5]);points[counter].style=5;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[2]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[3]);points[counter].style=5;counter++;bPointsRight=armyc2.c2sd.JavaLineArray.DISMSupport.DetermineDirectionDouble(savepoints);armyc2.c2sd.JavaLineArray.DISMSupport.CalcEndpieceDeltasDouble(savepoints,iDeltaX,iDeltaY,armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);if((savepoints[0].y-savepoints[1].y)<0){if(bPointsRight!==0){armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints2);}else{armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints2);}}else{if(bPointsRight!==0){armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints2);}else{armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints2);}} -points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[1]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[0]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[3]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[3]);points[counter].style=10;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[1]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[0]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[3]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[3]);points[counter].style=10;counter++;pointsCorner=null;rectpts=null;savepoints=null;deltapoints1=null;deltapoints2=null;pts=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMByImpDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMByImpDouble",exc));}else{throw exc;}} -return counter;},GetDISMSupportByFireDouble:function(points,linetype){var counter=0;try{var pts=new Array(3);var savepoints=new Array(4);var j=0;var iDiagEOL_length=0;var dAngle1=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;for(j=0;j<4;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -armyc2.c2sd.JavaLineArray.DISMSupport.ReorderSptByFirePoints(savepoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;iDiagEOL_length=(Math.sqrt((savepoints[0].x-savepoints[1].x)*(savepoints[0].x-savepoints[1].x)+(savepoints[0].y-savepoints[1].y)*(savepoints[0].y-savepoints[1].y))/10);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_length2){distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(savepoints[1],savepoints[2],savepoints[0]);ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],2,distToLine);ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],3,distToLine);distanceToPointAboveLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptAboveLine);distanceToPointBelowLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptBelowLine);if(distanceToPointAboveLinesavepoints[1].x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[1],savepoints[2]);}}}else{distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(savepoints[1],savepoints[2],savepoints[0]);ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],0,distToLine);ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],1,distToLine);distanceToPointLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptLeftOfLine);distanceToPointRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptRightOfLine);if(distanceToPointRightOfLinesavepoints[1].y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[1],savepoints[2]);}}} -points[1].x=savepoints[1].x;points[1].y=savepoints[1].y;points[2].x=savepoints[2].x;points[2].y=savepoints[2].y;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"ReorderAtkByFirePoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMSupportByFireDouble",exc));}else{throw exc;}}},ReorderSptByFirePoints:function(points){try{var ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var distToLine=0;var distanceToPointAboveLine=0;var distanceToPointBelowLine=0;var distanceToPointLeftOfLine=0;var distanceToPointRightOfLine=0;var midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(points[0],points[1],0);if(Math.abs(points[2].x-points[3].x)>2){distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(points[1],points[2],midpt);ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],2,distToLine);ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],3,distToLine);distanceToPointAboveLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptAboveLine);distanceToPointBelowLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptBelowLine);if(distanceToPointAboveLinepoints[1].x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[0],points[1]);armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[2],points[3]);}}}else{distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(points[1],points[2],midpt);ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],0,distToLine);ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],1,distToLine);distanceToPointLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptLeftOfLine);distanceToPointRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptRightOfLine);if(distanceToPointLeftOfLinepoints[1].y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[0],points[1]);armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[2],points[3]);}}else{if(points[2].yarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(dMBR/1020) -dist=20;var dist2=dist;switch(linetype){case 23222000:dist=1.5*dist;dist2=dist/2;break;default:dist2=dist;break;} -pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[1],savepoints[0],dist);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[2],savepoints[0],dist2);points[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[0]);points[4].style=0;points[5]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[0],savepoints[1],dist);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[3],savepoints[1],dist2);points[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[1]);points[6].style=0;points[7]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[0],savepoints[2],dist2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[3],savepoints[2],dist);points[8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[2]);points[8].style=0;points[9]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[1],savepoints[3],dist2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[2],savepoints[3],dist);points[10]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[3]);points[10].style=0;points[11]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts=null;savepoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMGapDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMGapDouble",exc));}else{throw exc;}} -return 12;},GetDISMMinefieldDisruptDouble:function(points,linetype){var counter=0;try{var pts=new Array(2);var ptsArrow=new Array(3);var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;var savepoints=new Array(3);var dAngle1=0;var d=0;var dist=0;var deltapoints1=new Array(4);var deltapoints2=new Array(4);var deltapoints3=new Array(4);var iDiagEOL_length=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;var ptTail=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArrow);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints1);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints2);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints3);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;ptCenter.x=(savepoints[0].x+savepoints[1].x)/2;ptCenter.y=(savepoints[0].y+savepoints[1].y)/2;ptsArrow[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);ptsArrow[1].x=ptCenter.x+(savepoints[2].x-savepoints[0].x)*4/5;ptsArrow[1].y=ptCenter.y+(savepoints[2].y-savepoints[0].y)*4/5;ptsArrow[2].x=savepoints[1].x+(savepoints[2].x-savepoints[0].x)*3/5;ptsArrow[2].y=savepoints[1].y+(savepoints[2].y-savepoints[0].y)*3/5;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[2]);points[counter].style=5;counter++;pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[1]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptCenter);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[2],savepoints[0]);d=dist;if(d>5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(d<5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength;} -ptTail.x=(savepoints[0].x+ptCenter.x)/2;ptTail.y=(savepoints[0].y+ptCenter.y)/2;pts[0].x=ptTail.x-(savepoints[2].x-savepoints[0].x)/5;pts[0].y=ptTail.y-(savepoints[2].y-savepoints[0].y)/5;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[0],ptTail,-d/5);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTail);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[0]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;iDiagEOL_length=((Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y))+Math.sqrt((savepoints[2].x-savepoints[1].x)*(savepoints[2].x-savepoints[1].x)+(savepoints[2].y-savepoints[1].y)*(savepoints[2].y-savepoints[1].y)))/15);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} -if(dMBR/20250) -dMBR=250;for(j=0;jdist){var ptTemp=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);savepoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);savepoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTemp);ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptCenter2);dAngle1=dAngle2;} -dRadius=Math.sqrt((savepoints[1].x-ptCenter.x)*(savepoints[1].x-ptCenter.x)+(savepoints[1].y-ptCenter.y)*(savepoints[1].y-ptCenter.y));armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptCenter.x-dRadius),(ptCenter.y-dRadius),(ptCenter.x+dRadius),(ptCenter.y+dRadius),savepoints[2].x,savepoints[2].y,savepoints[1].x,savepoints[1].y,arcpoints);for(j=0;j<17;j++){pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);pLinePoints[counter].style=0;counter++;} -pLinePoints[counter-1].style=5;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);dAngle1c=Math.atan2(ptCenter.y-savepoints[1].y,ptCenter.x-savepoints[1].x);dAngle2c=Math.atan2(ptCenter.y-savepoints[2].y,ptCenter.x-savepoints[2].x);dAngle12c=(dAngle1c+dAngle2c)/2;if((dAngle1c>0)&&(dAngle2c<0)){pts[1].x=ptCenter.x+Math.cos(dAngle12c)*dRadius;pts[1].y=ptCenter.y+Math.sin(dAngle12c)*dRadius;}else{pts[1].x=ptCenter.x-Math.cos(dAngle12c)*dRadius;pts[1].y=ptCenter.y-Math.sin(dAngle12c)*dRadius;} -pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);pLinePoints[counter].style=0;counter++;pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);pLinePoints[counter].style=5;counter++;dAngle0=Math.atan2(pts[1].y-savepoints[0].y,pts[1].x-savepoints[0].x);iArrowLength=((Math.sqrt((savepoints[1].x-savepoints[2].x)*(savepoints[1].x-savepoints[2].x)+(savepoints[1].y-savepoints[2].y)*(savepoints[1].y-savepoints[2].y))+Math.sqrt((savepoints[0].x-ptMid.x)*(savepoints[0].x-ptMid.x)+(savepoints[0].y-ptMid.y)*(savepoints[0].y-ptMid.y)))/20);if(iArrowLength>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength) -iArrowLength=Math.floor(armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);if(iArrowLengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength) -d=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;if(d0) -pLinePoints=new Array(vblCounter);else{shapes=null;return null;} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);if(vblSaveCounter>pts.size()) -vblSaveCounter=pts.size();if(vblSaveCounter>pLinePoints.length) -vblSaveCounter=pLinePoints.length;for(j=0;jpLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt0,3,10);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt1,3,10);nCounter++;} -if(pLinePoints[j].xpLinePoints[j+1].y){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt0,0,10);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt1,0,10);nCounter++;}} -pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-3],10,0);nCounter++;} -pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nCounter++;} -for(j=0;jpLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pSpikePoints[nCounter-1],pt0,2,dSpikeSize);} -if(pLinePoints[j].x=0&&oppSegment=1||bolVertical===0){nOrientation=0;for(j=0;j=Y0)||(pLinePoints[j].y>=Y0&&pLinePoints[j+1].y<=Y0)){bolVertical2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pLinePoints[j],pLinePoints[j+1],m);if(bolVertical2===1&&m.value[0]===0){nInOutCounter++;nInOutCounter--;} -if(bolVertical2===0){if(pLinePoints[j].x=X0)||(pLinePoints[j].x>=X0&&pLinePoints[j+1].x<=X0)){bolVertical2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pLinePoints[j],pLinePoints[j+1],m);if(bolVertical2===0){nInOutCounter++;nInOutCounter--;} -if(bolVertical2===1&&m.value[0]===0){if(pLinePoints[j].y0){pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-remainder/2,0);pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-10-remainder/2,0);}else{pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20,0);pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-10,0);} -switch(lineType){case 23115000:case 23114000:case 23113000:case 23111000:case 23111001:case 22624000:pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nCounter-1],5);break;case 23350000:case 22134000:pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-1]);break;default:break;} -pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt2,pt0,nDirection,10);switch(lineType){case 23115000:case 23114000:case 23113000:case 23111000:case 23111001:case 22624000:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-2],10,0);break;case 23350000:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-2]);break;case 22134000:pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-2],10,0);pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt2,pt3,nDirection,10);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);break;default:break;} -nCounter++;if(lineType===22624000) -pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-4]);} -pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);} -for(j=0;j0) -pSpikePoints[nCounter-1].style=5;} -for(j=0;jd){return true;}else{return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.arraysupport._className,"IsTurnArcReversed",new armyc2.c2sd.renderer.utilities.RendererException("IsTurnArcReversed",exc));}else{throw exc;}} -return false;},GetIsolatePointsDouble:function(pLinePoints,lineType){try{var reverseTurn=false;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[1]);var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);if(pt0.x===pt1.x&&pt0.y===pt1.y) -pt1.x+=1;var C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var E=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;var k=0;var l=0;var ptsArc=new Array(26);var midPts=new Array(7);var trianglePts=new Array(21);var pArrowPoints=new Array(3);var reversepArrowPoints=new Array(3);var dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);var dLength=Math.abs(dRadius-20);if(dRadius<40){dLength=dRadius/1.5;} -var d=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(pLinePoints,2);var ptsSeize=new Array(2);var savepoints=new Array(3);for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);} -if(pLinePoints.length>=3){savepoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);} -armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArc);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(midPts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(trianglePts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArrowPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(reversepArrowPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsSeize);if(d/7>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){d=7*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(d/7140) -d=140;var ptsArc2=new Array(26);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArc2);E.x=2*pt1.x-pt0.x;E.y=2*pt1.y-pt0.y;ptsArc[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[1]);ptsArc[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(E);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(ptsArc,0,dRadius,lineType);for(j=0;j<26;j++){ptsArc[j].style=0;pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[j].style=0;} -if(lineType!==211600000) -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,0);else -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(1.75*d)/7),pArrowPoints,0);pLinePoints[25].style=5;switch(lineType){case 212600000:case 212500000:case 211400000:for(j=1;j<=23;j++){if(j%3===0){midPts[k].x=pt0.x-Math.floor(((dLength/dRadius)*(pt0.x-ptsArc[j].x)));midPts[k].y=pt0.y-Math.floor(((dLength/dRadius)*(pt0.y-ptsArc[j].y)));midPts[k].style=0;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j-1]);l++;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPts[k]);l++;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j+1]);trianglePts[l].style=5;l++;k++;}} -for(j=26;j<47;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(trianglePts[j-26]);} -pLinePoints[46].style=5;for(j=47;j<50;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-47]);pLinePoints[j].style=0;} -break;case 211600000:midPt.x=(pt1.x+ptsArc[25].x)/2;midPt.y=(pt1.y+ptsArc[25].y)/2;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(midPt,ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(1.75*d)/7),reversepArrowPoints,0);for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);} -for(j=29;j<32;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(reversepArrowPoints[j-29]);pLinePoints[j].style=0;} -break;case 212100000:for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=0;} -pLinePoints[28].style=5;break;case 23173000:var changeArc=armyc2.c2sd.JavaLineArray.arraysupport.IsTurnArcReversed(savepoints);if(reverseTurn===true||changeArc===true){pt0.x=pt1.x;pt0.y=pt1.y;pt1.x=pt2.x;pt1.y=pt2.y;} -ptsSeize[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);ptsSeize[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcClockwiseCenterDouble(ptsSeize);C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsSeize[0]);E=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsSeize[1]);ptsArc[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);ptsArc[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(E);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(ptsArc,0,dRadius,lineType);for(j=0;j<26;j++){ptsArc[j].style=0;pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[j].style=0;} -if(changeArc===true){armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[1],pt0,Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,5);}else{armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],pt1,Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,5);} -pLinePoints[25].style=5;for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=9;} -pLinePoints[28].style=10;break;case 211900000:for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=0;} -pLinePoints[28].style=5;k=29;for(j=1;j<24;j++){pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[k].style=0;k++;pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,ptsArc[j],Math.floor(Math.floor(d)/7));pLinePoints[k].style=5;k++;} -break;default:break;} -savepoints=null;ptsArc=null;midPts=null;trianglePts=null;pArrowPoints=null;reversepArrowPoints=null;ptsSeize=null;ptsArc2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.arraysupport._className,"GetIsolatePointsDouble",new armyc2.c2sd.renderer.utilities.RendererException("GetIsolatePointsDouble "+Integer.toString(lineType),exc));}else{throw exc;}} -return;},AreaWithCenterFeatureDouble:function(pLinePoints,vblCounter,lineType){try{var k=0;var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var d=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(pLinePoints,vblCounter);if(d>350) -d=350;for(k=0;k0){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+45,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+4,5);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-1,20);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-7,0);}else{pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-45,0);} -break;case 31131300:if(k>0){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+45,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+10,5);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter-1],pLinePoints[j+1],5,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter-1],pLinePoints[j+1],10,5);nCounter++;crossPt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nCounter-2],pSpikePoints[nCounter-1],pSpikePoints[nCounter-1],2,5,0);crossPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nCounter-1],pSpikePoints[nCounter-2],pSpikePoints[nCounter-2],3,5,5);pSpikePoints[nCounter]=crossPt1;nCounter++;pSpikePoints[nCounter]=crossPt2;nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-13,0);}else{pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-45,0);} -break;default:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-30,0);break;} -if(lineType===31131000){pSpikePoints[nCounter].style=0;} -nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-dSpikeSize,0);if(lineType===31131000||lineType===31131200||lineType===31131300){pSpikePoints[nCounter].style=9;} -nCounter++;pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nCounter-1],dSpikeSize/2);if(pLinePoints[j].x>pLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pSpikePoints[nCounter-1],pt0,2,dSpikeSize);} -if(pLinePoints[j].x0){pSquallSegPts=new Array(segQty);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSquallSegPts);}else{continue;} -armyc2.c2sd.JavaLineArray.lineutility.GetSquallSegment(StartSegPt,EndSegPt,pSquallSegPts,sign,amplitude,quantity,length);for(k=0;k0){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt2,20);} -dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,pt2);lNumSegs=Math.floor((dDistance/20));if(lNumSegs>0){points2=Clazz.newArray(lNumSegs*32,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetAnchorageFlotSegment(vbPoints,Math.floor(pt1.x),Math.floor(pt1.y),Math.floor(pt2.x),Math.floor(pt2.y),l,points2,bFlip,lDirection,lLastDirection);points=Clazz.newArray(numSegPts,0);for(j=0;j2) -pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);pt0.style=0;pt1.style=0;pt2.style=0;var xPoints=null;pOriginalLinePoints=new Array(vblSaveCounter);for(j=0;j=pLinePoints[2].y){pLinePoints[0].style=0;pLinePoints[2].style=1;}else{pLinePoints[0].style=1;pLinePoints[2].style=0;}} -break;default:break;} -acCounter=4;break;case 23224000:armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pLinePoints[2],pt0,pt1);pLinePoints[0].style=1;pLinePoints[1].style=5;pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2].style=1;pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[3].style=5;acCounter=4;break;case 23194000:pts=new Array(4);for(j=0;j<4;j++){pts[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);} -dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(pLinePoints[0],pLinePoints[1],pLinePoints[2]);pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[1],d,0);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[0],d,5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[1],-d,0);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[0],-d,5);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],0);midpt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[0],midpt,d);pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,105,dRadius/2);pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,-75,dRadius/2);pLinePoints[5].style=5;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],0);midpt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],midpt,d);pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,105,dRadius/2);pLinePoints[7]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,-75,dRadius/2);pLinePoints[7].style=5;acCounter=8;break;case 221311000:case 22340000:case 2237000:armyc2.c2sd.JavaLineArray.arraysupport.AreaWithCenterFeatureDouble(pLinePoints,vblCounter,lineType);acCounter=vblCounter;armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,vblCounter,points);break;case 22431100:for(j=0;jpt1.y){direction=0;}else{direction=1;}} -if(bolVertical!==0&&m.value[0]<=1){if(pt0.x1){if(pt0.xpt1.y){direction=1;} -if(pt0.xpt1.x&&pt0.y>pt1.y){direction=1;} -if(pt0.x>pt1.x&&pt0.yarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/20500) -dMBR=500;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,direction,dMBR/20);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,direction,dMBR/20);acCounter=4;break;case 211400000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=50;break;case 212600000:case 212500000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=50;armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);break;case 211600000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=32;break;case 211900000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=75;break;case 212100000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=29;break;case 23173000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=29;break;case 22624000:acCounter=armyc2.c2sd.JavaLineArray.arraysupport.GetZONEPointsDouble2(pLinePoints,lineType,vblSaveCounter);break;case 23111001:pUpperLinePoints=new Array(vblSaveCounter);pLowerLinePoints=new Array(vblSaveCounter);pUpperLowerLinePoints=new Array(2*vblCounter);for(j=0;j=1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,10);}} -if(pLinePoints[j].x>pLinePoints[j+1].x){if(m.value[0]<1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,3,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,3,10);} -if(m.value[0]>=1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,10);}} -if(bolVertical===0){if(pLinePoints[j].y>pLinePoints[j+1].y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,10);}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,10);}} -pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);nCounter++;pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);nCounter++;d=10;if(dMBR/20=1) -{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,15);}} -if(pLinePoints[j].x>pLinePoints[j+1].x){if(m.value[0]<1) -{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,3,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,3,15);} -if(m.value[0]>=1) -{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,15);}} -if(bolVertical===0){if(pLinePoints[j].y>pLinePoints[j+1].y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,15);}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,15);}} -pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);nCounter++;pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);nCounter++;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt3,pt2,Math.floor(d),Math.floor(d),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);nCounter++;}}} -acCounter=nCounter;break;case 24220000:for(j=0;jarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){d=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(d/10500) -d=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt2,Math.floor(Math.floor(d)/10),Math.floor(Math.floor(d)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=pArrowPoints[k];} -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(d)/10),Math.floor(Math.floor(d)/10),pArrowPoints,18);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=pArrowPoints[k];} -acCounter=vblCounter;break;case 23225000:armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pLinePoints[2],pt4,pt5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);for(j=0;j1){pt0=savepoints[0];pt1=savepoints[1];} -midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);var dist0=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt0);var dist1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt1);if(dist0>dist1){armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt0,pt4,pt5);}else{armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt1,pt4,pt5);} -pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);}else{midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pLinePoints[0],pLinePoints[1],0);dist0=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt0);dist1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt1);if(dist0>dist1) -armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt0,pt4,pt5);else -armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt1,pt4,pt5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);} -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pt0,-10,0);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[3],pt1,-10,0);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pt0,10,0);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[3],pt1,10,0);dWidth=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);pointCounter=4;n=1;pLinePoints[pointCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[pointCounter].style=0;pointCounter++;if((drawJaggies).booleanValue()) -while(dExtendLengtharmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=30*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/30750) -dMBR=500;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);if(darmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/10250) -dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt3,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} -pLinePoints[vblSaveCounter-1].style=5;acCounter=vblCounter;break;case 23227000:pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[vblCounter-8],pLinePoints[vblCounter-7],dMBR/2);pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-7]);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],dMBR/2);if(dMBR/10>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/10200) -dMBR=200;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt3,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/5),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/5),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} -pLinePoints[vblSaveCounter-1].style=5;acCounter=vblCounter;break;case 22522100:armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLinePoints,vblSaveCounter);for(k=vblSaveCounter-1;k>0;k--){d+=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[k],pLinePoints[k-1]);if(d>60) -break;} -if(d>60){middleSegment=k;pt2=pLinePoints[middleSegment];if(middleSegment>=1) -pt3=pLinePoints[middleSegment-1];}else{if(vblSaveCounter<=3) -middleSegment=1;else -middleSegment=2;pt2=pLinePoints[middleSegment];if(middleSegment>=1) -pt3=pLinePoints[middleSegment-1];} -pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);if(dMBR/20>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/20250) -dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-11],pLinePoints[vblCounter-10],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[vblCounter-9+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} -pLinePoints[vblCounter-6].x=(pLinePoints[vblCounter-11].x+pLinePoints[vblCounter-10].x)/2;pLinePoints[vblCounter-6].y=(pLinePoints[vblCounter-11].y+pLinePoints[vblCounter-10].y)/2;pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-6]);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-11],pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);if(middleSegment>=1){pt0=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt2,pt3,0);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt3,pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);} -for(j=0;j<3;j++){pLinePoints[vblCounter-6+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-10],pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);if(middleSegment>=1){pt0=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt2,pt3,0);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);} -for(j=0;j<3;j++){pLinePoints[vblCounter-3+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} -var airPts=new java.util.ArrayList();pLinePoints[middleSegment-1].style=5;if(vblSaveCounter===2) -pLinePoints[1].style=5;for(j=0;jarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR250) -dMBR=250;pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,-dMBR/10);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=pt2.y+(1/m.value[0])*pt2.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,-2);pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,2);pLinePoints[4].style=0;} -if(bolVertical!==0&&m.value[0]===0){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3].y=pt2.y-2;pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[4].y=pt2.y+2;pLinePoints[4].style=0;} -if(bolVertical===0){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3].x=pt2.x-2;pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[4].x=pt2.x+2;pLinePoints[4].style=0;} -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt1,pt0,-dMBR/10);if(bolVertical!==0&&m.value[0]!==0){b=pt2.y+(1/m.value[0])*pt2.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,2);pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,-2);} -if(bolVertical!==0&&m.value[0]===0){pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[5].y=pt2.y+2;pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[6].y=pt2.y-2;} -if(bolVertical===0){pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[5].x=pt2.x+2;pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[6].x=pt2.x-2;} -pLinePoints[6].style=0;pLinePoints[7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[3]);pLinePoints[7].style=5;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[0],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[8+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} -armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[2],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[11+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);pLinePoints[11+j].style=0;} -acCounter=14;break;case 22522220:armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLinePoints,vblSaveCounter);if(dMBR/20>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/20500) -dMBR=500;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-5],pLinePoints[vblCounter-4],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-k-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} -acCounter=vblCounter;break;case 23120000:pts2=new Array(2);pts2[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts2[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.GetPixelsMin(pts2,2,offsetX,offsetY);if(offsetX.value[0]<=0){offsetX.value[0]=offsetX.value[0]-100;}else{offsetX.value[0]=0;} -if(dMBR>300) -dMBR=300;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],-dMBR/10);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);midpt.x=(pt0.x+pLinePoints[0].x)/2;midpt.y=(pt0.y+pLinePoints[0].y)/2;pLinePoints[vblCounter-3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[vblCounter-4].style=5;pLinePoints[vblCounter-3].style=0;if(bolVertical!==0&&m.value[0]!==0){b=midpt.y+(1/m.value[0])*midpt.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,dMBR/20);if(pLinePoints[vblCounter-2].y>=midpt.y){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dMBR/20);}} -if(bolVertical!==0&&m.value[0]===0){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midpt);pLinePoints[vblCounter-2].y=midpt.y-dMBR/20;} -if(bolVertical===0){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midpt);pLinePoints[vblCounter-2].x=midpt.x-dMBR/20;} -pLinePoints[vblCounter-2].style=0;pLinePoints[vblCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,vblCounter,points);acCounter=vblCounter;break;case 23157000:pts2=new Array(2);if(Math.abs(pt0.y-pt1.y)<1){pt1.y=pt0.y+1;} -pts2[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts2[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pts=new Array(26);dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1)/2;midpt.x=(pt1.x+pt0.x)/2;midpt.y=(pt1.y+pt0.y)/2;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=midpt.y+(1/m.value[0])*midpt.x;ptYIntercept.x=0;ptYIntercept.y=b;pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,dRadius);if(pLinePoints[0].x<=pLinePoints[1].x){if(pt2.y>=midpt.y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dRadius);}}else{if(pt2.y<=midpt.y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dRadius);}}} -if(bolVertical!==0&&m.value[0]===0){pt2=midpt;if(pLinePoints[0].x<=pLinePoints[1].x){pt2.y=midpt.y-dRadius;}else{pt2.y=midpt.y+dRadius;}} -if(bolVertical===0){pt2=midpt;if(pLinePoints[0].y<=pLinePoints[1].y){pt2.x=midpt.x+dRadius;}else{pt2.x=midpt.x-dRadius;}} -pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(midpt,pt2,100);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(pts,0,dRadius,lineType);pLinePoints[0].style=1;pLinePoints[1].style=5;for(j=0;j<26;j++){pLinePoints[2+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[j]);pLinePoints[2+j].style=1;} -acCounter=28;break;case 231100000:dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(pt0,pt1,pt2);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=pt1.y+1/m.value[0]*pt1.x;b1=pt2.y-m.value[0]*pt2.x;calcPoint0=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);b=calcPoint1.y+1/m.value[0]*calcPoint1.x;calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);b=calcPoint2.y+1/m.value[0]*calcPoint2.x;calcPoint4=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);b=pt1.y+1/m.value[0]*pt1.x;calcPoint0=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} -if(bolVertical!==0&&m.value[0]===0){calcPoint0.x=pt1.x;calcPoint0.y=pt2.y;calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=pt2;calcPoint3.x=calcPoint0.x+dRadius/2;calcPoint3.y=calcPoint0.y;calcPoint4.x=pt1.x+dRadius;calcPoint4.y=pt2.y;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} -if(bolVertical===0){calcPoint0.x=pt2.x;calcPoint0.y=pt1.y;calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=pt2;calcPoint3.y=calcPoint0.y+dRadius/2;calcPoint3.x=calcPoint0.x;calcPoint4.y=pt1.y+dRadius;calcPoint4.x=pt2.x;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} -arcPts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(calcPoint1);arcPts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(calcPoint3);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(arcPts,0,dRadius,lineType);pLinePoints[0].style=5;pLinePoints[1].style=5;for(k=0;k<26;k++){pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcPts[k]);} -for(k=25;karmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/10150) -dMBR=150;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],-2*dMBR/10);for(k=0;karmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} -if(dMBR/100;k--){pLinePoints[vblCounter-k].style=5;} -acCounter=12;break;case 23223000:lLinestyle=9;if(dMBR/10>armyc2.c2sd.JavaLineArray.arraysupport.maxLength) -dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;if(dMBR/10250) -dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-8],pLinePoints[vblCounter-7],Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,lLinestyle);for(k=0;k<3;k++) -pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[0],Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,lLinestyle);for(k=0;k<3;k++) -pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);acCounter=8;break;case 26220000:pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt0,-10,0);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt0,pt1,-10,0);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt3,10,0);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt3,-10,0);pt7=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt4,10,0);pt8=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt4,-10,0);if(pt5.ypt8.y){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt7);}else{pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt8);} -pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);acCounter=4;break;case 23330000:acCounter=armyc2.c2sd.JavaLineArray.arraysupport.GetFORTLPointsDouble(pLinePoints,lineType,vblSaveCounter);break;case 21400000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCanalizeDouble(pLinePoints,lineType);break;case 21200000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBreachDouble(pLinePoints,lineType);break;case 212210000:case 212220000:case 212230000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDouble(pLinePoints,lineType);break;case 212210001:case 212220001:case 212230001:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDoubleRevC(pLinePoints,lineType,vblSaveCounter);break;case 22139000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDouble(pLinePoints,lineType);break;case 211000000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMDisruptDouble(pLinePoints,lineType);break;case 21600000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMContainDouble(pLinePoints,lineType);break;case 211700000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMPenetrateDouble(pLinePoints,lineType);acCounter=7;break;case 23171000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBlockDouble2(pLinePoints,lineType);acCounter=4;break;case 21100000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBlockDouble2(pLinePoints,lineType);acCounter=4;break;case 24250000:case 24211000:case 24260000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMLinearTargetDouble(pLinePoints,lineType,vblCounter);break;case 23163000:case 23221000:case 23222000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMGapDouble(pLinePoints,lineType);acCounter=12;break;case 23174000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMMinefieldDisruptDouble(pLinePoints,lineType);break;case 22534000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSupportByFireDouble(pLinePoints,lineType);break;case 22533000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMATKBYFIREDouble(pLinePoints,lineType);break;case 23213000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMByImpDouble(pLinePoints,lineType);break;case 21500000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMClearDouble(pLinePoints,lineType);break;case 23212000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMByDifDouble(pLinePoints,lineType,clipBounds);break;case 212300000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSeizeDouble(pLinePoints,lineType,0);break;case 212300001:var radius=0;if(rev===1){radius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[3]);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);} -acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSeizeDouble(pLinePoints,lineType,radius);break;case 211100000:case 23172000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMFixDouble(pLinePoints,lineType,clipBounds);break;case 211800000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMRIPDouble(pLinePoints,lineType);break;case 21800000:case 212400000:case 212410000:case 212000000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDelayGraphicEtcDouble(pLinePoints);break;case 23211000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMEasyDouble(pLinePoints,lineType);break;case 22310000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMDeceiveDouble(pLinePoints);acCounter=4;break;case 21300000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBypassDouble(pLinePoints,lineType);break;case 24326100:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMPAADouble(pLinePoints,lineType);acCounter=5;break;case 22611000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.AmbushPointsDouble(pLinePoints);break;case 22122000:acCounter=armyc2.c2sd.JavaLineArray.flot.GetFlotDouble(pLinePoints,vblSaveCounter);break;default:acCounter=vblSaveCounter;break;} -switch(lineType){case 22121000:armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);return points;case 21600000:case 21100000:case 212230000:case 212210000:case 212220000:case 212230001:case 212210001:case 212220001:case 24326100:case 211210000:case 211200000:case 21200000:case 21300000:case 21400000:case 21500000:case 211000000:case 211100000:case 211400000:case 211600000:case 211700000:case 211900000:case 212100000:case 212300000:case 212300001:case 14000000:case 15000003:armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);break;default:if(shapes===null){armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);return points;} -break;} -if(shapes===null) -return points;var shape=null;var gp=null;var redShape=null;var blueShape=null;var paleBlueShape=null;var whiteShape=null;var redFillShape=null;var blueFillShape=null;var blackShape=null;var blueStroke;var paleBlueStroke;var blueArea=null;var paleBlueArea=null;var whiteArea=null;var beginLine=true;var poly=null;switch(lineType){case 15000001:case 15000003:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(pLinePoints[0]);for(j=0;j0;j--){if(pLinePoints[acCounter-j-1].style===5){shape.moveTo(pLinePoints[acCounter-j]);}else{shape.lineTo(pLinePoints[acCounter-j]);}} -shapes.add(shape);break;case 32214000:whiteShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);whiteShape.setFillColor(armyc2.c2sd.renderer.utilities.Color.WHITE);var whiteStroke=new armyc2.c2sd.graphics2d.BasicStroke(28);blueShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);blueShape.setFillColor(new armyc2.c2sd.renderer.utilities.Color(30,144,255));paleBlueStroke=new armyc2.c2sd.graphics2d.BasicStroke(14);paleBlueShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);paleBlueShape.setFillColor(new armyc2.c2sd.renderer.utilities.Color(153,204,255));poly=new armyc2.c2sd.graphics2d.Polygon();for(k=0;k0&&k0&&k0) -if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5) -continue;if(k===0) -shape.set_Style(pLinePoints[k].style);shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} -if(k===vblCounter-1){if(shape!==null&&shape.getShape()!==null) -shapes.add(shape);}} -for(k=0;k0) -if(points.get(k).style===5&&points.get(k-1).style===5) -shape.lineTo(points.get(k));shape.moveTo(points.get(k));beginLine=false;}else{shape.lineTo(points.get(k));if(points.get(k).style===5||points.get(k).style===10){beginLine=true;}} -if(k===points.size()-1){if(shape!==null&&shape.getShape()!==null) -shapes.add(shape);}} -break;case 221311000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pLinePoints[0]);for(k=1;k0){if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5&&k1) -if(pLinePoints[k].style===5&&pLinePoints[k+1].style===5) -continue;shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5||pLinePoints[k].style===10){beginLine=true;}} -if(k===acCounter-1){if(shape!==null&&shape.getShape()!==null) -shapes.add(shape);}} -break;} -switch(lineType){case 23111001:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(pUpperLinePoints[0]);for(j=1;j=0;j--){shape.lineTo(pLowerLinePoints[j]);} -shape.lineTo(pUpperLinePoints[0]);shapes.add(0,shape);break;case 22522100:var outLineCounter=0;var ptOutline=new Array(4);for(k=0;k1) -count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(pLinePoints[0],pLinePoints[1],clipBounds);else -count=0;break;case 23212000:if(clipBounds!==null){armyc2.c2sd.JavaLineArray.countsupport.GetByDifSegment(pLinePoints,pointsCorner);var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMinX(),clipBounds.getMinY());var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMaxX(),clipBounds.getMaxY());var ptsCorner=armyc2.c2sd.JavaLineArray.lineutility.BoundOneSegment(pointsCorner[0],pointsCorner[1],ul,lr);if(ptsCorner!==null) -count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(ptsCorner[0],ptsCorner[1],clipBounds);else -count=20;}else -count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(pLinePoints[0],pLinePoints[1],clipBounds);break;default:count=vblCounter;break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.countsupport._className,"GetCountersDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCountersDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} -return Math.floor(count);},GetReefCount:function(pLinePoints,vblCounter){var count=0;try{var d=0;for(var j=0;j24){switch(vbiDrawThis){case 23132000:vblXCounter+=5*nHowManyThisSegment+1;break;default:vblXCounter+=4*nHowManyThisSegment;break;}}else{vblXCounter+=2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.countsupport._className,"GetDitchcountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDitchCountDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} -return vblXCounter;},GetSquallQty:function(pLinePoints,quantity,length,numPoints){var counter=0;try{var j=0;var dist=0;var numCurves=0;for(j=0;jarmyc2.c2sd.JavaLineArray.countsupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.countsupport.maxLength;} -if(dJaggyHalfAmp=vbPoints[2]){bFlip.value[0]=1;}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(x1,y1,x2,y2);nNumSegs=Math.floor((dDistance/20));if(nNumSegs%2===0){nNumSegs-=1;}dRemainder=nNumSegs*20-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){lTotalpts+=lNumSegs*12;}else{lTotalpts+=1;}} -lTotalpts+=1;vbPoints2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.flot._className,"GetAnchorageCountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetAnchorageCountDouble",exc));}else{throw exc;}} -return(lTotalpts);},GetFlotCount2Double:function(vbPoints,numPts,lineType){var lTotalpts=0;try{var j=0;var lNumSegs=0;var dDistance=0;var dIncrement=0;var nFactor=10;switch(lineType){case 31132000:case 31132100:dIncrement=40;break;case 31132200:dIncrement=60;nFactor=17;break;case 31132300:dIncrement=60;nFactor=20;break;default:dIncrement=20;break;} -for(j=0;j0){points=Clazz.newArray(lNumSegs*30,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,l,points,lineType,bFlip,lDirection,lLastDirection);for(j=0;j=vbPoints[2]){if(lineType!==31134000&&lineType!==31134100&&lineType!==31134200&&lineType!==31134300){bFlip.value[0]=1;}else{bFlip.value[0]=0;}}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(vbPoints[2*segment],vbPoints[2*segment+1],vbPoints[2*segment+2],vbPoints[2*segment+3]);nNumSegs=Math.floor((dDistance/dIncrement));dRemainder=nNumSegs*dIncrement-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){points=Clazz.newArray(lNumFlots*30,0);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}pFlotPoints[nFlotCounter].style=9;if(lineType===31133100){pFlotPoints[nFlotCounter].style=0;}}if((nFlotCounter+1)%10===0){if(lineType===31133000||lineType===31133100){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pFlotPoints[nFlotCounter-9]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pFlotPoints[nFlotCounter-9]);if(d2>d1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1-20);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2+20);}if(lineType===31133000){pFlotPoints[nFlotCounter].style=10;}if(lineType===31133100){pFlotPoints[nFlotCounter].style=5;}}if(lineType===31134000){pFlotPoints[nFlotCounter].style=23;}}k+=3;nFlotCounter++;} -points=null;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);for(k=0;kd1){tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-d1-dIncrement/2,0);}else{tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pLinePoints[j+1],-d2+dIncrement/2,0);}break;case 31134000:if(d2>d1){tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-d1-dIncrement/8,0);}else{tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pLinePoints[j+1],-d2+dIncrement/8,0);}break;default:break;} -spikeLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],tempPoint);if(spikeLength+dSpikeSized2){pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-1],dSpikeSize/2);}else{pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-1],-dSpikeSize/2);}if(bolTooLong===0){if(bolVertical!==0){if(pLinePoints[j].xpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}pSpikePoints[nSpikeCounter-1].style=9;if(bolTooLong===0){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-2]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2]);if(d1>d2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nSpikeCounter-2],dSpikeSize,0);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2],-dSpikeSize,0);}if(lineType===31133000){pSpikePoints[nSpikeCounter].style=10;}if(lineType===31133100){pSpikePoints[nSpikeCounter].style=5;}if(lineType===31134000){pSpikePoints[nSpikeCounter].style=24;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;} -if(nSpikeCounter===0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter].style=5;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+2].style=5;nSpikeCounter+=3;}} -for(j=0;j360){angle=angle-360;}if(0<=angle&&angle<=90){nQuadrant=0;angle=90-angle;angle=Math.abs(angle)*(0.017453292519943295);}if(90=vbPoints[2]){bFlip.value[0]=1;}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(vbPoints[2*segment],vbPoints[2*segment+1],vbPoints[2*segment+2],vbPoints[2*segment+3]);nNumSegs=Math.floor((dDistance/20));dRemainder=nNumSegs*20-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){points=Clazz.newArray(lNumSegs*30,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetFlotSegment(vbPoints,l,points,bFlip,lDirection,lLastDirection);for(j=0;j0){lTotalpts+=lNumSegs*10;}else{lTotalpts+=1;}} -lTotalpts+=1;vbPoints2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.flot._className,"GetFlotCountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetFlotCountDouble",exc));}else{throw exc;}} -return(lTotalpts);},GetOFYPointsDouble:function(pLinePoints,numPts,lineType){var nTotalCounter=0;try{var j=0;var k=0;var lNumSegs=0;var l=0;var lNumFlots=0;var lNumSpikes=0;var dDistance=0;var m=new armyc2.c2sd.JavaLineArray.ref();var lTotalPoints=0;var points=null;var pSpikePoints=null;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var tempPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pFlotPoints=null;var pSegmentPoints=null;var dSpikeSize=20;var dIncrement=80;var vbPoints=null;var nFlotCounter=0;var nSpikeCounter=0;var nSegmentCounter=0;var flots=null;var segmentLength=0;var spikeLength=0;var bolTooLong=0;var d1=0;var d2=0;var bolVertical=0;var pFlotStart=null;var pFlotEnd=null;var pSpikeStart=null;var pSpikeEnd=null;var nSpikeEndCounter=0;var nFlotEndCounter=0;var bFlip=new armyc2.c2sd.JavaLineArray.ref();var lDirection=new armyc2.c2sd.JavaLineArray.ref();var lLastDirection=new armyc2.c2sd.JavaLineArray.ref();m.value=Clazz.newArray(1,0);bFlip.value=Clazz.newArray(1,0);lDirection.value=Clazz.newArray(1,0);lLastDirection.value=Clazz.newArray(1,0);lTotalPoints=armyc2.c2sd.JavaLineArray.flot.GetOFYCountDouble(pLinePoints,numPts,lineType);vbPoints=Clazz.newArray(numPts*2,0);pSpikePoints=new Array(lTotalPoints);pFlotPoints=new Array(lTotalPoints);pSegmentPoints=new Array(lTotalPoints);for(j=0;j0){points=Clazz.newArray(lNumFlots*30,0);pFlotStart=new Array(lNumFlots);pFlotEnd=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}pFlotPoints[nFlotCounter].style=9;}if((nFlotCounter+1)%10===0){if(lineType===31133200){pFlotEnd[Math.floor(l/10)]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotPoints[nFlotCounter]);nFlotEndCounter++;d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pFlotPoints[nFlotCounter-9]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pFlotPoints[nFlotCounter-9]);if(d2>d1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1-20);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2+20);}pFlotPoints[nFlotCounter].style=10;}}k+=3;nFlotCounter++;} -points=null;}else{pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegmentPoints[nSegmentCounter++].style=5;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);pSpikeStart=new Array(lNumSpikes);pSpikeEnd=new Array(lNumSpikes);for(k=0;kpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}pSpikePoints[nSpikeCounter-1].style=9;if(bolTooLong===0){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-2]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2]);if(d1>d2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nSpikeCounter-2],dSpikeSize,0);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2],-dSpikeSize,0);}pSpikeEnd[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter]);nSpikeEndCounter++;if(lineType===31133200){pSpikePoints[nSpikeCounter].style=10;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;} -if(nSpikeEndCounter===0&&nFlotEndCounter===1){pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[0]);pSegmentPoints[nSegmentCounter++].style=5;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[0]);pSegmentPoints[nSegmentCounter++].style=5;}for(l=0;l0){points=Clazz.newArray(lNumFlots*30,0);pFlotStart=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pFlotStart);pFlotEnd=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pFlotEnd);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}if(lineType===31134100){pFlotPoints[nFlotCounter].style=19;}else{pFlotPoints[nFlotCounter].style=9;}}if((nFlotCounter+1)%10===0){if(lineType===31134100){pFlotPoints[nFlotCounter].style=5;}else{pFlotPoints[nFlotCounter].style=23;}pFlotEnd[Math.floor(l/10)]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotPoints[nFlotCounter]);}if(l===0){pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegPoints[nSegCounter++].style=19;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[l]);pSegPoints[nSegCounter++].style=5;}if(l===lNumFlots*10-1){pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegPoints[nSegCounter++].style=19;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[Math.floor(l/10)]);pSegPoints[nSegCounter++].style=5;}k+=3;nFlotCounter++;} -points=null;}else{pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegPoints[nSegCounter++].style=0;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegPoints[nSegCounter++].style=5;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);pSpikeStart=new Array(lNumSpikes);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSpikeStart);pSpikeEnd=new Array(lNumSpikes);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSpikeEnd);for(k=0;kpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}if(lineType==31134100){pSpikePoints[nSpikeCounter-1].style=25;}else{pSpikePoints[nSpikeCounter-1].style=9;}if(bolTooLong==0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nSpikeCounter-2],pLinePoints[j+1],dSpikeSize);if(lineType==31134100){pSpikePoints[nSpikeCounter].style=5;}else{pSpikePoints[nSpikeCounter].style=24;}pSpikeEnd[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter]);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;if(lineType==31134000||lineType==31134100){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotStart[k],pSpikeStart[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotStart[k],pLinePoints[j+1],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotEnd[k],pLinePoints[j],d1/2,5);if(k==lNumSpikes-2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotStart[k+1],pLinePoints[j+1],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotEnd[k+1],pLinePoints[j],d1/2,5);}pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeStart[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeEnd[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2,5);if(lineType==31134100){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k]);pSpikePoints[nSpikeCounter++].style=5;if(k==lNumSpikes-2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k+1]);pSpikePoints[nSpikeCounter++].style=5;}pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeEnd[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeStart[k]);pSpikePoints[nSpikeCounter++].style=5;}}if(lineType==31134200){pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],dSpikeSize/2,22);pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],dSpikeSize/2,20);}if(lineType==31134300){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotStart[k],pSpikeStart[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/4);pSpikePoints[nSpikeCounter].style=25;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2);pSpikePoints[nSpikeCounter+2].style=19;pSpikePoints[nSpikeCounter+3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],3*d1/4);pSpikePoints[nSpikeCounter+3].style=5;pSpikePoints[nSpikeCounter+4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter],pLinePoints[j],pSpikePoints[nSpikeCounter],2,5,25);pSpikePoints[nSpikeCounter+5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter+3],pLinePoints[j],pSpikePoints[nSpikeCounter+3],3,5,5);nSpikeCounter+=6;d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotEnd[k+1],pSpikeEnd[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/4);pSpikePoints[nSpikeCounter].style=25;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2);pSpikePoints[nSpikeCounter+2].style=19;pSpikePoints[nSpikeCounter+3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],3*d1/4);pSpikePoints[nSpikeCounter+3].style=5;pSpikePoints[nSpikeCounter+4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter],pLinePoints[j+1],pSpikePoints[nSpikeCounter],3,5,19);pSpikePoints[nSpikeCounter+5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter+3],pLinePoints[j+1],pSpikePoints[nSpikeCounter+3],2,5,5);nSpikeCounter+=6;}} -if(nSpikeCounter==0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter].style=5;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+2].style=5;nSpikeCounter+=3;}} -for(j=0;j0;k--){d+=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[k],pLinePoints[k-1]);if(d>60){break;}} -if(d>60){middleSegment=k;}else{if(vblSaveCounter<=3){middleSegment=1;}else{middleSegment=2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetDirAtkAirMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDirAtkAirMiddleSegment",exc));}else{throw exc;}} -return middleSegment;},CalcSegmentAngleDouble:function(pt0,pt1){var dAngle=0;try{var nTemp=0;var m=new armyc2.c2sd.JavaLineArray.ref();nTemp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(nTemp===0) -dAngle=1.5707963267948966;else{dAngle=Math.atan(m.value[0]);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcSegmentAngleDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcSegmentAngleDouble",exc));}else{throw exc;}} -return dAngle;},InitializePOINT2Array:function(pts){if(pts===null||pts.length===0) -return;for(var j=0;jdMaxX) -dMaxX=pLinePoints[j].x;if(pLinePoints[j].y>dMaxY) -dMaxY=pLinePoints[j].y;} -CenterLinePoint.x=(dMinX+dMaxX)/2;CenterLinePoint.y=(dMinY+dMaxY)/2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcCenterPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcCenterPointDouble",exc));}else{throw exc;}} -return CenterLinePoint;},CalcCenterPointDouble2:function(pLinePoints,vblCounter){var pt0=pLinePoints[0];var CenterLinePoint=new armyc2.c2sd.JavaLineArray.POINT2();try{var j=0;var dMinX=pt0.x;var dMinY=pt0.y;var dMaxX=pt0.x;var dMaxY=pt0.y;dMinX=pt0.x;dMinY=pt0.y;dMaxX=pt0.x;dMaxY=pt0.y;var pt;for(j=0;jdMaxX) -dMaxX=pt.x;if(pt.y>dMaxY) -dMaxY=pt.y;} -CenterLinePoint.x=(dMinX+dMaxX)/2;CenterLinePoint.y=(dMinY+dMaxY)/2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcCenterPointDouble2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcCenterPointDouble2",exc));}else{throw exc;}} -return CenterLinePoint;},CalcDistanceDouble:function(p1,p2){var returnValue=0;try{returnValue=Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));var xdist=Math.abs(p1.x-p2.x);var ydist=Math.abs(p1.y-p2.y);var max=xdist;if(ydist>xdist) -max=ydist;if(returnValue===0||Double.isInfinite(returnValue)){if(max>0) -returnValue=max;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcDistanceDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcDistanceDouble",exc));}else{throw exc;}} -return returnValue;},CalcTrueSlopeDouble:function(firstLinePoint,lastLinePoint,slope){var result=1;try{if(slope.value===null) -slope.value=Clazz.newArray(1,0);var deltaX=0;var deltaY=0;deltaX=firstLinePoint.x-lastLinePoint.x;if(deltaX===0){deltaX=1;result=1;} -deltaY=firstLinePoint.y-lastLinePoint.y;slope.value[0]=deltaY/deltaX;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcTrueSlopeDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcTrueSlopeDouble",exc));}else{throw exc;}} -return result;},WriteFile:function(str){try{}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"WriteFile",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside WriteFile",exc));}else{throw exc;}}},ReversePointsDouble2:function(pLowerLinePoints,vblCounter){try{var pResultPoints=new Array(vblCounter);var k=0;for(k=0;k0){tempLinePoint.x=endLinePoint.x;tempLinePoint.y=endLinePoint.y+dOffset;}else{tempLinePoint.x=endLinePoint.x;tempLinePoint.y=endLinePoint.y-dOffset;} -return tempLinePoint;} -if(dy===0){if(dx>0){tempLinePoint.x=endLinePoint.x+dOffset;tempLinePoint.y=endLinePoint.y;}else{tempLinePoint.x=endLinePoint.x-dOffset;tempLinePoint.y=endLinePoint.y;} -return tempLinePoint;} -if(dy===0) -dAngle=0;else -dAngle=Math.atan(dx/dy)+1.5707963267948966;dHypotenuse=nOffset;if(endLinePoint.x>startLinePoint.x) -tempLinePoint.x=endLinePoint.x+dHypotenuse*Math.abs(Math.cos(dAngle));else -tempLinePoint.x=endLinePoint.x-dHypotenuse*Math.abs(Math.cos(dAngle));if(endLinePoint.y>startLinePoint.y) -tempLinePoint.y=endLinePoint.y+dHypotenuse*Math.abs(Math.sin(dAngle));else -tempLinePoint.y=endLinePoint.y-dHypotenuse*Math.abs(Math.sin(dAngle));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetOffsetPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetOffsetPointDouble",exc));}else{throw exc;}} -return(tempLinePoint);},GetArcFEBADouble:function(dRadius,pLinePoints,vblCounter,pResultLinePoints){try{var dStartAngle=0;var dEndAngle=6.283185307179586;var dIncrement=(dEndAngle-dStartAngle)/25.0;var i=0;var j=0;var nArcCounter=0;var x=0;var y=0;var CenterLinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pArcLinePoints=new Array(26);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArcLinePoints);for(i=0;i10) -iterations+=1;for(k=0;k1){if(pt2.x0) -{pt3.x=(dOriginalDistance+dist)/dOriginalDistance*(pt2.x-pt1.x)+pt1.x;pt3.y=(dOriginalDistance+dist)/dOriginalDistance*(pt2.y-pt1.y)+pt1.y;pt3.style=styl;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"ExtendLine2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendLine2Double",exc));}else{throw exc;}} -return pt3;},ExtendAngledLine:function(pt0,pt1,pt2,alpha,d){var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var psi=Math.atan((pt1.y-pt0.y)/(pt1.x-pt0.x));var alpha1=3.141592653589793*alpha/180;var theta=psi+alpha1;var dx=d*Math.cos(theta);var dy=d*Math.sin(theta);pt.x=pt2.x+dx;pt.y=pt2.y+dy;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"ExtendAngledLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendAngledLine",exc));}else{throw exc;}} -return pt;},GetQuadrantDouble:function(){var nQuadrant=-1;try{if(arguments.length===2) -{var pt1=arguments[0];var pt2=arguments[1];if(pt2.x>=pt1.x&&pt2.y<=pt1.y) -nQuadrant=1;if(pt2.x>=pt1.x&&pt2.y>=pt1.y) -nQuadrant=2;if(pt2.x<=pt1.x&&pt2.y>=pt1.y) -nQuadrant=3;if(pt2.x<=pt1.x&&pt2.y<=pt1.y) -nQuadrant=4;} -else if(arguments.length===4) -{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];if(x2>=x1&&y2<=y1) -nQuadrant=1;if(x2>=x1&&y2>=y1) -nQuadrant=2;if(x2<=x1&&y2>=y1) -nQuadrant=3;if(x2<=x1&&y2<=y1) -nQuadrant=4;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetQuadrantDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetQuadrantDouble",exc));}else{throw exc;}} -return nQuadrant;},GetPixelsMin:function(ptsSeize,vblCounter,x,y){try{var xmin=Infinity;var ymin=Infinity;var j=0;for(j=0;j0) -dAngle=3.141592653589793;else -dAngle=0;}else -dAngle=Math.atan(dx/dy)+1.5707963267948966;tempLinePoint.style=0;if(dx<=0.0&&dy<=0.0) -dSign=-1.0;if(dx>=0.0&&dy<=0.0) -dSign=-1.0;if(dx<=0.0&&dy>=0.0) -dSign=1.0;if(dx>=0.0&&dy>=0.0) -dSign=1.0;dHypotenuse=dSign*nBiSector;AHBX=endLinePoint.x+dHypotenuse*Math.cos(dAngle);AHBY=endLinePoint.y-dHypotenuse*Math.sin(dAngle);dHypotenuse=dSign*(nBase/2.0);AHBLX=AHBX-dHypotenuse*Math.sin(dAngle);AHBLY=AHBY-dHypotenuse*Math.cos(dAngle);AHBRX=AHBX+dHypotenuse*Math.sin(dAngle);AHBRY=AHBY+dHypotenuse*Math.cos(dAngle);tempLinePoint.x=Math.floor(AHBLX);tempLinePoint.y=Math.floor(AHBLY);pResultLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tempLinePoint);pResultLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(endLinePoint);tempLinePoint.x=Math.floor(AHBRX);tempLinePoint.y=Math.floor(AHBRY);pResultLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tempLinePoint);switch(styl){case 0:for(j=0;j<2;j++) -pResultLinePoints[j].style=0;pResultLinePoints[2].style=5;break;case 9:for(j=0;j<2;j++) -pResultLinePoints[j].style=9;pResultLinePoints[2].style=10;break;case 18:for(j=0;j<2;j++) -pResultLinePoints[j].style=18;pResultLinePoints[2].style=5;break;default:for(j=0;j<2;j++) -pResultLinePoints[j].style=styl;pResultLinePoints[2].style=5;break;} -return;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetArrowhead4Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetArrowhead4Double",exc));}else{throw exc;}}},MidPointDouble:function(pt0,pt1,styl){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);try{ptResult.x=(pt0.x+pt1.x)/2;ptResult.y=(pt0.y+pt1.y)/2;ptResult.style=styl;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MidPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MidPointDouble",exc));}else{throw exc;}} -return ptResult;},RotateGeometryDoubleOrigin:function(pLinePoints,vblCounter,lAngle){try{var j=0;var dRotate=0;var dTheta=0;var dGamma=0;var x=0;var y=0;if(lAngle!==0){var pdCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();dRotate=lAngle*3.141592653589793/180;pdCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);for(j=0;j=pdCenter.x){dGamma=dGamma+3.141592653589793;} -dTheta=dRotate+dGamma;y=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.sin(dTheta);x=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.cos(dTheta);pLinePoints[j].y=pdCenter.y+y;pLinePoints[j].x=pdCenter.x+x;} -return pLinePoints;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"RotateGeometryDoubleOrigin",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RotateGeometryDoubleOrigin",exc));}else{throw exc;}} -return pLinePoints;},ExtendTrueLinePerpDouble:function(pt0,pt1,pt2,d,styl){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);try{var ptYIntercept=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);var m=new armyc2.c2sd.JavaLineArray.ref();var b=0;var b1=0;var nTemp=0;var offsetX=new armyc2.c2sd.JavaLineArray.ref();var offsetY=new armyc2.c2sd.JavaLineArray.ref();var pts=new Array(3);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pts[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);armyc2.c2sd.JavaLineArray.lineutility.GetPixelsMin(pts,3,offsetX,offsetY);if(offsetX.value[0]<=0) -offsetX.value[0]=offsetX.value[0]-100;else -offsetX.value[0]=0;nTemp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);switch(nTemp){case 0:if(pt0.y0){dy=-m1*dWidth/Math.sqrt(1+m1*m1);dx=-dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;} -break;case 3:if(m1<=0){dy=-m1*dWidth/Math.sqrt(1+m1*m1);dx=dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;}else{dy=m1*dWidth/Math.sqrt(1+m1*m1);dx=-dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;} -break;default:X.value[0]=p2.x;Y.value[0]=p2.y;break;} -return 1;} -X.value[0]=(b2-b1)/(m1-m2);Y.value[0]=(m1*(X.value[0])+b1);return 1;}catch(exc){if(Clazz.instanceOf(exc)){X.value[0]=p2.x;Y.value[0]=p2.y;armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcTrueIntersectDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendTrueIntersectDouble",exc));}else{throw exc;}} -return 1;},CalcDistance2:function(x1,y1,x2,y2){var dResult=0;try{dResult=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));var xdist=Math.abs(x1-x2);var ydist=Math.abs(y1-y2);var max=xdist;if(ydist>xdist) -max=ydist;if(dResult===0||Double.isInfinite(dResult)){if(max>0) -dResult=max;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcDistance2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcDistance2",exc));}else{throw exc;}} -return dResult;},GetSAAFRSegment:function(pLinePoints,lineType,dMRR,rev){try{var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt4=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt5=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var m=new armyc2.c2sd.JavaLineArray.ref();var bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pLinePoints[0],pLinePoints[1],m);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pLinePoints[1],-dMRR,5);pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[1],pLinePoints[0],-dMRR,0);if(bolVertical!==0&&m.value[0]<1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],2,dMRR);pt2.style=0;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],2,dMRR);pt3.style=5;pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],3,dMRR);pt4.style=0;pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],3,dMRR);pt5.style=5;}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],0,dMRR);pt2.style=0;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],0,dMRR);pt3.style=5;pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],1,dMRR);pt4.style=0;pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],1,dMRR);pt5.style=5;} -pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[5].style=5;if(lineType===22223000) -pLinePoints[0].style=5;if(rev===1) -pLinePoints[0].style=5;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetSAAFRSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSAAFRSegment",exc));}else{throw exc;}} -return;},ArcArrayDouble:function(pResultLinePoints,vblCounter,dRadius,linetype){try{var startangle=0;var endangle=0;var increment=0;var length=0;var M=0;var j;var numarcpts=0;var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[0]);var a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[1]);var e=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[0]);var pArcLinePoints=null;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(a,e,m);if(bolVertical!==0) -M=Math.atan(m.value[0]);else{if(a.y=minX&&pt.y<=maxY&&pt.y>=minY) -return 1;else -return 0;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"PointInBounds2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointInBounds2",exc));}else{throw exc;}} -return 1;},intersectSegment:function(pt0,pt1,sidePt0,sidePt1){var pt=null;try{if(pt0.x===pt1.x){return null;} -var m=(pt1.y-pt0.y)/(pt1.x-pt0.x);var dx=0;var dy=0;var x=0;var y=0;var upper=null;var lower=null;var left=null;var right=null;var bolVertical=new Boolean(false);if(sidePt0.x===sidePt1.x){bolVertical=new Boolean(true);if(sidePt0.y=pt.x&&pt.x>=pt1.x){if(upper.y<=pt.y&&pt.y<=lower.y){return pt;}}}else{dy=left.y-pt0.y;dx=dy/m;x=pt0.x+dx;y=left.y;pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);if(pt0.y<=pt.y&&pt.y<=pt1.y){if(left.x<=pt.x&&pt.x<=right.x){return pt;}}else if(pt0.y>=pt.y&&pt.y>=pt1.y){if(left.x<=pt.x&&pt.x<=right.x){return pt;}}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"intersectSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside intersectSegment",exc));}else{throw exc;}} -return null;},BoundOneSegment:function(pt0,pt1,ul,lr){var line=new Array(2);try{if(pt0.ylr.y&&pt1.y>lr.y){return null;} -if(pt0.xlr.x&&pt1.x>lr.x){return null;} -var bolVertical=new Boolean(false);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(line);if(pt0.x===pt1.x){bolVertical=new Boolean(true);} -if(bolVertical.booleanValue()){line[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);if(line[0].ylr.y){line[0].y=lr.y;} -line[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);if(line[1].ylr.y){line[1].y=lr.y;} -return line;} -var dx=0;var dy=0;var x=0;var y=0;var m=(pt1.y-pt0.y)/(pt1.x-pt0.x);var side0Intersect=new Boolean(false);var side1Intersect=new Boolean(false);var side2Intersect=new Boolean(false);var side3Intersect=new Boolean(false);var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(lr.x,ul.y);var ll=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ul.x,lr.y);var pt0Intersect=null;if(armyc2.c2sd.JavaLineArray.lineutility.PointInBounds2(pt0,ul,lr)===1){pt0Intersect=pt0;} -if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ll,ul);side0Intersect=new Boolean(true);} -if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ul,ur);side1Intersect=new Boolean(true);} -if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ur,lr);side2Intersect=new Boolean(true);} -if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ll,lr);side3Intersect=new Boolean(true);} -var pt1Intersect=null;if(armyc2.c2sd.JavaLineArray.lineutility.PointInBounds2(pt1,ul,lr)===1){pt1Intersect=pt1;} -if(pt1Intersect===null&&side0Intersect.booleanValue()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ll,ul);} -if(pt1Intersect===null&&side1Intersect.booleanValue()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ul,ur);} -if(pt1Intersect===null&&side2Intersect.booleanValue()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ur,lr);} -if(pt1Intersect===null&&side3Intersect.booleanValue()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ll,lr);} -if(pt0Intersect!==null&&pt1Intersect!==null){line[0]=pt0Intersect;line[1]=pt1Intersect;}else{line=null;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"BoundOneSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BoundOneSegment",exc));}else{throw exc;}} -return line;},GetDitchSpikeDouble:function(pLinePoints,nOldCounter,bWayIs,linetype){var nSpikeCounter=0;try{var nNumberOfSegments=0;var lCircleCounter=0;var bolVertical=0;var nTemp=0;var i;var j;var dPrinter=1.0;var dIntLocation1x=0;var dIntLocation2x=0;var dIntLocation1y=0;var dIntLocation2y=0;var r=0;var s=0;var use=0;var length=0;var k=0;var bint=0;var pdAnswer=new armyc2.c2sd.JavaLineArray.ref();var m=new armyc2.c2sd.JavaLineArray.ref();var UpperLinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var Lower1LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var Lower2LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var b=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pCirclePoints=new Array(pLinePoints.length);var averagePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var lastAveragePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pTempLinePoints=null;var minLength=24;pTempLinePoints=new Array(nOldCounter);for(j=0;jminLength*dPrinter){if(bWayIs!==0){if(pLinePoints[i].x<=pLinePoints[i+1].x){use=r;} -if(pLinePoints[i].x>=pLinePoints[i+1].x){use=s;}}else{if(pLinePoints[i].x<=pLinePoints[i+1].x){use=s;} -if(pLinePoints[i].x>=pLinePoints[i+1].x){use=r;}} -for(j=1;j<=nNumberOfSegments;j++){k=j;a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[i]);b=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[i+1]);if(j>1){dIntLocation1x=dIntLocation2x;}else{dIntLocation1x=pLinePoints[i].x+((k*12.0-12)*dPrinter/length)*(pLinePoints[i+1].x-pLinePoints[i].x);} -if(j>1){dIntLocation1y=dIntLocation2y;}else{dIntLocation1y=pLinePoints[i].y+((k*12.0-6.0)*dPrinter/length)*(pLinePoints[i+1].y-pLinePoints[i].y);} -dIntLocation2x=pLinePoints[i].x+((k*12.0+6.0)*dPrinter/length)*(pLinePoints[i+1].x-pLinePoints[i].x);dIntLocation2y=pLinePoints[i].y+((k*12.0+6.0)*dPrinter/length)*(pLinePoints[i+1].y-pLinePoints[i].y);if(m.value[0]!==0&&bolVertical!==0){bint=(dIntLocation1y+dIntLocation2y)/2.0+(1/m.value[0])*(dIntLocation1x+dIntLocation2x)/2.0;UpperLinePoint=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m.value[0],use,-1/m.value[0],bint,1,1,pLinePoints[0].x,pLinePoints[0].y);} -if(bolVertical===0){if(dIntLocation1y1&&j1){if(j%2===0){pCirclePoints[lCircleCounter]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(averagePoint,lastAveragePoint,20);lCircleCounter++;}} -if(j1){if(pLinePoints[1].y===pLinePoints[0].y) -pLinePoints[1].y++;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MoveSingleCPixels",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MoveSingleCPixels",exc));}else{throw exc;}}},RotateGeometryDouble:function(pLinePoints,vblCounter,lAngle){try{var j=0;var dRotate=0;var dTheta=0;var dGamma=0;var x=0;var y=0;if(lAngle!==0){var pdCenter;dRotate=lAngle*3.141592653589793/180;pdCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble(pLinePoints,vblCounter);for(j=0;jpdCenter.y)) -dGamma=4.71238898038469;else -dGamma=1.5707963267948966;}else -dGamma=3.141592653589793+Math.atan((pLinePoints[j].y-pdCenter.y)/(pLinePoints[j].x-pdCenter.x));if(pLinePoints[j].x>=pdCenter.x) -dGamma=dGamma+3.141592653589793;dTheta=dRotate+dGamma;y=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.sin(dTheta);x=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.cos(dTheta);pLinePoints[j].y=pdCenter.y+y;pLinePoints[j].x=pdCenter.x+x;} -return;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"RotateGeometryDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RotateGeometryDouble",exc));}else{throw exc;}} -return;},adjustCATKBYFIREControlPoint:function(linetype,pLinePoints,dist){try{if(linetype!==21710000) -return;var dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints.get(0),pLinePoints.get(1));if(dist2<=dist) -return;var pt=null;var count=pLinePoints.size();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(0));var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(1));var controlPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(count-1));var pt4=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(pt0,pt1,pt1,controlPt);pt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt4,controlPt,dist);pLinePoints.set(count-1,pt);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"adjustCATKBYFIREControlPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside adjustCATKBYFIREControlPoint",exc));}else{throw exc;}} -return;},PointRelativeToLine:function(){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var pt0=arguments[0];var pt1=arguments[1];var atPoint=null;var ptRelative=null;if(arguments.length===3) -{ptRelative=arguments[2];var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var midPt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);var b1=0;var b2=0;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){ptResult.x=ptRelative.x;ptResult.y=midPt.y;} -if(bolVertical!==0&&m.value[0]===0){ptResult.x=midPt.x;ptResult.y=ptRelative.y;} -if(bolVertical!==0&&m.value[0]!==0){b1=midPt.y+(1/m.value[0])*midPt.x;b2=ptRelative.y-m.value[0]*ptRelative.x;ptResult=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);}} -else if(arguments.length===4) -{atPoint=arguments[2];ptRelative=arguments[3];bolVertical=0;m=new armyc2.c2sd.JavaLineArray.ref();b1=0;b2=0;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){ptResult.x=ptRelative.x;ptResult.y=atPoint.y;} -if(bolVertical!==0&&m.value[0]===0){ptResult.x=atPoint.x;ptResult.y=ptRelative.y;} -if(bolVertical!==0&&m.value[0]!==0){b1=atPoint.y+(1/m.value[0])*atPoint.x;b2=ptRelative.y-m.value[0]*ptRelative.x;ptResult=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);}}} -catch(exc) -{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"PointRelativeToLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointRelativeToLine",exc));}else{throw exc;}} -return ptResult;},LineRelativeToLine:function(pt0,pt1,ptRelative,pt2,pt3){try{var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var b1=0;var b2=0;var pt2Temp=null;var pt3Temp=null;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){pt2.x=ptRelative.x;pt2.y=pt0.y;pt3.x=ptRelative.x;pt3.y=pt1.y;} -if(bolVertical!==0&&m.value[0]===0){pt2.x=pt0.x;pt2.y=ptRelative.y;pt3.x=pt1.x;pt3.y=ptRelative.y;} -if(bolVertical!==0&&m.value[0]!==0){b1=pt0.y+(1/m.value[0])*pt0.x;b2=ptRelative.y-m.value[0]*ptRelative.x;pt2Temp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);b1=pt1.y+(1/m.value[0])*pt1.x;pt3Temp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);pt2.x=pt2Temp.x;pt2.y=pt2Temp.y;pt3.x=pt3Temp.x;pt3.y=pt3Temp.y;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"LineRelativeToLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LineRelativeToLine",exc));}else{throw exc;}} -return;},CalcMBR:function(pLinePoints,numpts,ulx,uly,lrx,lry){try{var j=0;ulx.value=Clazz.newArray(1,0);uly.value=Clazz.newArray(1,0);lrx.value=Clazz.newArray(1,0);lry.value=Clazz.newArray(1,0);ulx.value[0]=1.7976931348623157E308;uly.value[0]=1.7976931348623157E308;lrx.value[0]=-1.7976931348623157E308;lry.value[0]=-1.7976931348623157E308;for(j=0;jlrx.value[0]) -lrx.value[0]=pLinePoints[j].x;if(pLinePoints[j].y>lry.value[0]) -lry.value[0]=pLinePoints[j].y;if(pLinePoints[j].xlr.x) -lr.x=pLinePoints[j].x;if(pLinePoints[j].y>lr.y) -lr.y=pLinePoints[j].y;if(pLinePoints[j].xxdist) -max=ydist;if(result===0||Double.isInfinite(result)){if(max>0) -result=max;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MBRDistance",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MBRDistance",exc));}else{throw exc;}} -return result;},Reverse2Points:function(pt1,pt2){try{var tempPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();tempPt.x=pt1.x;tempPt.y=pt1.y;pt1.x=pt2.x;pt1.y=pt2.y;pt2.x=tempPt.x;pt2.y=tempPt.y;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"Reverse2Points",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside Reverse2Points",exc));}else{throw exc;}} -return;},createStrokedShape:function(shape){var newshape=new armyc2.c2sd.graphics2d.GeneralPath();try{var coords=Clazz.newArray(6,0);for(var i=shape.getPathIterator(null);!i.isDone();i.next()){var type=i.currentSegment(coords);switch(type){case 0:newshape.moveTo(coords[0],coords[1]);break;case 1:newshape.lineTo(coords[0],coords[1]);break;case 2:newshape.quadTo(coords[0],coords[1],coords[2],coords[3]);break;case 3:newshape.curveTo(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5]);break;case 4:newshape.closePath();break;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"createStrokedShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createStrokedShape",exc));}else{throw exc;}} -return newshape;},setPOINT2:function(){var pt2=new armyc2.c2sd.JavaLineArray.POINT2();pt2.x=0;pt2.y=0;pt2.segment=0;pt2.style=0;if(arguments.length===1) -{pt2.x=arguments[0].x;pt2.y=arguments[0].y;pt2.segment=arguments[0].segment;pt2.style=arguments[0].style;} -else if(arguments.length===2) -{pt2.x=arguments[0];pt2.y=arguments[1];} -else if(arguments.length===3) -{pt2.x=arguments[0];pt2.y=arguments[1];pt2.style=arguments[2];} -else if(arguments.length===4) -{pt2.x=arguments[0];pt2.y=arguments[1];pt2.segment=arguments[2];pt2.style=arguments[3];} -return pt2;},getExteriorPoints:function(pLinePoints,vblCounter,lineType,interior){var j;var index;var pt0;var pt1;var pt2;var m01=new armyc2.c2sd.JavaLineArray.ref();var m12=new armyc2.c2sd.JavaLineArray.ref();var direction;var intersectPt;var intersectPoints=new java.util.ArrayList();var b01;var b12;var dist=pLinePoints[0].style;for(j=0;j0){dist=pt1.style;} -var pt00;var pt01;var pt10;var pt11;index=j-1;if(index<0){index=vblCounter-1;} -var pts=new Array(pLinePoints.length);for(var k=0;kendIndex){modifier.textPath[0]=tg.Pixels.get(startIndex);modifier.textPath[1]=tg.Pixels.get(endIndex);if(rightOrLeft!==null){if(rightOrLeft.equals("left")){modifier.textPath[0].x-=spaces;modifier.textPath[1].x-=spaces;}else{modifier.textPath[0].x+=spaces;modifier.textPath[1].x+=spaces;}} -tg.modifiers.add(modifier);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddOffsetModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddOffsetModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier=function(tg,text,type,lineFactor,ptStart,ptEnd){try{if(text===null||text.equals("")){return;} -var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(text===null||text.equals("")){return;} -if(tg.Pixels===null||tg.Pixels.size()<2){return;} -modifier.text=text;modifier.set_IsIntegral(false);modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=ptStart;modifier.textPath[1]=ptEnd;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2=function(tg,text,type,lineFactor,pt0,pt1,isIntegral,modifierType){try{if(text===null||text.equals("")){return;} -var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(text===null||text.equals("")){return;} -modifier.text=text;if(isIntegral!==undefined) -modifier.set_IsIntegral(isIntegral);modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;modifier.isIntegral=isIntegral;modifier.textID=modifierType;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier=function(tg,text,type,lineFactor,startIndex,endIndex,isIntegral){try{if(text===null||text.equals("")){return;} -var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(isIntegral!==undefined) -modifier.set_IsIntegral((isIntegral).booleanValue());if(text===null||text.equals("")){return;} -if(tg.Pixels===null||tg.Pixels.isEmpty()){return;} -modifier.text=text;modifier.type=type;modifier.lineFactor=lineFactor;if(tg.Pixels.size()>endIndex){modifier.textPath[0]=tg.Pixels.get(startIndex);modifier.textPath[1]=tg.Pixels.get(endIndex);tg.modifiers.add(modifier);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddIntegralModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier=function(tg,text,type,lineFactor,pt0,pt1,modifierType){try{if(text===null||text.equals("")){return;} -var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();modifier.text=text;modifier.set_IsIntegral(true);if(pt0===null||pt1===null){return;} -modifier.type=type;if(arguments.length>6) -modifier.textID=modifierType;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddAreaModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddAreaModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier=function(tg,text,type,lineFactor,pt0,pt1,isIntegral,modifierType){try{if(text===null||text.equals("")){return;} -var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();modifier.set_IsIntegral((isIntegral).booleanValue());modifier.text=text;if(text===null||text.equals("")){return;} -if(pt0===null||pt1===null){return;} -modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;modifier.textID=modifierType;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddAreaModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddAreaModifier",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR=function(tg,ptUl,ptUr,ptLr,ptLl){try{var j=0;var x=tg.Pixels.get(0).x;var y=tg.Pixels.get(0).y;for(j=1;jptLr.x){ptLr.x=x;ptUr.x=x;} -if(y>ptLl.y){ptLl.y=y;ptLr.y=y;} -if(y3) -middleSegment=Math.floor(tg.Pixels.size()/4);if(tg.Pixels.size()>3) -middleSegment2=Math.floor(3*tg.Pixels.size()/4);switch(linetype){case 22340000:case 22350000:case 23164000:label="M";break;case 23180000:label="UXO";break;case 22431000:case 22431100:if(echelonSymbol!==null&&!echelonSymbol.isEmpty()) -startIndex=1;break;default:break;} -if(label===null||label.isEmpty()) -return;var stringWidth=metrics.stringWidth(label);var foundLongSegment=false;var dist=0;var pt0=null;var pt1=null;for(j=startIndex;j1.5*stringWidth){foundLongSegment=true;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,0,pt0,pt1,new Boolean(true));}} -if(foundLongSegment===false){if(middleSegment!==startIndex) -armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment,middleSegment+1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment2,middleSegment2+1,new Boolean(true));}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"areasWithENY",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside areasWithENY",exc));}else{throw exc;}} -return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment=function(tg,clipBounds){var middleSegment=-1;try{var pt0=null;var pt1=null;var j=0;middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;var foundVisibleSegment=new Boolean(false);if(clipBounds===null) -return middleSegment;for(j=middleSegment;j0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);if(clipBounds.containsPt2(pt0.x,pt0.y)||clipBounds.containsPt2(pt1.x,pt1.y)){middleSegment=j-1;foundVisibleSegment=new Boolean(true);break;}}} -if(foundVisibleSegment.booleanValue()===false) -middleSegment=Math.floor(tg.Pixels.size()/2)-1;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMiddleSegment",exc));}else{throw exc;}} -return middleSegment;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getvisibleMiddleSegment2=function(tg,clipBounds){var middleSegment=-1;try{var clipBoundsPoly=new armyc2.c2sd.graphics2d.Polygon();var pt0=null;var pt1=null;var j=0;var x=0;var y=0;middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;var foundVisibleSegment=new Boolean(false);if(clipBounds===null) -return middleSegment;for(j=0;j0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);if(clipBoundsPoly.contains(pt0.x,pt0.y)||clipBoundsPoly.contains(pt1.x,pt1.y)){middleSegment=j-1;foundVisibleSegment=new Boolean(true);break;}}} -if(foundVisibleSegment.booleanValue()===false) -middleSegment=Math.floor(tg.Pixels.size()/2)-1;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMiddleSegment",exc));}else{throw exc;}} -return middleSegment;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.removeModifier=function(tg,modifierType){try{var j=0;var modifier=null;for(j=0;j=0) -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt0,pt0,3,Math.abs((lineFactor)*stringHeight));else -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt0,pt0,2,Math.abs((lineFactor)*stringHeight));if(lineFactor>=0) -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt1,pt1,3,Math.abs((lineFactor)*stringHeight));else -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt1,pt1,2,Math.abs((lineFactor)*stringHeight));x1=pt2.x;y1=pt2.y;x2=pt3.x;y2=pt3.y;if(mbrPoly.contains(x1,y1)&&mbrPoly.contains(x2,y2)) -modifier.fitsMBR=true;else -modifier.fitsMBR=false;}else -modifier.fitsMBR=true;} -for(j=0;j0){factor=10/tg.get_Font().getSize();}else -return;var lastIndex=tg.Pixels.size()-1;var nextToLastIndex=tg.Pixels.size()-2;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var pt1=null;var pt2=null;var pt3=null;var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex));var ptNextToLast=null;if(lastIndex>0) -ptNextToLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex-1));if(tg.Pixels.size()>1) -pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(1));armyc2.c2sd.JavaTacticalRenderer.Modifier2.shiftModifierPath(tg,pt0,pt1,ptLast,ptNextToLast);var label=armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetCenterLabel(tg);var pts=tg.Pixels.toArray();var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble2(pts,pts.length);var middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;if(clipRect!==null) -middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment(tg,clipRect);else if(clipArray!==null) -middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment2(tg,clipArray);var affiliation=tg.get_Affiliation();if(tg.Pixels.size()>2){pt2=tg.Pixels.get(2);} -if(tg.Pixels.size()>3){pt3=tg.Pixels.get(3);} -var TLineFactor=0;var T1LineFactor=0;var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ll=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var index=0;var nextIndex=0;var size=tg.Pixels.size();switch(linetype){case 15000000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),1,T1LineFactor,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),1,T1LineFactor,ptLast,ptNextToLast,new Boolean(false));break;case 15000001:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));break;case 22131001:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(true));break;case 2237000:if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_N(),2,0,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_N(),2,0,Math.floor(lastIndex/2),Math.floor(lastIndex/2)+1,new Boolean(true));} -if(tg.Pixels.size()===3) -{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,1,2,new Boolean(true));} -else -{if(lastIndex>3) -armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,Math.floor(lastIndex/2)-1,Math.floor(lastIndex/2),new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,Math.floor(lastIndex/2)+1,Math.floor(lastIndex/2)+2,new Boolean(true));} -break;case 24313000:y=pt0.y;index=0;for(j=1;j0){if(tg.Pixels.get(index-1).ystringWidth) -stringWidth=stringWidth2;foundSegment=false;for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,j,j+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,j,j+1,new Boolean(true));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,0.7*csFactor,j,j+1,new Boolean(true));} -foundSegment=true;}} -if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(true));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,0.7*csFactor,middleSegment,middleSegment+1,new Boolean(true));}} -break;case 25223000:stringWidth=Math.floor((1.5*metrics.stringWidth(label+tg.get_Name())));foundSegment=false;for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3*factor*csFactor,j,j+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));} -foundSegment=true;}} -if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}} -break;case 25225000:stringWidth=Math.floor((1.5*metrics.stringWidth(label+tg.get_Name())));foundSegment=false;for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-4.5*factor*csFactor,j,j+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));} -foundSegment=true;}} -if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-4.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}} -break;case 25310000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"DETAINEE",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 25320000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"EPW",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 23180000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 25330000:case 25351000:case 25352000:case 25353000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 31770000:case 31740000:case 317100000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,tg.get_H(),3,-0.5,ptCenter,ptCenter,"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,tg.get_H1(),3,0.5,ptCenter,ptCenter,"H1");break;case 25340000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"REFUGEE",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 25221000:case 25222000:foundSegment=false;for(j=0;jtg.Pixels.get(0).y){pt0=tg.Pixels.get(1);pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(0);pt3=tg.Pixels.get(2);}else{pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(2);pt2=tg.Pixels.get(1);pt3=tg.Pixels.get(3);} -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt0,pt2,-20);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt1,pt3,-20);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,0,pt2,pt3,new Boolean(false));break;case 23162000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_H(),2,-1.5*factor*csFactor,ul,ur,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),2,1.5*factor*csFactor,ll,lr,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22622000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,1.35*factor*csFactor,ll,lr,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",2,1.1*(factor*csFactor+csFactor),ll,lr,new Boolean(false));break;case 25211000:case 25212000:var convoyBlankString=armyc2.c2sd.JavaTacticalRenderer.Modifier2.blankString(metrics,35);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H()+convoyBlankString+tg.get_H1(),2,0,0,1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,1.2*csFactor,0,1,new Boolean(false));break;case 22522100:if(affiliation!==null&&affiliation.equals("H")){k=tg.Pixels.size();j=armyc2.c2sd.JavaLineArray.lineutility.GetDirAtkAirMiddleSegment(tg.Pixels.toArray(new Array(tg.Pixels.size())),tg.Pixels.size());pt1=tg.Pixels.get(k-j-1);pt0=tg.Pixels.get(k-j);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,2*dist/3);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_N(),2,0,pt0,pt1,true);} -break;case 22535000:case 22432000:case 22621000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));break;case 24322100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-3*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-2*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),3,-1*csFactor,ptCenter,ptCenter,new Boolean(false),"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),3,0,ptCenter,ptCenter,new Boolean(false),"H1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"Grids: "+tg.get_H2(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"H2");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"EFF: "+tg.get_DTG(),3,2*csFactor,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,3*csFactor,ptCenter,ptCenter,new Boolean(false),"W1");break;case 24323100:case 24325100:case 24351000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");break;case 24361000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_H1(),3,2*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 24324100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(true),"W+W1");break;case 24321100:case 24331100:case 24332100:case 24336100:case 24338100:case 24339100:case 24337100:case 24335100:case 24333100:case 24334100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);var ptLeft=ul;var ptRight=ur;if(tg.get_Client().equalsIgnoreCase("ge")){ptLeft.x-=Math.floor(font.getSize()/2);ptRight.x-=Math.floor(font.getSize()/2);} -armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),1,0.5*csFactor,ptLeft,ptRight,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),1,1.5*csFactor,ptLeft,ptRight,new Boolean(false),"W1");break;case 24314000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");break;case 22431000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_EchelonSymbol(),2,-0.2*csFactor,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22431100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_EchelonSymbol(),2,-0.2*csFactor,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22422000:pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,-22,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));break;case 22421000:stringWidth=metrics.stringWidth(label);pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pt1.x-=stringWidth+8;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptLast);pt1.x+=40;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));break;case 22625000:case 22626000:case 22532000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 22531000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"ASLT",3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"PSN",3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 22235000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME FROM: "+tg.get_DTG(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(true),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME TO: "+tg.get_DTG1(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(true),"W1");break;case 23114000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false),"W1");break;case 23115000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-1*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),3,0,ptCenter,ptCenter,new Boolean(true),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(true),"W1");break;case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-2.5,ptCenter,ptCenter,new Boolean(false),"");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-1.5,ptCenter,ptCenter,new Boolean(false),"T");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),3,-0.5,ptCenter,ptCenter,new Boolean(false),"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),3,0.5,ptCenter,ptCenter,new Boolean(false),"H1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME FROM: "+tg.get_DTG(),3,1.5,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME TO: "+tg.get_DTG1(),3,2.5,ptCenter,ptCenter,new Boolean(false),"W1");break;case 22223000:if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"SAAFR "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-4*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-5*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-6*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-7*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),2,-3*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),2,-2*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-2*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-3*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-4*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-5*csFactor,middleSegment,middleSegment+1,new Boolean(false));} -break;case 22221000:if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-4*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-5*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-6*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-7*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),2,-3*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),2,-2*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,-0.5*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_T1(),2,0.5*csFactor,middleSegment,middleSegment+1,new Boolean(false));} -break;case 22222001:case 22224001:case 22222000:case 22224000:case 22225000:if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-4*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-5*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-6*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-7*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),2,-3*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),2,-2*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,-0.5,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,0.5,middleSegment,middleSegment+1,new Boolean(false));} -break;case 221311000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22131000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));break;case 22134000:case 22624000:if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_N(),2,0,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_N(),2,0,middleSegment,middleSegment+1,new Boolean(true));} -break;case 22132000:case 22133000:case 22135000:case 22136000:case 22137000:case 22138000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 22121000:if(clipRect!==null) -{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddBoundaryModifiers(tg,g2d,clipRect);} -else if(clipArray!==null) -{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddBoundaryModifiers2(tg,g2d,clipArray);} -else -{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddBoundaryModifiers(tg,g2d,null);} -break;case 22340000:case 22350000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);if(affiliation!==null&&affiliation.equals("H")){pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,new Boolean(true));if(middleSegment!==0){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,new Boolean(true));}} -break;case 23164000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);if(affiliation!==null&&affiliation.equals("H")){pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,new Boolean(true));if(middleSegment!==0){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,new Boolean(true));}} -break;case 22124000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),1,T1LineFactor,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),1,T1LineFactor,ptLast,ptNextToLast,new Boolean(false));break;case 22525000:case 22526000:case 22613000:case 22527000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,ptLast,ptNextToLast,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));break;case 22125000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));break;case 22523000:case 22528000:if(usas===false){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,ptLast,ptNextToLast,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));}else -armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddNameAboveDTG(tg,metrics);break;case 24230000:if(usas===false){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"(PL "+tg.get_Name()+")",1,1*csFactor,ptLast,ptNextToLast,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddNameAboveDTG(tg,metrics);} -break;case 24210000:pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);pt2=tg.Pixels.get(tg.Pixels.size()-1);pt3=tg.Pixels.get(tg.Pixels.size()-2);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt2,pt3);stringWidth=Math.floor((metrics.stringWidth(tg.get_Name()+" "+label)));stringWidth2=Math.floor((metrics.stringWidth(tg.get_DTG())));if(stringWidth2>stringWidth) -stringWidth=stringWidth2;if(tg.Pixels.size()===2){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);if(dist>2*stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}}else{var dist3=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);} -if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}} -break;case 24220000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-0.7*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,0.7*csFactor,middleSegment,middleSegment+1,new Boolean(false));break;case 24240000:pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);pt2=tg.Pixels.get(tg.Pixels.size()-1);pt3=tg.Pixels.get(tg.Pixels.size()-2);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt2,pt3);stringWidth=Math.floor((metrics.stringWidth(label+" "+tg.get_Name())));stringWidth2=Math.floor((metrics.stringWidth(tg.get_DTG())));if(stringWidth2>stringWidth) -stringWidth=stringWidth2;if(tg.Pixels.size()===2){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);if(dist>2*stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}}else{dist3=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);} -if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}} -break;case 22122000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),1,-1*csFactor,pt0,pt1,new Boolean(false));} -armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),1,-1*csFactor,ptLast,ptNextToLast,new Boolean(false));} -break;case 22123000:var shiftFactor=1;if(shiftLines) -shiftFactor=0.5;if(affiliation!==null&&affiliation.equals("H")){if(pt0.x1) -nextToLastIndex=tg.Pixels.size()-2;var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex));var ptNextToLast=null;if(tg.Pixels.size()>1) -ptNextToLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(nextToLastIndex));var dash="";if(tg.get_DTG()!==null&&tg.get_DTG1()!==null&&tg.get_DTG().isEmpty()===false&&tg.get_DTG1().isEmpty()===false) -dash=" - ";var ptLeft=null;var ptRight=null;var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();var metrics=g2d.getFontMetrics();var stringWidth=0;var rfaLines=0;var pts=null;pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));if(tg.Pixels.size()>1) -pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(1));if(tg.get_Client().equals("cpof3d")) -csFactor=0.9;armyc2.c2sd.JavaTacticalRenderer.Modifier2.shiftModifierPath(tg,pt0,pt1,ptLast,ptNextToLast);if(tg.getSymbologyStandard()===1){switch(linetype){case 14000000:case 15000003:pts=new Array(4);for(j=0;j<4;j++) -pts[j]=tg.Pixels.get(j);ptCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble2(pts,4);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.125*csFactor,ptCenter,ptCenter,false);break;case 21200000:case 21300000:case 21400000:pt0=tg.Pixels.get(1);pt1=tg.Pixels.get(2);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211700000:case 21500000:pt0=tg.Pixels.get(2);pt1=tg.Pixels.get(3);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211000000:pt0=tg.Pixels.get(4);pt1=tg.Pixels.get(5);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211100000:pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211400000:case 211600000:case 211900000:case 212100000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(14);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 21600000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(14);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"C",2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 212300000:case 212300001:pt0=tg.Pixels.get(26);pt1=tg.Pixels.get(27);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;default:break;}} -switch(linetype){case 212600000:case 212500000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(0);stringWidth=metrics.stringWidth(label);if(pt0.xj*102+25){pt0=tg.Pixels.get(j*102+25);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"ALT "+H1[j],3,0,pt0,pt0);}}} -break;case 243112000:if(tg.get_H1()!==null&&tg.get_H1().equals("")===false){H1=tg.get_H1().$plit(",");for(j=0;jj*203+151){pt0=tg.Pixels.get(j*203+151);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"ALT "+H1[j],3,0,pt0,pt0);}}} -break;default:return;} -g2d.dispose();g2d=null;} -catch(exc) -{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifiers2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifiers2",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers=function(tg,g2d){try{var id=new armyc2.c2sd.graphics2d.AffineTransform();id.setToIdentity();g2d.setTransform(id);var font=g2d.getFont();var j=0;var modifier=null;g2d.setBackground(armyc2.c2sd.renderer.utilities.Color.white);var pt=null;var theta=0;var stringWidth=0;var stringHeight=0;var metrics=g2d.getFontMetrics();var s="";var x=0;var y=0;var pt1=null;var pt2=null;var quadrant=-1;for(j=0;jx2){theta-=3.141592653589793;} -switch(modifier.type){case 1:g2d.rotate(theta,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();if(x1y2)){x=Math.floor(x1)-stringWidth;y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);}else{x=Math.floor(x1);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);} -break;case 2:midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2((x1+x2)/2,(y1+y2)/2);g2d.rotate(theta,midPt.x,midPt.y);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(midPt.x)-Math.floor(stringWidth/2);y=Math.floor(midPt.y)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(midPt.y)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);break;case 3:g2d.rotate(0,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(x1)-Math.floor(stringWidth/2);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);break;case 4:if(tg.Pixels.size()>=14){pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(10);quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(pt1,pt2);theta=Math.atan2(pt2.y-pt1.y,pt2.x-pt1.x);switch(quadrant){case 1:theta+=1.5707963267948966;break;case 2:theta-=1.5707963267948966;break;case 3:theta-=1.5707963267948966;break;case 4:theta+=1.5707963267948966;break;default:break;} -g2d.rotate(theta,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(x1)-Math.floor(stringWidth/2);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);}else{stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(tg.Pixels.get(0).x);y=Math.floor(tg.Pixels.get(0).y);g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=y+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);} -break;default:break;} -g2d.setTransform(id);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"DisplayModifiers",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DisplayModifiers",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.BuildModifierShape=function(tg,pt0,pt1,stringWidth,stringHeight,lineFactor,isTextFlipped){var modifierFill=null;try{var ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);var ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);if(isTextFlipped===true) -lineFactor+=1;if(lineFactor<0){ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,2,-lineFactor*stringHeight);ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,2,-lineFactor*stringHeight);} -if(lineFactor>0){ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,3,lineFactor*stringHeight);ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,3,lineFactor*stringHeight);} -if(ptTemp0.y===ptTemp1.y){ptTemp0.y+=1;} -var pt3=null;var pt4=null;var pt5=null;var pt6=null;var pt7=null;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(ptTemp0,ptTemp1,-stringWidth);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,pt3,0,Math.floor(stringHeight/2));pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,pt3,1,Math.floor(stringHeight/2));pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,ptTemp0,1,Math.floor(stringHeight/2));pt7=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,ptTemp0,0,Math.floor(stringHeight/2));modifierFill=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);modifierFill.moveTo(pt4);modifierFill.lineTo(pt5);modifierFill.lineTo(pt6);modifierFill.lineTo(pt7);modifierFill.lineTo(pt4);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"BuildModifierShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BuildModifierShape",exc));}else{throw exc;}} -return modifierFill;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetIntegralTextShapes=function(tg,g2d,shapes){try{if(tg.Pixels===null||shapes===null) -return;var hmap=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getMSRSegmentColors(tg);var color=null;var shape=null;var segShape=null;g2d.setFont(tg.get_Font());var j=0;var affiliation=null;var metrics=g2d.getFontMetrics();var echelonSymbol=null;var stringWidthEchelonSymbol=0;var stringWidthENY=0;var lineTooShort=false;var ptEchelonStart=null;var ptEchelonEnd=null;var midpt;var ptENY0Start=null;var ptENY0End=null;var ptENY1Start;var ptENY1End;var pt0=null;var pt1=null;var dist=0;var stroke=null;switch(tg.get_LineType()){case 22121000:echelonSymbol=tg.get_EchelonSymbol();shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setLineColor(tg.get_LineColor());shape.set_Style(tg.get_LineStyle());affiliation=tg.get_Affiliation();stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke(tg.get_LineThickness(),shape.get_Style(),1,1);shape.setStroke(stroke);if(tg.get_Affiliation()!==null&&tg.get_Affiliation().equals("H")){stringWidthENY=metrics.stringWidth(tg.get_N());} -if(echelonSymbol!==null&&!echelonSymbol.isEmpty()) -stringWidthEchelonSymbol=metrics.stringWidth(echelonSymbol);for(j=0;j0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,midpt,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,midpt,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)-stringWidthENY/1.5;ptENY0Start=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)+stringWidthENY/1.5;ptENY0End=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);if(segShape!==null){segShape.moveTo(pt0);segShape.lineTo(ptENY0Start);segShape.moveTo(ptENY0End);}else{shape.moveTo(pt0);shape.lineTo(ptENY0Start);shape.moveTo(ptENY0End);}}else{if(segShape!==null) -segShape.moveTo(pt0);else -shape.moveTo(pt0);} -if(stringWidthEchelonSymbol>0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)-stringWidthEchelonSymbol/1.5;ptEchelonStart=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)+stringWidthEchelonSymbol/1.5;ptEchelonEnd=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);if(segShape!==null){segShape.lineTo(ptEchelonStart);segShape.moveTo(ptEchelonEnd);}else{shape.lineTo(ptEchelonStart);shape.moveTo(ptEchelonEnd);}} -if(stringWidthENY>0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,midpt,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,midpt,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,midpt)-stringWidthENY/1.5;ptENY1Start=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,midpt)+stringWidthENY/1.5;ptENY1End=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,dist);if(segShape!==null){segShape.lineTo(ptENY1End);segShape.moveTo(ptENY1Start);segShape.lineTo(pt1);}else{shape.lineTo(ptENY1End);shape.moveTo(ptENY1Start);shape.lineTo(pt1);}}else{if(segShape!==null) -segShape.lineTo(pt1);else -shape.lineTo(pt1);} -if(segShape!==null) -shapes.add(segShape);} -shapes.add(shape);break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"GetIntegralTextShapes",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetIntegralTextShapes",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.switchDirection=function(direction){var result=-1;switch(direction){case 0:return 1;case 1:return 0;case 2:return 3;case 3:return 2;} -return result;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2=function(tg,g2d,shapes,isTextFlipped,converter){try{if(shapes===null) -return;if(tg.modifiers===null||tg.modifiers.isEmpty()) -return;var font=null;var j=0;var modifier=null;var fontBackColor=tg.get_FontBackColor();var textColor=tg.get_TextColor();var theta=0;var stringWidth=0;var stringHeight=0;var s="";var x=0;var y=0;var pt0=null;var pt1=null;var pt2=null;var pt3=null;var quadrant=-1;var shape2=null;font=tg.get_Font();if(font===null){font=g2d.getFont();} -g2d.setFont(font);var metrics=g2d.getFontMetrics();if(fontBackColor!==null){g2d.setBackground(fontBackColor);}else{g2d.setBackground(armyc2.c2sd.renderer.utilities.Color.white);} -if(textColor===null) -textColor=tg.get_LineColor();var direction=-1;var glyphPosition=null;for(j=0;jx2){theta-=3.141592653589793;} -pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x1,y1);pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x2,y2);midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2((x1+x2)/2,(y1+y2)/2);switch(modifier.type){case 1:dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);direction=2;if(lineFactor>=0) -direction=2;else -direction=3;if(tg.get_LineType()===22123000||tg.get_Client().equalsIgnoreCase("ge")){direction=armyc2.c2sd.JavaTacticalRenderer.Modifier2.switchDirection(direction);} -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt0,pt1,direction,lineFactor*stringHeight);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt0,pt0,direction,lineFactor*stringHeight);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt3,pt2,-stringWidth/1.5);glyphPosition=new armyc2.c2sd.graphics2d.Point(pt3.x,pt3.y);break;case 2:if(converter!==null){var pt1Geo=converter.PixelsToGeo(new armyc2.c2sd.graphics2d.Point(Math.floor(pt0.x),Math.floor(pt0.y)));var pt2Geo=converter.PixelsToGeo(new armyc2.c2sd.graphics2d.Point(Math.floor(pt1.x),Math.floor(pt1.y)));var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();a12.value=Clazz.newArray(1,0);a21.value=Clazz.newArray(1,0);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo.x,pt1Geo.y),armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2Geo.x,pt2Geo.y),a12,a21);var midPtGeo=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo.x,pt1Geo.y),dist/2,a12.value[0]);var pt2d=new armyc2.c2sd.graphics2d.Point2D(midPtGeo.x,midPtGeo.y);var midPt2D=converter.GeoToPixels(pt2d);midPt.x=midPt2D.getX();midPt.y=midPt2D.getY();} -x=Math.floor(midPt.x)-Math.floor(Math.floor(stringWidth)/2);y=Math.floor(midPt.y)+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));if(pt0.x<=pt1.x) -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(midPt,pt0,0.5*stringWidth);else -pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(midPt,pt1,0.5*stringWidth);if(tg.get_Client().equals("2D")) -lineFactor+=0.5;if(lineFactor>=0) -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,3,Math.abs((lineFactor)*stringHeight));else -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,2,Math.abs((lineFactor)*stringHeight));if(x1===x2&&y1>y2) -pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,1,Math.abs((lineFactor)*stringHeight));if(x1===x2&&y1=14){pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(10);quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(pt1,pt2);theta=Math.atan2(pt2.y-pt1.y,pt2.x-pt1.x);if(Math.abs(theta)<0.39269908169872414){if(theta<0){theta-=1.5707963267948966;} -else{theta+=1.5707963267948966;}} -switch(quadrant){case 1:theta+=1.5707963267948966;break;case 2:theta-=1.5707963267948966;break;case 3:theta-=1.5707963267948966;break;case 4:theta+=1.5707963267948966;break;default:break;} -x=Math.floor(x1)-Math.floor(Math.floor(stringWidth)/2);y=Math.floor(y1)-Math.floor(Math.floor(stringHeight)/2)+Math.floor((lineFactor*stringHeight));y=Math.floor(y1)+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));}else{theta=0;x=Math.floor(tg.Pixels.get(0).x);y=Math.floor(tg.Pixels.get(0).y);x=x-Math.floor(Math.floor(stringWidth)/2);y=y-Math.floor(Math.floor(stringHeight)/2)+Math.floor((lineFactor*stringHeight));y=y+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));} -glyphPosition=new armyc2.c2sd.graphics2d.Point(x,y);break;default:break;} -shape2=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);shape2.setStroke(new armyc2.c2sd.graphics2d.BasicStroke(0,1,1,3));if(tg.get_TextColor()!==null){shape2.setFillColor(tg.get_TextColor());}else if(tg.get_LineColor()!==null){shape2.setFillColor(tg.get_LineColor());} -if(tg.get_LineColor()!==null){shape2.setLineColor(tg.get_LineColor());} -var tl=new armyc2.c2sd.graphics2d.TextLayout(s,font,g2d.getFontMetrics().getFontRenderContext());shape2.setTextLayout(tl);if(converter!==null) -shape2.setGlyphPosition(glyphPosition);else -shape2.setGlyphPosition(new armyc2.c2sd.graphics2d.Point2D(0,0));shape2.setModifierString(s);shape2.setModifierStringAngle(theta*180/3.141592653589793);if(shape2!==null){shapes.add(shape2);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"DisplayModifiers2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DisplayModifiers2",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getTextShape=function(g2d,str,font,tx){var tl=null;var frc=null;try{frc=g2d.getFontRenderContext();tl=new armyc2.c2sd.graphics2d.TextLayout(str,font,frc);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getTextShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getTextShape",exc));}else{throw exc;}} -return tl.getOutline(tx);};armyc2.c2sd.JavaTacticalRenderer.Modifier2.createTextOutline=function(originalText){var siOutline=null;try{var outline=originalText.getShape();siOutline=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);siOutline.setShape(outline);if(originalText.getFillColor().getRed()===255&&originalText.getFillColor().getGreen()===255&&originalText.getFillColor().getBlue()===255) -siOutline.setLineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);else -siOutline.setLineColor(armyc2.c2sd.renderer.utilities.Color.WHITE);var width=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTextOutlineWidth();siOutline.setStroke(new armyc2.c2sd.graphics2d.BasicStroke(width,1,1,3));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"createTextOutline",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createTextOutline",exc));}else{throw exc;}} -return siOutline;};armyc2.c2sd.JavaTacticalRenderer.Modifier2._className="Modifier2";armyc2.c2sd.JavaTacticalRenderer.Modifier2.toEnd=1;armyc2.c2sd.JavaTacticalRenderer.Modifier2.aboveMiddle=2;armyc2.c2sd.JavaTacticalRenderer.Modifier2.area=3;armyc2.c2sd.JavaTacticalRenderer.Modifier2.screen=4;armyc2.c2sd.JavaTacticalRenderer.Modifier2.fillAlphaCanObscureText=50;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.P1=function(){this.start=0;this.end_Renamed=0;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.TGLight=function(){this.LatLongs=null;this.Pixels=null;this.modifiers=null;this.tp=null;this.maskOff=false;this.font=null;this.lineType=0;this.lineStyle=0;this.lineColor=null;this.fillStyle=0;this.fillColor=null;this.fontBackColor=null;this.textColor=null;this.lineThickness=0;this.t="";this.client="";this.t1="";this.h="";this.h1="";this.y="";this.n="ENY";this.h2="";this.w="";this.w1="";this.affiliation=null;this.echelon=null;this.echelonSymbol="";this.symbolId=null;this.status=null;this.visibleModifiers=false;this.visibleLabels=false;this._SymbologyStandard=0;this._useLineInterpolation=false;this.fontBackColor=armyc2.c2sd.renderer.utilities.Color.WHITE;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LatLongs=function(){return this.LatLongs;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LatLongs=function(value){this.LatLongs=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Pixels=function(){return this.Pixels;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Pixels=function(value){this.Pixels=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Modifiers=function(){return this.modifiers;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Modifiers=function(value){this.modifiers=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_TexturePaint=function(value){this.tp=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_TexturePaint=function(){return this.tp;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Font=function(value){this.font=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Font=function(){return this.font;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineType=function(value){this.lineType=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineType=function(){return this.lineType;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineStyle=function(value){this.lineStyle=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineStyle=function(){return this.lineStyle;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineColor=function(){return this.lineColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineColor=function(value){this.lineColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FillStyle=function(){return this.fillStyle;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Fillstyle=function(value){this.fillStyle=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FillColor=function(){return this.fillColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_FillColor=function(value){this.fillColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FontBackColor=function(){return this.fontBackColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_FontBackColor=function(value){this.fontBackColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_TextColor=function(){return this.textColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_TextColor=function(value){this.textColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineThickness=function(){return this.lineThickness;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineThickness=function(value){this.lineThickness=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Name=function(){if(this.visibleModifiers) -return this.t;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Client=function(){return this.client;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_client=function(value){this.client=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Name=function(value){this.t=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_T1=function(){if(this.visibleModifiers) -return this.t1;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_T1=function(value){this.t1=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H=function(){if(this.visibleModifiers||this.lineType===24311000) -return this.h;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H=function(value){this.h=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Location=function(){if(this.visibleModifiers) -return this.y;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Location=function(value){this.y=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H1=function(){if(this.visibleModifiers) -return this.h1;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H1=function(value){this.h1=value.toString();};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_N=function(){return this.n;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_N=function(value){this.n=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H2=function(){if(this.visibleModifiers||this.lineType===24311000) -return this.h2;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H2=function(value){this.h2=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_DTG=function(){if(this.visibleModifiers) -return this.w;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_DTG=function(value){this.w=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_DTG1=function(){if(this.visibleModifiers) -return this.w1;else -return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_DTG1=function(value){this.w1=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Affiliation=function(){return this.affiliation;};this.set_Affiliation=function(value){this.affiliation=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Echelon=function(){return this.echelon;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Echelon=function(value){this.echelon=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_EchelonSymbol=function(){return this.echelonSymbol;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_EcheclonSymbol=function(value){this.echelonSymbol=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_SymbolId=function(){return this.symbolId;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Status=function(){return this.status;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Status=function(value){this.status=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_SymbolId=function(value){try{this.symbolId=value;var letter;if(this.symbolId.length===15){this.status=this.symbolId.substring(3,4);if(this.status.equals("A")&&!value.equalsIgnoreCase("BS_AREA--------")){this.lineStyle=1;} -this.affiliation=this.symbolId.substring(1,2);this.echelon=this.symbolId.substring(11,12);if(this.echelon.equals("M")) -this.echelonSymbol="XXXXXX";else if(this.echelon.equals("L")) -this.echelonSymbol="XXXXX";else if(this.echelon.equals("K")) -this.echelonSymbol="XXXX";else if(this.echelon.equals("J")) -this.echelonSymbol="XXX";else if(this.echelon.equals("I")) -this.echelonSymbol="XX";else if(this.echelon.equals("H")) -this.echelonSymbol="X";else if(this.echelon.equals("G")) -this.echelonSymbol="III";else if(this.echelon.equals("F")) -this.echelonSymbol="II";else if(this.echelon.equals("E")) -this.echelonSymbol="I";else if(this.echelon.equals("D")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter)+(letter)+(letter);}else if(this.echelon.equals("C")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter)+(letter);}else if(this.echelon.equals("B")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter);}else if(this.echelon.equals("A")){letter=String.fromCharCode(216);this.echelonSymbol=(letter);}}} -catch(exc) -{if(Clazz.instanceOf(exc)) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.TGLight._className,"set_SymbolId",exc);} -else -{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_VisibleModifiers=function(value){this.visibleModifiers=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_VisibleModifiers=function(){return this.visibleModifiers;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_VisibleLabels=function(value){this.visibleLabels=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_VisibleLabels=function(){return this.visibleLabels;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.setSymbologyStandard=function(standard){this._SymbologyStandard=standard;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.getSymbologyStandard=function(){return this._SymbologyStandard;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_UseLineInterpolation=function(){return this._useLineInterpolation;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_UseLineInterpolation=function(value){this._useLineInterpolation=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight._className="TGLight";var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility={GetPartitions:function(segments,partitions){try{var j=0;var nextSegment=false;var p1=new armyc2.c2sd.JavaTacticalRenderer.P1();if(segments[0]===false){return 0;} -if(partitions!==null){partitions.clear();}else{return 0;} -p1.start=0;for(j=0;j0){returnValue=channelPixels.length;}else{returnValue=0;} -if(lineCount>0){channelPixels[lineCount-1]=5;} -goodUpperPixels=null;goodLowerPixels=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility._className,"DrawGoodChannel2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DrawGoodChannel2",exc));}else{throw exc;}} -return returnValue;},DrawSegments:function(pixels,partitions,linetype,channelWidth,shapes,channelPoints,distanceToChannelPoint,rev){try{var j=0;var n=0;for(j=0;j=x){dx=splinePoints.get(j+1).x-splinePoints.get(j).x;dy=splinePoints.get(j+1).y-splinePoints.get(j).y;m=dy/dx;y=splinePoints.get(j).y+(x-splinePoints.get(j).x)*m;pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);return pt2;} -if(splinePoints.get(j).x>=x&&splinePoints.get(j+1).x<=x){dx=splinePoints.get(j+1).x-splinePoints.get(j).x;dy=splinePoints.get(j+1).y-splinePoints.get(j).y;m=dy/dx;y=splinePoints.get(j).y+(x-splinePoints.get(j).x)*m;pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);return pt2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"ExtrapolatePointFromCurve",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtrapolatePointfromCurve",exc));}else{throw exc;}} -return pt2;},GetMeTOCShape:function(tg,shapes,rev){try{if(shapes===null) -return;var lineObject=null;var lineObject2=null;var splinePoints=new java.util.ArrayList();var splinePoints2=new java.util.ArrayList();var d=0;var j=0;var k=0;var l=0;var shape=null;var ptLast=tg.Pixels.get(tg.Pixels.size()-1);var twoSplines=null;var upperSpline=null;var lowerSpline=null;var originalPixels=null;var pixels=null;originalPixels=null;var partitions=null;armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetMeTOCProperties(tg);switch(tg.get_LineType()){case 31134000:case 31134100:case 31134200:case 31134300:case 31132300:case 31132200:case 31132000:case 31132100:case 31131100:case 31131000:case 31131200:case 31131300:case 31133000:case 31133100:case 31133200:case 31141000:case 31144000:case 31145000:case 31142000:case 31143000:case 31146000:case 31147000:case 31148000:case 31710000:case 31720000:case 31730000:case 31740000:case 31750000:case 31751000:case 31760000:case 31770000:case 31780000:case 31790000:case 317100000:case 31870000:case 32151000:case 32152000:case 32153000:case 32214000:case 32222000:case 32223000:case 32224000:case 32232400:case 32540000:case 32670000:case 32254200:case 32255200:case 32323000:case 32324000:case 32231500:case 32231400:case 32680000:case 32550000:case 32530000:case 322510000:case 32134000:case 32225200:case 32225100:case 32233100:case 32233400:case 32233500:case 32244200:case 32253000:case 32259000:case 322512000:case 32321000:case 32322000:case 32510000:case 32520000:case 32560000:case 32620000:case 32630000:case 32311000:case 32312000:case 32313000:case 32314000:case 32315000:case 32316000:case 32317000:case 32318000:case 32319000:case 32411100:case 32411200:case 32411300:case 32411400:case 32411500:case 32411600:case 32411700:case 32411800:case 32411900:case 324111000:case 324111100:case 324111200:case 324111300:case 324111400:case 324111500:case 324111600:case 324111700:case 32412100:case 32412200:case 32412300:case 32413100:case 32413200:case 32413300:case 32414100:case 32414200:case 32414300:case 32414400:case 32414500:case 32415100:case 32415200:case 32415300:case 32416100:case 32416200:case 32416300:case 32416400:case 32416500:case 32416600:case 32416700:case 32416800:case 32416900:armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(tg.get_LineType(),tg.Pixels,shapes,null,rev);break;case 31810000:case 31810001:case 31820000:case 31820001:case 31830000:case 31830001:case 31840000:case 31840001:case 31850000:case 31850001:case 31860000:case 31860001:case 32154000:case 32154001:case 32155000:case 32155001:case 32161000:case 32161001:case 32212000:case 32212001:case 32213000:case 32213001:case 32221000:case 32221001:case 32231700:case 32231701:case 32233600:case 32233601:case 32233700:case 32233701:case 32234100:case 32234101:case 32234200:case 32234201:case 32234300:case 32234301:case 32272000:case 32273000:case 32272001:case 32273001:case 32610000:case 32610001:case 31430000:case 31440000:case 31430001:case 31440001:lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);break;case 22612001:case 22623001:if(tg.get_FillColor()!==null&&tg.get_FillColor().getAlpha()>1){lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.setShape(lineObject2);shapes.add(shape);splinePoints.clear();} -lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetShapeProperties(tg,shapes,null);return;case 22612000:case 22623000:lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());if(tg.get_FillColor()!==null&&tg.get_FillColor().getAlpha()>1){if(splinePoints!==null&&splinePoints.size()>0){shape.moveTo(splinePoints.get(0));for(j=1;jj) -array2=splinePoints2Arrays.get(j);else -break;if(splinePointsArrays.size()>=splinePoints2Arrays.size()){for(k=0;kk) -pt=array.get(k);else -break;pt2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.ExtrapolatePointFromCurve(array2,pt);if(pt2!==null){lineObject.moveTo(pt.x,pt.y);lineObject.lineTo(pt2.x,pt2.y);}}}else{for(k=0;kj) -array2=splinePoints2Arrays.get(j);else -break;if(splinePointsArrays.size()>=splinePoints2Arrays.size()){for(k=0;kk) -pt=array.get(k);else -break;pt2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.ExtrapolatePointFromCurve(array2,pt);if(pt2!==null){lineObject.moveTo(pt.x,pt.y);lineObject.lineTo(pt2.x,pt2.y);}}}else{for(k=0;k0) -lineObject2.moveTo(splinePoints.get(0).x,splinePoints.get(0).y);else{lineObject2.moveTo(tg.Pixels.get(0).x,tg.Pixels.get(0).y);for(j=0;j=j-1) -lineObject2.lineTo(splinePoints.get(j).x,splinePoints.get(j).y);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);lineObject2=new armyc2.c2sd.graphics2d.GeneralPath();lineObject2.moveTo(splinePoints.get(n).x,splinePoints.get(n).y);for(j=n+1;j=j-1) -lineObject2.lineTo(splinePoints.get(j).x,splinePoints.get(j).y);} -shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shape.set_Style(1);shapes.add(shape);break;default:break;} -if(tg.get_LineType()!==32163000&&tg.get_LineType()!==32163001&&tg.get_LineType()!==32164000&&tg.get_LineType()!==32164001&&tg.get_LineType()!==32156000){if(splinePoints!==null&&splinePoints.size()>0){lineObject2=new armyc2.c2sd.graphics2d.GeneralPath();lineObject2.moveTo(splinePoints.get(splinePoints.size()-1).x,splinePoints.get(splinePoints.size()-1).y);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shape.set_Style(0);shapes.add(shape);}} -armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetShapeProperties(tg,shapes,null);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"GetMeTOCShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetMeTOCShape",exc));}else{throw exc;}}},GetImageFile:function(tg){var fileName="";try{switch(tg.get_LineType()){case 32232400:fileName="visualAssets/Weirs.png";break;case 32540000:fileName="visualAssets/SweptArea.png";break;case 32670000:fileName="visualAssets/OilRigField.png";break;case 32254200:fileName="visualAssets/FoulGround.png";break;case 32255200:fileName="visualAssets/Kelp.png";break;case 32324000:fileName="visualAssets/BeachSlopeSteep.png";break;case 32223000:fileName="visualAssets/BeigeStipple.png";break;case 32323000:fileName="visualAssets/BeachSlopeModerate.png";break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"GetImageFile",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetImageFile",exc));}else{throw exc;}} -return fileName;},SetShapeProperties:function(tg,shapes,bi){try{if(shapes===null){return;} -switch(tg.get_LineType()){case 32214000:return;default:break;} -var j=0;var shape=null;var stroke=null;var inFile=null;var bi2=null;var dash=null;var lineThickness=tg.get_LineThickness();var rect=null;var grid=null;var tp=tg.get_TexturePaint();var fileName=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetImageFile(tg);switch(tg.get_LineType()){case 32232400:case 32540000:case 32670000:case 32254200:case 32255200:case 32323000:case 32324000:case 32223000:shape=shapes.get(0);shape.setLineColor(tg.get_LineColor());if(inFile!==null){bi2=armyc2.c2sd.graphics2d.ImageIO.read(inFile);rect=new armyc2.c2sd.graphics2d.Rectangle2D(0,0,bi2.getWidth(),bi2.getHeight());tp=new armyc2.c2sd.graphics2d.TexturePaint(bi2,rect);shape.setTexturePaint(tp);inFile.close();} -break;case 31134000:case 31134100:case 31134200:case 31134300:for(j=0;j0) -tmpArray.get(tmpArray.size()-1).style=47;} -splinePoints2.addAll(tmpArray);splinePoints=tmpArray;switch(tg.get_LineType()){case 32272000:if(i===array.size()-2){if(splinePoints.size()>=2) -armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} -break;case 32273000:if(i===array.size()-2){if(splinePoints.size()>=2) -armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);}else if(i===0&&splinePoints.size()>1){pt0=splinePoints.get(0);pt1=splinePoints.get(1);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,20);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,30);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt3,pt2,pt2,3,10);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt4,pt3,pt3,3,10);lineObject.moveTo(pt3.x,pt3.y);lineObject.lineTo(pt5.x,pt5.y);lineObject.moveTo(pt4.x,pt4.y);lineObject.lineTo(pt6.x,pt6.y);} -break;case 31440000:case 31430000:if(i===0&&splinePoints.size()>1){armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(1),splinePoints.get(0),10,lineObject);} -break;case 32273001:if(i===array.size()-2){lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j=2) -armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);}else if(i===0&&splinePoints.size()>1){pt0=splinePoints.get(0);pt1=splinePoints.get(1);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,20);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,30);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt3,pt2,pt2,3,10);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt4,pt3,pt3,3,10);lineObject.moveTo(pt3.x,pt3.y);lineObject.lineTo(pt5.x,pt5.y);lineObject.moveTo(pt4.x,pt4.y);lineObject.lineTo(pt6.x,pt6.y);} -break;case 32272001:if(i===array.size()-2){lineObject=new armyc2.c2sd.graphics2d.GeneralPath();lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j=2) -armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} -break;case 31430001:case 31440001:if(i===0&&splinePoints.size()>1){armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(1),splinePoints.get(0),10,lineObject);} -if(i===array.size()-2){lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j0) -return;switch(tg.get_LineType()){case 22421000:shape.setFillColor(null);shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());break;case 24324100:case 24324300:case 24324200:case 24351000:case 24361000:case 24352000:case 24362000:case 24353000:case 24363000:case 23450000:case 23460000:case 23440000:case 22235000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(3);shape.setFillColor(tg.get_FillColor());} -break;case 23115000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(0);shape.setFillColor(tg.get_FillColor());} -break;case 221310000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(2);shape.setFillColor(tg.get_FillColor());} -break;case 23200001:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(1);shape.setFillColor(tg.get_LineColor());} -if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());} -break;case 22522100:case 23131200:case 23132000:case 22139000:case 211210000:case 23223000:case 23172000:case 23173000:case 23174000:case 23211000:case 23212000:case 23213000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(1);shape.setFillColor(tg.get_LineColor());} -if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());} -break;case 22310000:case 23157000:case 21700000:case 21710000:case 22528000:case 23191000:case 24220000:case 23224000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());} -break;case 22431100:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());shape.setFillColor(tg.get_FillColor());shape.set_Fillstyle(tg.get_FillStyle());} -break;case 22340000:case 22350000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==1){shape.set_Style(lineStyle);}}} -break;case 2237000:case 22330000:case 211200000:case 23192000:case 23225000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==1){shape.set_Style(lineStyle);}}} -break;case 22320000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==2){shape.set_Style(lineStyle);}}} -break;default:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());} -if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){if(lineType!==22123000){shape.setLineColor(tg.get_LineColor());} -shape.set_Style(lineStyle);if(hasFill||armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType)||armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,null)){if(lineType!==243111000&&lineType!==243112000&&lineType!==15000001){shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());}} -switch(lineType){case 13000000:case 14000000:shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());break;case 15000003:shape.setFillColor(null);break;default:break;}} -break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"ResolveModifierShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ResolveModifierShape",exc));}else{throw exc;}} -return;},GetOpaqueColor:function(color){var r=color.getRed();var g=color.getGreen();var b=color.getBlue();return new armyc2.c2sd.renderer.utilities.Color(r,g,b);},LinesWithFill:function(linetype){var result=false;try{switch(linetype){case 10000000:case 24326100:case 24220000:case 22330000:case 22522100:case 22121000:case 211400000:case 212600000:case 212500000:case 211600000:case 211900000:case 212100000:case 22122000:case 22123000:case 22124000:case 22125000:case 22221000:case 22223000:case 22421000:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22613000:case 23112000:case 23120000:case 23131100:case 23134000:case 231112000:case 231113000:case 231111000:case 22528000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 24250000:case 24211000:case 24210000:case 24230000:case 24225000:case 24240000:case 25211000:case 25212000:case 25221000:case 25222000:case 25223000:case 25225000:case 25224000:result=true;break;default:result=false;break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} -return result;},tweakFillColor:function(tg){try{if((armyc2.c2sd.JavaTacticalRenderer.clsUtility.isSameColor(tg.get_LineColor(),tg.get_FillColor())).booleanValue()===false) -return;var fillColor=tg.get_FillColor();var r=fillColor.getRed();var g=fillColor.getGreen();var b=fillColor.getBlue();var alpha=fillColor.getAlpha();r*=0.9;g*=0.9;b*=0.9;alpha*=0.8;fillColor=new armyc2.c2sd.renderer.utilities.Color(r,g,b,alpha);tg.set_FillColor(fillColor);} -catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"tweakFillColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside tweakFillColor",exc));}else{throw exc;}} -return;},isSameColor:function(c1,c2){try{if(c1===null||c2===null) -return true;var r1=c1.getRed();var r2=c2.getRed();var g1=c1.getGreen();var g2=c2.getGreen();var b1=c1.getBlue();var b2=c2.getBlue();if(Math.abs(r1-r2)<5) -if(Math.abs(g1-g2)<5) -if(Math.abs(b1-b2)<5) -return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"isSameColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside isSameColor",exc));}else{throw exc;}} -return false;},getLineStroke:function(width,style,cap,round){var stroke=null;try{switch(style){case 0:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;case 1:var dash=[2*width,2*width,2*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dash,0);break;case 2:var dot=[0.1*width,2*width,0.1*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dot,0);break;case 3:var dashdot=[4*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdot,0);break;case 4:var dashdotdot=[2*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdotdot,0);break;default:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"getLineStroke",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getLineStroke",exc));}else{throw exc;}} -return stroke;},getLineStroke2:function(width,style,cap,round){var stroke=null;try{switch(style){case 0:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;case 1:var dash=[2*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dash,0);break;case 2:var dot=[0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dot,0);break;case 3:var dashdot=[4*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdot,0);break;case 4:var dashdotdot=[2*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdotdot,0);break;default:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;}} -catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"getLineStroke",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getLineStroke",exc));}else{throw exc;}} -return stroke;},SetShapeProperties:function(tg,shapes,bi){try{if(shapes===null){return;} -var j=0;var shape=null;var stroke=null;var dash=null;var lineThickness=tg.get_LineThickness();var shapeType=-1;var lineType=tg.get_LineType();var hasFill=armyc2.c2sd.JavaTacticalRenderer.clsUtility.LinesWithFill(lineType);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,null);var isClosedPolygon=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);for(j=0;j2){numSectors=Math.floor((tg.LatLongs.size()-2)/2);for(k=0;k2){var ptCenter=tg.LatLongs.get(0);var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var dist=0;var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();var rad=0;var temp="";for(var j=2;j0){radius=Clazz.newArray(n,0);}else{return null;} -if(lineType===243111000){for(var k=0;k0){count2=count;}else{count2=Math.floor(pixels.length/2);} -bolNoRepeats=false;do{bolNoRepeats=true;for(j=0;j3.141592653589793){dblAngle=dblAngle-6.283185307179586;} -if(dblAngle<-3.141592653589793){dblAngle=dblAngle+6.283185307179586;} -var dblWidth=30;locD.x=(locC.x+dblWidth*Math.cos(dblAngle));locD.y=(locC.y-dblWidth*Math.sin(dblAngle));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"ComputeLastPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ComputeLastPoint",exc));}else{throw exc;}} -return locD;},GetSegments:function(pixels,segments,factor){try{var j=0;var m1=new armyc2.c2sd.JavaLineArray.ref();var m2=new armyc2.c2sd.JavaLineArray.ref();var numPoints=0;var bolVertical1=false;var bolVertical2=false;var pt0F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt1F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt2F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);segments[0]=true;numPoints=Math.floor(pixels.length/2);for(j=0;jfactor)&&(bolVertical2===false||Math.abs(m2.value[0])>factor)&&armyc2.c2sd.JavaTacticalRenderer.clsUtility.InYOrder(pt0F,pt1F,pt2F)===false){segments[j+1]=false;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"GetSegments",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSegments",exc));}else{throw exc;}} -return;},SetLCColor:function(tg,shape){try{var affiliation=tg.get_Affiliation();if(affiliation!==null&&affiliation.equals("H")){if(shape.getLineColor()===armyc2.c2sd.renderer.utilities.Color.RED){shape.setLineColor(tg.get_LineColor());}else{shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}else{if(shape.getLineColor()!==armyc2.c2sd.renderer.utilities.Color.RED){shape.setLineColor(tg.get_LineColor());}else{shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"SetLCColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SetLCColor",exc));}else{throw exc;}}},ReverseUSASLCPointsByQuadrant:function(tg){try{if(tg.Pixels.size()<2) -return;var quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(tg.Pixels.get(0),tg.Pixels.get(1));switch(tg.get_LineType()){case 22123000:case 22123001:if(tg.get_Affiliation()!==null&&tg.get_Affiliation().equals("H")){switch(quadrant){case 2:case 3:break;case 1:case 4:var n=tg.Pixels.size();var pts2=tg.Pixels.clone();for(var j=0;joriginalPixels.size()-1) -break;color=hmap.get(key);segPt0=originalPixels.get((key).intValue());segPt1=originalPixels.get((key).intValue()+1);for(j=0;jglyphSize||dist2>glyphSize||delta>20){hmapPixels.put(new Integer(j),tg.Pixels.get(j));hmapGeo.put(new Integer(j),tg.LatLongs.get(j));currentIndex=j;}}} -var pixels=new java.util.ArrayList();var geo=new java.util.ArrayList();for(j=0;j1){pPoints2.add(ptCenter);} -if(a12.value[0]0){brng12=brngA;brng21=6.283185307179586-brngB;}else{brng12=6.283185307179586-brngA;brng21=brngB;} -var alpha1=(brng13-brng12+3.141592653589793)%(6.283185307179586)-3.141592653589793;var alpha2=(brng21-brng23+3.141592653589793)%(6.283185307179586)-3.141592653589793;if(Math.sin(alpha1)===0&&Math.sin(alpha2)===0){return null;} -if(Math.sin(alpha1)*Math.sin(alpha2)<0){return null;} -var alpha3=Math.acos(-Math.cos(alpha1)*Math.cos(alpha2)+Math.sin(alpha1)*Math.sin(alpha2)*Math.cos(dist12));var dist13=Math.atan2(Math.sin(dist12)*Math.sin(alpha1)*Math.sin(alpha2),Math.cos(alpha2)+Math.cos(alpha1)*Math.cos(alpha3));var lat3=Math.asin(Math.sin(lat1)*Math.cos(dist13)+Math.cos(lat1)*Math.sin(dist13)*Math.cos(brng13));var dLon13=Math.atan2(Math.sin(brng13)*Math.sin(dist13)*Math.cos(lat1),Math.cos(dist13)-Math.sin(lat1)*Math.sin(lat3));var lon3=lon1+dLon13;lon3=(lon3+3.141592653589793)%(6.283185307179586)-3.141592653589793;ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.RadToDeg(lon3),armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.RadToDeg(lat3));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic._className,"IntersectLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside IntersectLines",exc));}else{throw exc;}} -return ptResult;},SegmentGeoPoints:function(geoPoints,interval,lineType){var resultPts=new java.util.ArrayList();try{switch(lineType){case 22350000:case 23350000:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231114000:case 231113000:case 231112000:case 23112000:case 22123000:case 22122000:case 23134000:case 22624000:case 23113000:case 23115000:case 23114000:case 23131100:case 23131200:case 23132000:case 22134000:case 23330000:case 23111000:case 23111001:break;default:return geoPoints;} -var j=0;var k=0;var n=0;var pt0=null;var pt1=null;var pt=null;var dist=0;var az=0;var remainder=0;for(j=0;j16777215)alpha=(color>>>24);return alpha;};armyc2.c2sd.renderer.utilities.Color.getRedFromColor=function(color) -{var red=255;red=(color>>16)&0xFF;return red;};armyc2.c2sd.renderer.utilities.Color.getGreenFromColor=function(color) -{var green=255;green=(color>>8)&0xFF;return green;};armyc2.c2sd.renderer.utilities.Color.getBlueFromColor=function(color) -{var blue=255;if(color>16777215) -blue=color&0x000000FF;else -blue=color&0x0000FF;return blue;};armyc2.c2sd.renderer.utilities.Color.getColorFromHexString=function(hexValue) -{var hexOriginal=new String(hexValue);var hexAlphabet="0123456789ABCDEF";if(hexValue.charAt(0)==='#') -hexValue=hexValue.substring(1);if(hexValue.substring(0,2)===("0x")||hexValue.substring(0,2)===("0X")) -hexValue=hexValue.substring(2);hexValue=hexValue.toUpperCase();var count=hexValue.length,value=null,k=0,int1=0,int2=0;if(count===8||count===6) -{value=new Array();for(var i=0;i=_level) -{if(console!==undefined) -{message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ -this.getLevelName(level)+": "+message;console.info(message);}}},LogWarning:function(sourceClass,sourceMethod,message,level) -{if(level===undefined||level===null) -level=900;if(level>=_level) -{if(console!==undefined) -{message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ -this.getLevelName(level)+": "+message;console.warn(message);}}},LogException:function(sourceClass,sourceMethod,err,param,level) -{if(level===undefined||level===null) -level=1000;if(level>=_level) -{if(console!==undefined) -{var message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ -this.getLevelName(level)+": ";message+=err.name+": "+err.message;var stack=null;if(err.stack) -{stack=err.stack;} -if(console.groupCollapsed) -{console.error(message);if(stack!==null) -{console.groupCollapsed("Stack Trace:");console.error(err.stack);if(console.dir&¶m) -{console.dir(param);} -console.groupEnd();}} -else -{if(stack!==null) -{message+="\n"+stack;} -console.error(message);if(console.dir&¶m) -{console.info(param);}}}}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.RendererException=function(message,throwable){throwable.message+=" - "+message;return throwable;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.MilStdSymbol=function(symbolID,uniqueID,coordinates,modifiers){var SymbolUtilties=armyc2.c2sd.renderer.utilities.SymbolUtilities;var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;this._Properties={};this._X_Altitude=null;this._AM_Distance=null;this._AN_Azimuth=null;this._symbolID="";this._UUID=null;this._SymbolShapes=null;this._ModifierShapes=null;this._Coordinates=null;this._UnitSize=0;this._scale=0;this._KeepUnitRatio=true;this._LineWidth=3;this._LineColor=null;this._FillColor=null;this._Rotation=0.0;this._Outline=false;this._OutLineColor=null;this._OutLineWidth=0;this._symStd=0;this._UseLineInterpolation=true;this._DrawAffiliationModifierAsLabel=true;this._tp=null;this._Tag=null;if(modifiers===undefined||modifiers===null) -modifiers={};else -this._Properties=modifiers;this._UUID=uniqueID;this._Coordinates=coordinates;this.setSymbolID(symbolID);this._LineColor=SymbolUtilties.getLineColorOfAffiliation(this._symbolID);if(SymbolUtilties.hasDefaultFill(this._symbolID)) -this._FillColor=SymbolUtilties.getFillColorOfAffiliation(this._symbolID);this._KeepUnitRatio=true;this._symStd=RendererSettings.getSymbologyStandard();this._DrawAffiliationModifierAsLabel=RendererSettings.getDrawAffiliationModifierAsLabel();this._UseLineInterpolation=RendererSettings.getUseLineInterpolation();this._OutLineWidth=RendererSettings.getSinglePointSymbolOutlineWidth();};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifier_AM_AN_X=function(modifier,value,index) -{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) -{var modifiers=null;if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) -{if(this._AM_Distance===null) -this._AM_Distance=new Array();modifiers=this._AM_Distance;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) -{if(this._AN_Azimuth===null) -this._AN_Azimuth=new Array();modifiers=this._AN_Azimuth;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) -{if(this._X_Altitude===null) -this._X_Altitude=new Array();modifiers=this._X_Altitude;} -if(index+1>modifiers.length) -{modifiers.push(value);} -else -{modifiers[index]=value;}}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifier=function(modifier,value,index) -{if(this._Properties===null) -{this._Properties={};} -else if(index===undefined) -{index=0;} -if(value!==undefined&&value!==null&&value!=="") -{if(!(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH)) -{this._Properties[modifier]=value;} -else -{this.setModifier_AM_AN_X(modifier,value,index);}}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbolID=function(value) -{var current=this._symbolID;try -{if(value!==null&&value!==""&¤t!==value){this._symbolID=value;} -if(armyc2.c2sd.renderer.utilities.SymbolUtilities.getAffiliation(value)===("H")){var basicID=armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolID(value);if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isObstacle(basicID)||basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")){this.setModifier("N","ENY");}}} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdSymbol","setSymbolID",err);}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbologyStandard=function(symStd) -{this._symStd=symStd;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbologyStandard=function() -{return this._symStd;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setFillStyle=function(value) -{this._tp=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getFillStyle=function() -{return this._tp;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setUseLineInterpolation=function(value) -{this._UseLineInterpolation=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getUseLineInterpolation=function() -{return this._UseLineInterpolation;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifierMap=function(value) -{this._Properties=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifierMap=function() -{return this._Properties;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifier_AM_AN_X=function(modifier,index) -{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) -{if(this._AM_Distance!==null&&this._AM_Distance.length>index) -{return this._AM_Distance[index];} -else -return null;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) -{if(this._AN_Azimuth===null&&this._AN_Azimuth.length>index) -{return this._AN_Azimuth[index];} -else -return null;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) -{if(this._X_Altitude===null&&this._X_Altitude.length>index) -{return this._X_Altitude[index];} -else -return null;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifier=function(modifier,index) -{if(index===undefined) -{index=0;} -if(modifier==="AM"||modifier==="AN"||modifier==="XN") -{return this.getModifier_AM_AN_X(modifier,index);} -else if(this._Properties[modifier]!==undefined) -{return this._Properties[modifier];} -else -return null;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifiers_AM_AN_X=function(modifier) -{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) -{return this._AM_Distance;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) -{return this._AN_Azimuth;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) -{return this._X_Altitude;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifiers_AM_AN_X=function(modifier,values) -{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) -{this._AM_Distance=values;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) -{this._AN_Azimuth=values;} -else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) -{this._X_Altitude=values;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setFillColor=function(value) -{this._FillColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getFillColor=function() -{return this._FillColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setLineWidth=function(value) -{this._LineWidth=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getLineWidth=function() -{return this._LineWidth;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setLineColor=function(value) -{this._LineColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getLineColor=function() -{return this._LineColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setOutlineColor=function(value) -{this._OutLineColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getOutlineColor=function() -{return this._OutLineColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setTag=function(value) -{this._Tag=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getTag=function() -{return this._Tag;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setCoordinates=function(value) -{this._Coordinates=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getCoordinates=function() -{return this._Coordinates;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifierShapes=function(value) -{this._ModifierShapes=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifierShapes=function() -{return this._ModifierShapes;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbolShapes=function(value) -{this._SymbolShapes=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbolShapes=function() -{return this._SymbolShapes;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbolID=function() -{return this._symbolID;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ModifiersTG={A_SYMBOL_ICON:"A",B_ECHELON:"B",C_QUANTITY:"C",H_ADDITIONAL_INFO_1:"H",H1_ADDITIONAL_INFO_2:"H1",H2_ADDITIONAL_INFO_3:"H2",N_HOSTILE:"N",Q_DIRECTION_OF_MOVEMENT:"Q",S_OFFSET_INDICATOR:"S",T_UNIQUE_DESIGNATION_1:"T",T1_UNIQUE_DESIGNATION_2:"T1",V_EQUIP_TYPE:"V",W_DTG_1:"W",W1_DTG_2:"W1",X_ALTITUDE_DEPTH:"X",Y_LOCATION:"Y",AM_DISTANCE:"AM",AN_AZIMUTH:"AN",LENGTH:"Length",WIDTH:"Width",RADIUS:"Radius",ANGLE:"Angle"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.PointConversion=function(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight) -{this._pixelWidth=0;this._PixelHeight=0;this._geoTop=0;this._geoLeft=0;this._geoBottom=0;this._geoRight=0;this._pixelMultiplierX=0;this._pixelMultiplierY=0;this.UpdateExtents(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight);};armyc2.c2sd.renderer.utilities.PointConversion.prototype.UpdateExtents=function(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight) -{this._pixelWidth=Number(pixelWidth);this._PixelHeight=Number(pixelHeight);this._geoTop=Number(geoTop);this._geoLeft=Number(geoLeft);this._geoBottom=Number(geoBottom);this._geoRight=Number(geoRight);this._pixelMultiplierX=(this._geoRight-this._geoLeft)/(this._pixelWidth);this._pixelMultiplierY=(this._geoTop-this._geoBottom)/(this._PixelHeight);if(this._geoRight-this._geoLeft<-180){this._pixelMultiplierX=(this._geoRight-this._geoLeft+360)/(this._pixelWidth);} -if(this._geoRight-this._geoLeft>180){this._pixelMultiplierX=(360-(this._geoRight-this._geoLeft))/(this._pixelWidth);} -if(this._geoTop180)x-=360;if(x<-180)x+=360;coords.setLocation(x,y);return coords;};armyc2.c2sd.renderer.utilities.PointConversion.prototype.GeoToPixels=function(coord) -{var pixel=new armyc2.c2sd.graphics2d.Point2D();var x=0;var y=0;var temp;temp=((coord.getX()-this._geoLeft)/this._pixelMultiplierX);x=Math.round(temp);temp=((this._geoTop-coord.getY())/this._pixelMultiplierY);y=Math.round(temp);pixel.setLocation(x,y);return pixel;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.PointConverter3D=function(controlLong,controlLat,scale) -{this._controlLat=0,this._controlLong=0,this._scale=0,this._metersPerPixel=0;this._controlLat=Number(controlLat);this._controlLong=Number(controlLong);this._scale=Number(scale);this._metersPerPixel=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.metersPerPixel(scale);};armyc2.c2sd.renderer.utilities.PointConverter3D.prototype.PixelsToGeo=function(pixel) -{var pt2dGeo=null;var y=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.y2lat(pixel.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.x2long(pixel.getX(),this._scale,this._controlLong,y,this._metersPerPixel);pt2dGeo=new armyc2.c2sd.graphics2d.Point2D(x,y);return pt2dGeo;};armyc2.c2sd.renderer.utilities.PointConverter3D.prototype.GeoToPixels=function(coord) -{var ptPixels=null;var y=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.lat2y(coord.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.long2x(coord.getX(),this._scale,this._controlLong,coord.getY(),this._metersPerPixel);ptPixels=new armyc2.c2sd.graphics2d.Point2D(x,y);return ptPixels;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.RendererSettings=(function(){var _SymbologyStandard=0,_UseLineInterpolation=true,_TextBackgroundAutoColorThreshold=160,_TextOutlineWidth=1,_TextBackgroundMethod=2,_ColorLabelForeground=null,_ColorLabelBackground=null,_SymbolOutlineWidth=3,_CenterOnHQStaff=true,_ModifierFontName="Arial, sans-serif",_ModifierFontSize=10,_ModifierFontStyle="bold",_ModifierFont="bold 10pt Arial, sans-serif",_scaleEchelon=false,_DrawAffiliationModifierAsLabel=true,_SPFontSize=60,_UnitFontSize=50,_PixelSize=35;return{TextBackgroundMethod_NONE:0,TextBackgroundMethod_COLORFILL:1,TextBackgroundMethod_OUTLINE:2,TextBackgroundMethod_OUTLINE_QUICK:3,Symbology_2525Bch2_USAS_13_14:0,Symbology_2525C:1,setTextBackgroundMethod:function(textBackgroundMethod) -{_TextBackgroundMethod=textBackgroundMethod;},getTextBackgroundMethod:function() -{return _TextBackgroundMethod;},setSymbologyStandard:function(standard){_SymbologyStandard=standard;},getSymbologyStandard:function(){return _SymbologyStandard;},setUseLineInterpolation:function(value){_UseLineInterpolation=value;},getUseLineInterpolation:function(){return _UseLineInterpolation;},setCenterOnHQStaff:function(value){_CenterOnHQStaff=value;},getCenterOnHQStaff:function(){return _CenterOnHQStaff;},setTextOutlineWidth:function(width){_TextOutlineWidth=width;},getTextOutlineWidth:function(){return _TextOutlineWidth;},setDefaultPixelSize:function(size){_PixelSize=size;},getDefaultPixelSize:function(){return _PixelSize;},setLabelForegroundColor:function(value){_ColorLabelForeground=value;},getLabelForegroundColor:function(){return _ColorLabelForeground;},setLabelBackgroundColor:function(value){_ColorLabelBackground=value;},getLabelBackgroundColor:function(){return _ColorLabelBackground;},setTextBackgroundAutoColorThreshold:function(value){_TextBackgroundAutoColorThreshold=value;},getTextBackgroundAutoColorThreshold:function(){return _TextBackgroundAutoColorThreshold;},setSinglePointSymbolOutlineWidth:function(width){_SymbolOutlineWidth=width;if(width>0) -_SymbolOutlineWidth=(width*2)+1;else -_SymbolOutlineWidth=0;},getSinglePointSymbolOutlineWidth:function(){return _SymbolOutlineWidth;},setScaleEchelon:function(value){_scaleEchelon=value;},getScaleEchelon:function(){return _scaleEchelon;},setDrawAffiliationModifierAsLabel:function(value){_DrawAffiliationModifierAsLabel=value;},getDrawAffiliationModifierAsLabel:function(){return _DrawAffiliationModifierAsLabel;},setModifierFont:function(name,size,style){_ModifierFontName=name;_ModifierFontSize=size;if(style!=='bold'||style!=='normal') -{_ModifierFontStyle=style;} -else -{_ModifierFontStyle='bold';} -_ModifierFont=style+" "+size+"pt "+name;},getModifierFont:function(){return _ModifierFont;},getModifierFontName:function(){return _ModifierFontName;},getModifierFontSize:function(){return _ModifierFontSize;},getModifierFontStyle:function(){return _ModifierFontStyle;},getInstance:function(){return armyc2.c2sd.renderer.utilities.RendererSettings;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolUtilities={};armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolID=function(symbolID){var basic=symbolID;if(symbolID&&symbolID.length===15) -{var scheme=symbolID[0];if(scheme==='G') -{basic=scheme+'*'+basic[2]+'*'+basic.substring(4,10)+"****X";} -else if(scheme!=='W'&&scheme!=='B') -{basic=scheme+'*'+basic[2]+'*'+basic.substring(4,10)+"*****";}} -return basic;};armyc2.c2sd.renderer.utilities.SymbolUtilities.reconcileSymbolID=function(symbolID,isMultiPoint) -{if(isMultiPoint!==true) -isMultiPoint=false;var sb="";var codingScheme=symbolID.charAt(0);if(symbolID.indexOf("BS_")===0||symbolID.indexOf("BBS_")===0) -{return symbolID;} -if(symbolID.length<15) -{while(symbolID.length<15) -{symbolID+="-";}} -if(symbolID.length>15) -{symbolID=symbolID.substring(0,15);} -if(symbolID!==null&&symbolID.length===15) -{if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') -{sb+=(codingScheme);if(this.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));if(this.hasValidBattleDimension(symbolID)===false) -{sb="S"+sb.substring(1);sb+=('Z');} -else -sb+=(symbolID.charAt(2));if(this.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));} -else if(codingScheme==='G') -{sb+=(codingScheme);if(this.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));sb+=('G');if(this.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));if(isMultiPoint) -sb+=("GAG---");else -sb+=("GPP---");sb+=(symbolID.substring(10,15));} -else if(codingScheme==='W') -{return"SUZP-----------";} -else -{sb+=('S');if(this.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));if(this.hasValidBattleDimension(symbolID)===false) -{sb+=('Z');} -else -sb+=(symbolID.charAt(2));if(this.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));}} -else -{return"SUZP-----------";} -return sb;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidStatus=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) -{var status=SymbolID.charAt(3),codingScheme=SymbolID.charAt(0);if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') -{if(status==='A'||status==='P'||status==='C'||status==='D'||status==='X'||status==='F') -{return true;} -else -return false;} -else if(codingScheme==='G') -{if(status==='A'||status==='S'||status==='P'||status==='K') -{return true;} -else -return false;} -else if(codingScheme==='W') -{return true;} -return false;} -else -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidAffiliation=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) -{var affiliation=SymbolID.charAt(1);if(affiliation==='P'||affiliation==='U'||affiliation==='A'||affiliation==='F'||affiliation==='N'||affiliation==='S'||affiliation==='H'||affiliation==='G'||affiliation==='W'||affiliation==='M'||affiliation==='D'||affiliation==='L'||affiliation==='J'||affiliation==='K') -return true;else -return false;} -else -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidCodingScheme=function(symbolID){if(symbolID!==null&&symbolID.length>0) -{var codingScheme=symbolID.charAt(0);if(codingScheme==='S'||codingScheme==='G'||codingScheme==='W'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') -{return true;} -else -{return false;}} -else -{return false;}};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidBattleDimension=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) -{var codingScheme=SymbolID.charAt(0),bd=SymbolID.charAt(2);if(codingScheme==='S') -{if(bd==='P'||bd==='A'||bd==='G'||bd==='S'||bd==='U'||bd==='F'||bd==='Z') -return true;else -return false;} -else if(codingScheme==='O') -{if(bd==='V'||bd==='L'||bd==='O'||bd==='I'||bd==='P'||bd==='G'||bd==='R') -return true;else -return false;} -else if(codingScheme==='E') -{if(bd==='I'||bd==='N'||bd==='O'||bd==='F') -return true;else -return false;} -else if(codingScheme==='G') -{if(bd==='T'||bd==='G'||bd==='M'||bd==='F'||bd==='S'||bd==='O') -{return true;} -else -return false;} -else if(codingScheme==='W') -{return true;} -else if(codingScheme==='I') -{if(bd==='P'||bd==='A'||bd==='G'||bd==='S'||bd==='U'||bd==='Z') -return true;else -return false;} -else -return false;} -else -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isLetter=function(str) -{var returnVal=true,len=str.length,code=0;for(var i=0;i=65&&code<=90)||(code>=97&&code<=122)) -{returnVal=false;break;}} -return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidCountryCode=function(symbolID) -{if(this.isLetter(symbolID.substring(12,14))) -return true;else -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getDateLabel=function(date){var strDate=null,day,hour,min,sec,zulu,month,strMonth,year,strYear,months;if(date instanceof Date) -{day=date.getDate();hour=date.getHours();min=date.getMinutes();sec=date.getSeconds();zulu=date.getTimezoneOffset();if(zulu!==0){zulu=zulu/-60;} -month=date.getMonth();year=date.getFullYear();months=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];strMonth=months[month];strYear=year.toString();strYear=strYear.substr(2,2);strDate=this.formatNumberLength(day,2)+this.formatNumberLength(hour,2)+this.formatNumberLength(min,2)+this.formatNumberLength(sec,2)+this.getZuluCharacter(zulu)+strMonth+strYear;} -return strDate;};armyc2.c2sd.renderer.utilities.SymbolUtilities.formatNumberLength=function(number,length){var r="";r=r+number;while(r.length-1) -returnVal=true;}} -return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfAffiliation=function(symbolID){var retColor=null,basicSymbolID=this.getBasicSymbolID(symbolID);var AffiliationColors=armyc2.c2sd.renderer.utilities.AffiliationColors;if((symbolID===null)||(symbolID===(""))) -{return retColor;} -if(this.isTacticalGraphic(symbolID)) -{if(this.isWeather(symbolID)) -{retColor=this.getLineColorOfWeather(symbolID);} -else if(this.isObstacle(symbolID)) -{retColor=armyc2.c2sd.renderer.utilities.Color.GREEN;} -else if((this.isNBC(symbolID))&&(basicSymbolID===("G*M*NR----****X")||basicSymbolID===("G*M*NC----****X")||basicSymbolID===("G*M*NB----****X"))) -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -else -{var switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) -{if(this.getBasicSymbolID(symbolID)===("G*G*GLC---****X")) -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -else -{retColor=armyc2.c2sd.renderer.utilities.Color.RED;}} -else if(switchChar===("N")||switchChar===("L")) -{retColor=armyc2.c2sd.renderer.utilities.Color.GREEN;} -else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) -{retColor=armyc2.c2sd.renderer.utilities.Color.YELLOW;} -else -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;}}} -else -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getFillColorOfAffiliation=function(symbolID){var retColor=null,basicSymbolID=this.getBasicSymbolID(symbolID);var AffiliationColors=armyc2.c2sd.renderer.utilities.AffiliationColors;var switchChar;if((symbolID===null)||(symbolID===(""))) -{return retColor;} -if(basicSymbolID===("G*M*NZ----****X")||basicSymbolID===("G*M*NEB---****X")||basicSymbolID===("G*M*NEC---****X")) -{retColor=AffiliationColors.UnknownUnitFillColor;} -else if(this.isTacticalGraphic(symbolID)&&!this.isTGSPWithFill(symbolID)) -{if(basicSymbolID===("G*M*NZ----****X")||basicSymbolID===("G*M*NEB---****X")||basicSymbolID===("G*M*NEC---****X")) -{retColor=armyc2.c2sd.renderer.utilities.Color.yellow;} -else -{switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) -{retColor=AffiliationColors.FriendlyGraphicFillColor;} -else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) -{retColor=AffiliationColors.HostileGraphicFillColor;} -else if(switchChar===("N")||switchChar===("L")) -{retColor=AffiliationColors.NeutralGraphicFillColor;} -else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FFFACD");} -else -{retColor=null;}}} -else -{switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) -{retColor=AffiliationColors.FriendlyUnitFillColor;} -else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) -{retColor=AffiliationColors.HostileUnitFillColor;} -else if(switchChar===("N")||switchChar===("L")) -{retColor=AffiliationColors.NeutralUnitFillColor;} -else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) -{retColor=AffiliationColors.UnknownUnitFillColor;} -else -{retColor=AffiliationColors.UnknownUnitFillColor;}} -return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfWeather=function(symbolID){var retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;if(symbolID===("WAS-WSGRL-P----")||symbolID===("WAS-WSGRMHP----")||symbolID===("WAS-PL----P----")||symbolID===("WAS-PC----P----")||symbolID===("WAS-WSIC--P----")||symbolID===("WAS-WSPLL-P----")||symbolID===("WAS-WSPLM-P----")||symbolID===("WAS-WSPLH-P----")||symbolID===("WAS-WST-NPP----")||symbolID===("WAS-WSTMR-P----")||symbolID===("WAS-WSTHR-P----")||symbolID===("WAS-WSTMH-P----")||symbolID===("WAS-WSTHH-P----")||symbolID===("WAS-WST-FCP----")||symbolID===("WAS-WST-SQP----")||symbolID===("WAS-WST-LGP----")||symbolID===("WAS-WSFGFVP----")||symbolID===("WAS-WSFGFOP----")||symbolID===("WAS-WSTSD-P----")||symbolID===("WAS-WSTSS-P----")||symbolID===("WAS-WSTSH-P----")||symbolID===("WAS-WSRFL-P----")||symbolID===("WAS-WSRFMHP----")||symbolID===("WAS-WSDFL-P----")||symbolID===("WAS-WSDFMHP----")||symbolID===("WOS-HHDMDBP----")||symbolID===("WOS-HHDMDFP----")||symbolID.substring(0,7)===("WA-DPFW")||symbolID===("WA-DBAIF----A--")||symbolID===("WA-DBAFP----A--")||symbolID===("WA-DBAT-----A--")||symbolID===("WA-DIPIS---L---")||symbolID===("WA-DIPTH---L---")||symbolID===("WA-DWJ-----L---")) -{retColor=armyc2.c2sd.renderer.utilities.Color.RED;} -else if(symbolID===("WAS-PH----P----")||symbolID===("WAS-PA----P----")||symbolID===("WA-DBAMV----A--")||symbolID===("WA-DBATB----A--")||symbolID.substring(0,5)===("WAS-T")||symbolID.substring(0,7)===("WA-DPFC")) -{retColor=armyc2.c2sd.renderer.utilities.Color.BLUE;} -else if(symbolID===("WAS-WSFGPSP----")||symbolID===("WAS-WSFGCSP----")||symbolID===("WAS-WSFGP-P----")||symbolID===("WAS-WSFGSVP----")||symbolID===("WAS-WSFGSOP----")||symbolID===("WA-DBAFG----A--")||symbolID===("WAS-WSBR--P----")) -{retColor=armyc2.c2sd.renderer.utilities.Color.YELLOW;} -else if(symbolID===("WAS-WSFU--P----")||symbolID===("WAS-WSHZ--P----")||symbolID===("WAS-WSDSLMP----")||symbolID===("WAS-WSDSS-P----")||symbolID===("WAS-WSDD--P----")||symbolID===("WA-DBAD-----A--")||symbolID===("WAS-WSBD--P----")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#A52A2A");} -else if(symbolID===("WA-DBALPNC--A--")||symbolID===("WA-DBALPC---A--")||symbolID===("WA-DIPID---L---")||symbolID===("WO-DHCF----L---")||symbolID===("WO-DHCF-----A--")||symbolID===("WAS-WSR-LIP----")||symbolID===("WAS-WSR-LCP----")||symbolID===("WAS-WSR-MIP----")||symbolID===("WAS-WSR-MCP----")||symbolID===("WAS-WSR-HIP----")||symbolID===("WAS-WSR-HCP----")||symbolID===("WAS-WSRSL-P----")||symbolID===("WAS-WSRSMHP----")||symbolID===("WAS-WSRST-P----")||symbolID===("WAS-WSD-LIP----")||symbolID===("WAS-WSD-LCP----")||symbolID===("WAS-WSD-MIP----")||symbolID===("WAS-WSD-MCP----")||symbolID===("WAS-WSD-HIP----")||symbolID===("WAS-WSD-HCP----")||symbolID===("WAS-WSM-L-P----")||symbolID===("WAS-WSM-MHP----")||symbolID===("WAS-WSMSL-P----")||symbolID===("WAS-WSMSMHP----")||symbolID===("WAS-WSS-LIP----")||symbolID===("WAS-WSS-LCP----")||symbolID===("WAS-WSS-MIP----")||symbolID===("WAS-WSS-MCP----")||symbolID===("WAS-WSS-HIP----")||symbolID===("WAS-WSS-HCP----")||symbolID===("WAS-WSSBLMP----")||symbolID===("WAS-WSSBH-P----")||symbolID===("WAS-WSSG--P----")||symbolID===("WAS-WSSSL-P----")||symbolID===("WAS-WSSSMHP----")||symbolID===("WAS-WSUKP-P----")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#00FF00");} -else if(symbolID===("WA-DBAI-----A--")||symbolID.indexOf("WAS-IC")===0||symbolID.indexOf("WAS-IR")===0||symbolID.indexOf("WAS-IM")===0) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#806010");} -else if(symbolID===("WOS-HDS---P----")||symbolID===("WOS-HHDF--P----")||symbolID===("WO-DHHDF----A--")||symbolID===("WOS-HPFS--P----")||symbolID===("WOS-HPFS---L---")||symbolID===("WOS-HPFF----A--")||symbolID===("WO-DHDDL---L---")||symbolID===("WO-DHDDC---L---")||symbolID===("WO-DHCC----L---")||symbolID===("WO-DHPBP---L---")||symbolID===("WO-DHPMO---L---")||symbolID===("WO-DHPSPA--L---")||symbolID===("WO-DHPSPB--L---")||symbolID===("WO-DHPSPS--L---")||symbolID===("WO-DHHDK--P----")||symbolID===("WO-DHHDK----A--")||symbolID===("WO-DHHDB---L---")||symbolID===("WO-DTCCCFE-L---")||symbolID===("WO-DTCCCFF-L---")||symbolID===("WOS-TCCTD-P----")||symbolID===("WO-DHCW-----A--")) -retColor=armyc2.c2sd.renderer.utilities.Color.GRAY;else if(symbolID===("WAS-WSVE--P----")||symbolID===("WAS-WSVA--P----")||symbolID===("WAS-WST-LVP----")||symbolID===("WAS-WSF-LVP----")) -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -else if(symbolID===("WOS-HPBA--P----")||symbolID===("WOS-HPBA---L---")||symbolID===("WOS-HPBA----A--")||symbolID===("WOS-HPCP--P----")||symbolID===("WOS-HPFH--P----")||symbolID===("WOS-HPM-FC-L---")||symbolID===("WOS-HABM--P----")||symbolID===("WOS-HAL---P----")||symbolID===("WA-DIPIT---L---")||symbolID===("WOS-TCCTG-P----")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FF00FF");} -else if(symbolID.substring(0,7)===("WA-DPFO")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#E29FFF");} -else if(symbolID===("WA-DPXITCZ-L---")||symbolID===("WA-DPXCV---L---")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FF7F00");} -else if(symbolID.indexOf("WAS-IC")===0||symbolID.indexOf("WAS-IR")===0||symbolID.indexOf("WAS-IM")===0) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#806010");} -else if(symbolID===("WO-DHCI-----A--")||symbolID===("WO-DHCB-----A--")||symbolID===("WO-DHPMO---L---")||symbolID===("WO-DHCI-----A--")) -{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#D2B06A");} -else -{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} -return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getFillColorOfWeather=function(symbolID){if(symbolID===("WOS-HPM-R-P----")) -return new armyc2.c2sd.renderer.utilities.Color(148,48,0);else if(symbolID===("WOS-HPD---P----")) -return new armyc2.c2sd.renderer.utilities.Color(148,48,0);else if(symbolID===("WOS-HABB--P----")) -return new armyc2.c2sd.renderer.utilities.Color(255,0,255);else if(symbolID===("WOS-HHRS--P----")) -return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-HHDS--P----")) -return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-HHDWB-P----")) -return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-TCCTG-P----")) -return new armyc2.c2sd.renderer.utilities.Color(210,176,106);else return null;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getColorFromHexString=function(hexValue) -{var hexOriginal=new String(hexValue);var hexAlphabet="0123456789ABCDEF";if(hexValue.charAt(0)==='#') -hexValue=hexValue.substring(1);if(hexValue.substring(0,2)===("0x")||hexValue.substring(0,2)===("0X")) -hexValue=hexValue.substring(2);hexValue=hexValue.toUpperCase();var count=hexValue.length,value=null,k=0,int1=0,int2=0;if(count===8||count===6) -{value=new Array();for(var i=0;i5&&(hierarchy.indexOf("5.X.10")===0||hierarchy.indexOf("5.X.11")===0||hierarchy.indexOf("5.X.12")===0||hierarchy.indexOf("5.X.13")===0||hierarchy.indexOf("5.X.14")===0)) -{return true;} -else -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isMOOTW=function(strSymbolID){if(strSymbolID.charAt(0)===('O')) -{return true;} -else -{return false;} -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isSTBOPS=function(strSymbolID){if(strSymbolID.substring(0,1)===('O')) -{return true;} -else -{return false;} -return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEvent=function(strSymbolID) -{var arr=null;var category=strSymbolID.charAt(2);var strBasicSymbolID=this.getBasicSymbolID(strSymbolID);if(this.isMOOTW(strSymbolID)||(this.isEMS(strSymbolID)&&(category==='I'||category==='N'||category==='O'))) -return true;else -{arr=new Array("S*G*EXI---*****","S*G*EXI---MO***");var arrLength=arr.length;for(var i=0;i0)||(basicCode.substring(0,5)===("E*O*E")&&basicCode.indexOf("----*****")>0)||basicCode===("E*F*BA----*****")||basicCode===("E*F*LF----*****")||basicCode===("E*F*MA----*****")||basicCode===("E*F*MC----*****")) -{blRetVal=true;}} -return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMS=function(strSymbolID){return(strSymbolID[0]==='E');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMSNaturalEvent=function(strSymbolID){return(strSymbolID.charAt(0)==='E'&&strSymbolID.charAt(2)==='N');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMSIncident=function(strSymbolID){return(strSymbolID.charAt(0)==='E'&&strSymbolID.charAt(2)==='I');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isInstallation=function(strSymbolID){var blRetVal=((strSymbolID.charAt(0)===('S'))&&(strSymbolID.charAt(2)===('G'))&&(strSymbolID.charAt(4)===('I')));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isSIGINT=function(strSymbolID){var blRetVal=((strSymbolID.charAt(0)===('I')));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isFeintDummyInstallation=function(strSymbolID){var blRetVal=(strSymbolID.charAt(10)===('H')&&strSymbolID.charAt(11)===('B'));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasInstallationModifier=function(strSymbolID){var blRetVal=(strSymbolID.charAt(10)===('H'));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getAffiliation=function(strSymbolID){return strSymbolID.charAt(1);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getStatus=function(strSymbolID){return strSymbolID.charAt(3);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getEchelon=function(strSymbolID){return strSymbolID.charAt(11);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getUnitAffiliationModifier=function(symbolID,symStd){var textChar=null,affiliation=null;if(symStd===undefined) -{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} -affiliation=symbolID.charAt(1);if(affiliation===('F')||affiliation===('H')||affiliation===('U')||affiliation===('N')||affiliation===('P')) -{textChar=null;} -else if(affiliation===('A')||affiliation===('S')) -{if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525Bch2_USAS_13_14) -textChar="?";else -textChar=null;} -else if(affiliation===('J')) -textChar="J";else if(affiliation===('K')) -textChar="K";else if(affiliation===('D')||affiliation===('L')||affiliation===('G')||affiliation===('W')) -textChar="X";else if(affiliation===('M')) -{if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525Bch2_USAS_13_14) -textChar="X?";else -textChar="X";} -if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525C) -{if(symbolID.charAt(4)==='W'&&symbolID.charAt(0)==='S'&&symbolID.charAt(5)==='M') -{var temp=symbolID.substring(6,8);if(temp==="GX"||temp==="MX"||temp==="FX"||temp==="SX"||temp.charAt(0)==="X") -textChar="X";else -textChar=null;}} -return textChar;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasAMmodifierWidth=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolID(symbolID);if(symStd===undefined) -{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} -var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolID(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) -{var dc=sd.drawCategory;switch(dc) -{case SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} -return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasAMmodifierRadius=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolID(symbolID);if(symStd===undefined) -{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} -var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolID(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) -{var dc=sd.drawCategory;switch(dc) -{case SymbolDefTable.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} -return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasANmodifier=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolID(symbolID);if(symStd===undefined) -{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} -var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolID(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) -{var dc=sd.drawCategory;switch(dc) -{case SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} -return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isMultiPoint=function(symbolID,symStd){return armyc2.c2sd.renderer.utilities.SymbolDefTable.isMultiPoint(symbolID,symStd);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ShapeInfo=function(shape,shapeType) -{var _Shape=null,stroke=null,gp=null,fillStyle=null,texturePaint=null,_shapeType=-1,lineColor=null,fillColor=null,lineWidth=2,affineTransform=null,_TextLayout=null,_Position=null,_ModifierString=null,_ModifierStringPosition=null,_ModifierStringAngle=0,_Tag=null,_Polylines=null;if(shapeType) -{_shapeType=shapeType;} -if(shape) -{_Shape=shape;} -this.getShape=function() -{return _Shape;};this.setShape=function(value) -{_Shape=value;};this.setModifierString=function(value) -{_ModifierString=value;};this.getModifierString=function() -{return _ModifierString;};this.setModifierStringPosition=function(value) -{_ModifierStringPosition=value;};this.getModifierStringPosition=function() -{return _ModifierStringPosition;};this.getGlyphPosition=function() -{return _Position;};this.setGlyphPosition=function(value) -{_Position=value;};this.setModifierStringAngle=function(value) -{_ModifierStringAngle=value;};this.getModifierStringAngle=function() -{return _ModifierStringAngle;};this.setTag=function(value) -{_Tag=value;};this.getTag=function() -{return _Tag;};this.setLineColor=function(value) -{lineColor=value;};this.getLineColor=function() -{return lineColor;};this.setFillColor=function(value) -{fillColor=value;};this.getFillColor=function() -{return fillColor;};this.setAffineTransform=function(value) -{affineTransform=value;};this.getAffineTransform=function() -{return affineTransform;};this.setStroke=function(value) -{stroke=value;};this.getStroke=function() -{return stroke;};this.getTexturePaint=function() -{return texturePaint;};this.setTexturePaint=function(value) -{texturePaint=value;};this.setTextLayout=function(value) -{_TextLayout=value;};this.getTextLayout=function() -{return _TextLayout;};this.setShapeType=function(value) -{_shapeType=value;};this.getShapeType=function() -{return _shapeType;};this.setPolylines=function(value) -{_Polylines=value;};this.getPolylines=function() -{return _Polylines;};this.getBounds=function() -{var temp=null;if(_Shape!==null) -{temp=this._Shape.getBounds();if(this._Shape instanceof armyc2.c2sd.graphics2d.GeneralPath) -{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_OUTLINE) -{if(lineColor!==null&&stroke!==null){var bs=this.stroke;if(bs!==null&&bs.getLineWidth()>2) -temp.grow(Math.floor(Math.round(bs.getLineWidth())/2),Math.floor(Math.round(bs.getLineWidth())/2));}} -else -{if(lineColor!==null&&stroke!==null) -{var bs=stroke;if(bs!==null&&bs.getLineWidth()>2) -temp.grow(Math.round(bs.getLineWidth())-1,Math.round(bs.getLineWidth())-1);}}}} -if(_TextLayout!==null&&_Position!==null){temp=_TextLayout.getPixelBounds(null,_Position.getX(),_Position.getY());}else if(_TextLayout!==null){temp=new armyc2.c2sd.graphics2d.Rectangle(0,0,0,0);temp.setRect(this._TextLayout.getBounds());}else -return null;if(this.affineTransform!==null){var sTemp=temp;sTemp=this.affineTransform.createTransformedShape(temp);temp=sTemp.getBounds();} -return temp;};};armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_POLYLINE=0;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL=1;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_MODIFIER=2;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_MODIFIER_FILL=3;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_FRAME=4;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_FILL=5;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_SYMBOL1=6;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_SYMBOL2=7;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_DISPLAY_MODIFIER=8;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_ECHELON=9;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_AFFILIATION_MODIFIER=10;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_HQ_STAFF=11;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_FILL=12;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_FRAME=13;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_Q_MODIFIER=14;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_OUTLINE=15;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_SINGLE_POINT_OUTLINE=16;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_OUTLINE=17;armyc2.c2sd.renderer.utilities.ShapeInfoTextLayout=function(textLayout,position) -{var si=armyc2.c2sd.renderer.utilities.ShapeInfo();si.setTextLayout(textLayout);si.setGlyphPosition(position);};armyc2.c2sd.renderer.utilities.ShapeInfoGlyphVector=function(glyphVector,position) -{var si=armyc2.c2sd.renderer.utilities.ShapeInfo();si.setGlyphPosition(position);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolDefTable=(function(){var symbolMapB=null,symbolMapC=null,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,parser;return{DRAW_CATEGORY_DONOTDRAW:0,DRAW_CATEGORY_LINE:1,DRAW_CATEGORY_AUTOSHAPE:2,DRAW_CATEGORY_POLYGON:3,DRAW_CATEGORY_ARROW:4,DRAW_CATEGORY_ROUTE:5,DRAW_CATEGORY_TWOPOINTLINE:6,DRAW_CATEGORY_POINT:8,DRAW_CATEGORY_TWOPOINTARROW:9,DRAW_CATEGORY_SUPERAUTOSHAPE:15,DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:16,DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:17,DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:18,DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:19,DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:20,DRAW_CATEGORY_3D_AIRSPACE:40,DRAW_CATEGORY_UNKNOWN:99,xmlDoc:null,init:function() -{var i,data=null,symbol=null,symbols,count;if(symbolMapB===null&&armyc2.c2sd.renderer.xml.SymbolConstantsB!==undefined) -{symbols=armyc2.c2sd.renderer.xml.SymbolConstantsB.SYMBOLCONSTANTS.SYMBOL;armyc2.c2sd.renderer.xml.SymbolConstantsB=null;symbolMapB={};count=symbols.length;for(i=0;i1) -{returnVal=true;} -else -{switch(sd.drawCategory) -{case this.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:case this.DRAW_CATEGORY_ROUTE:returnVal=true;break;default:returnVal=false;}} -return returnVal;}else{return false;}} -else if(symbolID.substring(0,3)==="BS_"||symbolID.substring(0,4)==="BBS_") -{return true;} -else -{return false;}}};}());var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.Angle=function() -{};org.gavaghan.geodesy.Angle.toRadians=function(degrees){return degrees*0.017453292519943295;};org.gavaghan.geodesy.Angle.toDegrees=function(radians){return radians/0.017453292519943295;};org.gavaghan.geodesy.Angle.PiOver180=0.017453292519943295;var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.Ellipsoid=function() -{this.mSemiMajorAxis=0;this.mSemiMinorAxis=0;this.mFlattening=0;this.mInverseFlattening=0;var semiMajor=arguments[0];var semiMinor=arguments[1];var flattening=arguments[2];var inverseFlattening=arguments[3];this.mSemiMajorAxis=semiMajor;this.mSemiMinorAxis=semiMinor;this.mFlattening=flattening;this.mInverseFlattening=inverseFlattening;this.getSemiMajorAxis=function(){return this.mSemiMajorAxis;};this.getSemiMinorAxis=function(){return this.mSemiMinorAxis;};this.getFlattening=function(){return this.mFlattening;};this.getInverseFlattening=function(){return this.mInverseFlattening;};};org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF=function(semiMajor,inverseFlattening){var f=1.0/inverseFlattening;var b=(1.0-f)*semiMajor;return new org.gavaghan.geodesy.Ellipsoid(semiMajor,b,f,inverseFlattening);};org.gavaghan.geodesy.Ellipsoid.fromAAndF=function(semiMajor,flattening){var inverseF=1.0/flattening;var b=(1.0-flattening)*semiMajor;return new org.gavaghan.geodesy.Ellipsoid(semiMajor,b,flattening,inverseF);};org.gavaghan.geodesy.Ellipsoid.WGS84=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378137.0,298.257223563);org.gavaghan.geodesy.Ellipsoid.GRS80=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378137.0,298.257222101);org.gavaghan.geodesy.Ellipsoid.GRS67=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378160.0,298.25);org.gavaghan.geodesy.Ellipsoid.ANS=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378160.0,298.25);org.gavaghan.geodesy.Ellipsoid.WGS72=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378135.0,298.26);org.gavaghan.geodesy.Ellipsoid.Clarke1858=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378293.645,294.26);org.gavaghan.geodesy.Ellipsoid.Clarke1880=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378249.145,293.465);org.gavaghan.geodesy.Ellipsoid.Sphere=org.gavaghan.geodesy.Ellipsoid.fromAAndF(6371000,0.0);var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticCalculator=function() -{this.TwoPi=6.283185307179586;this.calculateEndingGlobalCoordinates=function(ellipsoid,start,startBearing,distance){return org.gavaghan.geodesy.GeodeticCalculator.calculateEndingGlobalCoordinates(ellipsoid,start,startBearing,distance,null);};this.calculateGeodeticCurve=function(ellipsoid,start,end){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var lambda1=org.gavaghan.geodesy.Angle.toRadians(start.getLongitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var lambda2=org.gavaghan.geodesy.Angle.toRadians(end.getLongitude());var a2=a*a;var b2=b*b;var a2b2b2=(a2-b2)/b2;var omega=lambda2-lambda1;var tanphi1=Math.tan(phi1);var tanU1=(1.0-f)*tanphi1;var U1=Math.atan(tanU1);var sinU1=Math.sin(U1);var cosU1=Math.cos(U1);var tanphi2=Math.tan(phi2);var tanU2=(1.0-f)*tanphi2;var U2=Math.atan(tanU2);var sinU2=Math.sin(U2);var cosU2=Math.cos(U2);var sinU1sinU2=sinU1*sinU2;var cosU1sinU2=cosU1*sinU2;var sinU1cosU2=sinU1*cosU2;var cosU1cosU2=cosU1*cosU2;var lambda=omega;var A=0.0;var B=0.0;var sigma=0.0;var deltasigma=0.0;var lambda0;var converged=false;for(var i=0;i<20;i++){lambda0=lambda;var sinlambda=Math.sin(lambda);var coslambda=Math.cos(lambda);var sin2sigma=(cosU2*sinlambda*cosU2*sinlambda)+(cosU1sinU2-sinU1cosU2*coslambda)*(cosU1sinU2-sinU1cosU2*coslambda);var sinsigma=Math.sqrt(sin2sigma);var cossigma=sinU1sinU2+(cosU1cosU2*coslambda);sigma=Math.atan2(sinsigma,cossigma);var sinalpha=(sin2sigma===0)?0.0:cosU1cosU2*sinlambda/sinsigma;var alpha=Math.asin(sinalpha);var cosalpha=Math.cos(alpha);var cos2alpha=cosalpha*cosalpha;var cos2sigmam=cos2alpha===0.0?0.0:cossigma-2*sinU1sinU2/cos2alpha;var u2=cos2alpha*a2b2b2;var cos2sigmam2=cos2sigmam*cos2sigmam;A=1.0+u2/16384*(4096+u2*(-768+u2*(320-175*u2)));B=u2/1024*(256+u2*(-128+u2*(74-47*u2)));deltasigma=B*sinsigma*(cos2sigmam+B/4*(cossigma*(-1+2*cos2sigmam2)-B/6*cos2sigmam*(-3+4*sin2sigma)*(-3+4*cos2sigmam2)));var C=f/16*cos2alpha*(4+f*(4-3*cos2alpha));lambda=omega+(1-C)*f*sinalpha*(sigma+C*sinsigma*(cos2sigmam+C*cossigma*(-1+2*cos2sigmam2)));var change=Math.abs((lambda-lambda0)/lambda);if((i>1)&&(change<0.0000000000001)){converged=true;break;}} -var s=b*A*(sigma-deltasigma);var alpha1;var alpha2;if(!converged){if(phi1>phi2){alpha1=180.0;alpha2=0.0;}else if(phi1=360.0) -alpha1-=360.0;if(alpha2>=360.0) -alpha2-=360.0;return new org.gavaghan.geodesy.GeodeticCurve(s,alpha1,alpha2);};this.calculateGeodeticMeasurement=function(refEllipsoid,start,end){var elev1=start.getElevation();var elev2=end.getElevation();var elev12=(elev1+elev2)/2.0;var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var phi12=(phi1+phi2)/2.0;var refA=refEllipsoid.getSemiMajorAxis();var f=refEllipsoid.getFlattening();var a=refA+elev12*(1.0+f*Math.sin(phi12));var ellipsoid=org.gavaghan.geodesy.Ellipsoid.fromAAndF(a,f);var start1=new org.gavaghan.geodesy.GlobalCoordinates(start.getLatitude(),start.getLongitude());var end1=new org.gavaghan.geodesy.GlobalCoordinates(end.getLatitude(),end.getLongitude());var averageCurve=org.gavaghan.geodesy.GeodeticCalculator.calculateGeodeticCurve(ellipsoid,start1,end1);return new org.gavaghan.geodesy.GeodeticMeasurement(averageCurve,elev2-elev1);};};org.gavaghan.geodesy.GeodeticCalculator.calculateEndingGlobalCoordinates=function(ellipsoid,start,startBearing,distance,endBearing){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var aSquared=a*a;var bSquared=b*b;var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var alpha1=org.gavaghan.geodesy.Angle.toRadians(startBearing);var cosAlpha1=Math.cos(alpha1);var sinAlpha1=Math.sin(alpha1);var s=distance;var tanU1=(1.0-f)*Math.tan(phi1);var cosU1=1.0/Math.sqrt(1.0+tanU1*tanU1);var sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var sin2Alpha=sinAlpha*sinAlpha;var cos2Alpha=1-sin2Alpha;var uSquared=cos2Alpha*(aSquared-bSquared)/bSquared;var A=1+(uSquared/16384)*(4096+uSquared*(-768+uSquared*(320-175*uSquared)));var B=(uSquared/1024)*(256+uSquared*(-128+uSquared*(74-47*uSquared)));var deltaSigma;var sOverbA=s/(b*A);var sigma=sOverbA;var sinSigma;var prevSigma=sOverbA;var sigmaM2;var cosSigmaM2;var cos2SigmaM2;for(;;){sigmaM2=2.0*sigma1+sigma;cosSigmaM2=Math.cos(sigmaM2);cos2SigmaM2=cosSigmaM2*cosSigmaM2;sinSigma=Math.sin(sigma);var cosSignma=Math.cos(sigma);deltaSigma=B*sinSigma*(cosSigmaM2+(B/4.0)*(cosSignma*(-1+2*cos2SigmaM2)-(B/6.0)*cosSigmaM2*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM2)));sigma=sOverbA+deltaSigma;if(Double.isNaN(sigma)||Double.isNaN(prevSigma)){throw new RuntimeException("Point values may be the same; approximation convereged to NaN");} -if(Math.abs(sigma-prevSigma)<0.0000000000001) -break;prevSigma=sigma;} -sigmaM2=2.0*sigma1+sigma;cosSigmaM2=Math.cos(sigmaM2);cos2SigmaM2=cosSigmaM2*cosSigmaM2;var cosSigma=Math.cos(sigma);sinSigma=Math.sin(sigma);var phi2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1.0-f)*Math.sqrt(sin2Alpha+Math.pow(sinU1*sinSigma-cosU1*cosSigma*cosAlpha1,2.0)));var lambda=Math.atan2(sinSigma*sinAlpha1,(cosU1*cosSigma-sinU1*sinSigma*cosAlpha1));var C=(f/16)*cos2Alpha*(4+f*(4-3*cos2Alpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cosSigmaM2+C*cosSigma*(-1+2*cos2SigmaM2)));var alpha2=Math.atan2(sinAlpha,-sinU1*sinSigma+cosU1*cosSigma*cosAlpha1);var latitude=org.gavaghan.geodesy.Angle.toDegrees(phi2);var longitude=start.getLongitude()+org.gavaghan.geodesy.Angle.toDegrees(L);if((endBearing!==null)&&(endBearing.length>0)){endBearing[0]=org.gavaghan.geodesy.Angle.toDegrees(alpha2);} -return new org.gavaghan.geodesy.GlobalCoordinates(latitude,longitude);};org.gavaghan.geodesy.GeodeticCalculator.calculateGeodeticCurve=function(ellipsoid,start,end){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var lambda1=org.gavaghan.geodesy.Angle.toRadians(start.getLongitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var lambda2=org.gavaghan.geodesy.Angle.toRadians(end.getLongitude());var a2=a*a;var b2=b*b;var a2b2b2=(a2-b2)/b2;var omega=lambda2-lambda1;var tanphi1=Math.tan(phi1);var tanU1=(1.0-f)*tanphi1;var U1=Math.atan(tanU1);var sinU1=Math.sin(U1);var cosU1=Math.cos(U1);var tanphi2=Math.tan(phi2);var tanU2=(1.0-f)*tanphi2;var U2=Math.atan(tanU2);var sinU2=Math.sin(U2);var cosU2=Math.cos(U2);var sinU1sinU2=sinU1*sinU2;var cosU1sinU2=cosU1*sinU2;var sinU1cosU2=sinU1*cosU2;var cosU1cosU2=cosU1*cosU2;var lambda=omega;var A=0.0;var B=0.0;var sigma=0.0;var deltasigma=0.0;var lambda0;var converged=false;for(var i=0;i<20;i++){lambda0=lambda;var sinlambda=Math.sin(lambda);var coslambda=Math.cos(lambda);var sin2sigma=(cosU2*sinlambda*cosU2*sinlambda)+(cosU1sinU2-sinU1cosU2*coslambda)*(cosU1sinU2-sinU1cosU2*coslambda);var sinsigma=Math.sqrt(sin2sigma);var cossigma=sinU1sinU2+(cosU1cosU2*coslambda);sigma=Math.atan2(sinsigma,cossigma);var sinalpha=(sin2sigma===0)?0.0:cosU1cosU2*sinlambda/sinsigma;var alpha=Math.asin(sinalpha);var cosalpha=Math.cos(alpha);var cos2alpha=cosalpha*cosalpha;var cos2sigmam=cos2alpha===0.0?0.0:cossigma-2*sinU1sinU2/cos2alpha;var u2=cos2alpha*a2b2b2;var cos2sigmam2=cos2sigmam*cos2sigmam;A=1.0+u2/16384*(4096+u2*(-768+u2*(320-175*u2)));B=u2/1024*(256+u2*(-128+u2*(74-47*u2)));deltasigma=B*sinsigma*(cos2sigmam+B/4*(cossigma*(-1+2*cos2sigmam2)-B/6*cos2sigmam*(-3+4*sin2sigma)*(-3+4*cos2sigmam2)));var C=f/16*cos2alpha*(4+f*(4-3*cos2alpha));lambda=omega+(1-C)*f*sinalpha*(sigma+C*sinsigma*(cos2sigmam+C*cossigma*(-1+2*cos2sigmam2)));var change=Math.abs((lambda-lambda0)/lambda);if((i>1)&&(change<0.0000000000001)){converged=true;break;}} -var s=b*A*(sigma-deltasigma);var alpha1;var alpha2;if(!converged){if(phi1>phi2){alpha1=180.0;alpha2=0.0;}else if(phi1=360.0) -alpha1-=360.0;if(alpha2>=360.0) -alpha2-=360.0;return new org.gavaghan.geodesy.GeodeticCurve(s,alpha1,alpha2);};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticCurve=function() -{this.mEllipsoidalDistance=0;this.mAzimuth=0;this.mReverseAzimuth=0;var ellipsoidalDistance=arguments[0];var azimuth=arguments[1];var reverseAzimuth=arguments[2];this.mEllipsoidalDistance=ellipsoidalDistance;this.mAzimuth=azimuth;this.mReverseAzimuth=reverseAzimuth;this.getEllipsoidalDistance=function(){return this.mEllipsoidalDistance;};this.getAzimuth=function(){return this.mAzimuth;};this.getReverseAzimuth=function(){return this.mReverseAzimuth;};this.toString=function(){var buffer="";buffer+="s=";buffer+=this.mEllipsoidalDistance;buffer+=";a12=";buffer+=this.mAzimuth;buffer+=";a21=";buffer+=this.mReverseAzimuth;buffer+=";";return buffer;};};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticMeasurement=function() -{this.mElevationChange=0;this.mP2P=0;this.mEllipsoidalDistance=0;this.mAzimuth=0;this.mReverseAzimuth=0;var ellipsoidalDistance;var azimuth;var reverseAzimuth;var elevationChange;if(arguments.length===4) -{ellipsoidalDistance=arguments[0];azimuth=arguments[1];reverseAzimuth=arguments[2];elevationChange=arguments[3];this.mEllipsoidalDistance=ellipsoidalDistance;this.mAzimuth=azimuth;this.mReverseAzimuth=reverseAzimuth;this.mElevationChange=elevationChange;this.mP2P=Math.sqrt(ellipsoidalDistance*ellipsoidalDistance+this.mElevationChange*this.mElevationChange);} -if(arguments.length===2) -{var averageCurve=arguments[0];elevationChange=arguments[1];this.mEllipsoidalDistance=averageCurve.getEllipsoidalDistance();this.mAzimuth=averageCurve.getAzimuth();this.mReverseAzimuth=averageCurve.getReverseAzimuth();this.mElevationChange=elevationChange;} -this.getElevationChange=function(){return this.mElevationChange;};this.getPointToPointDistance=function(){return this.mP2P;};this.toString=function(){var buffer="";buffer+="s=";buffer+=this.mEllipsoidalDistance;buffer+=";a12=";buffer+=this.mAzimuth;buffer+=";a21=";buffer+=this.mReverseAzimuth;buffer+=";";buffer+=("elev12=");buffer+=(this.mElevationChange);buffer+=(";p2p=");buffer+=(this.mP2P);return buffer;};};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GlobalCoordinates=function() -{this.mLatitude=0;this.mLongitude=0;var latitude=arguments[0];var longitude=arguments[1];this.mLatitude=latitude;this.mLongitude=longitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);this.canonicalize=function() -{this.mLatitude=(this.mLatitude+180)%360;if(this.mLatitude<0) -this.mLatitude+=360;this.mLatitude-=180;if(this.mLatitude>90){this.mLatitude=180-this.mLatitude;this.mLongitude+=180;}else if(this.mLatitude<-90){this.mLatitude=-180-this.mLatitude;this.mLongitude+=180;} -this.mLongitude=((this.mLongitude+180)%360);if(this.mLongitude<=0) -this.mLongitude+=360;this.mLongitude-=180;};this.getLatitude=function(){return this.mLatitude;};this.setLatitude=function(latitude){this.mLatitude=latitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);};this.getLongitude=function(){return this.mLongitude;};this.setLongitude=function(longitude){this.mLongitude=longitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);};this.compareTo=function(other){var retval;if(this.mLongitudeother.mLongitude) -retval=1;else if(this.mLatitudeother.mLatitude) -retval=1;else -retval=0;return retval;};this.hashCode=function(){return(Math.round((this.mLongitude*this.mLatitude*1000000+1021)))*1000033;};this.equals=function(obj){if(!(Clazz.instanceOf(obj,org.gavaghan.geodesy.GlobalCoordinates))) -return false;var other=obj;return(this.mLongitude===other.mLongitude)&&(this.mLatitude===other.mLatitude);};this.toString=function(){var buffer="";buffer+=(Math.abs(this.mLatitude));buffer+=(((this.mLatitude>=0)?'N':'S')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=(Math.abs(this.mLongitude));buffer+=(((this.mLongitude>=0)?'E':'W')).charCodeAt(0);buffer+=((';')).charCodeAt(0);return buffer;};};org.gavaghan.geodesy.GlobalCoordinates.canonicalize=function(that) -{that.mLatitude=(that.mLatitude+180)%360;if(that.mLatitude<0) -that.mLatitude+=360;that.mLatitude-=180;if(that.mLatitude>90){that.mLatitude=180-that.mLatitude;that.mLongitude+=180;}else if(that.mLatitude<-90){that.mLatitude=-180-that.mLatitude;that.mLongitude+=180;} -that.mLongitude=((that.mLongitude+180)%360);if(that.mLongitude<=0) -that.mLongitude+=360;that.mLongitude-=180;};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GlobalPosition=function() -{this.mElevation=0;this.mLatitude=0;this.mLongitude=0;var latitude;var longitude;var elevation;if(arguments.length===3) -{latitude=arguments[0];longitude=arguments[1];elevation=arguments[2];this.mLatitude=latitude;this.mLongitude=longitude;org.gavaghan.geodesy.GlobalPosition.canonicalize(this);this.mElevation=elevation;} -if(arguments.length===2) -{var coords=arguments[0];elevation=arguments[1];this.mLatitude=coords.getLatitude();this.mLongitude=coords.getLongitude();org.gavaghan.geodesy.GlobalPosition.canonicalize(this);this.mElevation=elevation;} -this.getElevation=function(){return this.mElevation;};this.setElevation=function(elevation){this.mElevation=elevation;};this.compareTo=function(other){var retval;if(this.mLongitudeother.mLongitude) -retval=1;else if(this.mLatitudeother.mLatitude) -retval=1;else -retval=0;if(retval===0){if(this.mElevationother.mElevation) -retval=1;} -return retval;};this.hashCode=function(){var hash=Clazz.superCall(this,org.gavaghan.geodesy.GlobalPosition,"hashCode",[]);if(this.mElevation!==0) -hash*=Math.round(this.mElevation);return hash;};this.equals=function(obj){if(!(Clazz.instanceOf(obj,org.gavaghan.geodesy.GlobalPosition))) -return false;var other=obj;return(this.mElevation===other.mElevation)&&(Clazz.superCall(this,org.gavaghan.geodesy.GlobalPosition,"equals",[other]));};this.toString=function(){var buffer="";buffer+=(Math.abs(this.mLatitude));buffer+=(((this.mLatitude>=0)?'N':'S')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=(Math.abs(this.mLongitude));buffer+=(((this.mLongitude>=0)?'E':'W')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=("elevation=");buffer+=(Double.toString(this.mElevation));buffer+=("m");return buffer;};this.canonicalize=function(){this.mLatitude=(this.mLatitude+180)%360;if(this.mLatitude<0) -this.mLatitude+=360;this.mLatitude-=180;if(this.mLatitude>90){this.mLatitude=180-this.mLatitude;this.mLongitude+=180;}else if(this.mLatitude<-90){this.mLatitude=-180-this.mLatitude;this.mLongitude+=180;} -this.mLongitude=((this.mLongitude+180)%360);if(this.mLongitude<=0) -this.mLongitude+=360;this.mLongitude-=180;};this.getLatitude=function(){return this.mLatitude;};this.getLongitude=function(){return this.mLongitude;};};org.gavaghan.geodesy.GlobalPosition.canonicalize=function(obj){obj.mLatitude=(obj.mLatitude+180)%360;if(obj.mLatitude<0) -obj.mLatitude+=360;obj.mLatitude-=180;if(obj.mLatitude>90){obj.mLatitude=180-obj.mLatitude;obj.mLongitude+=180;}else if(obj.mLatitude<-90){obj.mLatitude=-180-obj.mLatitude;obj.mLongitude+=180;} -obj.mLongitude=((obj.mLongitude+180)%360);if(obj.mLongitude<=0) -this.mLongitude+=360;obj.mLongitude-=180;};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoArc=function() -{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} -var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoArc.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distancerightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} -var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){count++;var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoArc.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D(0,0).distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} -break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} -it.next();}} -this.path.append(newPath,true);this.toPoints.add(point);};this.getToPoints=function(){return this.toPoints;};this.closePath=function(){if(this.toPoints.size()>0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.geoCalc=null;var pivot=arguments[0];var widthMeters=arguments[1];var heightMeters=arguments[2];var leftAzimuth=arguments[3];var rightAzimuth=arguments[4];var maxDistanceMeters=arguments[5];var flatnessDistanceMeters=arguments[6];var limit=arguments[7];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;this.flatnessDistanceMeters=flatnessDistanceMeters;this.limit=limit;this.moveTo(pivot);this.arcTo(pivot,widthMeters,heightMeters,leftAzimuth,rightAzimuth);this.closePath();};sec.geo.GeoArc.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoBlock=function() -{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.simplify=function(){var pi=this.path.getPathIterator(null);var pts=pi.getPoints();var newPts=new java.util.ArrayList();var j=0;var style=-1;var lastStyle=-1;var nextstyle=-1;var currentPt=null;var lastPt=null;for(j=0;j0){lastStyle=pts.get(j-1).style;lastPt=pts.get(j-1);} -if(lastStyle===1&&style===0){if(currentPt.x===lastPt.x&¤tPt.y===lastPt.y) -continue;} -newPts.add(currentPt);} -pi.setPathIterator(newPts);};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} -var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.geoCalc=null;var p1=arguments[0];var p2=arguments[1];var widthMeters=arguments[2];var maxDistanceMeters=arguments[3];var flatnessDistanceMeters=arguments[4];var limit=arguments[5];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;var c1=this.toGlobalCoord(p1);var c2=this.toGlobalCoord(p2);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,c2);var a1=curve.getAzimuth();var a2=curve.getReverseAzimuth();var radius=widthMeters/2;var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,a1-90,radius);this.moveToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c2,a2+90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c2,a2-90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,a1+90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());this.closePath();};sec.geo.GeoBlock.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoBlock2=function() -{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} -var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at,flatness){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.simplify=function(){var pi=this.path.getPathIterator(null);var pts=pi.getPoints();var newPts=new java.util.ArrayList();var j=0;var style=-1;var lastStyle=-1;var nextstyle=-1;var currentPt=null;var lastPt=null;for(j=0;j0){lastStyle=pts.get(j-1).style;lastPt=pts.get(j-1);} -if(lastStyle===1&&style===0){if(currentPt.x===lastPt.x&¤tPt.y===lastPt.y)continue;} -newPts.add(currentPt);} -pi.setPathIterator(newPts);};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.geoCalc=null;var p1=arguments[0];var p2=arguments[1];var leftWidthMeters=arguments[2];var rightWidthMeters=arguments[3];var maxDistanceMeters=arguments[4];var flatnessDistanceMeters=arguments[5];var limit=arguments[6];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;var c1=this.toGlobalCoord(p1);var c2=this.toGlobalCoord(p2);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,c2);var a1=curve.getAzimuth();var a2=curve.getReverseAzimuth();var leftRadius=leftWidthMeters;var rightRadius=rightWidthMeters;var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,a1-90,leftRadius);this.moveToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c2,a2+90,leftRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c2,a2-90,rightRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,a1+90,rightRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());this.closePath();};sec.geo.GeoBlock2.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoEllipse=function() -{this.arcTo=function(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var arc;if(leftAzimuthDegrees>rightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} -var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoEllipse.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D().distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} -break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} -it.next();}} -this.path.append(newPath,true);this.toPoints.add(point);};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} -var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoEllipse.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} -var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoPath.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distancerightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} -var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoPath.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D(0,0).distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} -break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} -it.next();}} -this.path.append(newPath,true);this.toPoints.add(point);};this.getToPoints=function(){return this.toPoints;};this.closePath=function(){if(this.toPoints.size()>0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};};sec.geo.GeoPath.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoPoint=function() -{this.x=0;this.y=0;if(arguments.length===2) -{var longitudeDegrees=arguments[0];var latitudeDegrees=arguments[1];this.x=longitudeDegrees;this.y=latitudeDegrees;} -this.getLatitude=function(){return this.y;};this.setLatitude=function(latitudeDegrees){this.y=latitudeDegrees;};this.getLongitude=function(){return this.x;};this.setLongitude=function(longitudeDegrees){this.x=longitudeDegrees;};this.toString=function(){return this.x+","+this.y;};this.equals=function(x1,y1) -{if(x1===this.x&&y1===this.y) -return true;else -return false;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.ShapeObject=function() -{this.type=-1;this.geoEllipse=null;this.geoPath=null;this.geoArc=null;this.geoBlock=null;this.geoBlock2=null;this.geoPoint=null;this.area=null;this.geoCalc=null;var obj=null;if(arguments.length===1) -obj=arguments[0];if(Clazz.instanceOf(obj,sec.geo.GeoArc)) -{this.geoArc=obj;this.type=0;} -else if(Clazz.instanceOf(obj,sec.geo.GeoPath)) -{this.geoPath=obj;this.type=4;} -else if(Clazz.instanceOf(obj,sec.geo.GeoEllipse)) -{this.geoEllipse=obj;this.type=3;} -else if(Clazz.instanceOf(obj,sec.geo.GeoBlock)) -{this.geoBlock=obj;this.type=1;} -else if(Clazz.instanceOf(obj,sec.geo.GeoBlock2)) -{this.geoBlock2=obj;this.type=2;} -else if(Clazz.instanceOf(obj,sec.geo.GeoPoint)) -{this.geoPoint=obj;this.type=5;} -else if(Clazz.instanceOf(obj,armyc2.c2sd.graphics2d.Area)){this.area=obj;this.type=6;} -this.arcTo=function(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees){switch(this.type){case 3:this.geoEllipse.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;case 0:this.geoArc.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;case 4:this.geoPath.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;default:break;}};this.getPathIterator=function(at){switch(this.type){case 3:return this.geoEllipse.getPathIterator(at);case 4:return this.geoPath.getPathIterator(at);case 1:return this.geoBlock.getPathIterator(at);case 2:return this.geoBlock2.getPathIterator(at,0);case 0:return this.geoArc.getPathIterator(at);default:return null;}};this.moveTo=function(point){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.moveTo(point);break;case 4:this.geoPath.moveTo(point);break;case 1:this.geoBlock.moveTo(point);break;case 2:this.geoBlock2.moveTo(point);break;default:break;}};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 4:this.geoPath.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 1:this.geoBlock.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 2:this.geoBlock2.moveToLatLong(longitudeDegrees,latitudeDegrees);break;default:break;}};this.lineTo=function(point){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.lineTo(point);break;case 4:this.geoPath.lineTo(point);break;case 1:this.geoBlock.lineTo(point);break;case 2:this.geoBlock2.lineTo(point);break;default:break;}};this.lineToLatLong=function(longitudeDegrees,latitudeDegrees){this.lineTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.closePath=function(){switch(this.type){case 0:this.geoArc.closePath();break;case 1:this.geoBlock.closePath();break;case 2:this.geoBlock2.closePath();break;case 4:this.geoPath.closePath();;break;default:break;}};};sec.geo.ShapeObject.GEOARC=0;sec.geo.ShapeObject.GEOBLOCK=1;sec.geo.ShapeObject.GEOBLOCK2=2;sec.geo.ShapeObject.GEOELLIPSE=3;sec.geo.ShapeObject.GEOPATH=4;sec.geo.ShapeObject.GEOPOINT=5;sec.geo.ShapeObject.AREA=6;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.AExtObject=function() -{this.type=-1;this.orbit=null;this.cake=null;this.circle=null;this.point=null;this.radarc=null;this.polyarc=null;this.polygon=null;this.line=null;this.route=null;this.track=null;var obj=arguments[0];if(Clazz.instanceOf(obj,Integer)) -{this.type=(obj).intValue();switch(this.type){case 1:this.line=new sec.geo.shape.Line();break;case 2:this.orbit=new sec.geo.shape.Orbit();break;case 5:this.radarc=new sec.geo.shape.Radarc();break;case 0:this.cake=new sec.geo.shape.Cake();break;default:break;}} -else if(Clazz.instanceOf(obj,sec.geo.shape.Line)){this.line=obj;this.type=1;}else if(Clazz.instanceOf(obj,sec.geo.shape.Route)){this.route=obj;this.type=8;}else if(Clazz.instanceOf(obj,sec.geo.shape.Polygon)){this.polygon=obj;this.type=7;}else if(Clazz.instanceOf(obj,sec.geo.shape.Radarc)){this.radarc=obj;this.type=5;}else if(Clazz.instanceOf(obj,sec.geo.shape.Polyarc)){this.polyarc=obj;this.type=6;}else if(Clazz.instanceOf(obj,sec.geo.shape.Orbit)){this.orbit=obj;this.type=2;}else if(Clazz.instanceOf(obj,sec.geo.shape.Cake)){this.cake=obj;this.type=0;}else if(Clazz.instanceOf(obj,sec.geo.shape.Circle)){this.circle=obj;this.type=4;}else if(Clazz.instanceOf(obj,sec.geo.shape.Point)){this.point=obj;this.type=3;}else if(Clazz.instanceOf(obj,sec.geo.shape.Track)){this.track=obj;this.type=9;} -this.getElements=function() -{if(this.track!==null) -return this.track.elements;else if(this.cake!==null) -return this.cake.elements;else -return null;};this.setMaxDistance=function(maxDistanceMeters){switch(this.type){case 2:this.orbit.setMaxDistance(maxDistanceMeters);break;case 4:this.circle.setMaxDistance(maxDistanceMeters);break;case 5:this.radarc.setMaxDistance(maxDistanceMeters);break;case 6:this.polyarc.setMaxDistance(maxDistanceMeters);break;case 7:this.polygon.setMaxDistance(maxDistanceMeters);break;case 8:this.route.setMaxDistance(maxDistanceMeters);break;case 1:this.line.setMaxDistance(maxDistanceMeters);break;case 4:this.circle.setMaxDistance(maxDistanceMeters);break;default:break;}};this.addPoint=function(point){switch(this.type){case 1:this.line.addPoint(point);break;case 5:break;case 2:this.orbit.addPoint(point);break;case 6:this.polyarc.addPoint(point);break;case 7:this.polygon.addPoint(point);break;case 8:this.route.addPoint(point);break;default:break;} -return;};this.setFlatness=function(flatnessDistanceMeters){switch(this.type){case 1:this.line.setFlatness(flatnessDistanceMeters);break;case 2:this.orbit.setFlatness(flatnessDistanceMeters);break;case 4:this.circle.setFlatness(flatnessDistanceMeters);break;case 5:this.radarc.setFlatness(flatnessDistanceMeters);break;case 6:this.polyarc.setFlatness(flatnessDistanceMeters);break;case 7:this.polygon.setFlatness(flatnessDistanceMeters);break;case 8:this.route.setFlatness(flatnessDistanceMeters);break;default:break;} -this.shapeChanged();};this.setLimit=function(limit){switch(this.type){case 1:this.line.setLimit(limit);break;case 2:this.orbit.setLimit(limit);break;case 4:this.circle.setLimit(limit);break;case 5:this.radarc.setLimit(limit);break;case 6:this.polyarc.setLimit(limit);break;case 7:this.polygon.setLimit(limit);break;case 8:this.route.setLimit(limit);break;default:break;} -this.shapeChanged();};this.getMinAltitude=function(){switch(this.type){case 1:return this.line.getMinAltitude();case 2:return this.orbit.getMinAltitude();case 4:return this.circle.getMinAltitude();case 6:return this.polyarc.getMinAltitude();case 7:return this.polygon.getMinAltitude();case 8:return this.route.getMinAltitude();case 5:return this.radarc.getMinAltitude();default:return-1;}};this.getMaxAltitude=function(){switch(this.type){case 1:return this.line.getMaxAltitude();case 2:return this.orbit.getMaxAltitude();case 4:return this.circle.getMaxAltitude();case 6:return this.polyarc.getMaxAltitude();case 7:return this.polygon.getMaxAltitude();case 8:return this.route.getMaxAltitude();case 5:return this.radarc.getMaxAltitude();default:return-1;} -return-1;};this.getAltitudeMode=function(){switch(this.type){case 1:return this.line.getAltitudeMode();case 2:return this.orbit.getAltitudeMode();case 4:return this.circle.getAltitudeMode();case 6:return this.polyarc.getAltitudeMode();case 7:return this.polygon.getAltitudeMode();case 8:return this.route.getAltitudeMode();case 5:return this.radarc.getAltitudeMode();default:return sec.geo.kml.KmlOptions.AltitudeMode.ABSOLUTE;}};this.getPathIterator=function(at){switch(this.type){case 1:return this.line.getShape().getPathIterator(at);case 2:return this.orbit.getShape().getPathIterator(at);case 7:return this.polygon.getShape().getPathIterator(at);case 6:return this.polyarc.getShape().getPathIterator(at);case 4:return this.circle.getShape().getPathIterator(at);case 5:return this.radarc.getShape().getPathIterator(at);case 8:return this.route.getShape().getPathIterator(at);default:return null;}};this.shapeChanged=function(){switch(this.type){case 7:this.polygon.shapeChanged();break;case 2:this.orbit.shapeChanged();break;case 8:this.route.shapeChanged();break;case 5:this.radarc.shapeChanged();break;case 6:this.polyarc.shapeChanged();break;default:break;}};};sec.geo.shape.AExtObject.CAKE=0;sec.geo.shape.AExtObject.LINE=1;sec.geo.shape.AExtObject.ORBIT=2;sec.geo.shape.AExtObject.POINT=3;sec.geo.shape.AExtObject.CIRCLE=4;sec.geo.shape.AExtObject.RADARC=5;sec.geo.shape.AExtObject.POLYARC=6;sec.geo.shape.AExtObject.POLYGON=7;sec.geo.shape.AExtObject.ROUTE=8;sec.geo.shape.AExtObject.TRACK=9;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Cake=function() -{this.elements=new java.util.ArrayList();this.pivot=new sec.geo.GeoPoint();this.addLayer=function(layer) -{if(Clazz.instanceOf(layer,sec.geo.shape.Polyarc)) -{layer.setPivot(this.pivot);this.elements.add(layer);} -else if(Clazz.instanceOf(layer,sec.geo.shape.Radarc)) -{layer.setPivot(this.pivot);this.elements.add(layer);} -else -{throw new IllegalArgumentException();}};this.setPivot=function(pivot) -{this.pivot=pivot;for(var j=0;j0){path.lineTo(this.points.get(i));}else{path.moveTo(this.points.get(i));}} -return new sec.geo.ShapeObject(path);};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} -return this.shape;};this.shapeChanged=function(){this.shape=null;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Orbit=function() -{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.altitudeMode=null;this.shape=null;this.limit=0;this.widthMeters=0;this.points=null;this.points=new java.util.ArrayList();this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.addPoint=function(point){this.points.add(point);this.shapeChanged();};this.addPoints=function(points){this.points.addAll(points);this.shapeChanged();};this.setWidth=function(widthMeters){this.widthMeters=widthMeters;this.shapeChanged();};this.createShape=function(){var orbit=new sec.sun.awt.geom.Area();var previousPoint=null;var point;var j=0;for(j=0;j0){path.lineTo(this.points.get(i));}else{path.moveTo(this.points.get(i));}} -path.closePath();return new sec.geo.ShapeObject(path);};this.shapeChanged=function(){this.shape=null;};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} -return this.shape;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Radarc=function() -{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.shape=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.minRadiusMeters=0;this.leftAzimuthDegrees=0;this.rightAzimuthDegrees=0;this.pivot=null;this.radiusMeters=0;this.altitudeMode=null;this.limit=0;this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.setRightAzimuthDegrees=function(rightAzimuthDegrees){this.rightAzimuthDegrees=rightAzimuthDegrees;this.shapeChanged();};this.setLeftAzimuthDegrees=function(leftAzimuthDegrees){this.leftAzimuthDegrees=leftAzimuthDegrees;this.shapeChanged();};this.setMinRadius=function(minRadiusMeters){this.minRadiusMeters=minRadiusMeters;this.shapeChanged();};this.shapeChanged=function(){this.shape=null;};this.createShape=function(){var arc=new sec.geo.GeoArc(this.pivot,this.radiusMeters*2,this.radiusMeters*2,this.leftAzimuthDegrees,this.rightAzimuthDegrees,this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);var arcObj=new sec.geo.ShapeObject(arc);var shape1=new sec.sun.awt.geom.Area(arcObj);var ellipse=new sec.geo.GeoEllipse(this.pivot,this.minRadiusMeters*2,this.minRadiusMeters*2,this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);var ellipseObj=new sec.geo.ShapeObject(ellipse);shape1.subtract(new sec.sun.awt.geom.Area(ellipseObj));return shape1;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};this.setRadius=function(radiusMeters){this.radiusMeters=radiusMeters;this.shapeChanged();};this.setPivot=function(pivot){this.pivot=pivot;this.shapeChanged();};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} -return this.shape;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Polyarc=function() -{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.shape=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.pivot=null;this.radiusMeters=0;this.leftAzimuthDegrees=0;this.rightAzimuthDegrees=0;this.altitudeMode=null;this.points=null;this.points=new java.util.ArrayList();this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.addPoint=function(point) -{this.points.add(point);this.shapeChanged();};this.addPoints=function(points) -{this.points.addAll(points);this.shapeChanged();};this.setRadius=function(radiusMeters) -{this.radiusMeters=radiusMeters;this.shapeChanged();};this.setPivot=function(pivot) -{this.pivot=pivot;this.shapeChanged();};this.setRightAzimuthDegrees=function(rightAzimuthDegrees) -{this.rightAzimuthDegrees=rightAzimuthDegrees;this.shapeChanged();};this.setLeftAzimuthDegrees=function(leftAzimuthDegrees) -{this.leftAzimuthDegrees=leftAzimuthDegrees;this.shapeChanged();};this.createShape=function() -{var path=new sec.geo.GeoPath(this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);for(var i=0;i1){return false;}} -return true;};this.isRectangular=function(){var size=this.curves.size();if(size===0){return true;} -if(size>3){return false;} -var c1=this.curves.get(1);var c2=this.curves.get(2);if(c1.getOrder()!==1||c2.getOrder()!==1){return false;} -if(c1.getXTop()!==c1.getXBot()||c2.getXTop()!==c2.getXBot()){return false;} -if(c1.getYTop()!==c2.getYTop()||c1.getYBot()!==c2.getYBot()){return false;} -return true;};this.isSingular=function(){if(this.curves.size()<3){return true;} -var enum_=this.curves.elements();enum_.nextElement();while(enum_.hasMoreElements()){if((enum_.nextElement()).getOrder()===0){return false;}} -return true;};this.invalidateBounds=function(){this.cachedBounds=null;};this.equals=function(other){if(other===this){return true;} -if(other===null){return false;} -var c=new sec.sun.awt.geom.SomeOp(3).calculate(this.curves,other.curves);return c.isEmpty();};this.getPathIterator=function(at){return new sec.sun.awt.geom.AreaIterator(this.curves,at);};};sec.sun.awt.geom.Area.pathToCurves=function(pi) -{var curves=new sec.sun.awt.geom.Vector();var windingRule=pi.getWindingRule();var coords=new Array(23);var movx=0;var movy=0;var curx=0;var cury=0;var newx;var newy;while(!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(movx>0) -movx-=360;if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);curx=movx=coords[0];cury=movy=coords[1];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(movx>0) -movx-=360;} -sec.sun.awt.geom.Curve.insertMove(curves,movx,movy);break;case 1:newx=coords[0];newy=coords[1];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(newx>0) -newx-=360;if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,newx,newy);curx=newx;cury=newy;break;case 2:newx=coords[2];newy=coords[3];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertQuad(curves,curx,cury,coords);curx=newx;cury=newy;break;case 3:newx=coords[4];newy=coords[5];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertCubic(curves,curx,cury,coords);curx=newx;cury=newy;break;case 4:if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(movx>0) -movx-=360;if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);curx=movx;cury=movy;break;} -pi.next();} -if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) -{if(movx>0) -movx-=360;if(curx>0) -curx-=360;} -sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);var operator2=null;if(windingRule===0){operator2=new sec.sun.awt.geom.AreaOp2(0);}else{operator2=new sec.sun.awt.geom.AreaOp2(1);} -var emptyCurves=new sec.sun.awt.geom.Vector();return operator2.calculate(curves,emptyCurves);};sec.sun.awt.geom.Area.normalizeGeoPoints=true;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.AreaIterator=function() -{this.transform=null;this.curves=null;this.index=0;this.prevcurve=null;this.thiscurve=null;var curves;var at;if(arguments.length===2) -{curves=arguments[0];at=arguments[1];this.curves=curves;this.transform=at;if(curves.size()>=1){this.thiscurve=curves.get(0);}} -this.getWindingRule=function(){return 1;};this.isDone=function(){return(this.prevcurve===null&&this.thiscurve===null);};this.next=function(){if(this.prevcurve!==null){this.prevcurve=null;}else{this.prevcurve=this.thiscurve;this.index++;if(this.index=left;cur--){e=edgelist[cur];if(e.getCurve().getYBot()>y){if(next>cur){edgelist[next]=e;} -next--;}} -left=next+1;if(left>=right){if(right>=numedges){break;} -y=edgelist[right].getCurve().getYTop();if(y>yrange[0]){sec.sun.awt.geom.AreaOp2.finalizeSubCurves(subcurves,chains);} -yrange[0]=y;} -while(righty){break;} -right++;} -yrange[1]=edgelist[left].getCurve().getYBot();if(righty){yrange[1]=y;}} -if(false){System.out.println("current line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curleft;next--){var prevedge=edgelist[next-1];var ordering=e.compareTo(prevedge,yrange);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping to "+yrange[1]+" from "+yrange[0]);} -if(ordering>=0){if(ordering===0){var eq=prevedge.getEquivalence();if(eq===0){eq=nexteq++;prevedge.setEquivalence(eq);} -e.setEquivalence(eq);} -break;} -edgelist[next]=prevedge;} -edgelist[next]=e;} -if(false){System.out.println("current sorted line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curfurthesty){longestmatch=e;furthesty=y;}}while(++cur0){edges.add(new sec.sun.awt.geom.Edge(c,curvetag));}}};sec.sun.awt.geom.AreaOp2.finalizeSubCurves=function(subcurves,chains){var numchains=chains.size();if(numchains===0){return;} -if((numchains&1)!==0){throw new InternalError("Odd number of chains!");} -var endlist=new Array(numchains);chains.toArray(endlist);for(var i=1;ilow&&sec.sun.awt.geom.Arrays.compare(dest[j-1],dest[j])>0;j--) -sec.sun.awt.geom.Arrays.swap(dest,j,j-1);return;} -var destLow=low;var destHigh=high;low+=off;high+=off;var mid=(low+high)>>>1;if(mid===45) -{sec.sun.awt.geom.Arrays.test=3;} -sec.sun.awt.geom.Arrays.mergeSort(dest,src,low,mid,-off);sec.sun.awt.geom.Arrays.mergeSort(dest,src,mid,high,-off);if(sec.sun.awt.geom.Arrays.compare(src[mid-1],src[mid])<=0){System.arraycopy(src,low,dest,destLow,length);} -for(i=destLow,p=low,q=mid;i=high||p=y1){return false;} -if(x0>=this.xhi&&x1>=this.xhi){return false;} -if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} -var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} -if(xstart>this.xlo||xend>this.xlo){return true;} -this.record(ystart,yend,direction);return false;};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} -var from=0;while(fromthis.yranges[from+1]){from+=2;} -var to=from;while(fromyhl){ystart=yhl;yhl=ylh;ylh=ystart;} -if(yll!==ylh){this.yranges[to++]=yll;this.yranges[to++]=ylh;} -ystart=yhl;yend=yhh;} -if(ystart>=yend){break;}} -if(to=this.yranges.length){var newranges=Clazz.newArray(to+10,0);System.arraycopy(this.yranges,0,newranges,0,to);this.yranges=newranges;} -this.yranges[to++]=ystart;this.yranges[to++]=yend;} -this.limit=to;};};sec.sun.awt.geom.Crossings.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.CrossingsObject=function() -{this.limit=0;this.yranges=null;this.xlo=0;this.ylo=0;this.xhi=0;this.yhi=0;this.crosscounts=null;this.evenOdd=null;this.crossings=null;this.nonZero=null;this.type=-1;this.tmp=null;this.yranges=Clazz.newArray(10,0);this.tmp=new sec.sun.awt.geom.Vector();var xlo=arguments[0];var ylo=arguments[1];var xhi=arguments[2];var yhi=arguments[3];var type=arguments[4];this.xlo=xlo;this.ylo=ylo;this.xhi=xhi;this.yhi=yhi;this.type=type;switch(type){case 0:this.crossings=new sec.sun.awt.geom.Crossings(xlo,ylo,xhi,yhi);break;case 1:this.nonZero=new sec.sun.awt.geom.NonZero(xlo,ylo,xhi,yhi);this.crosscounts=Clazz.newArray(Math.floor(this.yranges.length/2),0);break;case 2:this.evenOdd=new sec.sun.awt.geom.EvenOdd(xlo,ylo,xhi,yhi);break;} -this.getXLo=function(){switch(this.type){case 0:return this.crossings.getXLo();case 2:return this.evenOdd.getXLo();case 1:return this.nonZero.getXLo();default:return-1;}};this.getYLo=function(){switch(this.type){case 0:return this.crossings.getYLo();case 2:return this.evenOdd.getYLo();case 1:return this.nonZero.getYLo();default:return-1;}};this.getXHi=function(){switch(this.type){case 0:return this.crossings.getXHi();case 2:return this.evenOdd.getXHi();case 1:return this.nonZero.getXHi();default:return-1;}};this.getYHi=function(){switch(this.type){case 0:return this.crossings.getYHi();case 2:return this.evenOdd.getYHi();case 1:return this.nonZero.getYHi();default:return-1;}};this.isEmpty=function(){switch(this.type){case 0:return this.crossings.isEmpty();case 2:return this.evenOdd.isEmpty();case 1:return this.nonZero.isEmpty();default:return true;}};this.record=function(ystart,yend,direction){switch(this.type){case 0:this.crossings.record(ystart,yend,direction);case 2:this.evenOdd.record(ystart,yend,direction);case 1:this.nonZero.record(ystart,yend,direction);default:return;}};this.accumulateLine=function(x0,y0,x1,y1){switch(this.type){case 0:return this.crossings.accumulateLine(x0,y0,x1,y1);case 2:return this.evenOdd.accumulateLine(x0,y0,x1,y1);case 1:return this.nonZero.accumulateLine(x0,y0,x1,y1);default:return false;}};this.accumulateQuad=function(x0,y0,coords){if(y0this.yhi&&coords[1]>this.yhi&&coords[3]>this.yhi){return false;} -if(x0>this.xhi&&coords[0]>this.xhi&&coords[2]>this.xhi){return false;} -if(x0coords[3]){this.record(Math.max(coords[3],this.ylo),Math.min(y0,this.yhi),-1);} -return false;} -sec.sun.awt.geom.Curve.insertQuad(this.tmp,x0,y0,coords);var enum_=this.tmp.elements();while(enum_.hasMoreElements()){var c=enum_.nextElement();if(c.accumulateCrossings(this)){return true;}} -this.tmp.clear();return false;};this.accumulateCubic=function(x0,y0,coords){if(y0this.yhi&&coords[1]>this.yhi&&coords[3]>this.yhi&&coords[5]>this.yhi){return false;} -if(x0>this.xhi&&coords[0]>this.xhi&&coords[2]>this.xhi&&coords[4]>this.xhi){return false;} -if(x0y1) -{curves.add(new sec.sun.awt.geom.Order1(x1,y1,x0,y0,-1));}};sec.sun.awt.geom.Curve.insertQuad=function(curves,x0,y0,coords){var y1=coords[3];if(y0>y1){sec.sun.awt.geom.Order2.insert(curves,coords,coords[2],y1,coords[0],coords[1],x0,y0,-1);}else if(y0===y1&&y0===coords[1]){return;}else{sec.sun.awt.geom.Order2.insert(curves,coords,x0,y0,coords[0],coords[1],coords[2],y1,1);}};sec.sun.awt.geom.Curve.insertCubic=function(curves,x0,y0,coords){var y1=coords[5];if(y0>y1){sec.sun.awt.geom.Order3.insert(curves,coords,coords[4],y1,coords[2],coords[3],coords[0],coords[1],x0,y0,-1);}else if(y0===y1&&y0===coords[1]&&y0===coords[3]){return;}else{sec.sun.awt.geom.Order3.insert(curves,coords,x0,y0,coords[0],coords[1],coords[2],coords[3],coords[4],y1,1);}};sec.sun.awt.geom.Curve.pointCrossingsForPath=function(pi,px,py){if(pi.isDone()){return 0;} -var coords=Clazz.newArray(6,0);if(pi.currentSegment(coords)!==0){return-1;} -pi.next();var movx=coords[0];var movy=coords[1];var curx=movx;var cury=movy;var endx;var endy;var crossings=0;while(!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} -movx=curx=coords[0];movy=cury=coords[1];break;case 1:endx=coords[0];endy=coords[1];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,endx,endy);curx=endx;cury=endy;break;case 2:endx=coords[2];endy=coords[3];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,curx,cury,coords[0],coords[1],endx,endy,0);curx=endx;cury=endy;break;case 3:endx=coords[4];endy=coords[5];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,curx,cury,coords[0],coords[1],coords[2],coords[3],endx,endy,0);curx=endx;cury=endy;break;case 4:if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} -curx=movx;cury=movy;break;} -pi.next();} -if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} -return crossings;};sec.sun.awt.geom.Curve.pointCrossingsForLine=function(px,py,x0,y0,x1,y1){if(py=y0&&py>=y1) -return 0;if(px>=x0&&px>=x1) -return 0;if(px=xintercept) -return 0;return(y0=y0&&py>=yc&&py>=y1) -return 0;if(px>=x0&&px>=xc&&px>=x1) -return 0;if(px=y0){if(py=y1) -return-1;} -return 0;} -if(level>52) -return sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,x0,y0,x1,y1);var x0c=(x0+xc)/2;var y0c=(y0+yc)/2;var xc1=(xc+x1)/2;var yc1=(yc+y1)/2;xc=(x0c+xc1)/2;yc=(y0c+yc1)/2;if(Double.isNaN(xc)||Double.isNaN(yc)){return 0;} -return(sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,x0,y0,x0c,y0c,xc,yc,level+1)+sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,xc,yc,xc1,yc1,x1,y1,level+1));};sec.sun.awt.geom.Curve.pointCrossingsForCubic=function(px,py,x0,y0,xc0,yc0,xc1,yc1,x1,y1,level){if(py=y0&&py>=yc0&&py>=yc1&&py>=y1) -return 0;if(px>=x0&&px>=xc0&&px>=xc1&&px>=x1) -return 0;if(px=y0){if(py=y1) -return-1;} -return 0;} -if(level>52) -return sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,x0,y0,x1,y1);var xmid=(xc0+xc1)/2;var ymid=(yc0+yc1)/2;xc0=(x0+xc0)/2;yc0=(y0+yc0)/2;xc1=(xc1+x1)/2;yc1=(yc1+y1)/2;var xc0m=(xc0+xmid)/2;var yc0m=(yc0+ymid)/2;var xmc1=(xmid+xc1)/2;var ymc1=(ymid+yc1)/2;xmid=(xc0m+xmc1)/2;ymid=(yc0m+ymc1)/2;if(Double.isNaN(xmid)||Double.isNaN(ymid)){return 0;} -return(sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,x0,y0,xc0,yc0,xc0m,yc0m,xmid,ymid,level+1)+sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,xmid,ymid,xmc1,ymc1,xc1,yc1,x1,y1,level+1));};sec.sun.awt.geom.Curve.rectCrossingsforPath=function(pi,rxmin,rymin,rxmax,rymax){if(rxmax<=rxmin||rymax<=rymin){return 0;} -if(pi.isDone()){return 0;} -var coords=Clazz.newArray(6,0);if(pi.currentSegment(coords)!==0){return-1;} -pi.next();var curx;var cury;var movx;var movy;var endx;var endy;curx=movx=coords[0];cury=movy=coords[1];var crossings=0;while(crossings!==-2147483648&&!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(curx!==movx||cury!==movy){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} -movx=curx=coords[0];movy=cury=coords[1];break;case 1:endx=coords[0];endy=coords[1];crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,endx,endy);curx=endx;cury=endy;break;case 2:endx=coords[2];endy=coords[3];crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,curx,cury,coords[0],coords[1],endx,endy,0);curx=endx;cury=endy;break;case 3:endx=coords[4];endy=coords[5];crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,curx,cury,coords[0],coords[1],coords[2],coords[3],endx,endy,0);curx=endx;cury=endy;break;case 4:if(curx!==movx||cury!==movy){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} -curx=movx;cury=movy;break;} -pi.next();} -if(crossings!==-2147483648&&(curx!==movx||cury!==movy)){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} -return crossings;};sec.sun.awt.geom.Curve.rectCrossingsForLine=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1){if(y0>=rymax&&y1>=rymax) -return crossings;if(y0<=rymin&&y1<=rymin) -return crossings;if(x0<=rxmin&&x1<=rxmin) -return crossings;if(x0>=rxmax&&x1>=rxmax){if(y0=rymax) -crossings++;}else if(y1=rymax) -crossings--;} -return crossings;} -if((x0>rxmin&&x0rymin&&y0rxmin&&x1rymin&&y1rymax){xi0+=((rymax-y0)*(x1-x0)/(y1-y0));} -var xi1=x1;if(y1rymax){xi1+=((rymax-y1)*(x0-x1)/(y0-y1));} -if(xi0<=rxmin&&xi1<=rxmin) -return crossings;if(xi0>=rxmax&&xi1>=rxmax){if(y0=rymax) -crossings++;}else if(y1=rymax) -crossings--;} -return crossings;} -return-2147483648;};sec.sun.awt.geom.Curve.rectCrossingsForQuad=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc,yc,x1,y1,level){if(y0>=rymax&&yc>=rymax&&y1>=rymax) -return crossings;if(y0<=rymin&&yc<=rymin&&y1<=rymin) -return crossings;if(x0<=rxmin&&xc<=rxmin&&x1<=rxmin) -return crossings;if(x0>=rxmax&&xc>=rxmax&&x1>=rxmax){if(y0rymin) -crossings++;if(y0=rymax) -crossings++;}else if(y1rymin) -crossings--;if(y1=rymax) -crossings--;} -return crossings;} -if((x0rxmin&&y0rymin)||(x1rxmin&&y1rymin)){return-2147483648;} -if(level>52){return sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1);} -var x0c=(x0+xc)/2;var y0c=(y0+yc)/2;var xc1=(xc+x1)/2;var yc1=(yc+y1)/2;xc=(x0c+xc1)/2;yc=(y0c+yc1)/2;if(Double.isNaN(xc)||Double.isNaN(yc)){return 0;} -crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x0c,y0c,xc,yc,level+1);if(crossings!==-2147483648){crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,xc,yc,xc1,yc1,x1,y1,level+1);} -return crossings;};sec.sun.awt.geom.Curve.rectCrossingsForCubic=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc0,yc0,xc1,yc1,x1,y1,level){if(y0>=rymax&&yc0>=rymax&&yc1>=rymax&&y1>=rymax){return crossings;} -if(y0<=rymin&&yc0<=rymin&&yc1<=rymin&&y1<=rymin){return crossings;} -if(x0<=rxmin&&xc0<=rxmin&&xc1<=rxmin&&x1<=rxmin){return crossings;} -if(x0>=rxmax&&xc0>=rxmax&&xc1>=rxmax&&x1>=rxmax){if(y0rymin) -crossings++;if(y0=rymax) -crossings++;}else if(y1rymin) -crossings--;if(y1=rymax) -crossings--;} -return crossings;} -if((x0>rxmin&&x0rymin&&y0rxmin&&x1rymin&&y152){return sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1);} -var xmid=(xc0+xc1)/2;var ymid=(yc0+yc1)/2;xc0=(x0+xc0)/2;yc0=(y0+yc0)/2;xc1=(xc1+x1)/2;yc1=(yc1+y1)/2;var xc0m=(xc0+xmid)/2;var yc0m=(yc0+ymid)/2;var xmc1=(xmid+xc1)/2;var ymc1=(ymid+yc1)/2;xmid=(xc0m+xmc1)/2;ymid=(yc0m+ymc1)/2;if(Double.isNaN(xmid)||Double.isNaN(ymid)){return 0;} -crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc0,yc0,xc0m,yc0m,xmid,ymid,level+1);if(crossings!==-2147483648){crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,xmid,ymid,xmc1,ymc1,xc1,yc1,x1,y1,level+1);} -return crossings;};sec.sun.awt.geom.Curve.round=function(v){return v;};sec.sun.awt.geom.Curve.orderof=function(x1,x2){if(x1x2){return 1;} -return 0;};sec.sun.awt.geom.Curve.signeddifbits=function(y1,y2){return(Double.doubleToLongBits(y1)-Double.doubleToLongBits(y2));};sec.sun.awt.geom.Curve.diffbits=function(y1,y2){return Math.abs(Double.doubleToLongBits(y1)-Double.doubleToLongBits(y2));};sec.sun.awt.geom.Curve.prev=function(v){return Double.longBitsToDouble(Double.doubleToLongBits(v)-1);};sec.sun.awt.geom.Curve.next=function(v){return Double.longBitsToDouble(Double.doubleToLongBits(v)+1);};sec.sun.awt.geom.Curve.fairlyClose=function(v1,v2){return(Math.abs(v1-v2)=this.getYTop()&&y=xhi){return false;} -var xlo=c.getXLo();var ylo=c.getYLo();var yhi=c.getYHi();var y0=this.getYTop();var y1=this.getYBot();var tstart;var ystart;var tend;var yend;if(y0=yhi){return false;} -ystart=y0;tstart=0;} -if(y1>yhi){yend=yhi;tend=this.TforY(yhi);}else{yend=y1;tend=1;} -var hitLo=false;var hitHi=false;while(true){var x=this.XforT(tstart);if(xxlo){return true;} -hitLo=true;}else{if(hitLo){return true;} -hitHi=true;} -if(tstart>=tend){break;} -tstart=this.nextVertical(tstart,tend);} -if(hitLo){c.record(ystart,yend,this.getDirection());} -return false;};this.refineTforY=function(t0,yt0,y0){var t1=1;while(true){var th=(t0+t1)/2;if(th===t0||th===t1){return t1;} -var y=this.YforT(th);if(yy0){t1=th;}else{return t1;}}};this.findIntersect=function(that,yrange,ymin,slevel,tlevel,s0,xs0,ys0,s1,xs1,ys1,t0,xt0,yt0,t1,xt1,yt1){if(ys0>yt1||yt0>ys1){return false;} -if(Math.min(xs0,xs1)>Math.max(xt0,xt1)||Math.max(xs0,xs1)0.0010){var s=(s0+s1)/2;var xs=this.XforT(s);var ys=this.YforT(s);if(s===s0||s===s1){System.out.println("s0 = "+s0);System.out.println("s1 = "+s1);throw new InternalError("no s progress!");} -if(t1-t0>0.0010){var t=(t0+t1)/2;var xt=that.XforT(t);var yt=that.YforT(t);if(t===t0||t===t1){System.out.println("t0 = "+t0);System.out.println("t1 = "+t1);throw new InternalError("no t progress!");} -if(ys>=yt0&&yt>=ys0){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s0,xs0,ys0,s,xs,ys,t0,xt0,yt0,t,xt,yt)){return true;}} -if(ys>=yt){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s0,xs0,ys0,s,xs,ys,t,xt,yt,t1,xt1,yt1)){return true;}} -if(yt>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s,xs,ys,s1,xs1,ys1,t0,xt0,yt0,t,xt,yt)){return true;}} -if(ys1>=yt&&yt1>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s,xs,ys,s1,xs1,ys1,t,xt,yt,t1,xt1,yt1)){return true;}}}else{if(ys>=yt0){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel,s0,xs0,ys0,s,xs,ys,t0,xt0,yt0,t1,xt1,yt1)){return true;}} -if(yt1>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel,s,xs,ys,s1,xs1,ys1,t0,xt0,yt0,t1,xt1,yt1)){return true;}}}}else if(t1-t0>0.0010){var t=(t0+t1)/2;var xt=that.XforT(t);var yt=that.YforT(t);if(t===t0||t===t1){System.out.println("t0 = "+t0);System.out.println("t1 = "+t1);throw new InternalError("no t progress!");} -if(yt>=ys0){if(this.findIntersect(that,yrange,ymin,slevel,tlevel+1,s0,xs0,ys0,s1,xs1,ys1,t0,xt0,yt0,t,xt,yt)){return true;}} -if(ys1>=yt){if(this.findIntersect(that,yrange,ymin,slevel,tlevel+1,s0,xs0,ys0,s1,xs1,ys1,t,xt,yt,t1,xt1,yt1)){return true;}}}else{var xlk=xs1-xs0;var ylk=ys1-ys0;var xnm=xt1-xt0;var ynm=yt1-yt0;var xmk=xt0-xs0;var ymk=yt0-ys0;var det=xnm*ylk-ynm*xlk;if(det!==0){var detinv=1/det;var s=(xnm*ymk-ynm*xmk)*detinv;var t=(xlk*ymk-ylk*xmk)*detinv;if(s>=0&&s<=1&&t>=0&&t<=1){s=s0+s*(s1-s0);t=t0+t*(t1-t0);if(s<0||s>1||t<0||t>1){System.out.println("Uh oh!");} -var y=(this.YforT(s)+that.YforT(t))/2;if(y<=yrange[1]&&y>yrange[0]){yrange[1]=y;return true;}}}} -return false;};this.compareTo=function(that,yrange){if(this.order===1){return this.order1.compareTo(that,yrange);} -var y0=yrange[0];var y1=yrange[1];y1=Math.min(Math.min(y1,this.getYBot()),that.getYBot());if(y1<=yrange[0]){System.err.println("this === "+this);System.err.println("that === "+that);System.out.println("target range = "+yrange[0]+"=>"+yrange[1]);throw new InternalError("backstepping from "+yrange[0]+" to "+y1);} -yrange[1]=y1;if(this.getXMax()<=that.getXMin()){if(this.getXMin()===that.getXMax()){return 0;} -return-1;} -if(this.getXMin()>=that.getXMax()){return 1;} -var s0=this.TforY(y0);var ys0=this.YforT(s0);if(ys0maxbump){bump=maxbump;}}else{y-=bump;while(true){bump/=2;var newy=y+bump;if(newy<=y){break;} -if(sec.sun.awt.geom.Curve.fairlyClose(this.XforY(newy),that.XforY(newy))){y=newy;}} -break;} -y+=bump;} -if(y>y0){if(y"+yrange[1]);System.err.println("s y range is "+ys0+"=>"+ysh);System.err.println("t y range is "+yt0+"=>"+yth);System.err.println("ymin is "+ymin);return 0;}else{throw t;}} -if(yshyrange[0]){if(yshyrange[0]){if(ythcurve.getYBot()){throw new InternalError("bad curvelink ["+this.ytop+"=>"+this.ybot+"] for "+curve);} -this.absorb=function(link){return this.absorb2(link.curve,link.ytop,link.ybot,link.etag);};this.absorb2=function(curve,ystart,yend,etag){if(this.curve!==curve||this.etag!==etag||this.ybotyend) -{return false;} -if(ystartcurve.getYBot()) -{throw new InternalError("bad curvelink ["+ystart+"=>"+yend+"] for "+curve);} -this.ytop=Math.min(this.ytop,ystart);this.ybot=Math.max(this.ybot,yend);return true;};this.isEmpty=function(){return(this.ytop===this.ybot);};this.getCurve=function(){return this.curve;};this.getSubCurve=function(){if(this.ytop===this.curve.getYTop()&&this.ybot===this.curve.getYBot()) -{return this.curve.getWithDirection(this.etag);} -return this.curve.getSubCurve(this.ytop,this.ybot,this.etag);};this.getMoveto=function(){var order0=new sec.sun.awt.geom.Order0(this.getXTop(),this.getYTop());return new sec.sun.awt.geom.CurveObject(order0);};this.getXTop=function(){return this.curve.XforY(this.ytop);};this.getYTop=function(){return this.ytop;};this.getXBot=function(){return this.curve.XforY(this.ybot);};this.getYBot=function(){return this.ybot;};this.getX=function(){return this.curve.XforY(this.ytop);};this.getEdgeTag=function(){return this.etag;};this.setNext=function(link){this.next=link;};this.getNext=function(){return this.next;};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.EOWindOp=function() -{this.inside=false;this.newRow=function(){this.inside=false;};this.classify=function(e){var newInside=!this.inside;this.inside=newInside;return(newInside?1:-1);};this.getState=function(){return(this.inside?1:-1);};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.NZWindOp=function() -{this.count=0;this.newRow=function(){this.count=0;};this.classify=function(e){var newCount=this.count;var type=(newCount===0?1:0);newCount+=e.getCurve().getDirection();this.count=newCount;return(newCount===0?-1:type);};this.getState=function(){return((this.count===0)?-1:1);};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Edge=function() -{this.curve=null;this.ctag=0;this.etag=0;this.activey=0;this.equivalence=0;this.lastEdge=null;this.lastResult=0;this.lastLimit=0;var c=arguments[0];var ctag=arguments[1];var etag=0;if(arguments.length===3) -etag=arguments[2];this.curve=c;this.ctag=ctag;this.etag=etag;this.getCurve=function(){return this.curve;};this.getCurveTag=function(){return this.ctag;};this.getEdgeTag=function(){return this.etag;};this.setEdgeTag=function(etag){this.etag=etag;};this.getEquivalence=function(){return this.equivalence;};this.setEquivalence=function(eq){this.equivalence=eq;};this.compareTo=function(other,yrange){if(other===this.lastEdge&&yrange[0]this.lastLimit){yrange[1]=this.lastLimit;} -return this.lastResult;} -if(this===other.lastEdge&&yrange[0]other.lastLimit){yrange[1]=other.lastLimit;} -return 0-other.lastResult;} -var ret=this.curve.compareTo(other.curve,yrange);this.lastEdge=other;this.lastLimit=yrange[1];this.lastResult=ret;return ret;};this.record=function(yend,etag){this.activey=yend;this.etag=etag;};this.isActiveFor=function(y,etag){return(this.etag===etag&&this.activey>=y);};this.toString=function(){return("Edge["+this.curve+", "+(this.ctag===0?"L":"R")+", "+(this.etag===1?"I":(this.etag===-1?"O":"N"))+"]");};};sec.sun.awt.geom.Edge.INIT_PARTS=4;sec.sun.awt.geom.Edge.GROW_PARTS=10;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Enumeration=function() -{this._vector=null;this.currentIndex=0;var vector=arguments[0];this._vector=vector;this.nextElement=function(){if(this.currentIndex=yend);};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} -var from=0;while(fromthis.yranges[from+1]){from+=2;} -var to=from;while(fromyhl){ystart=yhl;yhl=ylh;ylh=ystart;} -if(yll!==ylh){this.yranges[to++]=yll;this.yranges[to++]=ylh;} -ystart=yhl;yend=yhh;} -if(ystart>=yend){break;}} -if(to=this.yranges.length){var newranges=Clazz.newArray(to+10,0);System.arraycopy(this.yranges,0,newranges,0,to);this.yranges=newranges;} -this.yranges[to++]=ystart;this.yranges[to++]=yend;} -this.limit=to;};this.getXLo=function(){return this.xlo;};this.getYLo=function(){return this.ylo;};this.getXHi=function(){return this.xhi;};this.getYHi=function(){return this.yhi;};this.isEmpty=function(){return(this.limit===0);};this.accumulateLine=function(x0,y0,x1,y1){if(y0<=y1){return this.accumulateLine2(x0,y0,x1,y1,1);}else{return this.accumulateLine2(x1,y1,x0,y0,-1);}};this.accumulateLine2=function(x0,y0,x1,y1,direction){if(this.yhi<=y0||this.ylo>=y1){return false;} -if(x0>=this.xhi&&x1>=this.xhi){return false;} -if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} -var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} -if(xstart>this.xlo||xend>this.xlo){return true;} -this.record(ystart,yend,direction);return false;};};sec.sun.awt.geom.EvenOdd.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.NonZero=function() -{this.limit=0;this.yranges=null;this.xlo=0;this.ylo=0;this.xhi=0;this.yhi=0;this.crosscounts=null;this.yranges=Clazz.newArray(10,0);var xlo=arguments[0];var ylo=arguments[1];var xhi=arguments[2];var yhi=arguments[3];this.xlo=xlo;this.ylo=ylo;this.xhi=xhi;this.yhi=yhi;this.crosscounts=Clazz.newArray(Math.floor(this.yranges.length/2),0);this.covers=function(ystart,yend){var i=0;while(i=yhi){continue;} -if(ystart=yend);};this.remove=function(cur){this.limit-=2;var rem=this.limit-cur;if(rem>0){System.arraycopy(this.yranges,cur+2,this.yranges,cur,rem);System.arraycopy(this.crosscounts,Math.floor(cur/2)+1,this.crosscounts,Math.floor(cur/2),Math.floor(rem/2));}};this.insert=function(cur,lo,hi,dir){var rem=this.limit-cur;var oldranges=this.yranges;var oldcounts=this.crosscounts;if(this.limit>=this.yranges.length){this.yranges=Clazz.newArray(this.limit+10,0);System.arraycopy(oldranges,0,this.yranges,0,cur);this.crosscounts=Clazz.newArray(Math.floor((this.limit+10)/2),0);System.arraycopy(oldcounts,0,this.crosscounts,0,Math.floor(cur/2));} -if(rem>0){System.arraycopy(oldranges,cur,this.yranges,cur+2,rem);System.arraycopy(oldcounts,Math.floor(cur/2),this.crosscounts,Math.floor(cur/2)+1,Math.floor(rem/2));} -this.yranges[cur+0]=lo;this.yranges[cur+1]=hi;this.crosscounts[Math.floor(cur/2)]=dir;this.limit+=2;};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} -var cur=0;while(curthis.yranges[cur+1]){cur+=2;} -if(cur=y1){return false;} -if(x0>=this.xhi&&x1>=this.xhi){return false;} -if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} -var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} -if(xstart>this.xlo||xend>this.xlo){return true;} -this.record(ystart,yend,direction);return false;};};sec.sun.awt.geom.NonZero.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Order0=function() -{this.x=0;this.y=0;this.direction=-1;this._parent=null;var x=arguments[0];var y=arguments[1];this.direction=1;this.x=x;this.y=y;this.getOrder=function(){return 0;};this.getXTop=function(){return this.x;};this.getYTop=function(){return this.y;};this.getXBot=function(){return this.x;};this.getYBot=function(){return this.y;};this.getXMin=function(){return this.x;};this.getxMax=function(){return this.x;};this.getX0=function(){return this.x;};this.getY0=function(){return this.y;};this.getX1=function(){return this.x;};this.getY1=function(){return this.y;};this.XforY=function(y){return y;};this.TforY=function(y){return 0;};this.XforT=function(t){return this.x;};this.YforT=function(t){return this.y;};this.dXforT=function(t,deriv){return 0;};this.dYforT=function(t,deriv){return 0;};this.nextVertical=function(t0,t1){return t1;};this.crossingsFor=function(x,y){return 0;};this.accumulateCrossings=function(c){return(this.x>c.getXLo()&&this.xc.getYLo()&&this.y=this.y1){return this.x1;} -return(this.x0+(y-this.y0)*(this.x1-this.x0)/(this.y1-this.y0));};this.TforY=function(y){if(y<=this.y0){return 0;} -if(y>=this.y1){return 1;} -return(y-this.y0)/(this.y1-this.y0);};this.XforT=function(t){return this.x0+t*(this.x1-this.x0);};this.YforT=function(t){return this.y0+t*(this.y1-this.y0);};this.dXforT=function(t,deriv){switch(deriv){case 0:return this.x0+t*(this.x1-this.x0);case 1:return(this.x1-this.x0);default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return this.y0+t*(this.y1-this.y0);case 1:return(this.y1-this.y0);default:return 0;}};this.nextVertical=function(t0,t1){return t1;};this.accumulateCrossings=function(c){var xlo=c.getXLo();var ylo=c.getYLo();var xhi=c.getXHi();var yhi=c.getYHi();if(this.xmin>=xhi){return false;} -var xstart;var ystart;var xend;var yend;if(this.y0=yhi){return false;} -ystart=this.y0;xstart=this.x0;} -if(this.y1>yhi){yend=yhi;xend=this.XforY(yhi);}else{yend=this.y1;xend=this.x1;} -if(xstart>=xhi&&xend>=xhi){return false;} -if(xstart>xlo||xend>xlo){return true;} -c.record(ystart,yend,this.direction);return false;};this.enlarge=function(r){r.add(this.x0,this.y0);r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir) -{if(ystart===this.y0&¥d===this.y1) -{return this.getWithDirection(dir);} -if(this.x0===this.x1) -{return new sec.sun.awt.geom.Order1(this.x0,ystart,this.x1,yend,dir);} -var num=this.x0-this.x1;var denom=this.y0-this.y1;var xstart=(this.x0+(ystart-this.y0)*num/denom);var xend=(this.x0+(yend-this.y0)*num/denom);return new sec.sun.awt.geom.Order1(xstart,ystart,xend,yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order1(this.x0,this.y0,this.x1,this.y1,-this.direction);};this.compareTo=function(other,yrange){var curve=other;var c1=curve.getCurve();if(yrange[1]<=yrange[0]){throw new InternalError("yrange already screwed up...");} -yrange[1]=Math.min(Math.min(yrange[1],this.y1),c1.y1);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]);} -if(this.xmax<=c1.xmin){return(this.xmin===c1.xmax)?0:-1;} -if(this.xmin>=c1.xmax){return 1;} -var dxa=this.x1-this.x0;var dya=this.y1-this.y0;var dxb=c1.x1-c1.x0;var dyb=c1.y1-c1.y0;var denom=dxb*dya-dxa*dyb;var y;if(denom!==0){var num=((this.x0-c1.x0)*dya*dyb-this.y0*dxa*dyb+c1.y0*dxb*dya);y=num/denom;if(y<=yrange[0]){y=Math.min(this.y1,c1.y1);}else{if(yy1){cy0=y1;} -this.x0=x0;this.y0=y0;this.cx0=cx0;this.cy0=cy0;this.x1=x1;this.y1=y1;this.xmin=Math.min(Math.min(x0,x1),cx0);this.xmax=Math.max(Math.max(x0,x1),cx0);this.xcoeff0=x0;this.xcoeff1=cx0+cx0-x0-x0;this.xcoeff2=x0-cx0-cx0+x1;this.ycoeff0=y0;this.ycoeff1=cy0+cy0-y0-y0;this.ycoeff2=y0-cy0-cy0+y1;this.getOrder=function(){return 2;};this.getXTop=function(){return this.x0;};this.getYTop=function(){return this.y0;};this.getXBot=function(){return this.x1;};this.getYBot=function(){return this.y1;};this.getXMin=function(){return this.xmin;};this.getXMax=function(){return this.xmax;};this.getX0=function(){return(this.direction===1)?this.x0:this.x1;};this.getY0=function(){return(this.direction===1)?this.y0:this.y1;};this.getCX0=function(){return this.cx0;};this.getCY0=function(){return this.cy0;};this.getx1=function(){return(this.direction===-1)?this.x0:this.x1;};this.getY1=function(){return(this.direction===-1)?this.y0:this.y1;};this.XforY=function(y){if(y<=this.y0){return this.x0;} -if(y>=this.y1){return this.x1;} -return this.XforT(this.TforY(y));};this.TforY=function(y){if(y<=this.y0){return 0;} -if(y>=this.y1){return 1;} -return sec.sun.awt.geom.Order2.TforY(y,this.ycoeff0,this.ycoeff1,this.ycoeff2);};this.XforT=function(t){return(this.xcoeff2*t+this.xcoeff1)*t+this.xcoeff0;};this.YforT=function(t){return(this.ycoeff2*t+this.ycoeff1)*t+this.ycoeff0;};this.dXforT=function(t,deriv){switch(deriv){case 0:return(this.xcoeff2*t+this.xcoeff1)*t+this.xcoeff0;case 1:return 2*this.xcoeff2*t+this.xcoeff1;case 2:return 2*this.xcoeff2;default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return(this.ycoeff2*t+this.ycoeff1)*t+this.ycoeff0;case 1:return 2*this.ycoeff2*t+this.ycoeff1;case 2:return 2*this.ycoeff2;default:return 0;}};this.nextVertical=function(t0,t1){var t=-this.xcoeff1/(2*this.xcoeff2);if(t>t0&&t0&&t<1){r.add(this.XforT(t),this.YforT(t));} -r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir){var t0;var t1;if(ystart<=this.y0){if(yend>=this.y1){return this.getWithDirection(dir);} -t0=0;}else{t0=sec.sun.awt.geom.Order2.TforY(ystart,this.ycoeff0,this.ycoeff1,this.ycoeff2);} -if(yend>=this.y1){t1=1;}else{t1=sec.sun.awt.geom.Order2.TforY(yend,this.ycoeff0,this.ycoeff1,this.ycoeff2);} -var eqn=Clazz.newArray(10,0);eqn[0]=this.x0;eqn[1]=this.y0;eqn[2]=this.cx0;eqn[3]=this.cy0;eqn[4]=this.x1;eqn[5]=this.y1;if(t1<1){sec.sun.awt.geom.Order2.split(eqn,0,t1);} -var i;if(t0<=0){i=0;}else{sec.sun.awt.geom.Order2.split(eqn,0,t0/t1);i=4;} -return new sec.sun.awt.geom.Order2(eqn[i+0],ystart,eqn[i+2],eqn[i+3],eqn[i+4],yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order2(this.x0,this.y0,this.cx0,this.cy0,this.x1,this.y1,-this.direction);};this.getSegment=function(coords){coords[0]=this.cx0;coords[1]=this.cy0;if(this.direction===1){coords[2]=this.x1;coords[3]=this.y1;}else{coords[2]=this.x0;coords[3]=this.y0;} -return 2;};this.controlPointString=function(){return("("+sec.sun.awt.geom.Curve.round(this.cx0)+", "+sec.sun.awt.geom.Curve.round(this.cy0)+"), ");};this.setParent=function(parent){this._parent=parent;};this.getParent=function(){return this._parent;};};sec.sun.awt.geom.Order2.TforY=function(y,ycoeff0,ycoeff1,ycoeff2){ycoeff0-=y;if(ycoeff2===0.0){var root=-ycoeff0/ycoeff1;if(root>=0&&root<=1){return root;}}else{var d=ycoeff1*ycoeff1-4.0*ycoeff2*ycoeff0;if(d>=0.0){d=Math.sqrt(d);if(ycoeff1<0.0){d=-d;} -var q=(ycoeff1+d)/-2.0;var root=q/ycoeff2;if(root>=0&&root<=1){return root;} -if(q!==0.0){root=ycoeff0/q;if(root>=0&&root<=1){return root;}}}} -var y0=ycoeff0;var y1=ycoeff0+ycoeff1+ycoeff2;return(0<(y0+y1)/2)?0.0:1.0;};sec.sun.awt.geom.Order2.split=function(coords,pos,t){var x0;var y0;var cx;var cy;var x1;var y1;coords[pos+8]=x1=coords[pos+4];coords[pos+9]=y1=coords[pos+5];cx=coords[pos+2];cy=coords[pos+3];x1=cx+(x1-cx)*t;y1=cy+(y1-cy)*t;x0=coords[pos+0];y0=coords[pos+1];x0=x0+(cx-x0)*t;y0=y0+(cy-y0)*t;cx=x0+(x1-x0)*t;cy=y0+(y1-y0)*t;coords[pos+2]=x0;coords[pos+3]=y0;coords[pos+4]=cx;coords[pos+5]=cy;coords[pos+6]=x1;coords[pos+7]=y1;};sec.sun.awt.geom.Order2.getHorizontalParams=function(c0,cp,c1,ret){if(c0<=cp&&cp<=c1){return 0;} -c0-=cp;c1-=cp;var denom=c0+c1;if(denom===0){return 0;} -var t=c0/denom;if(t<=0||t>=1){return 0;} -ret[0]=t;return 1;};sec.sun.awt.geom.Order2.addInstance=function(curves,x0,y0,cx0,cy0,x1,y1,direction){if(y0>y1){curves.add(new sec.sun.awt.geom.Order2(x1,y1,cx0,cy0,x0,y0,-direction));}else if(y1>y0){curves.add(new sec.sun.awt.geom.Order2(x0,y0,cx0,cy0,x1,y1,direction));}};sec.sun.awt.geom.Order2.insert=function(curves,tmp,x0,y0,cx0,cy0,x1,y1,direction){var numparams=sec.sun.awt.geom.Order2.getHorizontalParams(y0,cy0,y1,tmp);if(numparams===0){sec.sun.awt.geom.Order2.addInstance(curves,x0,y0,cx0,cy0,x1,y1,direction);return;} -var t=tmp[0];tmp[0]=x0;tmp[1]=y0;tmp[2]=cx0;tmp[3]=cy0;tmp[4]=x1;tmp[5]=y1;sec.sun.awt.geom.Order2.split(tmp,0,t);var i0=(direction===1)?0:4;var i1=4-i0;sec.sun.awt.geom.Order2.addInstance(curves,tmp[i0],tmp[i0+1],tmp[i0+2],tmp[i0+3],tmp[i0+4],tmp[i0+5],direction);sec.sun.awt.geom.Order2.addInstance(curves,tmp[i1],tmp[i1+1],tmp[i1+2],tmp[i1+3],tmp[i1+4],tmp[i1+5],direction);};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Order3=function() -{this.x0=0;this.y0=0;this.cx0=0;this.cy0=0;this.cx1=0;this.cy1=0;this.x1=0;this.y1=0;this.xmin=0;this.xmax=0;this.xcoeff0=0;this.xcoeff1=0;this.xcoeff2=0;this.xcoeff3=0;this.ycoeff0=0;this.ycoeff1=0;this.ycoeff2=0;this.ycoeff3=0;this.direction=-1;this.TforY1=0;this.YforT1=0;this.TforY2=0;this.YforT2=0;this.TforY3=0;this.YforT3=0;this._parent=null;var x0=arguments[0];var y0=arguments[1];var cx0=arguments[2];var cy0=arguments[3];var cx1=arguments[4];var cy1=arguments[5];var x1=arguments[6];var y1=arguments[7];var direction=arguments[8];this.direction=direction;if(cy0y1)cy1=y1;this.x0=x0;this.y0=y0;this.cx0=cx0;this.cy0=cy0;this.cx1=cx1;this.cy1=cy1;this.x1=x1;this.y1=y1;this.xmin=Math.min(Math.min(x0,x1),Math.min(cx0,cx1));this.xmax=Math.max(Math.max(x0,x1),Math.max(cx0,cx1));this.xcoeff0=x0;this.xcoeff1=(cx0-x0)*3.0;this.xcoeff2=(cx1-cx0-cx0+x0)*3.0;this.xcoeff3=x1-(cx1-cx0)*3.0-x0;this.ycoeff0=y0;this.ycoeff1=(cy0-y0)*3.0;this.ycoeff2=(cy1-cy0-cy0+y0)*3.0;this.ycoeff3=y1-(cy1-cy0)*3.0-y0;this.YforT1=this.YforT2=this.YforT3=y0;this.getOrder=function(){return 3;};this.getXTop=function(){return this.x0;};this.getYTop=function(){return this.y0;};this.getXBot=function(){return this.x1;};this.getYBot=function(){return this.y1;};this.getXMin=function(){return this.xmin;};this.getXMax=function(){return this.xmax;};this.getX0=function(){return(this.direction===1)?this.x0:this.x1;};this.getY0=function(){return(this.direction===1)?this.y0:this.y1;};this.getCX0=function(){return(this.direction===1)?this.cx0:this.cx1;};this.getCY0=function(){return(this.direction===1)?this.cy0:this.cy1;};this.getCX1=function(){return(this.direction===-1)?this.cx0:this.cx1;};this.getCY1=function(){return(this.direction===-1)?this.cy0:this.cy1;};this.getX1=function(){return(this.direction===-1)?this.x0:this.x1;};this.getY1=function(){return(this.direction===-1)?this.y0:this.y1;};this.TforY=function(y){if(y<=this.y0)return 0;if(y>=this.y1)return 1;if(y===this.YforT1)return this.TforY1;if(y===this.YforT2)return this.TforY2;if(y===this.YforT3)return this.TforY3;if(this.ycoeff3===0.0){return sec.sun.awt.geom.Order2.TforY(y,this.ycoeff0,this.ycoeff1,this.ycoeff2);} -var a=this.ycoeff2/this.ycoeff3;var b=this.ycoeff1/this.ycoeff3;var c=(this.ycoeff0-y)/this.ycoeff3;var roots=0;var Q=(a*a-3.0*b)/9.0;var R=(2.0*a*a*a-9.0*a*b+27.0*c)/54.0;var R2=R*R;var Q3=Q*Q*Q;var a_3=a/3.0;var t;if(R2y){t1=t;}else{break;}}} -if(t>=0){this.TforY3=this.TforY2;this.YforT3=this.YforT2;this.TforY2=this.TforY1;this.YforT2=this.YforT1;this.TforY1=t;this.YforT1=y;} -return t;};this.refine=function(a,b,c,target,t){if(t<-0.1||t>1.1){return-1;} -var y=this.YforT(t);var t0;var t1;if(y=t1){useslope=false;continue;} -t=t2;} -y=this.YforT(t);if(ytarget){t1=t;}else{break;}} -var verbose=false;if(false&&t>=0&&t<=1){y=this.YforT(t);var tdiff=sec.sun.awt.geom.Curve.diffbits(t,origt);var ydiff=sec.sun.awt.geom.Curve.diffbits(y,origy);var yerr=sec.sun.awt.geom.Curve.diffbits(y,target);if(yerr>0||(verbose&&tdiff>0)){System.out.println("target was y = "+target);System.out.println("original was y = "+origy+", t = "+origt);System.out.println("final was y = "+y+", t = "+t);System.out.println("t diff is "+tdiff);System.out.println("y diff is "+ydiff);System.out.println("y error is "+yerr);var tlow=sec.sun.awt.geom.Curve.prev(t);var ylow=this.YforT(tlow);var thi=sec.sun.awt.geom.Curve.next(t);var yhi=this.YforT(thi);if(Math.abs(target-ylow)1)?-1:t;};this.XforY=function(y){if(y<=this.y0){return this.x0;} -if(y>=this.y1){return this.x1;} -return this.XforT(this.TforY(y));};this.XforT=function(t){return(((this.xcoeff3*t)+this.xcoeff2)*t+this.xcoeff1)*t+this.xcoeff0;};this.YforT=function(t){return(((this.ycoeff3*t)+this.ycoeff2)*t+this.ycoeff1)*t+this.ycoeff0;};this.dXforT=function(t,deriv){switch(deriv){case 0:return(((this.xcoeff3*t)+this.xcoeff2)*t+this.xcoeff1)*t+this.xcoeff0;case 1:return((3*this.xcoeff3*t)+2*this.xcoeff2)*t+this.xcoeff1;case 2:return(6*this.xcoeff3*t)+2*this.xcoeff2;case 3:return 6*this.xcoeff3;default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return(((this.ycoeff3*t)+this.ycoeff2)*t+this.ycoeff1)*t+this.ycoeff0;case 1:return((3*this.ycoeff3*t)+2*this.ycoeff2)*t+this.ycoeff1;case 2:return(6*this.ycoeff3*t)+2*this.ycoeff2;case 3:return 6*this.ycoeff3;default:return 0;}};this.nextVertical=function(t0,t1){var eqn=[this.xcoeff1,2*this.xcoeff2,3*this.xcoeff3];var numroots=sec.sun.awt.geom.Curve.solveQuadratic(eqn,eqn);for(var i=0;it0&&eqn[i]0&&t<1){r.add(this.XforT(t),this.YforT(t));}} -r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir){if(ystart<=this.y0&¥d>=this.y1){return this.getWithDirection(dir);} -var eqn=Clazz.newArray(14,0);var t0;var t1;t0=this.TforY(ystart);t1=this.TforY(yend);eqn[0]=this.x0;eqn[1]=this.y0;eqn[2]=this.cx0;eqn[3]=this.cy0;eqn[4]=this.cx1;eqn[5]=this.cy1;eqn[6]=this.x1;eqn[7]=this.y1;if(t0>t1){var t=t0;t0=t1;t1=t;} -if(t1<1){sec.sun.awt.geom.Order3.split(eqn,0,t1);} -var i;if(t0<=0){i=0;}else{sec.sun.awt.geom.Order3.split(eqn,0,t0/t1);i=6;} -return new sec.sun.awt.geom.Order3(eqn[i+0],ystart,eqn[i+2],eqn[i+3],eqn[i+4],eqn[i+5],eqn[i+6],yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order3(this.x0,this.y0,this.cx0,this.cy0,this.cx1,this.cy1,this.x1,this.y1,-this.direction);};this.getSegment=function(coords){if(this.direction===1){coords[0]=this.cx0;coords[1]=this.cy0;coords[2]=this.cx1;coords[3]=this.cy1;coords[4]=this.x1;coords[5]=this.y1;}else{coords[0]=this.cx1;coords[1]=this.cy1;coords[2]=this.cx0;coords[3]=this.cy0;coords[4]=this.x0;coords[5]=this.y0;} -return 3;};this.controlPointString=function(){return(("("+sec.sun.awt.geom.Curve.round(this.getCX0())+", "+sec.sun.awt.geom.Curve.round(this.getCY0())+"), ")+("("+sec.sun.awt.geom.Curve.round(this.getCX1())+", "+sec.sun.awt.geom.Curve.round(this.getCY1())+"), "));};this.setParent=function(parent){this._parent=parent;};this.getParent=function(){return this._parent;};};sec.sun.awt.geom.Order3.insert=function(curves,tmp,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction){var numparams=sec.sun.awt.geom.Order3.getHorizontalParams(y0,cy0,cy1,y1,tmp);if(numparams===0){sec.sun.awt.geom.Order3.addInstance(curves,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction);return;} -tmp[3]=x0;tmp[4]=y0;tmp[5]=cx0;tmp[6]=cy0;tmp[7]=cx1;tmp[8]=cy1;tmp[9]=x1;tmp[10]=y1;var t=tmp[0];if(numparams>1&&t>tmp[1]){tmp[0]=tmp[1];tmp[1]=t;t=tmp[0];} -sec.sun.awt.geom.Order3.split(tmp,3,t);if(numparams>1){t=(tmp[1]-t)/(1-t);sec.sun.awt.geom.Order3.split(tmp,9,t);} -var index=3;if(direction===-1){index+=numparams*6;}while(numparams>=0){sec.sun.awt.geom.Order3.addInstance(curves,tmp[index+0],tmp[index+1],tmp[index+2],tmp[index+3],tmp[index+4],tmp[index+5],tmp[index+6],tmp[index+7],direction);numparams--;if(direction===1){index+=6;}else{index-=6;}}};sec.sun.awt.geom.Order3.addInstance=function(curves,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction){if(y0>y1){curves.add(new sec.sun.awt.geom.Order3(x1,y1,cx1,cy1,cx0,cy0,x0,y0,-direction));}else if(y1>y0){curves.add(new sec.sun.awt.geom.Order3(x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction));}};sec.sun.awt.geom.Order3.getHorizontalParams=function(c0,cp0,cp1,c1,ret) -{if(c0<=cp0&&cp0<=cp1&&cp1<=c1) -{return 0;} -c1-=cp1;cp1-=cp0;cp0-=c0;ret[0]=cp0;ret[1]=(cp1-cp0)*2;ret[2]=(c1-cp1-cp1+cp0);var numroots=sec.sun.awt.geom.Curve.solveQuadratic(ret,ret);var j=0;for(var i=0;i0&&t<1){if(j=left;cur--){e=edgelist[cur];if(e.getCurve().getYBot()>y){if(next>cur){edgelist[next]=e;} -next--;}} -left=next+1;if(left>=right){if(right>=numedges){break;} -y=edgelist[right].getCurve().getYTop();if(y>yrange[0]){sec.sun.awt.geom.SomeOp.finalizeSubCurves(subcurves,chains);} -yrange[0]=y;} -while(righty){break;} -right++;} -yrange[1]=edgelist[left].getCurve().getYBot();if(righty){yrange[1]=y;}} -if(false){System.out.println("current line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curleft;next--){var prevedge=edgelist[next-1];var ordering=e.compareTo(prevedge,yrange);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping to "+yrange[1]+" from "+yrange[0]);} -if(ordering>=0){if(ordering===0){var eq=prevedge.getEquivalence();if(eq===0){eq=nexteq++;prevedge.setEquivalence(eq);} -e.setEquivalence(eq);} -break;} -edgelist[next]=prevedge;} -edgelist[next]=e;} -if(false){System.out.println("current sorted line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curfurthesty){longestmatch=e;furthesty=y;}}while(++cur0) -{edges.add(new sec.sun.awt.geom.Edge(c,curvetag));}}};sec.sun.awt.geom.SomeOp.finalizeSubCurves=function(subcurves,chains) -{var numchains=chains.size();if(numchains===0){return;} -if((numchains&1)!==0){throw new InternalError("Odd number of chains!");} -var endlist=new Array(numchains);chains.toArray(endlist);for(var i=1;ij) -obj[j]=this._vector.get(j);else -obj[j]=null;}};this.add=function(obj) -{this._vector.add(obj);};this.clear=function() -{this._vector.clear();};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlOptions=function() -{this.mode="absolute";this.fromString=function(a){return a;throw new IllegalArgumentException("No AltitudeMode with mode \""+a+"\" found");};this.toString=function(){return this.mode;};this.getMode=function(){return this.mode;};};sec.geo.kml.KmlOptions.AltitudeMode={ABSOLUTE:"absolute",RELATIVE_TO_GROUND:"relativeToGround",RELATIVE_TO_SEA_FLOOR:"relativeToSeaFloor",CLAMP_TO_GROUND:"clampToGround",CLAMP_TO_SEA_FLOOR:"clampToSeaFloor"};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlPolygon=function() -{this.points=null;this.altitudeMode=null;this.altitudeModeField="#ALTITUDEMODE#";this.PREFIX=null;this.SUFFIX="\t\t\t\t\t\n\t\t\t\t\n";this.PREFIX=""+" \n"+" 1\n"+" "+this.altitudeModeField+"\n"+" ";this.SUFFIX=""+" \n"+" \n";this.altitudeMode=sec.geo.kml.KmlOptions.AltitudeMode.ABSOLUTE;this.points=new java.util.ArrayList();if(arguments.length===2) -{var points=arguments[0];var altitudeMode=arguments[1];this.points.addAll(points);this.altitudeMode=altitudeMode;} -this.addPoint=function(point){this.points.add(point);};this.addPoints=function(points){this.points.addAll(points);};this.toString=function(){var sb=new sec.geo.utilities.StringBuilder();sb.append(this.PREFIX);sb.append(this.toCoordString());sb.append(this.SUFFIX);var altitudeModeIndex=sb.indexOf(this.altitudeModeField);var altitudeModeLength=this.altitudeModeField.length;if(this.altitudeMode!==null) -sb.replace(altitudeModeIndex,altitudeModeIndex+altitudeModeLength,this.altitudeMode.toString());return sb.toString();};this.toCoordString=function(){var sb=new sec.geo.utilities.StringBuilder();var orderedPoints=this.getPointsCounterClockwise();if(orderedPoints===null) -return"";var point;for(var j=0;j0){result=this.reverse(result);return result;}else -return result;};this.getPointOrder=function(){if(this.points===null||this.points.size()<3) -return 0;var n=this.points.size();var j;var k;var count=0;var z;for(var i=0;i0) -count++;} -if(count>0) -return-1;else if(count<0) -return 1;else -return 0;};this.subList=function(al,fromIndex,toIndex){var result=new java.util.ArrayList();var j=0;for(j=fromIndex;j=0;j--) -result.add(al.get(j));return result;};};sec.geo.kml.KmlPolygon.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlRenderer=function() -{this.colorDefault="ff003fff";this.descriptionField="#DESCRIPTION#";this.extendedData="#EXTENDEDDATA#";this.colorField="#COLOR#";this.nameField="#NAME#";this.idField="#ID#";this.placemarkidField="#PLACEMARKID#";this.KML_START=null;this.KML_END="\n";this.PLACEMARK_START=null;this.PLACEMARK_END="\t\t\t\n\t\t\n";this.DEFAULT_EXDAT="#ID##SHAPETYPE##LAT##LON##ALT#";this.DEFAULT_BLSTY="";this.KML_START="\n";this.PLACEMARK_START="\t\t\n"+" \n"+" "+this.nameField+"\n"+" "+this.descriptionField+"\n"+" "+this.extendedData+"\n"+" \n";this.KML_START="\n";this.KML_END="\n";this.PLACEMARK_START=""+" \n"+" \n"+" "+this.nameField+"\n"+" "+this.descriptionField+"\n"+" "+this.extendedData+"\n"+" \n";this.PLACEMARK_END=""+" \n"+" \n";this.DEFAULT_EXDAT="#ID##SHAPETYPE##LAT##LON##ALT#";this.DEFAULT_BLSTY="";this.renderPolygons=function(ext){var polys=new java.util.ArrayList();ext.setMaxDistance(200000);ext.setFlatness(1);ext.setLimit(3);var perimeterPoints=new java.util.ArrayList();var it=null;var ait=null;var oit=ext.getPathIterator(null);if(Clazz.instanceOf(oit,armyc2.c2sd.graphics2d.PathIterator)) -it=oit;else if(Clazz.instanceOf(oit,sec.sun.awt.geom.AreaIterator)) -ait=oit;var pre=null;if(it!==null){while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var longitudeDegrees=strokePoints[0];var latitudeDegrees=strokePoints[1];switch(type){case 0:case 1:if(pre!==null){var ps=new java.util.ArrayList();ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));polys.add(new sec.geo.kml.KmlPolygon(ps,ext.getAltitudeMode()));} -pre=new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees);perimeterPoints.add(pre);} -it.next();}}else if(ait!==null){while(!ait.isDone()){var strokePoints=Clazz.newArray(6,0);var type=ait.currentSegment(strokePoints);var longitudeDegrees=strokePoints[0];var latitudeDegrees=strokePoints[1];switch(type){case 0:case 1:if(pre!==null){var ps=new java.util.ArrayList();ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));polys.add(new sec.geo.kml.KmlPolygon(ps,ext.getAltitudeMode()));} -pre=new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees);perimeterPoints.add(pre);} -ait.next();}} -if(perimeterPoints.size()>0){if(perimeterPoints.get(0).equals(perimeterPoints.get(perimeterPoints.size()-1))){polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMinAltitude()),ext.getAltitudeMode()));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMaxAltitude()),ext.getAltitudeMode()));}else{perimeterPoints.add(perimeterPoints.get(0));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMinAltitude()),ext.getAltitudeMode()));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMaxAltitude()),ext.getAltitudeMode()));}} -return polys;};this.getPlacemarkKml=function(ext,id,name,description,color){try{var sb=new sec.geo.utilities.StringBuilder();var polys=this.renderPolygons(ext);sb.append(this.PLACEMARK_START);var placemarkIdIndex=sb.indexOf(this.placemarkidField);var placemarkIdLength=this.placemarkidField.length;if(id!==null){sb.replace(placemarkIdIndex,placemarkIdIndex+placemarkIdLength,id+"_mg");} -var descriptionIndex=sb.indexOf(this.descriptionField);var descriptionLength=this.descriptionField.length;if(description!==null) -sb.replace(descriptionIndex,descriptionIndex+descriptionLength,description);var colorIndex=sb.indexOf(this.colorField);var colorLength=this.colorField.length;if(color!==null){sb.replace(colorIndex,colorIndex+colorLength,color);}else -sb.replace(colorIndex,colorIndex+colorLength,this.colorDefault);var lineColorIndex=sb.indexOf2(this.colorField,colorIndex+colorLength);if(color!==null){sb.replace(lineColorIndex,lineColorIndex+colorLength,color);}else -sb.replace(lineColorIndex,lineColorIndex+colorLength,this.colorDefault);var nameIndex=sb.indexOf(this.nameField);var nameLength=this.nameField.length;if(name!==null) -sb.replace(nameIndex,nameIndex+nameLength,name);for(var j=0;jarialWidth&&spWidth>arialWidth&&tgWidth>arialWidth) -returnVal=true;return returnVal;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ImageInfo=function(image,centerPoint,symbolBounds,bounds){this._canvas=image;this._center=centerPoint;this._symbolBounds=symbolBounds;this._bounds=bounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.toDataUrl=function(){return this._canvas.toDataURL();};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getImage=function(){return this._canvas;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getCenterPoint=function(){return this._center;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSymbolBounds=function(){return this._symbolBounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getImageBounds=function(){return this._bounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSquareIcon=function(){var iwidth,iheight,x,y;var width=this._bounds.getWidth();var height=this._bounds.getHeight();if(this._bounds.getWidth()>this._bounds.getHeight()) -{iwidth=this._bounds.getWidth();iheight=this._bounds.getWidth();x=0;y=(iheight-height)/2;} -else if(this._bounds.getWidth()height-point.getY()) -{height=(point.getY()*2.0);y=0;} -else -{height=((height-point.getY())*2);y=((height/2)-point.getY());} -if(point.getX()>width-point.getX()) -{width=(point.getX()*2.0);x=0;} -else -{width=((width-point.getX())*2);x=((width/2)-point.getX());} -bi=document.createElement('canvas');bi.width=width;bi.height=height;var ctx=bi.getContext('2d');ctx.drawImage(image,x,y);} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("ImageInfo","getCenteredImage",err);} -return bi;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getCenteredImageInfo=function(){var image=this._canvas,bi=null,ii=null,x=0,y=0,height=image.height,width=image.width,point=this._center;try -{if(point.getY()>height-point.getY()) -{height=(point.getY()*2.0);y=0;} -else -{height=((height-point.getY())*2);y=((height/2)-point.getY());} -if(point.getX()>width-point.getX()) -{width=(point.getX()*2.0);x=0;} -else -{width=((width-point.getX())*2);x=((width/2)-point.getX());} -bi=document.createElement('canvas');bi.width=width;bi.height=height;var ctx=bi.getContext('2d');ctx.drawImage(image,x,y);var center=point.clone();center.shift(x,y);var symbolBounds=this._symbolBounds.clone();symbolBounds.shift(x,y);var bounds=new armyc2.s2sd.renderer.so.Rectangle(0,0,width,height);ii=new armyc2.c2sd.renderer.utilities.ImageInfo(bi,center,symbolBounds,bounds);} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("ImageInfo","getCenteredImage",err);} -return ii;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSquareImageInfo=function(){var iwidth,iheight,x,y;var width=this._bounds.getWidth();var height=this._bounds.getHeight();var ii=null;if(this._bounds.getWidth()>this._bounds.getHeight()) -{iwidth=this._bounds.getWidth();iheight=this._bounds.getWidth();x=0;y=(iheight-height)/2;} -else if(this._bounds.getWidth()0) -{var bounds=new armyc2.c2sd.renderer.so.Rectangle(this.bounds.x-outlineOffset,this.bounds.y-outlineOffset,this.bounds.width+outlineOffset*2,this.bounds.height+outlineOffset*2);return bounds;} -else -{return this.bounds;}};armyc2.c2sd.renderer.utilities.TextInfo.prototype.getText=function(){return this.text;};armyc2.c2sd.renderer.utilities.TextInfo.prototype.getLocation=function(){return this.location;};armyc2.c2sd.renderer.utilities.TextInfo.prototype.outlineText=function(context){var thickness=armyc2.c2sd.renderer.utilities.RendererSettings.getTextOutlineWidth();for(var i=1;i<=thickness;i++) -{if(i%2!==0) -{context.fillText(this.text,this.location.getX()-i,this.location.getY()-i);context.fillText(this.text,this.location.getX()+i,this.location.getY()-i);context.fillText(this.text,this.location.getX()-i,this.location.getY()+i);context.fillText(this.text,this.location.getX()+i,this.location.getY()+i);} -else -{context.fillText(this.text,this.location.getX()-i,this.location.getY());context.fillText(this.text,this.location.getX()+i,this.location.getY());context.fillText(this.text,this.location.getX(),this.location.getY()+i);context.fillText(this.text,this.location.getX(),this.location.getY()-i);}}};armyc2.c2sd.renderer.utilities.TextInfo.prototype.strokeText=function(context){context.strokeText(this.text,this.location.getX(),this.location.getY());};armyc2.c2sd.renderer.utilities.TextInfo.prototype.fillText=function(context){context.fillText(this.text,this.location.getX(),this.location.getY());};armyc2.c2sd.renderer.utilities.TextInfo.prototype.createBuffer=function(width,height) -{var buffer=document.createElement('canvas');buffer.width=width;buffer.height=height;return buffer;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ModifiersUnits={A_SYMBOL_ICON:"A",B_ECHELON:"B",C_QUANTITY:"C",D_TASK_FORCE_INDICATOR:"D",E_FRAME_SHAPE_MODIFIER:"E",F_REINFORCED_REDUCED:"F",G_STAFF_COMMENTS:"G",H_ADDITIONAL_INFO_1:"H",H1_ADDITIONAL_INFO_2:"H1",H2_ADDITIONAL_INFO_3:"H2",J_EVALUATION_RATING:"J",K_COMBAT_EFFECTIVENESS:"K",L_SIGNATURE_EQUIP:"L",M_HIGHER_FORMATION:"M",N_HOSTILE:"N",P_IFF_SIF:"P",Q_DIRECTION_OF_MOVEMENT:"Q",R_MOBILITY_INDICATOR:"R",R2_SIGNIT_MOBILITY_INDICATOR:"R2",S_HQ_STAFF_OR_OFFSET_INDICATOR:"S",T_UNIQUE_DESIGNATION_1:"T",T1_UNIQUE_DESIGNATION_2:"T1",V_EQUIP_TYPE:"V",W_DTG_1:"W",W1_DTG_2:"W1",X_ALTITUDE_DEPTH:"X",Y_LOCATION:"Y",Z_SPEED:"Z",AA_SPECIAL_C2_HQ:"AA",AB_FEINT_DUMMY_INDICATOR:"AB",AC_INSTALLATION:"AC",AD_PLATFORM_TYPE:"AD",AE_EQUIPMENT_TEARDOWN_TIME:"AE",AF_COMMON_IDENTIFIER:"AF",AG_AUX_EQUIP_INDICATOR:"AG",AH_AREA_OF_UNCERTAINTY:"AH",AI_DEAD_RECKONING_TRAILER:"AI",AJ_SPEED_LEADER:"AJ",AK_PAIRING_LINE:"AK",AL_OPERATIONAL_CONDITION:"AL",AO_ENGAGEMENT_BAR:"AO",CC_COUNTRY_CODE:"CC",CN_CPOF_NAME_LABEL:"CN"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SinglePointLookupInfo=function(basicSymbolID,description,mappingP,mappingA,width,height){var _SymbolID=basicSymbolID,_Description=description,_mappingP=mappingP,_mappingA=mappingA,_width=width,_height=height;this.getBasicSymbolID=function(){return _SymbolID;};this.getDescription=function(){return _Description;};this.getMappingA=function(){return _mappingA;};this.getMappingP=function(){return _mappingP;};this.getWidth=function(){return _width;};this.getHeight=function(){return _height;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.UnitFontLookupInfo=function(basicSymbolID,description,mapping1U,mapping1F,mapping1N,mapping1H,mapping1Color,mapping2,mapping2Color){var _SymbolID=basicSymbolID,_Description=description,_mapping1U=mapping1U,_mapping1F=mapping1F,_mapping1N=mapping1N,_mapping1H=mapping1H,_mapping1Color=mapping1Color,_mapping2=mapping2,_mapping2Color=mapping2Color;this.getBasicSymbolID=function(){return _SymbolID;};this.getDescription=function(){return _Description;};this.getMapping1=function(symbolID){var affiliation=symbolID.charAt(1);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -return _mapping1F;else if(affiliation==='H'||affiliation==='S') -return _mapping1H;if(affiliation==='N'||affiliation==='L') -return _mapping1N;else -return _mapping1U;};this.getMapping2=function(){return _mapping2;};this.getColor1=function(){return _mapping1Color;};this.getColor2=function(){return _mapping2Color;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.TacticalGraphicLookup=(function(){var symbols=null,symbolMap=null,parser,spMappingXml={"TACTICALGRAPHICS":{"SYMBOL":[{"SYMBOLID":"G*T*B-----****X","MAPPING":"2001","DESCRIPTION":"Tactical Graphics_ Tasks_Block"},{"SYMBOLID":"G*T*H-----****X","MAPPING":"2002","DESCRIPTION":"Tactical Graphics_ Tasks_Breach"},{"SYMBOLID":"G*T*Y-----****X","MAPPING":"2003","DESCRIPTION":"Tactical Graphics_Tasks_Bypass"},{"SYMBOLID":"G*T*C-----****X","MAPPING":"2004","DESCRIPTION":"Tactical Graphics_Tasks_Canalize"},{"SYMBOLID":"G*T*X-----****X","MAPPING":"2005","DESCRIPTION":"Tactical Graphics_Tasks_Clear"},{"SYMBOLID":"G*T*J-----****X","MAPPING":"2006","DESCRIPTION":"Tactical Graphics_Tasks_Contain"},{"SYMBOLID":"G*T*K-----****X","MAPPING":"2007","DESCRIPTION":"Tactical Graphics_Tasks_Counterattach (CATK)"},{"SYMBOLID":"G*T*KF----****X","MAPPING":"2008","DESCRIPTION":"Tactical Graphics_Tasks_Counterattack (CATK)_Counterattack By Fire"},{"SYMBOLID":"G*T*L-----****X","MAPPING":"2009","DESCRIPTION":"Tactical Graphics_Tasks_Delay"},{"SYMBOLID":"G*T*T-----****X","MAPPING":"2011","DESCRIPTION":"Tactical Graphics_Tasks_Disrupt "},{"SYMBOLID":"G*T*F-----****X","MAPPING":"2012","DESCRIPTION":"Tactical Graphics_Tasks_Fix"},{"SYMBOLID":"G*T*A-----****X","MAPPING":"2013","DESCRIPTION":"Tactical Graphics_Tasks_Follow And Assume"},{"SYMBOLID":"G*T*AS----****X","MAPPING":"2014","DESCRIPTION":"Tactical Graphics_Tasks_Follow And Assume_Follow And Support "},{"SYMBOLID":"G*T*E-----****X","MAPPING":"2016","DESCRIPTION":"Tactical Graphics_Tasks_Isolate"},{"SYMBOLID":"G*T*O-----****X","MAPPING":"2018","DESCRIPTION":"Tactical Graphics_Tasks_Occupy"},{"SYMBOLID":"G*T*P-----****X","MAPPING":"2019","DESCRIPTION":"Tactical Graphics_Tasks_Penetrate"},{"SYMBOLID":"G*T*R-----****X","MAPPING":"2020","DESCRIPTION":"Tactical Graphics_Tasks_Relief In Place (RIP)"},{"SYMBOLID":"G*T*Q-----****X","MAPPING":"2021","DESCRIPTION":"Tactical Graphics_Tasks_Retain"},{"SYMBOLID":"G*T*M-----****X","MAPPING":"2022","DESCRIPTION":"Tactical Graphics_Tasks_Retirement"},{"SYMBOLID":"G*T*S-----****X","MAPPING":"2023","DESCRIPTION":"Tactical Graphics_Tasks_Secure"},{"SYMBOLID":"G*T*US----****X","MAPPING":"2024","DESCRIPTION":"Tactical Graphics_Tasks_Security_Screen"},{"SYMBOLID":"G*T*UG----****X","MAPPING":"2025","DESCRIPTION":"Tactical Graphics_Tasks_Security_Guard"},{"SYMBOLID":"G*T*UC----****X","MAPPING":"2026","DESCRIPTION":"Tactical Graphics_Tasks_Security_Cover"},{"SYMBOLID":"G*T*Z-----****X","MAPPING":"2027","DESCRIPTION":"Tactical Graphics_Tasks_Seize"},{"SYMBOLID":"G*T*W-----****X","MAPPING":"2028","DESCRIPTION":"Tactical Graphics_Tasks_Withdraw"},{"SYMBOLID":"G*T*WP----****X","MAPPING":"2029","DESCRIPTION":"Tactical Graphics_Tasks_Withdraw_Withdraw Under Pressure "},{"SYMBOLID":"G*T*V-----****X","MAPPING":"2016","DESCRIPTION":"Tactical Graphics_Tasks_Cordon_and_Search "},{"SYMBOLID":"G*T*2-----****X","MAPPING":"2016","DESCRIPTION":"Tactical Graphics_Tasks_Cordon_and_Knock "},{"SYMBOLID":"G*G*GLB---****X","MAPPING":"2030","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Boundaries "},{"SYMBOLID":"G*G*GLF---****X","MAPPING":"2031","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Forward Line Of Own Troops (Flot)"},{"SYMBOLID":"G*G*GLC---****X","MAPPING":"2032","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Line Of Contact "},{"SYMBOLID":"G*G*GLP---****X","MAPPING":"2033","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Phase Line "},{"SYMBOLID":"G*G*GLL---****X","MAPPING":"2034","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Light Line "},{"SYMBOLID":"G*G*GAG---****X","MAPPING":"2035","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_General Area"},{"SYMBOLID":"G*G*GAA---****X","MAPPING":"2036","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Assembly Area"},{"SYMBOLID":"G*G*GAE---****X","MAPPING":"2037","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Engagement Area"},{"SYMBOLID":"G*G*GAF---****X","MAPPING":"2038","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Lines_Fortified Area"},{"SYMBOLID":"G*G*GAD---****X","MAPPING":"2039","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Drop Zone "},{"SYMBOLID":"G*G*GAX---****X","MAPPING":"2040","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Area_Extraction Zone (EZ)"},{"SYMBOLID":"G*G*GAL---****X","MAPPING":"2041","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Landing Zone (LZ)"},{"SYMBOLID":"G*G*GAP---****X","MAPPING":"2042","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Pickup Zone (PZ)"},{"SYMBOLID":"G*G*GAS---****X","MAPPING":"2043","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Search Area/Reconnaissance Area"},{"SYMBOLID":"G*G*GAY---****X","MAPPING":"2044","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Limited Access Area"},{"SYMBOLID":"G*G*GAZ---****X","MAPPING":"2045","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_General_Areas_Airfield Zone "},{"SYMBOLID":"G*G*ALC---****X","MAPPING":"2046","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Lines_Air Corridor "},{"SYMBOLID":"G*G*ALM---****X","MAPPING":"2047","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Lines_Minimum Risk Route (MRR) "},{"SYMBOLID":"G*G*ALS---****X","MAPPING":"2048","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Lines_Standard-Use Army Aircraft Flight Route (SAAFR) "},{"SYMBOLID":"G*G*ALU---****X","MAPPING":"2049","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Lines_Unmanned Aerial Vehicle (UAV) Route "},{"SYMBOLID":"G*G*ALL---****X","MAPPING":"2050","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Lines_Low Level Transit Route (LLTR)"},{"SYMBOLID":"G*G*AAR---****X","MAPPING":"2051","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Restricted Operations Zone (ROZ)"},{"SYMBOLID":"G*G*AAF---****X","MAPPING":"2052","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Forward Area Ari Defense Zone (FAADEZ)"},{"SYMBOLID":"G*G*AAF---2525C","MAPPING":"2053","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_SHORT-RANGE_AIR_DEFENSE_ENGAGEMENT_ZONE (SHORADEZ)"},{"SYMBOLID":"G*G*AAH---****X","MAPPING":"2054","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_High Density Airpspace Control Zone (Hidacz) "},{"SYMBOLID":"G*G*AAM---****X","MAPPING":"2055","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Missile Engagement Zone (MEZ) "},{"SYMBOLID":"G*G*AAML--****X","MAPPING":"2056","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Missile Enagement Zone (MEZ) Low Altitude Mez "},{"SYMBOLID":"G*G*AAMH--****X","MAPPING":"2057","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Missile Engagement Zone (MEZ)_High Altitude MEZ"},{"SYMBOLID":"G*G*AAW---****X","MAPPING":"2058","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Aviation_Areas_Weapoins Free Zone "},{"SYMBOLID":"G*G*PD----****X","MAPPING":"2059","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Dummy (Deception) (Decoy) "},{"SYMBOLID":"G*G*PA----****X","MAPPING":"2060","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Axis Of Advance For Feint "},{"SYMBOLID":"G*G*PF----****X","MAPPING":"2061","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Direction Of Attack For Feint "},{"SYMBOLID":"G*G*PM----****X","MAPPING":"2062","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Decoy Mined Area"},{"SYMBOLID":"G*G*PY----****X","MAPPING":"2063","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Decoy Mined Area, Fenced "},{"SYMBOLID":"G*G*PC----****X","MAPPING":"2064","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Deception_Dummy Minefield - Dynamic "},{"SYMBOLID":"G*G*DLF---****X","MAPPING":"2065","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Defense_Lines_Forward Edge Of Battle Area (FEBA) "},{"SYMBOLID":"G*G*DLP---****X","MAPPING":"2066","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Defense_Lines_Principal Direction Of Fire (PDF)"},{"SYMBOLID":"G*G*DAB---****X","MAPPING":"2067","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Defense_Areas_Battle Position"},{"SYMBOLID":"G*G*DABP--****X","MAPPING":"2068","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Defense_Areas_Battle Position_Prepared But Not Occupied "},{"SYMBOLID":"G*G*DAE---****X","MAPPING":"2069","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Defense_Area_Engagement Area"},{"SYMBOLID":"G*G*OLAV--****X","MAPPING":"2070","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Axis Of Advance_Friendly Aviation"},{"SYMBOLID":"G*G*OLAA--****X","MAPPING":"2071","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Axis Of Advance_Friendly Airborne "},{"SYMBOLID":"G*G*OLAR--****X","MAPPING":"2072","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Axis Of Advance_Friendly Attack, Rotory Wing "},{"SYMBOLID":"G*G*OLAGM-****X","MAPPING":"2073","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Axis Of Advance_Ground_Main Attack "},{"SYMBOLID":"G*G*OLAGS-****X","MAPPING":"2074","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Axis Of Advance_Ground_Support Attack"},{"SYMBOLID":"G*G*OLKA--****X","MAPPING":"2075","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Direction Of Attack_Aviation "},{"SYMBOLID":"G*G*OLKGM-****X","MAPPING":"2076","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Direction Of Attack_Ground_Main Attack"},{"SYMBOLID":"G*G*OLKGS-****X","MAPPING":"2077","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Direction Of Attack_Ground_ Supporting Attack"},{"SYMBOLID":"G*G*OLF---****X","MAPPING":"2078","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Final Coordination Line "},{"SYMBOLID":"G*G*OLI---****X","MAPPING":"2079","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Infiltration Line "},{"SYMBOLID":"G*G*OLL---****X","MAPPING":"2080","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Limit Of Advance "},{"SYMBOLID":"G*G*OLT---****X","MAPPING":"2081","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Line Of Departure "},{"SYMBOLID":"G*G*OLC---****X","MAPPING":"2082","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Line Of Departure/Line Of Contact (LD.LC)"},{"SYMBOLID":"G*G*OLP---****X","MAPPING":"2083","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Lines_Probable Line Of Deployment (PLD) "},{"SYMBOLID":"G*G*OAA---****X","MAPPING":"2084","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Assault Position"},{"SYMBOLID":"G*G*OAK---****X","MAPPING":"2085","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Attack Position"},{"SYMBOLID":"G*G*OAF---****X","MAPPING":"2086","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Attack By Fire Position "},{"SYMBOLID":"G*G*OAS---****X","MAPPING":"2087","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Support By Fire Position "},{"SYMBOLID":"G*G*OAO---****X","MAPPING":"2088","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Objective "},{"SYMBOLID":"G*G*OAP---****X","MAPPING":"2089","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Offense_Areas_Penetration BoX"},{"SYMBOLID":"G*G*SLA---****X","MAPPING":"2090","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Line_Ambush"},{"SYMBOLID":"G*G*SLH---****X","MAPPING":"2091","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Line_Holding Line "},{"SYMBOLID":"G*G*SLR---****X","MAPPING":"2092","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Line_Release Line "},{"SYMBOLID":"G*G*SLB---****X","MAPPING":"2093","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Bridgehead"},{"SYMBOLID":"G*G*SAO---****X","MAPPING":"2094","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Area Of Operations (AO)"},{"SYMBOLID":"G*G*SAA---****X","MAPPING":"2095","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Airhead "},{"SYMBOLID":"G*G*SAE---****X","MAPPING":"2096","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Encirclement "},{"SYMBOLID":"G*G*SAN---****X","MAPPING":"2097","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Named Area Of Interest (NAI)"},{"SYMBOLID":"G*G*SAT---****X","MAPPING":"2098","DESCRIPTION":"Tactical Graphics_Command And Control And General Maneuver_Special_Area_Targeted Area Of Interest (TAI) "},{"SYMBOLID":"G*M*OGB---****X","MAPPING":"2099","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_General_Belt "},{"SYMBOLID":"G*M*OGL---****X","MAPPING":"2100","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_General_Line "},{"SYMBOLID":"G*M*OGZ---****X","MAPPING":"2101","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_General_Zone"},{"SYMBOLID":"G*M*OGF---****X","MAPPING":"2102","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_General_Obstacle Free Area"},{"SYMBOLID":"G*M*OGR---****X","MAPPING":"2103","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_General_Obstacle Restricted Area"},{"SYMBOLID":"G*M*OS----****X","MAPPING":"2104","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Abatis "},{"SYMBOLID":"G*M*OADU--****X","MAPPING":"2105","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Antitank Obstacles_Antitank Ditch_Under Construction"},{"SYMBOLID":"G*M*OADC--****X","MAPPING":"2106","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Antitank Obstacles_Antitank Ditch_Complete "},{"SYMBOLID":"G*M*OAR---****X","MAPPING":"2107","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Antitank Obstacles_Antitank Ditch Reinforced With Antitank Mines "},{"SYMBOLID":"G*M*OAW---****X","MAPPING":"2108","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Antitank Obstacles_Antitank Wall"},{"SYMBOLID":"G*M*OMC---****X","MAPPING":"2109","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Mines_Mine Cluster "},{"SYMBOLID":"G*M*OFD---****X","MAPPING":"2110","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Minefields_Dynamic Depiction"},{"SYMBOLID":"G*M*OFG---****X","MAPPING":"2111","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Minefields_Gap"},{"SYMBOLID":"G*M*OFA---****X","MAPPING":"2112","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Minefields_Minded Area"},{"SYMBOLID":"G*M*OEB---****X","MAPPING":"2113","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Obstacle Effect_Block"},{"SYMBOLID":"G*M*OEF---****X","MAPPING":"2114","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Obstacle Effect_FiX"},{"SYMBOLID":"G*M*OET---****X","MAPPING":"2115","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Obstacle Effect_Turn"},{"SYMBOLID":"G*M*OED---****X","MAPPING":"2116","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Obstacle Effect_Disrupt "},{"SYMBOLID":"G*M*OU----****X","MAPPING":"2117","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Unexploed Ordinance Area (UXO)"},{"SYMBOLID":"G*M*ORP---****X","MAPPING":"2118","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Roadblocks, Craters, And Blown Bridges_Planned "},{"SYMBOLID":"G*M*ORS---****X","MAPPING":"2119","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Roadblocks, Craters, And Blown Bridges_Explosives, State Of Readiness 1 (Safe)"},{"SYMBOLID":"G*M*ORA---****X","MAPPING":"2120","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Roadblocks, Craters, And Blown Bridges_Explosives, State Of Readiness 2 (Armed-But Passable) "},{"SYMBOLID":"G*M*ORC---****X","MAPPING":"2121","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Roadblocks, Craters, And Blown Bridges_Roadblock Complete (Executed)"},{"SYMBOLID":"G*M*OT----****X","MAPPING":"2122","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Trip Wire"},{"SYMBOLID":"G*M*OWU---****X","MAPPING":"2123","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle Unspecified "},{"SYMBOLID":"G*M*OWS---****X","MAPPING":"2124","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_ Single Fence "},{"SYMBOLID":"G*M*OWD---****X","MAPPING":"2125","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Double Fence"},{"SYMBOLID":"G*M*OWA---****X","MAPPING":"2126","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Double Apron Fence "},{"SYMBOLID":"G*M*OWL---****X","MAPPING":"2127","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Low Wire Fence "},{"SYMBOLID":"G*M*OWH---****X","MAPPING":"2128","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_High Wire Fence "},{"SYMBOLID":"G*M*OWCS--****X","MAPPING":"2129","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Single Concertina "},{"SYMBOLID":"G*M*OWCD--****X","MAPPING":"2130","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Double Strand Concertina "},{"SYMBOLID":"G*M*OWCT--****X","MAPPING":"2131","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Wire Obsticle_Triple Strand Concertina "},{"SYMBOLID":"G*M*OHO---****X","MAPPING":"2133","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacles_Aviation Overhead Wire "},{"SYMBOLID":"G*M*BDE---****X","MAPPING":"2134","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Obstacle Bypass Difficulty_Bypass Easy"},{"SYMBOLID":"G*M*BDD---****X","MAPPING":"2135","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Obstacle Bypass Difficulty_Bypass Difficult "},{"SYMBOLID":"G*M*BDI---****X","MAPPING":"2136","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Obstacle Bypass Difficulty_Bypass Impossible "},{"SYMBOLID":"G*M*BCA---****X","MAPPING":"2137","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Assault Crossing Area"},{"SYMBOLID":"G*M*BCB---****X","MAPPING":"2138","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Bridge Or Gap "},{"SYMBOLID":"G*M*BCF---****X","MAPPING":"2139","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Ferry"},{"SYMBOLID":"G*M*BCE---****X","MAPPING":"2140","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Ford Easy"},{"SYMBOLID":"G*M*BCD---****X","MAPPING":"2141","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Ford Difficult "},{"SYMBOLID":"G*M*BCL---****X","MAPPING":"2142","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Lane "},{"SYMBOLID":"G*M*BCR---****X","MAPPING":"2143","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Obstacle Bypass_Crossing Site/Water Crossing_Raft Site"},{"SYMBOLID":"G*M*SL----****X","MAPPING":"2144","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Surivability_Fortified Line "},{"SYMBOLID":"G*M*SW----****X","MAPPING":"2145","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Surivability_Foxhole, Emplacement Or Weapon Site "},{"SYMBOLID":"G*M*SP----****X","MAPPING":"2146","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Surivability_Strong Point"},{"SYMBOLID":"G*M*NM----****X","MAPPING":"2147","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Nuclear, Biological And Chemical_Minimum Safe Distrance Zones "},{"SYMBOLID":"G*M*NR----****X","MAPPING":"2148","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Nuclear, Biological And Chemical_Radio Active Area"},{"SYMBOLID":"G*M*NB----****X","MAPPING":"2149","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Nuclear, Biological And Chemical_Biologically Contaminated Area"},{"SYMBOLID":"G*M*NC----****X","MAPPING":"2150","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Nuclear, Biological And Chemical_Chemically Contaminated Area"},{"SYMBOLID":"G*M*NL----****X","MAPPING":"2151","DESCRIPTION":"Tactical Graphics_Mobility/Survivability_Nuclear, Biological And Chemical_Dose Rate Contour Lines "},{"SYMBOLID":"G*F*LT----****X","MAPPING":"2152","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Linear Target "},{"SYMBOLID":"G*F*LTS---****X","MAPPING":"2153","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Linear Smoke Target"},{"SYMBOLID":"G*F*LTF---****X","MAPPING":"2154","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Final Protective Fire (FPF)"},{"SYMBOLID":"G*F*LCF---****X","MAPPING":"2155","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Fire Support Coordination Line (FSCL) "},{"SYMBOLID":"G*F*LCC---****X","MAPPING":"2156","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Coordinated Fire Line (CFL) "},{"SYMBOLID":"G*F*LCN---****X","MAPPING":"2157","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_No-Fire Line (NFL) "},{"SYMBOLID":"G*F*LCR---****X","MAPPING":"2158","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Restrictive Fire Line (RFL) "},{"SYMBOLID":"G*F*LCM---****X","MAPPING":"2159","DESCRIPTION":"Tactical Graphics_Fire Support_Lines_Munition Flight Path (MFP) "},{"SYMBOLID":"G*F*AT----****X","MAPPING":"2160","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Area Target "},{"SYMBOLID":"G*F*ATR---****X","MAPPING":"2161","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Area Target_Rectangular "},{"SYMBOLID":"G*F*ATC---****X","MAPPING":"2162","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Area Target_Circular"},{"SYMBOLID":"G*F*ATG---****X","MAPPING":"2163","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Series Or Group Of Targets "},{"SYMBOLID":"G*F*ATS---****X","MAPPING":"2164","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Smoke "},{"SYMBOLID":"G*F*ATB---****X","MAPPING":"2165","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_Bomb Area"},{"SYMBOLID":"G*F*ACSI--****X","MAPPING":"2166","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FSA_Irregular"},{"SYMBOLID":"G*F*ACSR--****X","MAPPING":"2167","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FSA_Rectangular"},{"SYMBOLID":"G*F*ACSC--****X","MAPPING":"2168","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FSA_Circular"},{"SYMBOLID":"G*F*ACAI--****X","MAPPING":"2169","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_ACA_Irregular"},{"SYMBOLID":"G*F*ACAR--****X","MAPPING":"2170","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_ACA_Rectangular"},{"SYMBOLID":"G*F*ACAC--****X","MAPPING":"2171","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_ACA_Circular"},{"SYMBOLID":"G*F*ACFI--****X","MAPPING":"2172","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FFA_Irregular"},{"SYMBOLID":"G*F*ACFR--****X","MAPPING":"2173","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FFA_Rectangular"},{"SYMBOLID":"G*F*ACFC--****X","MAPPING":"2174","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_FFA_Circular"},{"SYMBOLID":"G*F*ACNI--****X","MAPPING":"2175","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_NFA_Irregular"},{"SYMBOLID":"G*F*ACNR--****X","MAPPING":"2176","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_NFA_Rectangular"},{"SYMBOLID":"G*F*ACNC--****X","MAPPING":"2177","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_NFA_Circular"},{"SYMBOLID":"G*F*ACRI--****X","MAPPING":"2178","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_RFA_Irregular"},{"SYMBOLID":"G*F*ACRR--****X","MAPPING":"2179","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_RFA_Rectangular"},{"SYMBOLID":"G*F*ACRC--****X","MAPPING":"2180","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_RFA_Circular"},{"SYMBOLID":"G*F*ACPR--****X","MAPPING":"2181","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_PAA_Rectangular "},{"SYMBOLID":"G*F*ACPC--****X","MAPPING":"2182","DESCRIPTION":"Tactical Graphics_Fire Support_Areas_PAA_Circular "},{"SYMBOLID":"G*F*AZII--****X","MAPPING":"2183","DESCRIPTION":"ATI_Irregular"},{"SYMBOLID":"G*F*AZIR--****X","MAPPING":"2184","DESCRIPTION":"ATI_Rectangular"},{"SYMBOLID":"G*F*AZIC--****X","MAPPING":"2185","DESCRIPTION":"ATI_Circular"},{"SYMBOLID":"G*F*AZXI--****X","MAPPING":"2186","DESCRIPTION":"CFFZ_Irregular"},{"SYMBOLID":"G*F*AZXR--****X","MAPPING":"2187","DESCRIPTION":"CFFZ_Rectangular"},{"SYMBOLID":"G*F*AZXC--****X","MAPPING":"2188","DESCRIPTION":"CFFZ_Circular"},{"SYMBOLID":"G*F*AZSI--****X","MAPPING":"2189","DESCRIPTION":"Sensor_Irregular"},{"SYMBOLID":"G*F*ACEI--****X","MAPPING":"2189","DESCRIPTION":"Sensor_Irregular"},{"SYMBOLID":"G*F*AZSR--****X","MAPPING":"2190","DESCRIPTION":"Sensor_Rectangular"},{"SYMBOLID":"G*F*ACER--****X","MAPPING":"2190","DESCRIPTION":"Sensor_Rectangular"},{"SYMBOLID":"G*F*AZSC--****X","MAPPING":"2191","DESCRIPTION":"Sensor_Circular"},{"SYMBOLID":"G*F*ACEC--****X","MAPPING":"2191","DESCRIPTION":"Sensor_Circular"},{"SYMBOLID":"G*F*AZCI--****X","MAPPING":"2192","DESCRIPTION":"Censor_Irregular"},{"SYMBOLID":"G*F*AZCR--****X","MAPPING":"2193","DESCRIPTION":"Censor_Rectangular"},{"SYMBOLID":"G*F*AZCC--****X","MAPPING":"2194","DESCRIPTION":"Censor_Circular"},{"SYMBOLID":"G*F*AZDI--****X","MAPPING":"2195","DESCRIPTION":"DA_Irregular"},{"SYMBOLID":"G*F*ACDI--****X","MAPPING":"2195","DESCRIPTION":"DA_Irregular"},{"SYMBOLID":"G*F*AZDR--****X","MAPPING":"2196","DESCRIPTION":"DA_Rectangular"},{"SYMBOLID":"G*F*ACDR--****X","MAPPING":"2196","DESCRIPTION":"DA_Rectangular"},{"SYMBOLID":"G*F*AZDC--****X","MAPPING":"2197","DESCRIPTION":"DA_Circular"},{"SYMBOLID":"G*F*ACDC--****X","MAPPING":"2197","DESCRIPTION":"DA_Circular"},{"SYMBOLID":"G*F*AZFI--****X","MAPPING":"2217","DESCRIPTION":"CFZ_Irregular"},{"SYMBOLID":"G*F*AZFR--****X","MAPPING":"2218","DESCRIPTION":"CFZ_Rectangular"},{"SYMBOLID":"G*F*AZFC--****X","MAPPING":"2219","DESCRIPTION":"CFZ_Circular"},{"SYMBOLID":"G*F*AZZI--****X","MAPPING":"2198","DESCRIPTION":"ZOR_Irregular"},{"SYMBOLID":"G*F*ACZI--****X","MAPPING":"2198","DESCRIPTION":"ZOR_Irregular"},{"SYMBOLID":"G*F*AZZR--****X","MAPPING":"2199","DESCRIPTION":"ZOR_Rectangular"},{"SYMBOLID":"G*F*ACZR--****X","MAPPING":"2199","DESCRIPTION":"ZOR_Rectangular"},{"SYMBOLID":"G*F*AZZC--****X","MAPPING":"2200","DESCRIPTION":"ZOR_Circular"},{"SYMBOLID":"G*F*ACZC--****X","MAPPING":"2200","DESCRIPTION":"ZOR_Circular"},{"SYMBOLID":"G*F*AZBI--****X","MAPPING":"2201","DESCRIPTION":"TBA_Irregular"},{"SYMBOLID":"G*F*ACBI--****X","MAPPING":"2201","DESCRIPTION":"TBA_Irregular"},{"SYMBOLID":"G*F*AZBR--****X","MAPPING":"2202","DESCRIPTION":"TBA_Rectangular"},{"SYMBOLID":"G*F*ACBR--****X","MAPPING":"2202","DESCRIPTION":"TBA_Rectangular"},{"SYMBOLID":"G*F*AZBC--****X","MAPPING":"2203","DESCRIPTION":"TBA_Circular"},{"SYMBOLID":"G*F*ACBC--****X","MAPPING":"2203","DESCRIPTION":"TBA_Circular"},{"SYMBOLID":"G*F*AZVI--****X","MAPPING":"2204","DESCRIPTION":"TVAR_Irregular"},{"SYMBOLID":"G*F*ACVI--****X","MAPPING":"2204","DESCRIPTION":"TVAR_Irregular"},{"SYMBOLID":"G*F*AZVR--****X","MAPPING":"2205","DESCRIPTION":"TVAR_Rectangular"},{"SYMBOLID":"G*F*ACVR--****X","MAPPING":"2205","DESCRIPTION":"TVAR_Rectangular"},{"SYMBOLID":"G*F*AZVC--****X","MAPPING":"2206","DESCRIPTION":"TVAR_Circular"},{"SYMBOLID":"G*F*ACVC--****X","MAPPING":"2206","DESCRIPTION":"TVAR_Circular"},{"SYMBOLID":"G*F*ACT---****X","MAPPING":"2210","DESCRIPTION":"TGMF"},{"SYMBOLID":"G*F*AXC---****X","MAPPING":"2207","DESCRIPTION":"Range_Fan"},{"SYMBOLID":"G*F*AXS---****X","MAPPING":"2208","DESCRIPTION":"Sector_Range_Fan"},{"SYMBOLID":"G*F*AKBC--****X","MAPPING":"2219","DESCRIPTION":"BKB Circular"},{"SYMBOLID":"G*F*AKBI--****X","MAPPING":"2220","DESCRIPTION":"BKB Irregular"},{"SYMBOLID":"G*F*AKBR--****X","MAPPING":"2221","DESCRIPTION":"BKB Rectangular"},{"SYMBOLID":"G*F*AKPC--****X","MAPPING":"2222","DESCRIPTION":"PKB Circular"},{"SYMBOLID":"G*F*AKPI--****X","MAPPING":"2223","DESCRIPTION":"PKB Irregular"},{"SYMBOLID":"G*F*AKPR--****X","MAPPING":"2224","DESCRIPTION":"PKB Rectangular"},{"SYMBOLID":"G*S*LCM---****X","MAPPING":"2226","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Convoys_Moving Convoy"},{"SYMBOLID":"G*S*LCH---****X","MAPPING":"2227","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Convoys_Halted Convoy"},{"SYMBOLID":"G*S*LRM---****X","MAPPING":"2228","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Supply Routes_Main Supply Route"},{"SYMBOLID":"G*S*LRA---****X","MAPPING":"2229","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Supply Routes_Alternate Supply Route "},{"SYMBOLID":"G*S*LRO---****X","MAPPING":"2230","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Supply Routes_One-Way Traffic"},{"SYMBOLID":"G*S*LRT---****X","MAPPING":"2231","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Supply Routes_Alternating Traffic "},{"SYMBOLID":"G*S*LRW---****X","MAPPING":"2232","DESCRIPTION":"Tactical Graphics_Combat Service Support_Lines_Supply Routes_Two-Way Traffic "},{"SYMBOLID":"G*S*AD----****X","MAPPING":"2233","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Detainee Holding Area"},{"SYMBOLID":"G*S*AE----****X","MAPPING":"2234","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Enemy Prisoner Of War (EPW) Holding Area "},{"SYMBOLID":"G*S*AR----****X","MAPPING":"2235","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Forward Arming And Refueling Area (FARP) "},{"SYMBOLID":"G*S*AH----****X","MAPPING":"2236","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Refugee Holding Area"},{"SYMBOLID":"G*S*ASB---****X","MAPPING":"2237","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Support Areas_Brigade (BSA)"},{"SYMBOLID":"G*S*ASD---****X","MAPPING":"2238","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Support Areas_Division (DSA)"},{"SYMBOLID":"G*S*ASR---****X","MAPPING":"2239","DESCRIPTION":"Tactical Graphics_Combat Service Support_Area_Support Areas_Regimental (RSA)"},{"SYMBOLID":"G*O*HN----****X","MAPPING":"2240","DESCRIPTION":"Tactical Graphics_Other_Hazard_Navigational"},{"SYMBOLID":"G*O*B-----****X","MAPPING":"2241","DESCRIPTION":"Tactical Graphics_Other_Bearing Line"},{"SYMBOLID":"G*O*BE----****X","MAPPING":"2242","DESCRIPTION":"Tactical Graphics_Other_Bearing Line_Electronic"},{"SYMBOLID":"G*O*BA----****X","MAPPING":"2243","DESCRIPTION":"Tactical Graphics_Other_Bearing Line_Acoustic"},{"SYMBOLID":"G*O*BT----****X","MAPPING":"2244","DESCRIPTION":"Tactical Graphics_Other_Bearing Line_Torpedo"},{"SYMBOLID":"G*O*BO----****X","MAPPING":"2245","DESCRIPTION":"Tactical Graphics_Other_Bearing Line_Electro-Optical Intercept"},{"SYMBOLID":"WA-DPFC----L---","MAPPING":"3000","DESCRIPTION":"Cold Front"},{"SYMBOLID":"WA-DPFCU---L---","MAPPING":"3001","DESCRIPTION":"Upper Cold Front"},{"SYMBOLID":"WA-DPFC-FG-L---","MAPPING":"3002","DESCRIPTION":"Cold Frontogenisis"},{"SYMBOLID":"WA-DPFC-FY-L---","MAPPING":"3003","DESCRIPTION":"Cold Frontolysis"},{"SYMBOLID":"WA-DPFW----L---","MAPPING":"3004","DESCRIPTION":"Warm Front"},{"SYMBOLID":"WA-DPFWU---L---","MAPPING":"3005","DESCRIPTION":"Upper Warm Front "},{"SYMBOLID":"WA-DPFW-FG-L---","MAPPING":"3006","DESCRIPTION":"Warm Frontogenesis "},{"SYMBOLID":"WA-DPFW-FY-L---","MAPPING":"3007","DESCRIPTION":"Warm Frontolysis "},{"SYMBOLID":"WA-DPFO----L---","MAPPING":"3008","DESCRIPTION":"Occluded Front "},{"SYMBOLID":"WA-DPFOU---L---","MAPPING":"3009","DESCRIPTION":"Upper Occluded Front "},{"SYMBOLID":"WA-DPFO-FY-L---","MAPPING":"3010","DESCRIPTION":"Occluded Frontolysis "},{"SYMBOLID":"WA-DPFS----L---","MAPPING":"3011","DESCRIPTION":"Stationary Front"},{"SYMBOLID":"WA-DPFSU---L---","MAPPING":"3012","DESCRIPTION":"Upper Stationary Front"},{"SYMBOLID":"WA-DPFS-FG-L---","MAPPING":"3013","DESCRIPTION":"Stationary Frontogenesis"},{"SYMBOLID":"WA-DPFS-FY-L---","MAPPING":"3014","DESCRIPTION":"Stationary Frontolysis"},{"SYMBOLID":"WA-DPXT----L---","MAPPING":"3015","DESCRIPTION":"Trough Axis"},{"SYMBOLID":"WA-DPXR----L---","MAPPING":"3016","DESCRIPTION":"Ridge Line "},{"SYMBOLID":"WA-DPXSQ---L---","MAPPING":"3017","DESCRIPTION":"Squall Line "},{"SYMBOLID":"WA-DPXIL---L---","MAPPING":"3018","DESCRIPTION":"Instability Line "},{"SYMBOLID":"WA-DPXSH---L---","MAPPING":"3019","DESCRIPTION":"Shear Line "},{"SYMBOLID":"WA-DPXITCZ-L---","MAPPING":"3020","DESCRIPTION":"Inter-Tropical Convergance Zone "},{"SYMBOLID":"WA-DPXCV---L---","MAPPING":"3021","DESCRIPTION":"Convergance Line "},{"SYMBOLID":"WA-DPXITD--L---","MAPPING":"3022","DESCRIPTION":"Inter-Tropical Discontinuity "},{"SYMBOLID":"WAS-WP----P----","MAPPING":"3023","DESCRIPTION":"Wind Plot"},{"SYMBOLID":"WA-DWJ-----L---","MAPPING":"3030","DESCRIPTION":"Jet Stream Line"},{"SYMBOLID":"WA-DWS-----L---","MAPPING":"3031","DESCRIPTION":"Stream Line"},{"SYMBOLID":"WA-DWSTSWA--A--","MAPPING":"3032","DESCRIPTION":"Tropical Storm Wind Areas"},{"SYMBOLID":"WA-DBAIF----A--","MAPPING":"3034","DESCRIPTION":"IFR"},{"SYMBOLID":"WA-DBAMV----A--","MAPPING":"3035","DESCRIPTION":"MVFR "},{"SYMBOLID":"WA-DBATB----A--","MAPPING":"3036","DESCRIPTION":"Weather Turbulence"},{"SYMBOLID":"WA-DBAI-----A--","MAPPING":"3037","DESCRIPTION":"Weather Icing"},{"SYMBOLID":"WA-DBALPNC--A--","MAPPING":"3038","DESCRIPTION":"Precipitation Non-Convective "},{"SYMBOLID":"WA-DBALPC---A--","MAPPING":"3039","DESCRIPTION":"Precipitation Convective"},{"SYMBOLID":"WA-DBAFP----A--","MAPPING":"3040","DESCRIPTION":"Frozen Precipitation"},{"SYMBOLID":"WA-DBAT-----A--","MAPPING":"3041","DESCRIPTION":"Weather Thunderstorm "},{"SYMBOLID":"WA-DBAFG----A--","MAPPING":"3042","DESCRIPTION":"Weather Fog"},{"SYMBOLID":"WA-DBAD-----A--","MAPPING":"3043","DESCRIPTION":"Weather Sand"},{"SYMBOLID":"WA-DBAFF----A--","MAPPING":"3044","DESCRIPTION":"Weather Freeform "},{"SYMBOLID":"WA-DIPIB---L---","MAPPING":"3045","DESCRIPTION":"Isobar Surface"},{"SYMBOLID":"WA-DIPCO---L---","MAPPING":"3046","DESCRIPTION":"Upper Air"},{"SYMBOLID":"WA-DIPIS---L---","MAPPING":"3047","DESCRIPTION":"Isotherm "},{"SYMBOLID":"WA-DIPIT---L---","MAPPING":"3048","DESCRIPTION":"Isotach"},{"SYMBOLID":"WA-DIPID---L---","MAPPING":"3049","DESCRIPTION":"Isodrosotherm"},{"SYMBOLID":"WA-DIPTH---L---","MAPPING":"3050","DESCRIPTION":"Isopleths "},{"SYMBOLID":"WA-DIPFF---L---","MAPPING":"3051","DESCRIPTION":"Operator Freeform "},{"SYMBOLID":"WO-DILOV---L---","MAPPING":"3052","DESCRIPTION":"Limit of Visual Observation"},{"SYMBOLID":"WO-DILUC---L---","MAPPING":"3053","DESCRIPTION":"Limit of Undercast"},{"SYMBOLID":"WO-DILOR---L---","MAPPING":"3054","DESCRIPTION":"Limit of Radar Observation"},{"SYMBOLID":"WO-DILIEO--L---","MAPPING":"3055","DESCRIPTION":"Observed Ice Edge "},{"SYMBOLID":"WO-DILIEE--L---","MAPPING":"3056","DESCRIPTION":"Estimated Ice Edge"},{"SYMBOLID":"WO-DILIER--L---","MAPPING":"3057","DESCRIPTION":"Ice Edge From Radar "},{"SYMBOLID":"WO-DIOC----L---","MAPPING":"3058","DESCRIPTION":"Cracks"},{"SYMBOLID":"WO-DIOCS---L---","MAPPING":"3059","DESCRIPTION":"Cracks Specific-Location "},{"SYMBOLID":"WO-DIOL----L---","MAPPING":"3060","DESCRIPTION":"Ice Openings-Lead"},{"SYMBOLID":"WO-DIOLF---L---","MAPPING":"3061","DESCRIPTION":"Frozen Lead "},{"SYMBOLID":"WO-DHDDL---L---","MAPPING":"3062","DESCRIPTION":"Depth Curve"},{"SYMBOLID":"WO-DHDDC---L---","MAPPING":"3063","DESCRIPTION":"Depth Contour"},{"SYMBOLID":"WO-DHDDA----A--","MAPPING":"3064","DESCRIPTION":"Depth Area "},{"SYMBOLID":"WO-DHCC----L---","MAPPING":"3065","DESCRIPTION":"Coastline "},{"SYMBOLID":"WO-DHCI-----A--","MAPPING":"3066","DESCRIPTION":"Island "},{"SYMBOLID":"WO-DHCB-----A--","MAPPING":"3067","DESCRIPTION":"Beach"},{"SYMBOLID":"WO-DHCW-----A--","MAPPING":"3068","DESCRIPTION":"Water "},{"SYMBOLID":"WO-DHCF----L---","MAPPING":"3069","DESCRIPTION":"Foreshore Line"},{"SYMBOLID":"WO-DHCF-----A--","MAPPING":"3070","DESCRIPTION":"Foreshore Area "},{"SYMBOLID":"WO-DHPBA---L---","MAPPING":"3071","DESCRIPTION":"Anchorage Line "},{"SYMBOLID":"WO-DHPBA----A--","MAPPING":"3072","DESCRIPTION":"Anchorage Area"},{"SYMBOLID":"WO-DHPBP---L---","MAPPING":"3073","DESCRIPTION":"Pier "},{"SYMBOLID":"WOS-HPFF----A--","MAPPING":"3074","DESCRIPTION":"Wiers"},{"SYMBOLID":"WO-DHPMD----A--","MAPPING":"3075","DESCRIPTION":"Drydock"},{"SYMBOLID":"WO-DHPMO---L---","MAPPING":"3076","DESCRIPTION":"Offshore Loading Facility Line"},{"SYMBOLID":"WO-DHPMO----A--","MAPPING":"3077","DESCRIPTION":"Offshore Loading Facility Area "},{"SYMBOLID":"WO-DHPMRA--L---","MAPPING":"3078","DESCRIPTION":"Ramp Above Water"},{"SYMBOLID":"WO-DHPMRB--L---","MAPPING":"3079","DESCRIPTION":"Ramp Below Water "},{"SYMBOLID":"WO-DHPSPA--L---","MAPPING":"3080","DESCRIPTION":"Jetty Above Water "},{"SYMBOLID":"WO-DHPSPB--L---","MAPPING":"3081","DESCRIPTION":"Jetty Below Water"},{"SYMBOLID":"WO-DHPSPS--L---","MAPPING":"3082","DESCRIPTION":"Seawall "},{"SYMBOLID":"WO-DHABP----A--","MAPPING":"3083","DESCRIPTION":"Perches "},{"SYMBOLID":"WO-DHALLA--L---","MAPPING":"3084","DESCRIPTION":"Leading Line"},{"SYMBOLID":"WO-DHHD-----A--","MAPPING":"3085","DESCRIPTION":"Underwater Hazard"},{"SYMBOLID":"WO-DHHDF----A--","MAPPING":"3200","DESCRIPTION":"Foul Ground"},{"SYMBOLID":"WO-DHHDK----A--","MAPPING":"3201","DESCRIPTION":"Kelp"},{"SYMBOLID":"WO-DHHDB---L---","MAPPING":"3086","DESCRIPTION":"Breaker "},{"SYMBOLID":"WOS-HHDR---L---","MAPPING":"3087","DESCRIPTION":"Reef"},{"SYMBOLID":"WO-DHHDD----A--","MAPPING":"3089","DESCRIPTION":"Discolored Water "},{"SYMBOLID":"WO-DTCCCFE-L---","MAPPING":"3090","DESCRIPTION":"Ebb Tide "},{"SYMBOLID":"WO-DTCCCFF-L---","MAPPING":"3091","DESCRIPTION":"Flood Tide"},{"SYMBOLID":"WO-DOBVA----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 1-2"},{"SYMBOLID":"WO-DOBVB----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 2-3 "},{"SYMBOLID":"WO-DOBVC----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 3-4"},{"SYMBOLID":"WO-DOBVD----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 4-5 "},{"SYMBOLID":"WO-DOBVE----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 5-6"},{"SYMBOLID":"WO-DOBVF----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 6-7 "},{"SYMBOLID":"WO-DOBVG----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 7-8"},{"SYMBOLID":"WO-DOBVH----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 8-9"},{"SYMBOLID":"WO-DOBVI----A--","MAPPING":"3092","DESCRIPTION":"VDR Level 9-10"},{"SYMBOLID":"WO-DBSF-----A--","MAPPING":"3093","DESCRIPTION":"Beach Slope Flat "},{"SYMBOLID":"WO-DBSG-----A--","MAPPING":"3094","DESCRIPTION":"Beach Slope Gentle"},{"SYMBOLID":"WO-DBSM-----A--","MAPPING":"3095","DESCRIPTION":"Beach Slope Moderate"},{"SYMBOLID":"WO-DBST-----A--","MAPPING":"3096","DESCRIPTION":"Beach Slope Steep"},{"SYMBOLID":"WO-DGMSR----A--","MAPPING":"3097","DESCRIPTION":"Solid Rock "},{"SYMBOLID":"WO-DGMSC----A--","MAPPING":"3098","DESCRIPTION":"Clay"},{"SYMBOLID":"WO-DGMSSVS--A--","MAPPING":"3098","DESCRIPTION":"Very Course Sand"},{"SYMBOLID":"WO-DGMSSC---A--","MAPPING":"3098","DESCRIPTION":"Coarse Sand"},{"SYMBOLID":"WO-DGMSSM---A--","MAPPING":"3098","DESCRIPTION":"Medium Sand"},{"SYMBOLID":"WO-DGMSSF---A--","MAPPING":"3098","DESCRIPTION":"Fine Sand "},{"SYMBOLID":"WO-DGMSSVF--A--","MAPPING":"3098","DESCRIPTION":"Very Fine Sand"},{"SYMBOLID":"WO-DGMSIVF--A--","MAPPING":"3098","DESCRIPTION":"Very Fine Silt "},{"SYMBOLID":"WO-DGMSIF---A--","MAPPING":"3098","DESCRIPTION":"Fine Silt"},{"SYMBOLID":"WO-DGMSIM---A--","MAPPING":"3098","DESCRIPTION":"Medium Silt "},{"SYMBOLID":"WO-DGMSIC---A--","MAPPING":"3098","DESCRIPTION":"Coarse Silt"},{"SYMBOLID":"WO-DGMSB----A--","MAPPING":"3098","DESCRIPTION":"Boulders"},{"SYMBOLID":"WO-DGMS-CO--A--","MAPPING":"3098","DESCRIPTION":"Oyster Shells"},{"SYMBOLID":"WO-DGMS-PH--A--","MAPPING":"3098","DESCRIPTION":"Pebbles Shells "},{"SYMBOLID":"WO-DGMS-SH--A--","MAPPING":"3098","DESCRIPTION":"Sand and Shells"},{"SYMBOLID":"WO-DGML-----A--","MAPPING":"3098","DESCRIPTION":"Bottom Sediments Land"},{"SYMBOLID":"WO-DGMN-----A--","MAPPING":"3098","DESCRIPTION":"Bottom Sediments Land"},{"SYMBOLID":"WO-DGMRS----A--","MAPPING":"3098","DESCRIPTION":"Bottom Roughness Smooth"},{"SYMBOLID":"WO-DGMRM----A--","MAPPING":"3098","DESCRIPTION":"Bottom Roughness Moderate"},{"SYMBOLID":"WO-DGMRR----A--","MAPPING":"3098","DESCRIPTION":"Bottom Roughness Rough"},{"SYMBOLID":"WO-DGMCL----A--","MAPPING":"3098","DESCRIPTION":"Clutter Low"},{"SYMBOLID":"WO-DGMCM----A--","MAPPING":"3098","DESCRIPTION":"Clutter Medium"},{"SYMBOLID":"WO-DGMCH----A--","MAPPING":"3098","DESCRIPTION":"Clutter High"},{"SYMBOLID":"WO-DGMIBA---A--","MAPPING":"3098","DESCRIPTION":"Impact Burial 0"},{"SYMBOLID":"WO-DGMIBB---A--","MAPPING":"3098","DESCRIPTION":"Impact Burial 10"},{"SYMBOLID":"WO-DGMIBC---A--","MAPPING":"3098","DESCRIPTION":"Impact Burial 20"},{"SYMBOLID":"WO-DGMIBD---A--","MAPPING":"3098","DESCRIPTION":"Impact Burial 75"},{"SYMBOLID":"WO-DGMIBE---A--","MAPPING":"3098","DESCRIPTION":"Impact Burial 100"},{"SYMBOLID":"WO-DGMBCA---A--","MAPPING":"3098","DESCRIPTION":"Bottom Category A"},{"SYMBOLID":"WO-DGMBCB---A--","MAPPING":"3098","DESCRIPTION":"Bottom Category B"},{"SYMBOLID":"WO-DGMBCC---A--","MAPPING":"3098","DESCRIPTION":"Bottom Category C"},{"SYMBOLID":"WO-DGMBTA---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type A1"},{"SYMBOLID":"WO-DGMBTB---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type A2"},{"SYMBOLID":"WO-DGMBTC---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type A3"},{"SYMBOLID":"WO-DGMBTD---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type B1"},{"SYMBOLID":"WO-DGMBTE---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type B2"},{"SYMBOLID":"WO-DGMBTF---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type B3"},{"SYMBOLID":"WO-DGMBTG---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type C1"},{"SYMBOLID":"WO-DGMBTH---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type C2"},{"SYMBOLID":"WO-DGMBTI---A--","MAPPING":"3098","DESCRIPTION":"Bottom Type C3"},{"SYMBOLID":"WO-DL-ML---L---","MAPPING":"3099","DESCRIPTION":"Maritime Limit"},{"SYMBOLID":"WO-DL-MA----A--","MAPPING":"3100","DESCRIPTION":"Maritime Area"},{"SYMBOLID":"WO-DL-RA---L---","MAPPING":"3101","DESCRIPTION":"Restricted Area"},{"SYMBOLID":"WO-DL-SA----A--","MAPPING":"3102","DESCRIPTION":"Swept Area"},{"SYMBOLID":"WO-DL-TA----A--","MAPPING":"3103","DESCRIPTION":"Training Area"},{"SYMBOLID":"WO-DL-O-----A--","MAPPING":"3104","DESCRIPTION":"Operator Defined"},{"SYMBOLID":"WO-DMCA----L---","MAPPING":"3105","DESCRIPTION":"Cable"},{"SYMBOLID":"WO-DMCC-----A--","MAPPING":"3106","DESCRIPTION":"Submerged Crib"},{"SYMBOLID":"WO-DMCD----L---","MAPPING":"3107","DESCRIPTION":"Canal"},{"SYMBOLID":"WO-DMOA-----A--","MAPPING":"3108","DESCRIPTION":"Oil Rig Field "},{"SYMBOLID":"WO-DMPA----L---","MAPPING":"3109","DESCRIPTION":"Pipe"},{"SYMBOLID":"CYLINDER-------","MAPPING":"900","DESCRIPTION":"Cylinder"},{"SYMBOLID":"ORBIT----------","MAPPING":"900","DESCRIPTION":"Orbit"},{"SYMBOLID":"ROUTE----------","MAPPING":"900","DESCRIPTION":"Route"},{"SYMBOLID":"POLYGON--------","MAPPING":"900","DESCRIPTION":"Polygon"},{"SYMBOLID":"RADARC---------","MAPPING":"900","DESCRIPTION":"Radarc"},{"SYMBOLID":"POLYARC--------","MAPPING":"900","DESCRIPTION":"Polyarc"},{"SYMBOLID":"CAKE-----------","MAPPING":"900","DESCRIPTION":"Cake"},{"SYMBOLID":"TRACK----------","MAPPING":"900","DESCRIPTION":"Track"},{"SYMBOLID":"CURTAIN--------","MAPPING":"900","DESCRIPTION":"Curtain"}]}};return{init:function() -{var i,data=null,symbol=null,count;if(symbolMap===null) -{symbols=spMappingXml.TACTICALGRAPHICS.SYMBOL;spMappingXml=null;symbolMap={};this.parser=null;count=symbols.length;for(i=0;i1) -{returnVal=true;} -else -{switch(sd.drawCategory) -{case this.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:case this.DRAW_CATEGORY_ROUTE:returnVal=true;break;default:returnVal=false;}} -return returnVal;}else{return false;}} -else if(symbolID.substring(0,3)==="BS_"||symbolID.substring(0,4)==="BBS_") -{return true;} -else -{return false;}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.UnitDefTable=(function(){var symbolMapB=null,symbolMapC=null,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;return{xmlDoc:null,init:function() -{var i,data=null,symbol=null,symbols,count;if(symbolMapB===null&&armyc2.c2sd.renderer.xml.UnitConstantsB!==undefined) -{symbols=armyc2.c2sd.renderer.xml.UnitConstantsB.UNITCONSTANTS.SYMBOL;armyc2.c2sd.renderer.xml.UnitConstantsB=null;symbolMapB={};count=symbols.length;for(i=0;i=10) -{scheme=SymbolID.charAt(0);affiliation=SymbolID.charAt(1);battleDimension=SymbolID.charAt(2);status=SymbolID.charAt(3);grdtrkSubset=SymbolID.charAt(4);if(symStd===undefined) -{symStd=RendererSettings.getSymbologyStandard();} -if(scheme==='S') -{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{if(battleDimension==='F'||battleDimension==='G') -{if(battleDimension==='F'||(battleDimension==='G'&&(grdtrkSubset==='U'||grdtrkSubset==='I'||grdtrkSubset==='0'||grdtrkSubset==='-'))) -{returnVal=803;} -else if(battleDimension==='G'&&grdtrkSubset==='E') -{returnVal=812;} -else -returnVal=803;} -else if(battleDimension==='A') -{returnVal=819;} -else if(battleDimension==='S') -{returnVal=this.getSeaSurfaceFill(SymbolID);} -else if(battleDimension==='U') -{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} -else if(battleDimension==='P') -{returnVal=843;} -else -{returnVal=812;}} -else if(affiliation==='H'||affiliation==='S') -{if(battleDimension==='F'||battleDimension==='G') -{returnVal=806;} -else if(battleDimension==='A') -{returnVal=816;} -else if(battleDimension==='S') -{returnVal=this.getSeaSurfaceFill(SymbolID);} -else if(battleDimension==='U') -{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} -else if(battleDimension==='P') -{returnVal=840;} -else -{returnVal=806;}} -else if(affiliation==='N'||affiliation==='L') -{if(battleDimension==='F'||battleDimension==='G') -{returnVal=809;} -else if(battleDimension==='A') -{returnVal=822;} -else if(battleDimension==='S') -{returnVal=this.getSeaSurfaceFill(SymbolID);} -else if(battleDimension==='U') -{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} -else if(battleDimension==='P') -{returnVal=846;} -else -{returnVal=809;}} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{if(battleDimension==='Z'||battleDimension==='G'||battleDimension==='F') -{returnVal=800;} -else if(battleDimension==='A') -{returnVal=825;} -else if(battleDimension==='S') -{returnVal=this.getSeaSurfaceFill(SymbolID);} -else if(battleDimension==='U') -{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} -else if(battleDimension==='P') -{returnVal=849;} -else -returnVal=800;} -else -returnVal=FillIndexUG;} -else if(scheme==='E') -{if(battleDimension!=='N') -{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{if(SymbolUtilities.isEMSEquipment(SymbolID)) -returnVal=812;else -returnVal=803;} -else if(affiliation==='H'||affiliation==='S') -{returnVal=806;} -else if(affiliation==='N'||affiliation==='L') -{returnVal=809;} -else -{returnVal=800;}} -else -{returnVal=-1;}} -else if(scheme==='I') -{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{if(battleDimension==='Z') -{returnVal=812;} -else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') -{if(scheme==='I') -returnVal=812;else -returnVal=803;} -else if(battleDimension==='A') -{returnVal=819;} -else if(battleDimension==='U') -{returnVal=831;} -else if(battleDimension==='P') -{returnVal=843;} -else -{if(scheme==='I') -returnVal=812;else -returnVal=803;}} -if(affiliation==='H'||affiliation==='S') -{if(battleDimension==='Z') -{returnVal=806;} -else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') -{returnVal=806;} -else if(battleDimension==='A') -{returnVal=816;} -else if(battleDimension==='U') -{returnVal=828;} -else if(battleDimension==='P') -{returnVal=840;} -else -{returnVal=806;}} -if(affiliation==='N'||affiliation==='L') -{if(battleDimension==='Z') -{returnVal=809;} -else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') -{returnVal=809;} -else if(battleDimension==='A') -{returnVal=822;} -else if(battleDimension==='U') -{returnVal=834;} -else if(battleDimension==='P') -{returnVal=846;} -else -{returnVal=809;}} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{if(battleDimension==='Z'||battleDimension==='G'||battleDimension==='S'||battleDimension==='F') -{returnVal=800;} -else if(battleDimension==='A') -{returnVal=825;} -else if(battleDimension==='U') -{returnVal=837;} -else if(battleDimension==='P') -{returnVal=849;} -else -{returnVal=800;}}} -else -{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{if(SymbolID.substring(0,3)==="OFI"&&SymbolID.substring(4,10)===("T-----")) -{returnVal=FillIndexFGE;} -else -{returnVal=803;}} -else if(affiliation==='H'||affiliation==='S') -{returnVal=806;} -else if(affiliation==='N'||affiliation==='L') -{returnVal=809;} -else -{returnVal=800;}}} -else -{returnVal=800;} -return returnVal;},getFrameCode:function(SymbolID,fillCode,symStd){var returnVal=0,status=SymbolID.charAt(3);if(status==='A') -returnVal=fillCode+2;else -returnVal=fillCode+1;if(symStd===undefined) -symStd=RendererSettings.getSymbologyStandard();if(symStd>RendererSettings.Symbology_2525Bch2_USAS_13_14&&status==='A') -{var affiliation=SymbolID.charAt(1);switch(affiliation) -{case'P':case'A':case'S':case'G':case'M':returnVal--;break;}} -if(returnVal===847) -returnVal=852;if(SymbolUtilities.isSeaSurface(SymbolID)) -{returnVal=this.getSeaSurfaceFrame(SymbolID,fillCode);} -if(SymbolUtilities.isSubSurface(SymbolID)) -{returnVal=this.getSubSurfaceFrame(SymbolID,fillCode);} -return returnVal;},getSeaSurfaceFill:function(SymbolID){var affiliation="U",affiliation=SymbolID.charAt(1);if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*S*O-----*****")) -{return 2016;} -else -{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{return FillIndexFS;} -else if(affiliation==='H'||affiliation==='S') -{return FillIndexHS;} -else if(affiliation==='N'||affiliation==='L') -{return FillIndexNS;} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{return FillIndexUS;} -else -{return FillIndexUG;}}},getSubSurfaceFill:function(SymbolID,symStd){var affiliation=0,status=0,returnVal=831;try -{if(symStd===undefined) -{symStd=RendererSettings.getSymbologyStandard();} -affiliation=SymbolID.charAt(1);status=SymbolID.charAt(3);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{returnVal=831;} -else if(affiliation==='H'||affiliation==='S') -{returnVal=828;} -else if(affiliation==='N'||affiliation==='L') -{returnVal=834;} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{returnVal=837;} -if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*X-----*****")) -{if(status==='A') -returnVal=returnVal+2;else -returnVal++;} -if(symStd===RendererSettings.Symbology_2525C) -{if(SymbolID.indexOf("WM")===4||SymbolID.indexOf("WDM")===4||SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*E-----*****")||SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*V-----*****")) -{returnVal++;if(status==='A') -returnVal++;} -else if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*ND----*****")) -{returnVal=2121;}} -else -{if(SymbolID.indexOf("WM")===4) -{if(SymbolID.indexOf("----",6)===6||SymbolID.indexOf("D---",6)===6) -returnVal=2059;else if(SymbolID.indexOf("G---",6)===6) -returnVal=2062;else if(SymbolID.indexOf("GD--",6)===6) -returnVal=2064;else if(SymbolID.indexOf("M---",6)===6) -returnVal=2073;else if(SymbolID.indexOf("MD--",6)===6) -returnVal=2075;else if(SymbolID.indexOf("F---",6)===6) -returnVal=2084;else if(SymbolID.indexOf("FD--",6)===6) -returnVal=2086;else if(SymbolID.indexOf("O---",6)===6||SymbolID.indexOf("OD--",6)===6) -returnVal=2094;} -else if(SymbolID.indexOf("WDM")===4) -{returnVal=2115;} -else if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*ND----*****")) -{returnVal=2121;}}} -catch(exc) -{return FillIndexUU;} -return returnVal;},getSeaSurfaceFrame:function(SymbolID,fillCode){var returnVal=fillCode+1;if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*S*O-----*****")) -returnVal=-1;else -{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') -return fillCode+2;else -return fillCode+1;} -return returnVal;},getSubSurfaceFrame:function(SymbolID,fillCode){var returnVal=fillCode+1;try -{if(RendererSettings.getSymbologyStandard()===RendererSettings.Symbology_2525C) -{if(SymbolID.indexOf("WM")===4||SymbolID.indexOf("WDM")===4||SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*E-----*****")||SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*V-----*****")||SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*X-----*****")) -{returnVal=-1;} -else if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*ND----*****")) -{returnVal=-1;} -else -{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') -return fillCode+2;else -return fillCode+1;}} -else -{if(SymbolID.indexOf("WM")===4) -{returnVal=-1;} -else if(SymbolID.indexOf("WDM")===4) -{returnVal=-1;} -else if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*ND----*****")) -{returnVal=-1;} -else if(SymbolUtilities.getBasicSymbolID(SymbolID)===("S*U*X-----*****")) -{returnVal=-1;} -else -{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') -return fillCode+2;else -return fillCode+1;}}} -catch(exc) -{return fillCode;} -return returnVal;},getUnitRatioHeight:function(characterIndex){if(characterIndex===FillIndexHP||characterIndex===FillIndexHA||characterIndex===FillIndexHU||characterIndex===(FillIndexHU+1)||characterIndex===(FillIndexHU+2)||characterIndex===FillIndexUP||characterIndex===FillIndexUA||characterIndex===FillIndexUU||characterIndex===(FillIndexUU+1)||characterIndex===(FillIndexUU+2)) -{return 1.3;} -else if(characterIndex===FillIndexHZ||characterIndex===FillIndexHG||characterIndex===FillIndexHGE||characterIndex===FillIndexHS||characterIndex===FillIndexHF||characterIndex===FillIndexUZ||characterIndex===FillIndexUG||characterIndex===FillIndexUGE||characterIndex===FillIndexUS||characterIndex===FillIndexUF) -{return 1.44;} -else if(characterIndex===FillIndexFGE||characterIndex===FillIndexFP||characterIndex===FillIndexFA||characterIndex===FillIndexFU||characterIndex===(FillIndexFU+1)||characterIndex===(FillIndexFU+2)||characterIndex===FillIndexFZ||characterIndex===FillIndexFS||characterIndex===FillIndexNP||characterIndex===FillIndexNA||characterIndex===FillIndexNU||characterIndex===(FillIndexNU+1)||characterIndex===(FillIndexNU+2)) -{return 1.2;} -else if(characterIndex===FillIndexNZ||characterIndex===FillIndexNG||characterIndex===FillIndexNGE||characterIndex===FillIndexNS||characterIndex===FillIndexNF) -{return 1.1;} -else if(characterIndex===FillIndexFG||characterIndex===FillIndexFGE) -{return 1.0;} -else -{return 1.2;}},getUnitRatioWidth:function(characterIndex){if(characterIndex===FillIndexUP||characterIndex===FillIndexUA||characterIndex===FillIndexUU||characterIndex===FillIndexUU+1||characterIndex===FillIndexUU+2||characterIndex===FillIndexFG||characterIndex===FillIndexFF) -{return 1.5;} -else if(characterIndex===FillIndexHZ||characterIndex===FillIndexHG||characterIndex===FillIndexHGE||characterIndex===FillIndexHS||characterIndex===FillIndexHF||characterIndex===FillIndexUZ||characterIndex===FillIndexUG||characterIndex===FillIndexUGE||characterIndex===FillIndexUS||characterIndex===FillIndexUF) -{return 1.44;} -else if(characterIndex===FillIndexFZ||characterIndex===FillIndexFGE||characterIndex===FillIndexFS) -{return 1.2;} -else -{return 1.1;}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolDimensions={};armyc2.c2sd.renderer.utilities.SymbolDimensions.getUnitBounds=function(charIndex,fontSize){var Rectangle=armyc2.c2sd.renderer.so.Rectangle,index=charIndex;var rect=null;switch(index) -{case 800:case 801:case 802:rect=new Rectangle(0,0,60.8,60.8);break;case 803:case 804:case 805:rect=new Rectangle(0,0,65,47);break;case 806:case 807:case 808:rect=new Rectangle(0,0,62.5,62.5);break;case 809:case 810:case 811:rect=new Rectangle(0,0,50.05,50.05);break;case 812:case 813:case 814:rect=new Rectangle(0,0,53.75,53.75);break;case 816:case 817:case 818:case 840:case 841:case 842:rect=new Rectangle(0,8,50.3,53);break;case 819:case 820:case 821:case 843:case 844:case 845:rect=new Rectangle(0,7,46.6,48);break;case 822:case 823:case 824:case 846:case 847:case 848:rect=new Rectangle(0,6,47,48);break;case 825:case 826:case 827:case 849:case 850:case 851:rect=new Rectangle(0,5,64.7,56);break;case 828:case 829:case 830:rect=new Rectangle(0,-8,50.3,53);break;case 831:case 832:case 833:rect=new Rectangle(0,-5,46.6,48);break;case 834:case 835:case 836:rect=new Rectangle(0,-5,46.5,48);break;case 837:case 838:case 839:rect=new Rectangle(0,-5,64.7,56);break;default:rect=new Rectangle(0,0,65,65);break;} -var ratio=1;if(fontSize!==50) -{ratio=fontSize/50;rect=new Rectangle(0,Math.ceil(rect.y*ratio),Math.ceil(rect.width*ratio),Math.ceil(rect.height*ratio));} -return rect;};armyc2.c2sd.renderer.utilities.SymbolDimensions.getSymbolBounds=function(symbolID,symStd,fontSize){var spli=armyc2.c2sd.renderer.utilities.SinglePointLookup.getSPLookupInfo(symbolID,symStd);var Rectangle=armyc2.c2sd.renderer.so.Rectangle;var rect=new Rectangle(0,0,spli.width,spli.height);if(fontSize!==60) -{var ratio=fontSize/60;rect=new Rectangle(0,0,Math.round(rect.width*ratio),Math.round(rect.height*ratio));} -return rect;};armyc2.c2sd.renderer.utilities.SymbolDimensions.getSymbolCenter=function(symbolID,bounds){var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;var basicID=SymbolUtilities.getBasicSymbolID(symbolID),center=new armyc2.c2sd.renderer.so.Point(bounds.width/2,bounds.height/2);if(basicID==="G*G*GPUUB-****X"||basicID==="G*G*GPUUL-****X"||basicID==="G*G*GPUUS-****X"||basicID==="G*G*GPRI--****X"||basicID==="G*G*GPWE--****X"||basicID==="G*G*GPWG--****X"||basicID==="G*G*GPWM--****X"||basicID==="G*G*GPP---****X"||basicID==="G*G*GPPC--****X"||basicID==="G*G*GPPL--****X"||basicID==="G*G*GPPP--****X"||basicID==="G*G*GPPR--****X"||basicID==="G*G*GPPA--****X"||basicID==="G*G*APD---****X"||basicID==="G*G*OPP---****X"||basicID.substring(0,7)==="G*M*OAO"||basicID==="G*M*BCP---****X"||basicID==="G*F*PCS---****X"||basicID==="G*F*PCB---****X"||basicID==="G*F*PCR---****X"||basicID==="G*F*PCH---****X"||basicID==="G*F*PCL---****X"||basicID.substring(0,5)==="G*S*P"||basicID==="G*O*ED----****X"||basicID==="G*O*EP----****X"||basicID==="G*O*EV----****X"||basicID==="G*O*SB----****X"||basicID==="G*O*SBM---****X"||basicID==="G*O*SBN---****X"||basicID==="G*O*SS----****X"||basicID==="G*G*GPPN--****X"||basicID==="G*S*PX----****X"||basicID==="G*O*ES----****X"||SymbolUtilities.isNBC(basicID)||SymbolUtilities.isDeconPoint(basicID)||SymbolUtilities.isCheckPoint(basicID)) -{center.x=bounds.width/2;center.y=bounds.height;} -else if(SymbolUtilities.isSonobuoy(basicID)) -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.66);} -else if((basicID.substring(0,7)==="G*G*GPO"&&basicID.substring(7,8)!=="-")) -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.33);} -else if(basicID==="G*M*OMD---****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.28);} -else if(basicID.substring(0,7)==="G*G*DPO") -{if(basicID.substring(7,8)==="C") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.55);} -else -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.65);}} -else if(basicID==="G*G*GPWD--****X"||basicID==="G*G*PN----****X"||basicID==="G*M*OB----****X"||basicID==="G*M*OME---****X"||basicID==="G*M*OMW---****X"||basicID==="G*M*OMP---****X"||basicID==="G*M*OHTL--****X"||basicID==="G*M*OHTH--****X"||basicID==="G*O*HM----****X"||basicID==="G*O*HI----****X"||basicID==="G*O*SM----****X") -{if(basicID==="G*G*GPWD--****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.85);} -if(basicID==="G*G*PN----****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.69);} -if(basicID==="G*M*OB----****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.8);} -if(basicID==="G*M*OME---****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.77);} -if(basicID==="G*M*OMW---****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.34);} -if(basicID==="G*M*OMP---****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.59);} -if(basicID==="G*M*OHTL--****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.95);} -if(basicID==="G*M*OHTH--****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.95);} -if(basicID==="G*O*HM----****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.7);} -if(basicID==="G*O*HI----****X") -{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.58);} -if(basicID==="G*O*SM----****X") -{center.x=0;center.y=Math.round(bounds.height*0.5);}} -else -{center.x=bounds.width/2;center.y=bounds.height/2;} -return center;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2={intersectPoint:function(pt0,pt1,currentEdge) -{var ptIntersect=null;try{var edgePt1=currentEdge.getP1();var edgePt2=currentEdge.getP2();var edge_x=0;var edge_y=0;var m=0;var deltaX=0;var deltaY=0;if(Math.abs(edgePt1.getX()-edgePt2.getX())=ul.getY()&¤t.getY()>=ul.getY()){ptsResult.add(current);} -if(previous.getY()>=ul.getY()&¤t.getY()=ul.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ul,ur);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} -ptsResult.add(current);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipTop",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipTop",exc));}else{throw exc;}} -return ptsResult;},clipBottom:function(pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var ulx=0;var uly=0;var lrx=0;var lry=0;ulx=clipBounds.getMinX();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,lry);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;jlr.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ll,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);}} -if(previous.getY()>lr.getY()&¤t.getY()>lr.getY()){continue;} -if(previous.getY()>lr.getY()&¤t.getY()<=lr.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ll,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} -ptsResult.add(current);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipBottom",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipBottom",exc));}else{throw exc;}} -return ptsResult;},clipRight:function(pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var uly=0;var lrx=0;var lry=0;uly=clipBounds.getMinY();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ur=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,uly);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;jlr.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ur,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);}} -if(previous.getX()>lr.getX()&¤t.getX()>lr.getX()){continue;} -if(previous.getX()>lr.getX()&¤t.getX()<=lr.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ur,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} -ptsResult.add(current);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipRight",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipRight",exc));}else{throw exc;}} -return ptsResult;},clipLeft:function(pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var ulx=0;var uly=0;var lry=0;ulx=clipBounds.getMinX();uly=clipBounds.getMinY();lry=clipBounds.getMaxY();var ul=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,uly);var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;j=ll.getX()&¤t.getX()>=ll.getX()){ptsResult.add(current);} -if(previous.getX()>=ll.getX()&¤t.getX()=ll.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ul,ll);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} -ptsResult.add(current);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipLeft",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipLeft",exc));}else{throw exc;}} -return ptsResult;},AddBoundaryPointsForLines:function(polygon,clipBounds){var result=0;try{var ulx=0;var uly=0;var lrx=0;var lry=0;ulx=clipBounds.getMinX();uly=clipBounds.getMinY();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ul=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx+10,uly+10);var ur=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx-10,uly+10);var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx+10,lry-10);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx-10,lry-10);var pt0=polygon.get(0);var ptn=polygon.get(polygon.size()-1);var addToFront=new Boolean(false);var addToEnd=new Boolean(false);if(pt0.getY()lrx){polygon.add(0,lr);addToFront=new Boolean(true);}else if(pt0.getY()>lry){polygon.add(0,lr);addToFront=new Boolean(true);} -if(ptn.getY()lrx){polygon.add(lr);addToEnd=new Boolean(true);}else if(ptn.getY()>lry){polygon.add(lr);addToEnd=new Boolean(true);} -if(addToFront.booleanValue()===false&&addToEnd.booleanValue()===false){result=0;} -if(addToFront.booleanValue()===true&&addToEnd.booleanValue()===false){result=1;} -if(addToFront.booleanValue()===false&&addToEnd.booleanValue()===true){result=2;} -if(addToFront.booleanValue()===true&&addToEnd.booleanValue()===true){result=3;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"AddBoundaryPointsForLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddBoundaryPointsForLines",exc));}else{throw exc;}} -return result;},closeAreaTG:function(tg){try{if(tg.Pixels===null||tg.Pixels.isEmpty()) -return;var pt0=tg.Pixels.get(0);var ptn=tg.Pixels.get(tg.Pixels.size()-1);if(pt0.x!==ptn.x||pt0.y!==ptn.y) -tg.Pixels.add(pt0);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"closeAreaTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside closeAreaTG",exc));}else{throw exc;}} -return;},fillDMA:function(tg,clipBounds){var shapes=new java.util.ArrayList();try{switch(tg.get_LineType()){case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 23131200:case 23132000:break;default:return shapes;} -var shape=null;var j=0;var tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();var n=0;if(tg.LatLongs!==null) -n=tg.LatLongs.size();else -n=tg.Pixels.size();for(j=0;j=300).valueOf()){dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x);dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x);dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x);var start=-1;var end=-1;if(dist0>=dist1&&dist0>=dist2){start=0;end=99;}else if(dist1>=dist0&&dist1>=dist2){start=100;end=199;}else{start=200;end=299;} -shape.moveTo(tg.Pixels.get(start));for(j=start;j<=end;j++) -shape.lineTo(tg.Pixels.get(j));} -break;case 23120000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();if(tg.Pixels!==null&&tg.Pixels.size()>2){tg2.Pixels.add(tg.Pixels.get(n-3));tg2.Pixels.add(tg.Pixels.get(n-2));tg2.Pixels.add(tg.Pixels.get(n-1));tg2.Pixels.add(tg.Pixels.get(n-3));shape.moveTo(tg2.Pixels.get(0));for(j=1;j1) -{shapes.add(shape);} -else -return null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} -return shapes;},ClipPolygon:function(tg,clipBounds){var poly=new java.util.ArrayList();try{var polygon=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.POINT2toPoint2D(tg.Pixels);var isClosed=new Boolean(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType()));var hashMap=new java.util.HashMap();var j=0;for(j=0;j0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;case 3:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;}} -if(isClosed.booleanValue()===true){if(poly.size()>2){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}else{if(poly.size()>1) -{tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);} -else -{tg.Pixels=new java.util.ArrayList();}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"ClipPolygon",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon",exc));}else{throw exc;}} -return poly;},ClipPolygon2:function(polygon,clipBounds,isClosed){var poly=new java.util.ArrayList();try{var addedLinePoints=0;if((isClosed).booleanValue()){if(polygon.size()>0) -polygon.remove(polygon.size()-1);isClosed=new Boolean(true);}else{addedLinePoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.AddBoundaryPointsForLines(polygon,clipBounds);} -poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipRight(polygon,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipTop(poly,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipLeft(poly,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipBottom(poly,clipBounds);if(isClosed.booleanValue()===true){if(poly.size()>0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;case 3:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"ClipPolygon2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon2",exc));}else{throw exc;}} -return poly;},_className:"clsClipPolygon2"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad={AddBoundaryPointsForLines:function(polygon,clipBounds){var result=0;try{var pt02d=polygon.get(0);var ptLast2d=polygon.get((polygon.size()-1));var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt02d.getX(),pt02d.getY());var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptLast2d.getX(),ptLast2d.getY());var nearestPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D();var clipArray=new armyc2.c2sd.graphics2d.Polygon();var j=0;var minDist=1.7976931348623157E308;var dist=0;var sidePt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var addToFront=new Boolean(false);var addToEnd=new Boolean(false);for(j=0;j1){clipBoundsPoint=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(clipBounds.get(index-2).getX(),clipBounds.get(index-2).getY());}else if(index===1){clipBoundsPoint=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(clipBounds.get(0).getX(),clipBounds.get(0).getY());} -if(pt2.getX()===pt1.getX()) -pt2.setLocation(pt2.getX()+1,pt2.getY());if(pt2.getY()===pt1.getY()) -pt2.setLocation(pt2.getX(),pt2.getY()+1);for(j=0;j=300).valueOf()){dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x);dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x);dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x);var start=-1;var end=-1;if(dist0>=dist1&&dist0>=dist2){start=0;end=99;}else if(dist1>=dist0&&dist1>=dist2){start=100;end=199;}else{start=200;end=299;} -shape.moveTo(tg.Pixels.get(start));for(j=start;j<=end;j++) -shape.lineTo(tg.Pixels.get(j));} -break;case 23120000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();if(tg.Pixels!==null&&tg.Pixels.size()>2){tg2.Pixels.add(tg.Pixels.get(n-3));tg2.Pixels.add(tg.Pixels.get(n-2));tg2.Pixels.add(tg.Pixels.get(n-1));tg2.Pixels.add(tg.Pixels.get(n-3));shape.moveTo(tg2.Pixels.get(0));for(j=1;j1){shapes.add(shape);}else -return null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} -return shapes;},closeAreaTG:function(tg){try{if(tg.Pixels===null||tg.Pixels.isEmpty()) -return;var pt0=tg.Pixels.get(0);var ptn=tg.Pixels.get(tg.Pixels.size()-1);if(pt0.x!==ptn.x||pt0.y!==ptn.y) -tg.Pixels.add(pt0);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"closeAreaTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside closeAreaTG",exc));}else{throw exc;}} -return;},fillDMA:function(tg,clipBounds){var shapes=new java.util.ArrayList();try{switch(tg.get_LineType()){case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 23131200:case 23132000:break;default:return shapes;} -var shape=null;var j=0;var tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();var n=0;if(tg.LatLongs!==null) -n=tg.LatLongs.size();else -n=tg.Pixels.size();for(j=0;j0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;case 3:if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(0);} -if(poly.size()>0){poly.remove(poly.size()-1);} -if(poly.size()>0){poly.remove(poly.size()-1);} -break;}} -if(isClosed.booleanValue()===true){if(poly.size()>2){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}else{if(poly.size()>1){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"ClipPolygon",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon",exc));}else{throw exc;}} -return poly;},_className:"clsClipQuad"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer={setClientCoords:function(milStd,tg){try{var latLongs=new java.util.ArrayList();var j=0;var coords=milStd.getCoordinates();var pt2d=null;var pt2=null;for(j=0;j0) -tg.set_H(Double.toString((X.get(0)).doubleValue()));if(X!==null&&X.size()>1) -tg.set_H1(Double.toString((X.get(1)).doubleValue()));break;case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:var pt=tg.LatLongs.get(0);var pt2d0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt.x,pt.y);var pt2d0Pixels=converter.GeoToPixels(pt2d0);var pt0Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d0Pixels.getX(),pt2d0Pixels.getY());var dist=10000;var pt2=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt,dist,0);var pt2d1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);var pt2d1Pixels=converter.GeoToPixels(pt2d1);var pt1Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d1Pixels.getX(),pt2d1Pixels.getY());var distPixels=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0Pixels,pt1Pixels);var pixelsPerMeter=distPixels/dist;AM=milStd.getModifiers_AM_AN_X("AM");if(AM!==null){var H2="";for(j=0;j0){for(j=0;jmaxWidth) -maxWidth=temp;}} -maxWidthMeters=maxWidth;maxWidth*=pixelsPerMeter/2;}} -if(tg.get_H2()!==null&&tg.get_H2().isEmpty()===false){if(strRadii!==null&&strRadii.length>0){var pixels=0;for(j=0;jj){if(strRadii.length>j){if(!Double.isNaN(Double.parseDouble(strRadii[j]))){pixels=Double.parseDouble(strRadii[j])*pixelsPerMeter/2;tg.Pixels.get(j).style=Math.floor(pixels);}else -tg.Pixels.get(j).style=Math.floor(maxWidth);}else -tg.Pixels.get(j).style=Math.floor(maxWidth);}}}} -tg.set_H2(Double.toString(maxWidthMeters));X=milStd.getModifiers_AM_AN_X("XN");if(X!==null&&X.size()>0) -tg.set_H(Double.toString((X.get(0)).doubleValue()));if(X!==null&&X.size()>1) -tg.set_H1(Double.toString((X.get(1)).doubleValue()));break;default:break;} -switch(lineType){case 24361000:case 24363000:case 24362000:X=milStd.getModifiers_AM_AN_X("XN");strH1="";if(X!==null){strH1=Double.toString((X.get(0)).doubleValue());tg.set_H1(strH1);} -break;default:break;} -if(lineType===243111000){AM=milStd.getModifiers_AM_AN_X("AM");X=milStd.getModifiers_AM_AN_X("XN");strH2="";strH1="";if(AM!==null){for(j=0;j0){var strT1=Double.toString((AM.get(0)).doubleValue());tg.set_T1(strT1);} -break;default:break;} -if(lineType===24311000){AM=milStd.getModifiers_AM_AN_X("AM");AN=milStd.getModifiers_AM_AN_X("AN");if(AM!==null&&AM.size()>1&&AN!==null&&AN.size()>0){strT1=Double.toString((AM.get(0)).doubleValue());var strH=Double.toString((AM.get(1)).doubleValue());tg.set_T1(strT1);tg.set_H(strH);var strH2=Double.toString((AN.get(0)).doubleValue());tg.set_H2(strH2);}} -milStd.setFillColor(tg.get_FillColor());milStd.setLineColor(tg.get_LineColor());milStd.setLineWidth(tg.get_LineThickness());milStd.setFillStyle(tg.get_TexturePaint());}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","createMilStdSymboFromTGLight",new armyc2.c2sd.renderer.utilities.RendererException("Failed to set geo points or pixels for "+tg.get_SymbolId(),exc));}else{throw exc;}} -return milStd;},createTGLightFromMilStdSymbol:function(milStd,converter){var tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();var modifiersTG=armyc2.c2sd.renderer.utilities.ModifiersTG;try{var symbolId=milStd.getSymbolID();var std=milStd.getSymbologyStandard();tg.setSymbologyStandard(std);armyc2.c2sd.JavaTacticalRenderer.clsUtility.initializeLinetypes(std);tg.set_SymbolId(symbolId);var useLineInterpolation=milStd.getUseLineInterpolation();tg.set_UseLineInterpolation(useLineInterpolation);var lineType=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId);if(lineType===23200000&&converter._scale>=250000) -lineType=23200001;tg.set_LineType(lineType);var status=tg.get_Status();if(status!==null&&status.equals("A")){if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isBasicShape(lineType)===false) -tg.set_LineStyle(1);} -tg.set_VisibleModifiers(true);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setClientCoords(milStd,tg);tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);tg.set_Font(new armyc2.c2sd.graphics2d.Font("Arial",armyc2.c2sd.graphics2d.Font.PLAIN,12));tg.set_FillColor(milStd.getFillColor());tg.set_LineColor(milStd.getLineColor());tg.set_LineThickness(milStd.getLineWidth());tg.set_TexturePaint(milStd.getFillStyle());tg.set_FontBackColor(armyc2.c2sd.renderer.utilities.Color.WHITE);tg.set_TextColor(tg.get_LineColor());if(milStd.getModifier("W")!==null){tg.set_DTG(milStd.getModifier("W"));} -if(milStd.getModifier("W1")!==null){tg.set_DTG1(milStd.getModifier("W1"));} -if(milStd.getModifier("H")!==null) -tg.set_H(milStd.getModifier("H"));if(milStd.getModifier("H1")!==null) -tg.set_H1(milStd.getModifier("H1"));if(milStd.getModifier("H2")!==null) -tg.set_H2(milStd.getModifier("H2"));if(milStd.getModifier("T")!==null) -tg.set_Name(milStd.getModifier("T"));if(milStd.getModifier("T1")!==null) -tg.set_T1(milStd.getModifier("T1"));if(milStd.getModifier("Y")!==null) -tg.set_Location(milStd.getModifier("Y"));if(milStd.getModifier("N")!==null) -tg.set_N(milStd.getModifier("N"));var isClosedArea=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);if(isClosedArea){armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels);armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs);} -if(lineType===243112000){var AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);var AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);var X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(AM!==null){var numSectors=AM.length-1;if(Math.floor(AN.length/2)maxLong) -maxLong=tg.LatLongs.get(j).x;if(tg.LatLongs.get(j).ymaxLat) -maxLat=tg.LatLongs.get(j).y;} -tg.LatLongs=new java.util.ArrayList();tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,maxLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(maxLong,maxLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(maxLong,minLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,minLat));if(lineType===15000004) -tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,maxLat));tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);} -switch(lineType){case 15000001:case 15000000:case 15000003:var H2=null;var dist=0;var pt0;var pt1;var AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);if(AM!==null&&AM.length>0){H2=AM[0].toString();tg.set_H2(H2);} -for(j=0;jj){if(!Double.isNaN(Double.parseDouble(H2))){if(j===0){dist=Double.parseDouble(H2);pt0=tg.LatLongs.get(0);pt1=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,dist,45);var pt02d=new armyc2.c2sd.graphics2d.Point2D();pt02d.x=pt0.x;pt02d.y=pt0.y;pt12d=new armyc2.c2sd.graphics2d.Point2D();pt12d.x=pt1.x;pt12d.y=pt1.y;pt02d=converter.GeoToPixels(pt02d);pt12d=converter.GeoToPixels(pt12d);pt0.x=pt02d.getX();pt0.y=pt02d.getY();pt1.x=pt12d.getX();pt1.y=pt12d.getY();dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);} -tg.Pixels.get(j).style=Math.round(dist);}else -tg.Pixels.get(j).style=0;}} -break;default:break;} -switch(lineType){case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:case 24322100:case 24322200:case 24322300:X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(X!==null&&X.length>0) -tg.set_H(X[0]);if(X!==null&&X.length>1) -tg.set_H1(X[1]);break;case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:var pt=tg.LatLongs.get(0);var pt2d0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt.x,pt.y);var pt2d0Pixels=converter.GeoToPixels(pt2d0);var pt0Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d0Pixels.getX(),pt2d0Pixels.getY());var dist=10000;var pt2=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt,dist,0);var pt2d1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);var pt2d1Pixels=converter.GeoToPixels(pt2d1);var pt1Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d1Pixels.getX(),pt2d1Pixels.getY());var distPixels=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0Pixels,pt1Pixels);var pixelsPerMeter=distPixels/dist;AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);if(AM!==null){var H2="";for(j=0;j0){for(j=0;jmaxWidth) -maxWidth=temp;}} -maxWidthMeters=maxWidth;maxWidth*=pixelsPerMeter/2;}} -if(tg.get_H2()!==null&&tg.get_H2().isEmpty()===false){if(strRadii!==null&&strRadii.length>0){var pixels=0;for(j=0;jj){if(strRadii.length>j){if(!Double.isNaN(Double.parseDouble(strRadii[j]))){pixels=Double.parseDouble(strRadii[j])*pixelsPerMeter/2;tg.Pixels.get(j).style=Math.floor(pixels);}else -tg.Pixels.get(j).style=Math.floor(maxWidth);}else -tg.Pixels.get(j).style=Math.floor(maxWidth);}}}} -tg.set_H2(Double.toString(maxWidthMeters));X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(X!==null&&X.length>0) -tg.set_H(X[0]);if(X!==null&&X.length>1) -tg.set_H1(X[1]);break;default:break;} -switch(lineType) -{case 24361000:case 24363000:case 24362000:X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);strH1="";if(X!==null){strH1=X[0];tg.set_H1(strH1);} -break;default:break;} -if(lineType===243111000) -{AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);var strH2="";strH1="";if(AM!==null) -{for(j=0;j0){var strT1=AM[0];tg.set_T1(strT1);} -else if(lineType===15000002&&tg.LatLongs.size()>1){var dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(tg.LatLongs.get(0),tg.LatLongs.get(1),null,null);var strT1=Double.toString(dist);tg.set_T1(strT1);} -break;default:break;} -if(lineType===24311000){AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);if(AM!==null&&AM.length>1&&AN!==null&&AN.length>0) -{strT1=AM[0];var strH=AM[1];tg.set_T1(strT1);tg.set_H(strH);strH2=AN[0];tg.set_H2(strH2);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","createTGLightfromMilStdSymbol",new armyc2.c2sd.renderer.utilities.RendererException("Failed to build multipoint TG for "+milStd.getSymbolID(),exc));}else{throw exc;}} -return tg;},render:function(symbol,converter){try{var tg=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(symbol,converter);var shapeInfos=new java.util.ArrayList();var modifierShapeInfos=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterPoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.GetLineArray(tg,converter,shapeInfos,modifierShapeInfos);symbol.setModifierShapes(modifierShapeInfos);symbol.setSymbolShapes(shapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","render",new armyc2.c2sd.renderer.utilities.RendererException("Failed to render "+symbol.getSymbolID(),exc));}else{throw exc;}} -return;},render_TG:function(tg,converter,shapeInfos,modifierShapeInfos){try{var lineType=-1;var isClosedArea=false;armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var symbolId=tg.get_SymbolId();lineType=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(symbolId);if(lineType<0){lineType=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId);} -isClosedArea=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);if(isClosedArea){armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels);armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs);} -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterPoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.GetLineArray(tg,converter,shapeInfos,modifierShapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","render",new armyc2.c2sd.renderer.utilities.RendererException("Failed to render "+tg.get_SymbolId(),exc));}else{throw exc;}} -return;},GetLineArray:function(tg,converter,shapeInfos,modifierShapeInfos){try{var shapes=new java.util.ArrayList();var modifierShapes=new java.util.ArrayList();var lineType=tg.get_LineType();var minPoints2=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetMinPoints(lineType);var minPoints=new armyc2.c2sd.JavaLineArray.ref();var channelPoints=new java.util.ArrayList();var bolChange1=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,minPoints);var bolMeTOC=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(tg.get_SymbolId());tg.modifiers=new java.util.ArrayList();var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiers(tg,g2d,null);var rev=tg.getSymbologyStandard();var hatchShape=null;if(converter===null) -armyc2.c2sd.JavaTacticalRenderer.clsUtility.getHatchShape(tg,bi);if(tg.Pixels.size()0){try{armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetMeTOCShape(tg,shapes,rev);}catch(ex){if(Clazz.instanceOf(ex)){armyc2.c2sd.JavaTacticalRenderer.clsUtility.WriteFile("Error in ClsMETOC.GetMeTOCShape");}else{throw ex;}}}else{if(armyc2.c2sd.JavaLineArray.CELineArray.CIsChannel(lineType)===0){if(lineType!==23111001){tg.Pixels=armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(lineType,tg.Pixels,shapes,null,rev);armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetIntegralTextShapes(tg,g2d,shapes);} -if(lineType===23111001){var tempShapes=null;var partitions=armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility.GetPartitions2(tg);var pixels=null;var l=0;var k=0;for(l=0;l0) -shapes.addAll(0,linesWithFillShapes);var bPostClip=false;bPostClip=true;if(bPostClip===true) -{if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===false&&clipBounds!==null) -{shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);} -else if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===false&&clipPoints!==null) -{shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipPoints);}} -if(modifierShapeInfos!==null){var textSpecs=new java.util.ArrayList();armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,(isTextFlipped).booleanValue(),converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);} -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.buildHatchFills2(tg,shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);if(clipBounds!==null) -{armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipBounds);} -else if(clipPoints!==null) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipPoints);else if(clipArea===null) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipBounds);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render_GE",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render_GE",exc));}else{throw exc;}} -return;},setHostileLC:function(tg){try{var usas1314=new Boolean(true);var pts=new java.util.ArrayList();var j=0;switch(tg.get_LineType()){case 22123000:if(usas1314.booleanValue()===false) -break;if(tg.get_Affiliation()!==null&&!tg.get_Affiliation().equals("H")) -break;pts=tg.Pixels.clone();for(j=0;j=250000) -tg.set_LineType(23200001);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"getScale",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getScale",exc));}else{throw exc;}} -return scale;},setClip:function(clipBounds,clipRect,clipArray){try{if(clipBounds===null){return false;}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle2D)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle2D)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(java.util.ArrayList)){clipArray.addAll(clipBounds);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"setClip",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside setClip",exc));}else{throw exc;}} -return true;},render:function(mss,converter,clipBounds){try{var shapeInfos=new java.util.ArrayList();var modifierShapeInfos=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.render(mss,converter,shapeInfos,modifierShapeInfos,clipBounds);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("render",exc));}else{throw exc;}}},render:function(mss,converter,shapeInfos,modifierShapeInfos,clipBounds){try{var shiftLines=armyc2.c2sd.JavaLineArray.Channels.getShiftLines();var clipRect=new armyc2.c2sd.graphics2d.Rectangle2D();var clipArray=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setClip(clipBounds,clipRect,clipArray);var rev=mss.getSymbologyStandard();armyc2.c2sd.JavaTacticalRenderer.clsUtility.initializeLinetypes(rev);var tg=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(mss,converter);armyc2.c2sd.JavaLineArray.CELineArray.setClient("generic");if(shiftLines){var affiliation=tg.get_Affiliation();armyc2.c2sd.JavaLineArray.Channels.setAffiliation(affiliation);} -armyc2.c2sd.JavaLineArray.CELineArray.setMinLength(2.5);armyc2.c2sd.JavaTacticalRenderer.clsUtility.setRevC(tg);var scale=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.getScale(tg,converter,clipBounds);var linetype=tg.get_LineType();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.RemoveDuplicatePoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.SegmentGeoPoints(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaTacticalRenderer.clsUtility.FilterVerticalSegments(tg);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype,null);var isTextFlipped=false;var farLeftPixels=new java.util.ArrayList();var farRightPixels=new java.util.ArrayList();if(isChange1Area===false) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetFarPixels(tg,converter,farLeftPixels,farRightPixels);var shapesLeft=new java.util.ArrayList();var shapesRight=new java.util.ArrayList();var shapes=null;var textSpecsLeft=null;var textSpecsRight=null;textSpecsLeft=new java.util.ArrayList();textSpecsRight=new java.util.ArrayList();if(farLeftPixels.size()>0){tg.Pixels=farLeftPixels;shapesLeft=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsLeft,isTextFlipped,null);} -if(farRightPixels.size()>0){tg.Pixels=farRightPixels;shapesRight=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsRight,isTextFlipped,null);} -var textSpecs=new java.util.ArrayList();if(shapesLeft.isEmpty()||shapesRight.isEmpty()){var linesWithFillShapes=null;if(clipArray!==null&&!clipArray.isEmpty()) -linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.LinesWithFill(tg,clipArray);else if(clipRect!==null&&clipRect.getWidth()!==0) -linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,clipRect);else -linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,null);if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===true&&clipBounds!==null){if(clipArray!==null&&!clipArray.isEmpty()) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipArray);else if(clipRect!==null&&clipRect.getWidth()!==0) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipRect);tg.LatLongs=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.PixelsToLatLong(tg.Pixels,converter);} -armyc2.c2sd.JavaTacticalRenderer.clsUtility.InterpolatePixels(tg);tg.modifiers=new java.util.ArrayList();armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiers(tg,g2d,clipBounds);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.FilterPoints2(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.ClearPixelsStyle(tg);var rangeFanFillShapes=null;var savefillStyle=tg.get_FillStyle();if(linetype===243111000) -tg.set_Fillstyle(0);shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);switch(linetype){case 243111000:case 243112000:var tg1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetCircularRangeFanFillTG(tg);tg1.set_Fillstyle(savefillStyle);rangeFanFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg1,converter,isTextFlipped,clipBounds);if(rangeFanFillShapes!==null){shapes.addAll(0,rangeFanFillShapes);} -break;default:break;} -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(),shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.addAbatisFill(tg,shapes);if(shapes!==null&&linesWithFillShapes!==null&&linesWithFillShapes.size()>0) -shapes.addAll(0,linesWithFillShapes);if(shapes!==null&&shapes.size()>0){armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,isTextFlipped,null);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);mss.setModifierShapes(modifierShapeInfos);}}else{shapes=shapesLeft;shapes.addAll(shapesRight);if(textSpecs!==null){textSpecs.addAll(textSpecsLeft);textSpecs.addAll(textSpecsRight);}} -if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===false&&clipBounds!==null){shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);} -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);mss.setSymbolShapes(shapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render",exc));}else{throw exc;}} -return;},render:function(tg,converter,shapeInfos,modifierShapeInfos,clipBounds){try{armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null);var isTextFlipped=false;var farLeftPixels=new java.util.ArrayList();var farRightPixels=new java.util.ArrayList();if(isChange1Area===false) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetFarPixels(tg,converter,farLeftPixels,farRightPixels);var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();var shapesLeft=new java.util.ArrayList();var shapesRight=new java.util.ArrayList();var shapes=null;var textSpecsLeft=null;var textSpecsRight=null;textSpecsLeft=new java.util.ArrayList();textSpecsRight=new java.util.ArrayList();if(farLeftPixels.size()>0){tg.Pixels=farLeftPixels;shapesLeft=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsLeft,isTextFlipped,null);} -if(farRightPixels.size()>0){tg.Pixels=farRightPixels;shapesRight=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsRight,isTextFlipped,null);} -var textSpecs=new java.util.ArrayList();if(shapesLeft.isEmpty()||shapesRight.isEmpty()){var linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,clipBounds);if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===true&&clipBounds!==null) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(),shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.addAbatisFill(tg,shapes);if(shapes!==null&&linesWithFillShapes!==null&&linesWithFillShapes.size()>0) -shapes.addAll(0,linesWithFillShapes);if(shapes!==null&&shapes.size()>0){armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,isTextFlipped,null);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);}}else{shapes=shapesLeft;shapes.addAll(shapesRight);if(textSpecs!==null){textSpecs.addAll(textSpecsLeft);textSpecs.addAll(textSpecsRight);}} -if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).booleanValue()===false&&clipBounds!==null) -shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render",exc));}else{throw exc;}}},_className:"clsRenderer"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2={getMSRShapes:function(tg,shapes){try{var linetype=tg.get_LineType();if(linetype!=25221000&&linetype!=25222000) -return;var hmap=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getMSRSegmentColors(tg);var shape=null;var stroke=null;if(tg.get_Client().equalsIgnoreCase("ge")) -stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke2(tg.get_LineThickness(),tg.get_LineStyle(),1,1);else -stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke(tg.get_LineThickness(),tg.get_LineStyle(),1,1);var j=0;var color=null;var segShape=null;shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setLineColor(tg.get_LineColor());shape.setStroke(stroke);var strH=tg.get_H();if(strH!=null&&!strH.isEmpty()){var strs=strH.$plit(",");if(strs.length<2){shape.moveTo(tg.Pixels.get(0));for(j=1;j10){shape.lineTo(pt1);lastPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);}else{dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(lastPt,pt1);if(dist2>10){shape.lineTo(pt1);lastPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);}}}}} -if(segShape!==null) -shapes.add(segShape);shapes.add(shape);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2._className,"getMSRShapes",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMSRShapes",exc));}else{throw exc;}}},GetLineArray:function(tg,converter,isTextFlipped,clipBounds){var shapes=new java.util.ArrayList();try{if(tg.Pixels===null||tg.Pixels.isEmpty()) -return null;var x=0;var y=0;var width=0;var height=0;var clipBounds2=null;var rev=tg.getSymbologyStandard();var clipRect=null;var clipArray=null;if(clipBounds!==null){if(clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle2D||clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle){clipRect=clipBounds;x=clipRect.getMinX()-50;y=clipRect.getMinY()-50;width=clipRect.getWidth()+100;height=clipRect.getHeight()+100;clipBounds2=new armyc2.c2sd.graphics2d.Rectangle2D(x,y,width,height);} -else if(clipBounds instanceof java.util.ArrayList) -clipArray=clipBounds;} -var lineType=tg.get_LineType();var minPoints2=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetMinPoints(lineType);var minPoints=new armyc2.c2sd.JavaLineArray.ref();var bolResult=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,minPoints);var bolMeTOC=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(tg.get_SymbolId());var pts=new java.util.ArrayList();var usas1314=new Boolean(true);var j=0;switch(tg.get_LineType()){case 22612000:case 22623000:case 22612001:case 22623001:if(tg.Pixels.size()<2) -return null;if((usas1314).booleanValue()) -break;pts.add(tg.Pixels.get(0));for(j=2;j0){if(tg.Pixels.size()<2) -return null;try{armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetMeTOCShape(tg,shapes,rev);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2._className,"GetLineArray",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetLineArray",exc));}else{throw exc;}}}else{if(tg.Pixels.size()<2) -if(lineType!==12000000) -return null;if(armyc2.c2sd.JavaLineArray.CELineArray.CIsChannel(lineType)===0){if(lineType===25222000||lineType===25221000){armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.getMSRShapes(tg,shapes);} -if(lineType!==23111001){tg.Pixels=armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(lineType,tg.Pixels,shapes,clipBounds2,rev);}else if(lineType===23111001){var tempShapes=null;var partitions=armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility.GetPartitions2(tg);var pixels=null;var l=0;var k=0;for(l=0;lminSpikeDistance){lastGoodPt=currentPt;pts.add(currentPt);ptsGeo.add(currentPtGeo);foundGoodPt=true;}else{if(j===tg.Pixels.size()-1){pts.set(pts.size()-1,currentPt);ptsGeo.set(ptsGeo.size()-1,currentPtGeo);}} -break;default:if(dist>minSpikeDistance||j===tg.Pixels.size()-1){lastGoodPt=currentPt;pts.add(currentPt);ptsGeo.add(currentPtGeo);foundGoodPt=true;} -break;}} -if(foundGoodPt===true){tg.Pixels=pts;tg.LatLongs=ptsGeo;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterPoints",exc));}else{throw exc;}}},PixelsToLatLong:function(pts,converter){var j=0;var pt=null;var ptGeo=null;var ptsGeo=new java.util.ArrayList();for(j=0;jpt0pt1dist){pts.add(pt0);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(pt0.x),Math.floor(pt0.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,relativeDist);pts.add(pt1);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(pt1.x),Math.floor(pt1.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);}else{foundGoodPoint=true;pts=tg.Pixels;ptsGeo=tg.LatLongs;} -if(foundGoodPoint===false){for(j=2;jpt0pt1dist)continue;else{pts.add(ptj);ptsGeo.add(ptjGeo);foundGoodPoint=true;}}} -pts.add(controlPt);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(controlPt.x),Math.floor(controlPt.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);} -var lastGoodPt=pts.get(1);var currentPt=null;var currentPtGeo=null;var dist=0;tg.Pixels=new java.util.ArrayList();tg.LatLongs=new java.util.ArrayList();for(j=0;j<2;j++){tg.Pixels.add(pts.get(j));tg.LatLongs.add(ptsGeo.get(j));} -for(j=2;j5){lastGoodPt=currentPt;tg.Pixels.add(currentPt);tg.LatLongs.add(currentPtGeo);}} -tg.Pixels.add(pts.get(pts.size()-1));tg.LatLongs.add(ptsGeo.get(ptsGeo.size()-1));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterAXADPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterAXADPoints",exc));}else{throw exc;}} -return;},RemoveDuplicatePoints:function(tg){try{if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.isAutoshape(tg))return;switch(tg.get_LineType()){case 21700000:case 21710000:case 22320000:case 22521100:case 22521200:case 22521300:case 22521420:case 22521410:return;case 22121000:case 25221000:case 25222000:var strH=tg.get_H();if(strH!==null&&!strH.isEmpty()){var strs=strH.$plit(",");if(strs.length>1)return;} -return;default:break;} -var linetype=tg.get_LineType();if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype,null))return;var ptCurrent=null;var ptLast=null;for(var j=1;j2){tg.Pixels.remove(j);tg.LatLongs.remove(j);}}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterVerticalSegments",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterVerticalSegments",exc));}else{throw exc;}} -return;},BestFitConverter:function(latLongs){var converter=null;try{var j=0;var pixelWidth=1000;var pixelHeight=1000;var geoTop=2.2250738585072014E-308;var geoBottom=1.7976931348623157E308;var geoLeft=1.7976931348623157E308;var geoRight=2.2250738585072014E-308;for(j=0;jgeoTop)geoTop=latLongs.get(j).y;if(latLongs.get(j).ygeoRight)geoRight=latLongs.get(j).x;if(latLongs.get(j).xxmax)xmax=pt.getX();if(pt.getY()<=ymin)ymin=pt.getY();if(pt.getY()>ymax)ymax=pt.getY();} -rect=new armyc2.c2sd.graphics2d.Rectangle2D(xmin,ymin,xmax-xmin,ymax-ymin);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility._className,"AddBoundaryPointsForLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddBoundaryPointsForLines",exc));}else{throw exc;}} -return rect;},_className:"clsUtility"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF={BuildDummyShapeSpec:function(){var shape=new armyc2.c2sd.renderer.utilities.ShapeInfo(null);try{var tx=new armyc2.c2sd.graphics2d.AffineTransform();tx.setToIdentity();var gp=new armyc2.c2sd.graphics2d.GeneralPath();shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.WHITE);shape.setFillColor(null);shape.setStroke(new armyc2.c2sd.graphics2d.BasicStroke());shape.setTexturePaint(null);gp.moveTo(-1000,-1000);gp.lineTo(-1001,-1001);shape.setShape(gp);shape.setAffineTransform(tx);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"BuidDummyShapeSpec",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BuildDummyShapeSpec",exc));} -else{throw exc;}} -return shape;},isValidShapeSpec:function(shape){if(shape===null) -return false;if(shape.getLineColor()===null&&shape.getFillColor()===null) -return false;if(shape.getShape()===null) -return false;if(shape.getStroke()===null) -return false;if(shape.getAffineTransform()===null) -return false;return true;},SetLCColor:function(tg,shape){try{var affiliation=tg.get_Affiliation();if(affiliation.equals("H")){if(shape.getLineColor()===armyc2.c2sd.renderer.utilities.Color.RED) -shape.setLineColor(tg.get_LineColor());else -shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}else{if(shape.getLineColor()!==armyc2.c2sd.renderer.utilities.Color.RED) -shape.setLineColor(tg.get_LineColor());else -shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"SetLCColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SetLCColor",exc));}else{throw exc;}}},ValidateShapeSpecs:function(originalShapes,clipRect){var shapes=null;try{var shape=null;if(originalShapes===null||originalShapes.length===0){shapes=new Array(0);}else{var j=0;var newShapes=new java.util.ArrayList();for(j=0;j0){shapes=new Array(newShapes.size());shapes=newShapes.toArray(shapes);}else{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildDummyShapeSpec();shapes=new Array(1);shapes[0]=shape;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"ValidateShapeSpecs",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ValidateShapeSpecs",exc));}else{throw exc;}} -return shapes;},PointLatLongToPixels:function(ptLatLong,converter){var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var x=ptLatLong.x;var y=ptLatLong.y;var pt2dGeo=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(x,y);var ptPixels=converter.GeoToPixels(pt2dGeo);pt.x=ptPixels.getX();pt.y=ptPixels.getY();pt.style=ptLatLong.style;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"PointLatLongToPixels",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointLatLongToPixels",exc));}else{throw exc;}} -return pt;},GetNumericFields:function(tg,lineType,radius,width,length,attitude){try{if(lineType===243111001) -return;var dist=0;var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);radius.value=Clazz.newArray(1,0);width.value=Clazz.newArray(1,0);attitude.value=Clazz.newArray(1,0);length.value=Clazz.newArray(1,0);switch(lineType){case 15000002:case 24312000:case 24321300:case 24323300:case 24324300:case 24325300:case 24326200:case 24331300:case 24332300:case 24333300:case 24334300:case 24335300:case 24336300:case 24337300:case 24338300:case 24339300:case 24322300:case 24353000:case 24363000:radius.value[0]=Double.parseDouble(tg.get_T1());break;case 24311000:length.value[0]=Double.parseDouble(tg.get_T1());width.value[0]=Double.parseDouble(tg.get_H());attitude.value[0]=Double.parseDouble(tg.get_H2())*(0.05625);var std=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getSymbologyStandard();if(std===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525C) -attitude.value[0]=Double.parseDouble(tg.get_H2());break;case 24326101:case 24321200:case 24323200:case 24322200:case 24324200:case 24325200:case 24331200:case 24332200:case 24333200:case 24334200:case 24335200:case 24336200:case 24337200:case 24338200:case 24339200:case 24352000:case 24362000:if(tg.LatLongs.size()>=2){if(tg.LatLongs.size()>=2){pt0=tg.LatLongs.get(0);pt1=tg.LatLongs.get(1);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(pt0,pt1,a12,a21);attitude.value[0]=a12.value[0];}} -width.value[0]=Double.parseDouble(tg.get_T1());break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetNumericFields",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetNumericFields",exc));}else{throw exc;}}},TransformPixels:function(tg,clipBounds){try{var top=clipBounds.getMaxY();var bottom=clipBounds.getMinY();var xfm=null;var pt2d=null;var j=0;var pt2=null;for(j=0;jmaxX) -maxX=tg.Pixels.get(j).x;} -var degWidth=(maxX-minX)*degLonPerPixel;if(Math.abs(degWidth)<180) -return;var midX=Math.abs(180/degLonPerPixel);var x=0;var y=0;for(j=0;jmidX){x-=2*midX;} -farLeftPixels.add(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y));} -for(j=0;j1){pt1=tg.LatLongs.get(1);}else{pt1=tg.LatLongs.get(0);} -var pPoints=null;var ptCenter=this.PointLatLongToPixels(pt0,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetNumericFields(tg,lineType,radius,width,length,attitude);switch(lineType){case 24326101:case 24321200:case 24323200:case 24322200:case 24324200:case 24325200:case 24331200:case 24332200:case 24333200:case 24334200:case 24335200:case 24336200:case 24337200:case 24338200:case 24339200:case 24352000:case 24362000:pt00=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,width.value[0]/2,attitude.value[0]-90);pt00=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(pt00,converter);pt00.style=0;tg.Pixels.add(pt00);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,width.value[0]/2,attitude.value[0]+90);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);ptTemp.style=0;tg.Pixels.add(ptTemp);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt1,width.value[0]/2,attitude.value[0]+90);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);ptTemp.style=0;tg.Pixels.add(ptTemp);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt1,width.value[0]/2,attitude.value[0]-90);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);ptTemp.style=0;tg.Pixels.add(ptTemp);tg.Pixels.add(pt00);break;case 24311000:ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,length.value[0]/2,attitude.value[0]-90);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTemp,width.value[0]/2,attitude.value[0]+0);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);tg.Pixels.add(ptTemp);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,length.value[0]/2,attitude.value[0]+90);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTemp,width.value[0]/2,attitude.value[0]+0);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);tg.Pixels.add(ptTemp);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,length.value[0]/2,attitude.value[0]+90);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTemp,width.value[0]/2,attitude.value[0]+180);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);tg.Pixels.add(ptTemp);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,length.value[0]/2,attitude.value[0]-90);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTemp,width.value[0]/2,attitude.value[0]+180);ptTemp=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(ptTemp,converter);tg.Pixels.add(ptTemp);tg.Pixels.add(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0).x,tg.Pixels.get(0).y));break;case 24312000:case 15000002:case 24321300:case 24322300:case 24323300:case 24324300:case 24325300:case 24326200:case 24331300:case 24332300:case 24333300:case 24334300:case 24335300:case 24336300:case 24337300:case 24338300:case 24339300:case 24353000:case 24363000:pt0=tg.LatLongs.get(0);ptTemp=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,radius.value[0],90);pPoints=new Array(3);pPoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pPoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTemp);pPoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTemp);var pPoints2=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.GetGeodesicArc(pPoints);var ptTemp2=null;for(j=0;j1) -armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.RangeFanOrientation(tg,lineType,converter);break;case 243112000:armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetSectorRangeFan(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.RangeFanOrientation(tg,lineType,converter);break;case 243111001:armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetSectorRangeFan(tg,converter);break;default:return false;} -var farLeftPixels=new java.util.ArrayList();var farRightPixels=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetFarPixels(tg,converter,farLeftPixels,farRightPixels);var shapesLeft=new java.util.ArrayList();var shapesRight=new java.util.ArrayList();if(farLeftPixels.isEmpty()||farRightPixels.isEmpty()){var tempPixels=new java.util.ArrayList();tempPixels.addAll(tg.Pixels);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postSegmentFSA(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Change1PixelsToShapes(tg,shapes);tg.Pixels=tempPixels;}else{tg.Pixels=farLeftPixels;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiers2(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Change1PixelsToShapes(tg,shapesLeft);tg.Pixels=farRightPixels;armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Change1PixelsToShapes(tg,shapesRight);shapes.addAll(shapesLeft);shapes.addAll(shapesRight);} -if(lineType===15000002) -{var shape=new armyc2.c2sd.JavaLineArray.Shape2(0);shape.moveTo(ptCenter);ptCenter.y+=1;shape.lineTo(ptCenter);shapes.add(shape);} -return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"Change1TacticalAreas",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside Change1TacticalAreas",exc));}else{throw exc;}} -return false;},Change1PixelsToShapes:function(tg,shapes){var shape=null;var beginLine=true;var currentPt=null;var lastPt=null;var k=0;var linetype=tg.get_LineType();for(k=0;k0) -lastPt=tg.Pixels.get(k-1);if(beginLine){if(k===0) -shape.set_Style(currentPt.style);if(k>0) -if(currentPt.style===5&&lastPt.style===5) -shape.lineTo(currentPt);shape.moveTo(currentPt);beginLine=false;}else{shape.lineTo(currentPt);if(currentPt.style===5||currentPt.style===10){beginLine=true;if(linetype===243111001&&kmaxx){maxx=max;maxIndex=k;}}}catch(e){if(Clazz.instanceOf(e,NumberFormatException)){return null;}else{throw e;}} -var strLeft=leftRightMinMax[4*maxIndex];var strRight=leftRightMinMax[4*maxIndex+1];var strMin=leftRightMinMax[4*maxIndex+2];var strMax=leftRightMinMax[4*maxIndex+3];strLeftRightMinMax=strLeft+","+strRight+","+strMin+","+strMax;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetMaxSector",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetMaxSector",exc));}else{throw exc;}} -return strLeftRightMinMax;},GetCircularRangeFanFillTG:function(tg){var tg1=null;try{tg1=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg1.set_VisibleModifiers(true);tg1.set_LineThickness(0);tg1.set_FillColor(tg.get_FillColor());tg1.set_Fillstyle(tg.get_FillStyle());tg1.LatLongs=new java.util.ArrayList();tg1.Pixels=new java.util.ArrayList();tg1.LatLongs.add(tg.LatLongs.get(0));tg1.Pixels.add(tg.Pixels.get(0));tg1.Pixels.add(tg.Pixels.get(1));tg1.set_LineType(243111001);var strH2=tg.get_H2();if(tg.get_LineType()!==243111000){tg1.set_H2(strH2);return tg1;} -var H2=strH2.$plit(",");var leftRightMinMax="";var j=0;for(j=0;j0) -leftRightMinMax+=",";leftRightMinMax+="0,0,"+H2[j]+","+H2[j+1];} -tg1.set_H2(leftRightMinMax);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetCircularRangeFanFillTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCircularRangeFanFillTG",exc));}else{throw exc;}} -return tg1;},addCircularRangeFanFillShapesFromTG:function(tgShapes,fillShapes){try{tgShapes.addAll(0,fillShapes);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"addCircularRangeFanFillShapesFromTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside addCircularRangeFanFillShapesFromTG",exc));}else{throw exc;}}},GetSectorRangeFan:function(tg,converter){var circle=false;try{var ptCenter=tg.LatLongs.get(0);var k=0;var l=0;var numSectors=0;armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetSectorRadiiFromPoints(tg);var pPoints=new java.util.ArrayList();var pPointsInnerArc=new java.util.ArrayList();var pPointsOuterArc=new java.util.ArrayList();var sectorPoints=new java.util.ArrayList();var allPoints=new java.util.ArrayList();var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var H2=tg.get_H2();var leftRightMinMax=H2.$plit(",");var left=0;var right=0;var min=0;var max=0;numSectors=Math.floor(leftRightMinMax.length/4);if(numSectors<1){return false;} -if(numSectors*4!==leftRightMinMax.length){return false;} -try{for(k=0;k=0;l--){pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pPointsOuterArc.get(l));sectorPoints.add(pt1);} -pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pPointsInnerArc.get(0));pt1.style=5;sectorPoints.add(pt1);for(l=0;l1){pt1=tg.LatLongs.get(1);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(pt0,pt1,a12,a21);orientation=a12.value[0];}else{var strLeftRightMinMax=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetMaxSector(tg);var sector=strLeftRightMinMax.$plit(",");var left=Double.parseDouble(sector[0]);var right=Double.parseDouble(sector[1]);var min=Double.parseDouble(sector[2]);var max=Double.parseDouble(sector[3]);while(left>360) -left-=360;while(right>360) -right-=360;while(left<0) -left+=360;while(right<0) -right+=360;if(left>right) -orientation=(left-360+right)/2;else -orientation=(left+right)/2;dist=max;} -radius=dist*1.1;var pt0F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt1F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptBaseF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptLeftF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptRightF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptTipF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();pt0=tg.LatLongs.get(0);pt0F=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(pt0,converter);pt1=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,radius,orientation);pt1F=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(pt1,converter);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0F,pt1F);ptBaseF=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0F,pt1F,dist+10);ptTipF=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0F,pt1F,dist+20);ptLeftF=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0F,ptBaseF,ptBaseF,0,10);ptRightF=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0F,ptBaseF,ptBaseF,1,10);tg.Pixels.add(pt0F);ptTipF.style=5;tg.Pixels.add(ptTipF);tg.Pixels.add(ptLeftF);ptTipF.style=0;tg.Pixels.add(ptTipF);tg.Pixels.add(ptRightF);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"RangeFanOrientation",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RangeFanOrientation",exc));}else{throw exc;}}},ClearPixelsStyle:function(tg){try{switch(tg.get_LineType()){case 15000001:case 15000000:case 15000003:case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:return;default:break;} -for(var j=0;j0) -return true;var linetype=tg.get_LineType();switch(linetype){case 2237000:case 23120000:case 22612000:case 22623000:case 22121000:case 22122000:case 22123000:case 22124000:case 22125000:case 22131000:case 11000000:case 10000000:case 22132000:case 22133000:case 22432000:case 22134000:case 22135000:case 22136000:case 22137000:case 22138000:case 221310000:case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:case 22235000:case 22330000:case 221311000:case 22340000:case 22350000:case 22421000:case 22431000:case 22431100:case 22522100:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22528000:case 22531000:case 22532000:case 22535000:case 22536000:case 22613000:case 22621000:case 22622000:case 22624000:case 22625000:case 22626000:case 23111000:case 23111001:case 23112000:case 23113000:case 23115000:case 23114000:case 23131100:case 23131200:case 23132000:case 23134000:case 23162000:case 23164000:case 23180000:case 231111000:case 231112000:case 231113000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 23350000:case 23440000:case 23450000:case 23460000:case 23490000:case 24250000:case 24211000:case 24260000:case 24210000:case 24220000:case 23200000:case 23200001:case 24230000:case 24225000:case 24240000:case 24330000:case 24313000:case 24314000:case 24315000:case 24321100:case 24322100:case 24323100:case 24324100:case 24325100:case 243100000:case 24331100:case 24332100:case 24336100:case 24333100:case 24334100:case 24335100:case 24337100:case 24338100:case 24339100:case 24351000:case 24361000:case 25221000:case 25222000:case 25223000:case 25225000:case 25224000:case 25310000:case 25320000:case 25330000:case 25340000:case 25351000:case 25352000:case 25353000:case 24226000:return true;default:return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"canClipPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside canClipPoints",exc));}else{throw exc;}} -return false;},LinesWithSeparateFill:function(linetype,shapes){if(shapes===null) -return false;switch(linetype){case 23410000:case 22612000:case 22623000:return true;case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 211100000:case 22121000:case 22122000:case 22123000:case 22124000:case 22125000:case 22330000:case 22522100:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22528000:case 22613000:case 23112000:case 23120000:case 23131100:case 23131200:case 23132000:case 23134000:case 23172000:case 231111000:case 231112000:case 231113000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 24250000:case 24211000:case 24210000:case 24220000:case 24230000:case 24225000:case 24240000:case 25221000:case 25222000:case 25223000:case 25225000:case 25224000:case 22222000:case 22222001:case 22224000:case 22224001:case 22221000:case 22223000:case 22225000:var shape=null;if(shapes!==null&&shapes.size()>0){for(var j=0;j1) -{tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg.set_LineType(22124000);tg.Pixels=pts2;if(clipBounds!==null) -{pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);} -else if(clipPoints!==null&&!clipPoints.isEmpty()) -pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipPoints);if(pts2d!==null&&pts2d.size()>1) -{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildShapeFromPoints(pts2d);gp.append(shape,false);} -pts2.clear();pts2.add(pt);} -else -pts2.add(pt);break;case 1:pts2.add(pt);break;default:pts2.add(pt);break;}} -if(pts2.size()>1){tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg.set_LineType(22124000);tg.Pixels=pts2;if(clipBounds!==null) -pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);else if(clipPoints!==null) -pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipPoints);if(pts2d!==null&&pts2d.size()>1) -{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildShapeFromPoints(pts2d);gp.append(shape,false);}} -shapeSpec2=new armyc2.c2sd.JavaLineArray.Shape2(shapeSpec.getShapeType());shapeSpec2.setLineColor(shapeSpec.getLineColor());shapeSpec2.setFillColor(shapeSpec.getFillColor());shapeSpec2.setStroke(shapeSpec.getStroke());shapeSpec2.setTexturePaint(shapeSpec.getTexturePaint());shapeSpec2.setShape(gp);shapeSpecs2.add(shapeSpec2);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"buildShapeSpecFromPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside buildShapeSpecFromPoints",exc));}else{throw exc;}} -return shapeSpecs2;},postClipShapes:function(tg,shapeSpecsArray,clipArea){var shapeSpecs2=null;var tempShapes=null;try{if(shapeSpecsArray===null||shapeSpecsArray.size()===0) -return null;shapeSpecs2=new java.util.ArrayList();var j=0;var shapeSpecs=new java.util.ArrayList();for(j=0;jmaxDist){maxDist=dist;}} -if(interval>maxDist) -interval=maxDist;for(j=0;j=interval/2) -resultPts.add(pt);} -resultPts.add(pt1);} -latLongs=resultPts;tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(latLongs,converter);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"postSegmentFSA",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside postSegmentFSA",exc));}else{throw exc;}}},SegmentGeoPoints:function(tg,converter){try{if(tg.get_Client().equals("2D")) -return;var resultPts=new java.util.ArrayList();var lineType=tg.get_LineType();var interval=1000000;switch(lineType){case 22528000:case 24220000:case 231111000:case 22350000:case 231117300:case 231117200:case 231117100:case 23131100:case 23131200:case 23132000:case 23134000:case 23112000:case 23111000:case 23111001:case 22522100:case 23350000:case 22624000:case 22122000:case 23113000:case 23115000:case 23114000:case 22134000:case 23330000:break;case 231116000:case 231115000:case 231114000:case 231113000:case 231112000:interval=500000;break;case 22123000:interval=2000000;break;default:if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.segmentAnticipatedLine(tg)) -{break;} -return;} -var j=0;var k=0;var n=0;var pt0=null;var pt1=null;var pt=null;var dist=0;var az=0;var maxDist=0;for(j=0;jmaxDist){maxDist=dist;}} -if(interval>maxDist) -interval=maxDist;for(j=0;j=interval/2) -resultPts.add(pt);} -resultPts.add(pt1);} -tg.LatLongs=resultPts;tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"SegmentGeoPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SegmentGeoPoints",exc));}else{throw exc;}} -return;},_className:"clsUtilityCPOF"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE={setSplineLinetype:function(tg){switch(tg.get_LineType()){case 22623000:tg.set_LineType(22623001);break;case 22612000:tg.set_LineType(22612001);break;case 32164000:tg.set_LineType(32164001);break;case 32163000:tg.set_LineType(32163001);break;case 32156000:tg.set_LineType(32156001);break;case 32162000:tg.set_LineType(32162001);break;case 32610000:tg.set_LineType(32610001);break;case 31430000:tg.set_LineType(31430001);break;case 31440000:tg.set_LineType(31440001);break;case 32273000:tg.set_LineType(32273001);break;case 32272000:tg.set_LineType(32272001);break;case 32234300:tg.set_LineType(32234301);break;case 32234200:tg.set_LineType(32234201);break;case 32234100:tg.set_LineType(32234101);break;case 32233700:tg.set_LineType(32233701);break;case 32233600:tg.set_LineType(32233601);break;case 32231700:tg.set_LineType(32231701);break;case 32221000:tg.set_LineType(32221001);break;case 32213000:tg.set_LineType(32213001);break;case 32212000:tg.set_LineType(32212001);break;case 32161000:tg.set_LineType(32161001);break;case 32155000:tg.set_LineType(32155001);break;case 32154000:tg.set_LineType(32154001);break;case 31830000:tg.set_LineType(31830001);break;case 31820000:tg.set_LineType(31820001);break;case 31810000:tg.set_LineType(31810001);break;case 31850000:tg.set_LineType(31850001);break;case 31840000:tg.set_LineType(31840001);break;case 31860000:tg.set_LineType(31860001);break;default:break;} -return;},createDashedPolylines:function(tg,polylines,shape){try{if(shape.getLineColor()===null) -return polylines;var dashedPolylines=new java.util.ArrayList();var s=shape.getStroke();var dash=s.getDashArray();var lineThickness=tg.get_LineThickness();if(dash===null||dash.length<2) -return polylines;if(dash.length===8){dash=Clazz.newArray(2,0);dash[0]=2;dash[1]=2;s=new armyc2.c2sd.graphics2d.BasicStroke(2,1,0,2,dash,0);shape.setStroke(s);} -if(dash.length===4){if(dash[0]===lineThickness*2&&dash[1]===lineThickness*2&&dash[2]===lineThickness*2&&dash[3]===lineThickness*2){dash=Clazz.newArray(2,0);dash[0]=lineThickness;dash[1]=lineThickness;}} -var j=0;var k=0;var i=0;var l=0;var n=0;var polyline=null;var dashedPolyline=null;var pt2d0=null;var pt2d1=null;var pt2d2=null;var pt2d3=null;var pt0=null;var pt1=null;var pt2=null;var pt3=null;var dist=0;var patternLength=0;var numSegments=0;for(j=0;j0) -{dashedPolyline=new java.util.ArrayList();pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt0,pt1,numSegments*patternLength+remainder/2);pt2d2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);dashedPolyline.add(pt2d2);dashedPolyline.add(pt2d1);dashedPolylines.add(dashedPolyline);}}} -return dashedPolylines;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"createDashedPolylines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createDashedPolylines",exc));}else{throw exc;}}},createSimpleFillShape:function(tg,shape,polylines){try{var s=shape.getStroke();var dash=s.getDashArray();if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType())===false) -if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null)===false) -{return null;} -if(dash===null||dash.length<2) -return null;var j=0;var k=0;var shape2=new armyc2.c2sd.renderer.utilities.ShapeInfo(shape.getShape());shape2.setShapeType(armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL);var polylines2=new java.util.ArrayList();var polyline=null;var polyline2=null;var pt2d=null;s=new armyc2.c2sd.graphics2d.BasicStroke(0);shape2.setStroke(s);shape2.setFillColor(shape.getFillColor());for(j=0;j=0) -return true;switch(linetype){case 15000001:case 15000003:case 21700000:case 21700000:case 21710000:case 22320000:case 22521100:case 22521200:case 22521300:case 22521410:case 22521420:case 22139000:case 243112000:case 243111000:case 23172000:case 23173000:case 23174000:case 23200001:case 23211000:case 23131200:case 23132000:case 23223000:case 23212000:case 23213000:case 32214000:return true;default:return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"allowFillForThese",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside allowFillForThese",exc));}else{throw exc;}} -return false;},SetShapeInfosPolylines:function(tg,shapeInfos,clipBounds){try{var j=0;var shape=null;var shapeInfo=null;var polylines=null;var type=-1;var simpleFillShape=null;var isClosed=new Boolean(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType()));var linetype=tg.get_LineType();var fillColor=null;for(j=0;j0) -{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL) -{if(ptsPoly[ptsPoly.length-1].getX()!==ptsPoly[0].getX()||ptsPoly[ptsPoly.length-1].getY()!==ptsPoly[0].getY()) -{pt2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ptsPoly[0].getX(),ptsPoly[0].getY());ptsPoly.add(pt2d)}} -polylines2.add(ptsPoly);} -ptsPoly=new java.util.ArrayList();ptPoly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(coords[0],coords[1]);ptsPoly.add(ptPoly);break;case 1:ptPoly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(coords[0],coords[1]);ptsPoly.add(ptPoly);break;case 2:break;case 3:break;case 4:break;}} -if(ptsPoly.size()>0) -{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL) -{if(ptsPoly.get(ptsPoly.size()-1).getX()!==ptsPoly.get(0).getX()||ptsPoly.get(ptsPoly.size()-1).getY()!==ptsPoly.get(0).getY()) -{pt2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ptsPoly.get(0).getX(),ptsPoly.get(0).getY());ptsPoly.add(pt2d);}} -polylines2.add(ptsPoly);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"createRenderableFromShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createRenderableFromShape",exc));}else{throw exc;}} -return polylines2;},expandPolygon:function(pts,expand){var lgPoly=null;try{var j=0;var destPts=null;var isClosed=false;if(pts.get(pts.size()-1).getX()===pts.get(0).getX()&&pts.get(pts.size()-1).getY()===pts.get(0).getY()){pts.remove(pts.size()-1);isClosed=true;} -var pts2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.Points2DToPOINT2(pts);var pt0=null;var pt1=null;var pt2=null;var pt3=null;var m=0;var m1=0;var b=0;var b1=0;var lineSegments=new java.util.ArrayList();for(j=0;j0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);line=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);intersects=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.lineIntersectsClipArea(line,clipPoints);if(intersects===true){backIndex=j;break;}else if(area.containsPt2(Math.floor(pt0.x),Math.floor(pt0.y))||area.containsPt2(Math.floor(pt1.x),Math.floor(pt1.y))){backIndex=j;break;}} -var pts=new java.util.ArrayList();for(j=frontIndex;j<=backIndex;j++){pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(j));pts.add(pt0);} -tg.Pixels=pts;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","removeTrailingPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside removeTrailingPoints",exc));}else{throw exc;}}},lineIntersectsClipArea:function(line,clipPts){var result=false;try{var j=0;var poly=new armyc2.c2sd.graphics2d.Polygon();for(j=0;jheight) -height=width;else -width=height;width*=2;height*=2;var horizLimit=0;var vertLimit=0;var j=0;var vertPts=new java.util.ArrayList();var horizPts=new java.util.ArrayList();var vertPt=null;var horizPt=null;if(hatch===armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.Hatch_BackwardDiagonal){horizLimit=Math.floor((width/20.0));vertLimit=Math.floor((height/20.0));for(j=0;j1) -return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"segmentColorsSet",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside segmentColorsSet",exc));}else{throw exc;}} -return false;},setPoint2D:function(){var pt2d=new armyc2.c2sd.graphics2d.Point2D();if(arguments.length===1) -{pt2d.x=arguments[0].x;pt2d.y=arguments[0].y;} -else if(arguments.length===2) -{pt2d.x=arguments[0];pt2d.y=arguments[1];} -return pt2d;},setLine2D:function() -{var line=new armyc2.c2sd.graphics2d.Line2D();if(arguments.length===1) -{var line1=arguments[0];line.x1=line1.x1;line.y1=line1.y1;line.x2=line1.x2;line.y2=line1.y2;} -else if(arguments.length===2) -{var pt1=arguments[0];var pt2=arguments[1];line.x1=pt1.x;line.y1=pt1.y;line.x2=pt2.x;line.y2=pt2.y;} -else if(arguments.length===4) -{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];line.x1=x1;line.y1=y1;line.x2=x2;line.y2=y2;} -return line;},_className:"clsUtilityGE",Hatch_ForwardDiagonal:2,Hatch_BackwardDiagonal:3,Hatch_Vertical:4,Hatch_Horizontal:5,Hatch_Cross:8};var java=java||{};java.util=java.util||{};java.util.ArrayList=function() -{this.array=[];if(arguments.length===1) -{var obj=arguments[0];if(obj instanceof java.util.ArrayList) -{this.array=obj.getArray();} -else if(obj instanceof Array) -{this.array=arguments[0];}}};java.util.ArrayList.prototype.getArray=function() -{return this.array;};java.util.ArrayList.prototype.setArray=function(obj) -{this.array=obj;};java.util.ArrayList.prototype.add=function(obj) -{if(arguments.length===1) -this.array.push(obj);else if(arguments.length===2) -{var j=0,k=0;var array2=[];var location=arguments[0];var obj2=arguments[1];if(location===this.array.length) -{this.array.push(obj2);} -else -{for(j=0;j=0) -{var fontSize=fontSizeForTGIcons;var ratio=size/40.0;var strSymbol=String.fromCharCode(charSymbolIndex);var pixel=new armyc2.c2sd.renderer.so.Point(0,0);if(ratio>0) -{fontSize=fontSize*ratio;} -fontSize=(fontSize/96*72);var buffer=this.createBuffer(size,size),ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=5;ctx.fillStyle=color;ctx.font=fontSize+"pt TacticalGraphics";var x=Math.round(size/2),y=Math.round(size/2);ctx.fillText(strSymbol,x,y);var centerPoint=new armyc2.c2sd.renderer.so.Point(x,y),symbolBounds=new armyc2.c2sd.renderer.so.Rectangle(0,0,size,size),imageBounds=symbolBounds.clone();var ii=new armyc2.c2sd.renderer.utilities.ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);return ii;}},createBuffer:function(width,height) -{var buffer=document.createElement('canvas');buffer.width=width;buffer.height=height;return buffer;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.SinglePointRenderer=(function(){var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,UnitFontLookup=armyc2.c2sd.renderer.utilities.UnitFontLookup,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,SO=armyc2.c2sd.renderer.so,RendererUtilities=armyc2.c2sd.renderer.utilities.RendererUtilities,TextInfo=armyc2.c2sd.renderer.utilities.TextInfo,ImageInfo=armyc2.c2sd.renderer.utilities.ImageInfo,MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes,SymbolDimensions=armyc2.c2sd.renderer.utilities.SymbolDimensions,ModifiersUnits=armyc2.c2sd.renderer.utilities.ModifiersUnits,ModifiersTG=armyc2.c2sd.renderer.utilities.ModifiersTG,SinglePointLookup=armyc2.c2sd.renderer.utilities.SinglePointLookup;var textInfoBuffer=null,textInfoContext=null,textInfoContextFont=null,_bufferUnit=null,_bufferUnitSize=150,_bufferSymbol=null,_bufferSymbolSize=150,_bufferDisplayModifiers=null,_document=document;var _statusColorMap={"C":"#00FF00","D":"#FFFF00","X":"#FF0000","F":"#0000FF"},_unitTextModifierKeys=["B","C","F","G","H","H1","H2","J","K","L","M","N","P","R2","T","T1","V","W","W1","X","Y","Z","AC","AD","AE","AF","CN"],_tgTextModifierKeys=["B","C","F","G","H","H1","H2","N","T","T1","V","W","W1","X","Y","AM","AN","Length","Width","Radius","Angle"];return{checkModifierFont:function() -{if(textInfoBuffer===null) -textInfoBuffer=this.createBuffer(1,1);if(textInfoContext===null&&textInfoBuffer.getContext!==undefined) -{textInfoContext=textInfoBuffer.getContext('2d');textInfoContext.lineCap="butt";textInfoContext.lineJoin="miter";textInfoContext.miterLimit=3;} -if(textInfoContextFont!==RendererSettings.getModifierFont()) -{textInfoContextFont=RendererSettings.getModifierFont();textInfoContext.font=textInfoContextFont;}},renderUnit:function(symbolID,modifiers) -{var render=true;if(modifiers["RENDER"]!==undefined) -render=modifiers["RENDER"];if(render&&_bufferUnit===null) -{_bufferUnit=this.createBuffer(_bufferUnitSize,_bufferUnitSize);ctx=_bufferUnit.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;} -if(modifiers===undefined||modifiers===null) -modifiers={};var pixel=null,basicID=SymbolUtilities.getBasicSymbolID(symbolID),symStd=modifiers[MilStdAttributes.SymbologyStandard]||RendererSettings.getSymbologyStandard(),ufli=UnitFontLookup.getUnitLookup(basicID,symStd),strUnitFont="";var intFill=UnitFontLookup.getFillCode(symbolID),intFrame=UnitFontLookup.getFrameCode(symbolID,intFill,symStd),fillColor=SymbolUtilities.getFillColorOfAffiliation(symbolID).toHexString(false),lineColor=SymbolUtilities.getLineColorOfAffiliation(symbolID).toHexString(false),fill=(intFill>0)?String.fromCharCode(intFill):null,frame=(intFrame>0)?String.fromCharCode(intFrame):null,mapping1=ufli.getMapping1(symbolID),mapping2=ufli.getMapping2(),symbol1=(mapping1!==null)?String.fromCharCode(mapping1):null,symbol2=(mapping2!==null)?String.fromCharCode(mapping2):null,color1=ufli.getColor1(),color2=ufli.getColor2(),buffer=null,ctx=null;var hasDisplayModifiers=false;var hasTextModifiers=false;var intFrameAssume=-1,frameAssume=null;if(render===false) -ctx={};if(symStd>RendererSettings.Symbology_2525Bch2_USAS_13_14) -{var affiliation=symbolID.charAt(1);switch(affiliation) -{case'P':case'A':case'S':case'G':case'M':intFrameAssume=intFill+2;break;} -if(intFrameAssume>0) -frameAssume=String.fromCharCode(intFrameAssume);} -this.checkModifierFont();if(modifiers===undefined||modifiers===null) -modifiers={};var pixelSize=-1;if(modifiers[MilStdAttributes.PixelSize]) -{pixelSize=modifiers[MilStdAttributes.PixelSize];} -else -{pixelSize=RendererSettings.getDefaultPixelSize();} -var keepUnitRatio=true;if(modifiers[MilStdAttributes.KeepUnitRatio]!==undefined) -{keepUnitRatio=modifiers[MilStdAttributes.KeepUnitRatio];} -var icon=false;if(modifiers[MilStdAttributes.Icon]!==undefined) -{icon=modifiers[MilStdAttributes.Icon];} -if(icon) -{keepUnitRatio=false;hasDisplayModifiers=false;hasTextModifiers=false;symbolID=symbolID.substring(0,10)+"-----";} -else -{hasDisplayModifiers=this.hasDisplayModifiers(symbolID,modifiers);hasTextModifiers=this.hasTextModifiers(symbolID,modifiers);} -if(modifiers[MilStdAttributes.LineColor]!==undefined) -{lineColor=modifiers[MilStdAttributes.LineColor];} -if(modifiers[MilStdAttributes.FillColor]!==undefined) -{fillColor=modifiers[MilStdAttributes.FillColor];} -var symbolBounds=SymbolDimensions.getUnitBounds(intFill,50);var rect=SymbolDimensions.getUnitBounds(intFill,50);if(pixelSize>0&&keepUnitRatio===true) -{var heightRatio=UnitFontLookup.getUnitRatioHeight(intFill),widthRatio=UnitFontLookup.getUnitRatioWidth(intFill);var ratio=-1;if(heightRatio>widthRatio) -{pixelSize=(pixelSize/1.5)*heightRatio;} -else -{pixelSize=(pixelSize/1.5)*widthRatio;}} -if(pixelSize>0) -{ratio=Math.min((pixelSize/rect.getHeight()),(pixelSize/rect.getWidth()));var fontsize=50;fontsize=(((fontsize*ratio)/96)*72);strUnitFont=fontsize+"pt UnitFont";symbolBounds=SymbolDimensions.getUnitBounds(intFill,(50*ratio));} -else -{strUnitFont=150+"pt UnitFont";} -var symbolWidth=Math.round(symbolBounds.getWidth()),symbolHeight=Math.round(symbolBounds.getHeight());if(render===true) -{if(hasDisplayModifiers===true||hasTextModifiers===true) -{buffer=_bufferUnit;ctx=buffer.getContext('2d');ctx.clearRect(0,0,_bufferUnitSize,_bufferUnitSize);} -else -{buffer=this.createBuffer(symbolWidth,symbolHeight);ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;} -ctx.font=strUnitFont;} -var x=Math.round(symbolBounds.getWidth()/2),y=Math.round((symbolBounds.getHeight()/2)+symbolBounds.getY());if(render===true) -{if(color1==="") -{color1="#000000";} -if(fill!==null&&fill!=="") -{ctx.fillStyle=fillColor;ctx.fillText(fill,x,y);} -if(frame!==null&&frame!=="") -{ctx.fillStyle=lineColor;ctx.fillText(frame,x,y);} -if(frameAssume!==null&&frameAssume!=="") -{ctx.fillStyle="#ffffff";ctx.fillText(frameAssume,x,y);} -if(symbol2!==null&&symbol2!=="") -{ctx.fillStyle=color2;ctx.fillText(symbol2,x,y);} -if(symbol1!==null&&symbol1!=="") -{ctx.fillStyle=color1;ctx.fillText(symbol1,x,y);}} -symbolBounds.setLocation(0,0);var imageBounds=new SO.Rectangle(0,0,symbolWidth,symbolHeight);var centerPoint=new SO.Point(x,y);var ii=new ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);var iinew=null;if(hasDisplayModifiers===true) -iinew=this.processUnitDisplayModifiers(ii,symbolID,modifiers,hasTextModifiers);if(iinew!==null) -ii=iinew;iinew=null;if(hasTextModifiers===true) -iinew=this.processUnitModifiers(ii,symbolID,modifiers);if(iinew!==null) -ii=iinew;ctx=null;buffer=null;if(icon) -return ii.getSquareImageInfo();else -return ii;},processUnitDisplayModifiers:function(ii,symbolID,modifiers){var render=true;if(modifiers["RENDER"]!==undefined) -render=modifiers["RENDER"];var newii=null,symbolBounds=ii.getSymbolBounds(),imageBounds=ii.getImageBounds(),centerPoint=ii.getCenterPoint(),tiEchelon=null,echelonBounds=null,amBounds=null,buffer=null,ctx=null,offsetX=0,offsetY=0,symStd=modifiers[MilStdAttributes.SymbologyStandard]||RendererSettings.getSymbologyStandard();var mobilityBounds=null;var shapes=new Array();if(symbolID.charAt(10)===("M")||symbolID.charAt(10)===("N")) -{var x=0,y=0,centerX=0,bottomY=0,height=0,width=0,middleY=0,wheelOffset=1,wheelSize=5,rrHeight=5,rrArcWidth=8;var mobility=symbolID.substring(10,12);x=symbolBounds.getX()+1;y=symbolBounds.getY();height=Math.round(symbolBounds.getHeight());width=Math.round(symbolBounds.getWidth())-1;bottomY=y+height+1;if(symbolID.charAt(10)===("M")){wheelSize=width/7;rrHeight=width/7;switch(mobility) -{case"MO":shapes.push(new SO.Line(x,bottomY,x+width,bottomY));shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));break;case"MP":var line=new SO.Line(x,bottomY,x+width,bottomY);shapes.push(line);shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+(width/2)-(wheelSize/2),bottomY+wheelOffset,wheelSize,wheelSize));break;case"MQ":shapes.push(new SO.RoundedRectangle(x,bottomY,width,rrHeight,rrArcWidth));break;case"MR":shapes.push(new SO.RoundedRectangle(x,bottomY,width,rrHeight,rrArcWidth));shapes.push(new SO.Ellipse(x-wheelSize-wheelSize,bottomY,wheelSize,wheelSize));break;case"MS":var line=new SO.Line(x+wheelSize,bottomY+(wheelSize/2),x+width-wheelSize,bottomY+(wheelSize/2));shapes.push(line);shapes.push(new SO.Ellipse(x,bottomY,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY,wheelSize,wheelSize));break;case"MT":var line=new SO.Line(x,bottomY,x+width,bottomY);shapes.push(line);shapes.push(new SO.Ellipse(x+wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));break;case"MU":var muPath=new SO.Path();muPath.moveTo(x,bottomY);muPath.lineTo(x+5,bottomY+5);muPath.lineTo(x+width,bottomY+5);shapes.push(muPath);break;case"MV":var path=new SO.Path();path.moveTo(x,bottomY);path.bezierCurveTo(x,bottomY,x-rrArcWidth,bottomY+3,x,bottomY+rrHeight);path.lineTo(x+width,bottomY+rrHeight);shapes.push(path);break;case"MW":centerX=Math.round(symbolBounds.getCenterX());var mwPath=new SO.Path();mwPath.moveTo(centerX,bottomY+rrHeight+2);mwPath.lineTo(centerX-3,bottomY);mwPath.lineTo(centerX-6,bottomY+rrHeight+2);mwPath.moveTo(centerX,bottomY+rrHeight+2);mwPath.lineTo(centerX+3,bottomY);mwPath.lineTo(centerX+6,bottomY+rrHeight+2);shapes.push(mwPath);break;case"MX":centerX=Math.round(symbolBounds.getCenterX());var line=new SO.Line(x+width,bottomY,x,bottomY);shapes.push(line);var quarterX=(centerX-x)/2;shapes.push(new SO.BCurve(x,bottomY,x+quarterX,bottomY+rrHeight,centerX+quarterX,bottomY+rrHeight,x+width,bottomY));break;case"MY":var incrementX=width/7,middleY=(bottomY+(rrHeight/2));var x=Math.round(x+(incrementX/2));var r=Math.round(incrementX/2);var path=new SO.Path();path.arc(x,middleY,r,180,0);path.arc(x+incrementX,middleY,r,180,0,true);path.arc(x+incrementX*2,middleY,r,180,0);path.arc(x+incrementX*3,middleY,r,180,0,true);path.arc(x+incrementX*4,middleY,r,180,0);path.arc(x+incrementX*5,middleY,r,180,0,true);path.arc(x+incrementX*6,middleY,r,180,0);shapes.push(path);break;default:break;}} -else if(symbolID.charAt(10)===("N")){var offsetY=1;centerX=symbolBounds.getCenterX();var squareOffset=Math.round(wheelSize/2);middleY=((rrHeight/2)+bottomY)+offsetY;if(symbolID.substring(10,12)===("NS")) -{shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1,bottomY+rrHeight+3));shapes.push(new SO.Line(x,middleY,x+width,middleY));shapes.push(new SO.Rectangle(x-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset),bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(x+width-squareOffset,bottomY+offsetY,5,5));} -else if(symbolID.substring(10,12)===("NL")) -{var leftX=x+(centerX-x)/2,rightX=centerX+(x+width-centerX)/2;shapes.push(new SO.Line(leftX,bottomY-1,leftX,bottomY+rrHeight+3));shapes.push(new SO.Line(rightX,bottomY-1,rightX,bottomY+rrHeight+3));shapes.push(new SO.Line(x,middleY,x+width,middleY));shapes.push(new SO.Rectangle(x-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(centerX-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(x+width-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(leftX-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(rightX-squareOffset,bottomY+offsetY,5,5));}} -if(shapes!==null&&shapes.length>0) -{mobilityBounds=shapes[0].getBounds();var size=shapes.length;var tempShape=null;for(var i=1;isymbolBounds.getX()+symbolBounds.getWidth()))) -{y=Math.round(symbolBounds.getY()-amOffset),x=echelonBounds.getX()+echelonBounds.getWidth();} -else -{y=Math.round(symbolBounds.getY()-amOffset),x=Math.round(symbolBounds.getX()+symbolBounds.getWidth());} -tiAM.setLocation(x,y);tiAM.getTextBounds().shiftBR(0+outlineOffset,Math.round(-(amBounds.getHeight()*0.3)));amBounds=tiAM.getTextOutlineBounds();amBounds.shift(0,-outlineOffset);tiAM.setLocation(x,y-outlineOffset);imageBounds.union(amBounds);} -var tfBounds=null,tfRectangle=null;if(SymbolUtilities.isTaskForce(symbolID)) -{if(echelonBounds!==null) -{tfRectangle=new SO.Rectangle(echelonBounds.getX()-1,echelonBounds.getY()-1,echelonBounds.getWidth()+3,echelonBounds.getHeight()+3);tfBounds=new SO.Rectangle(echelonBounds.getX()-2,echelonBounds.getY()-2,echelonBounds.getWidth()+5,echelonBounds.getHeight()+4);} -else -{var height=Math.round(symbolBounds.getHeight()/4),width=Math.round(symbolBounds.getWidth()/3);tfRectangle=new SO.Rectangle(symbolBounds.getX()+width,symbolBounds.getY()-height,width,height);tfBounds=new SO.Rectangle(tfRectangle.getX()+-1,tfRectangle.getY()-1,tfRectangle.getWidth()+2,tfRectangle.getWidth()+2);} -imageBounds.union(tfBounds);} -var fdiBounds=null,fdiTop=null,fdiLeft=null,fdiRight=null;if(SymbolUtilities.isFeintDummy(symbolID)||SymbolUtilities.isFeintDummyInstallation(symbolID)) -{fdiLeft=new SO.Point(symbolBounds.getX(),symbolBounds.getY());fdiRight=new SO.Point(symbolBounds.getX()+symbolBounds.getWidth(),symbolBounds.getY());var affiliation=symbolID.charAt(1);if(affiliation===("F")||affiliation===("A")||affiliation===("D")||affiliation===("M")||affiliation===("J")||affiliation===("K")) -{fdiTop=new SO.Point(Math.round(symbolBounds.getCenterX()),Math.round(symbolBounds.getY()-(symbolBounds.getHeight()*.75)));} -else -{fdiTop=new SO.Point(Math.round(symbolBounds.getCenterX()),Math.round(symbolBounds.getY()-(symbolBounds.getHeight()*.54)));} -fdiBounds=new SO.Rectangle(fdiLeft.getX(),fdiLeft.getY(),1,1);fdiBounds.unionPoint(fdiTop);fdiBounds.unionPoint(fdiRight);if(echelonBounds!==null) -{var shiftY=(symbolBounds.getY()-echelonBounds.getHeight()-2);fdiLeft.shift(0,shiftY);fdiTop.shift(0,shiftY);fdiRight.shift(0,shiftY);fdiBounds.shift(0,shiftY);} -imageBounds.union(fdiBounds);} -var instRectangle=null,instBounds=null;if(SymbolUtilities.hasInstallationModifier(symbolID)) -{var affiliation=SymbolUtilities.getAffiliation(symbolID);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') -{height=Math.round(symbolBounds.getHeight()/4);width=Math.round(symbolBounds.getWidth()/3);} -else if(affiliation==='H'||affiliation==='S') -{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} -else if(affiliation==='N'||affiliation==='L') -{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} -else -{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} -if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K'||affiliation==='N'||affiliation==='L') -{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,symbolBounds.getY()-height,width,height);} -else if(affiliation==='H'||affiliation==='S') -{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,Math.round(symbolBounds.getY()-(height*0.15)),width,height);} -else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') -{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,Math.round(symbolBounds.getY()-(height*0.3)),width,height);} -else -{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,Math.round(symbolBounds.getY()-(height*0.3)),width,height);} -instBounds=new SO.Rectangle(instRectangle.getX()+-1,instRectangle.getY()-1,instRectangle.getWidth()+2,instRectangle.getWidth()+2);imageBounds.union(instBounds);} -var hqBounds=null;if(SymbolUtilities.isHQ(symbolID)) -{var pt1HQ=null,pt2HQ=null,affiliation=symbolID.charAt(1);if(affiliation===("F")||affiliation===("A")||affiliation===("D")||affiliation===("M")||affiliation===("J")||affiliation===("K")||affiliation===("N")||affiliation===("L")) -{pt1HQ=new SO.Point(symbolBounds.getX()+1,symbolBounds.getY()+symbolBounds.getHeight());pt2HQ=new SO.Point(pt1HQ.getX(),pt1HQ.getY()+symbolBounds.getHeight());} -else -{pt1HQ=new SO.Point(symbolBounds.getX()+1,symbolBounds.getY()+(symbolBounds.getHeight()/2));pt2HQ=new SO.Point(pt1HQ.getX(),pt1HQ.getY()+symbolBounds.getHeight());} -hqBounds=new SO.Rectangle(pt1HQ.getX(),pt1HQ.getY(),2,pt2HQ.getY()-pt1HQ.getY());imageBounds.shiftBR(0,pt2HQ.getY()-imageBounds.getBottom());centerPoint.setLocation(pt2HQ.getX(),pt2HQ.getY());} -var domPoints=null,domBounds=null;if(modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT]!==undefined) -{var q=modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT];var isY=(modifiers[ModifiersUnits.Y_LOCATION]!==undefined);domPoints=this.createDOMArrowPoints(symbolID,symbolBounds,centerPoint,q,isY);domBounds=new SO.Rectangle(domPoints[0].getX(),domPoints[0].getY(),1,1);var temp=null;for(var i=1;i<6;i++) -{temp=domPoints[i];if(temp!==null) -domBounds.unionPoint(temp);} -imageBounds.union(domBounds);} -var ociBounds=null;var ociOffset=2;if(mobilityBounds!==null) -{ociOffset=Math.round(mobilityBounds.bottom-symbolBounds.bottom)+2;} -var ociShape=this.processOperationalConditionIndicator(symbolID,symbolBounds,ociOffset);if(ociShape!==null) -{ociBounds=ociShape.getBounds();} -imageBounds.union(ociBounds);if(imageBounds.getX()<0||imageBounds.getY()<0) -{var shiftX=Math.abs(imageBounds.getX()),shiftY=Math.abs(imageBounds.getY());if(hqBounds!==null) -{pt1HQ.shift(shiftX,shiftY);pt2HQ.shift(shiftX,shiftY);} -if(echelonBounds!==null) -{tiEchelon.setLocation(tiEchelon.getLocation().getX()+shiftX,tiEchelon.getLocation().getY()+shiftY);} -if(amBounds) -{tiAM.setLocation(tiAM.getLocation().getX()+shiftX,tiAM.getLocation().getY()+shiftY);} -if(tfBounds!==null) -{tfRectangle.shift(shiftX,shiftY);tfBounds.shift(shiftX,shiftY);} -if(instBounds!==null) -{instRectangle.shift(shiftX,shiftY);instBounds.shift(shiftX,shiftY);} -if(fdiBounds!==null) -{fdiBounds.shift(shiftX,shiftY);fdiLeft.shift(shiftX,shiftY);fdiTop.shift(shiftX,shiftY);fdiRight.shift(shiftX,shiftY);} -if(ociBounds!==null) -{ociBounds.shift(shiftX,shiftY);ociShape.shift(shiftX,shiftY);} -if(domBounds!==null) -{for(var i=0;i<6;i++) -{temp=domPoints[i];if(temp!==null) -temp.shift(shiftX,shiftY);} -domBounds.shift(shiftX,shiftY);} -if(mobilityBounds!==null) -{var size=shapes.length;var tempShape=null;for(var i=0;i19) -{ctx.setLineDash([6,4]);} -else -{ctx.setLineDash([5,3]);} -ctx.lineCap="butt";ctx.lineJoin="miter";ctx.strokeStyle="#000000";ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(fdiLeft.getX(),fdiLeft.getY());ctx.lineTo(fdiTop.getX(),fdiTop.getY());ctx.lineTo(fdiRight.getX(),fdiRight.getY());ctx.stroke();ctx.setLineDash(oldDash);fdiBounds=null;} -if(mobilityBounds!==null) -{if(symbolID.charAt(10)===("M")) -{ctx.lineWidth=2;ctx.strokeStyle="#000000";ctx.fillStyle="#000000";} -else -{ctx.lineWidth=1;ctx.strokeStyle="#000000";ctx.fillStyle="#000000";} -var size=shapes.length;var tempShape=null;for(var i=0;i0) -barSize=Math.round(pixelSize/5);if(barSize<2) -barSize=2;offsetY+=Math.round(symbolBounds.getY()+symbolBounds.getHeight());bar=new SO.Rectangle(symbolBounds.getX()+1,offsetY,Math.round(symbolBounds.getWidth())-2,barSize);} -return bar;},processUnitModifiers:function(ii,symbolID,modifiers){var render=true;if(modifiers["RENDER"]!==undefined) -render=modifiers["RENDER"];var bufferXL=5,bufferXR=5,bufferY=2,bufferText=2,x=0,y=0,cpofNameX=0,newii=null;var tiArray=new Array(),descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj"),bounds=null,labelBounds=null,labelWidth,labelHeight;var bounds=ii.getSymbolBounds().clone(),symbolBounds=ii.getSymbolBounds().clone(),centerPoint=ii.getCenterPoint(),imageBounds=ii.getImageBounds().clone(),imageBoundsOld=ii.getImageBounds().clone();var echelon=SymbolUtilities.getEchelon(symbolID),echelonText=SymbolUtilities.getEchelonText(echelon),amText=SymbolUtilities.getUnitAffiliationModifier(symbolID,symStd);if(modifiers.Q===undefined) -{bounds=new SO.Rectangle(imageBounds.getX(),symbolBounds.getY(),imageBounds.getWidth(),symbolBounds.getHeight());} -else -{if(echelonText!==null||amText!==null) -{bounds=new SO.Rectangle(imageBounds.getX(),bounds.getY(),imageBounds.getWidth(),bounds.getHeight());} -else if(symbolID.substring(10,12)==="MR") -{x=-(Math.round((symbolBounds.getWidth()-1)/7)*2);if(xmaxHeight) -byLabelHeight=true;var symStd=modifiers[MilStdAttributes.SymbologyStandard]||RendererSettings.getSymbologyStandard();var affiliationModifier=null;if(RendererSettings.getDrawAffiliationModifierAsLabel()) -{affiliationModifier=SymbolUtilities.getUnitAffiliationModifier(symbolID,symStd);} -if(affiliationModifier!==null) -{modifiers[ModifiersUnits.E_FRAME_SHAPE_MODIFIER]=affiliationModifier;} -if(SymbolUtilities.hasValidCountryCode(symbolID)) -{modifiers[ModifiersUnits.CC_COUNTRY_CODE]=symbolID.substring(12,14);} -var modifierValue=null;var tiTemp=null;if(modifiers.C!==undefined&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.C_QUANTITY)) -{var text=modifiers[ModifiersUnits.C_QUANTITY];tiTemp=new TextInfo(text,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=Math.round((symbolBounds.x+(symbolBounds.width*0.5))-(labelWidth*0.5));y=Math.round(symbolBounds.y-bufferY-descent);tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.X!==undefined||modifiers.Y!==undefined) -{modifierValue=null;var xm=null,ym=null;if(modifiers.X!==undefined) -xm=modifiers.X;if(modifiers.Y!==undefined) -ym=modifiers.Y;if(xm===null&&ym!==null) -modifierValue=ym;else if(xm!==null&&ym===null) -modifierValue=xm;else if(xm!==null&&ym!==null) -modifierValue=xm+" "+ym;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) -{x=bounds.x-labelBounds.width-bufferXL;y=bounds.y+labelHeight-descent;} -else -{x=bounds.x-labelBounds.width-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText));y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.G!==undefined&&modifiers.G!==null) -{modifierValue=modifiers.G;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) -{x=bounds.x+bounds.width+bufferXR;y=bounds.y+labelHeight-descent;} -else -{x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText));y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) -cpofNameX=x+labelWidth+3;} -if(modifiers.V!==undefined) -{modifierValue=modifiers.V;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x-labelBounds.width-bufferXL;y=(bounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.H!==undefined) -{modifierValue=modifiers.H;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) -cpofNameX=x+labelWidth+3;} -if(modifiers.T!==undefined) -{modifierValue=modifiers[ModifiersUnits.T_UNIQUE_DESIGNATION_1];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) -{x=bounds.x-labelWidth-bufferXL;y=bounds.y+bounds.height;} -else -{x=bounds.x-labelWidth-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText));y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.M!==undefined||modifiers.CC!==undefined) -{modifierValue="";if(modifiers[ModifiersUnits.M_HIGHER_FORMATION]) -modifierValue+=modifiers[ModifiersUnits.M_HIGHER_FORMATION];if(modifiers[ModifiersUnits.CC_COUNTRY_CODE]) -{if(modifiers[ModifiersUnits.M_HIGHER_FORMATION]) -modifierValue+=" ";modifierValue+=modifiers[ModifiersUnits.CC_COUNTRY_CODE];} -tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) -y=bounds.y+bounds.height;else -{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText));y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) -cpofNameX=x+labelWidth+3;} -if(modifiers.Z!==undefined) -{modifierValue=modifiers[ModifiersUnits.Z_SPEED];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) -y=Math.round(bounds.y+bounds.height+labelHeight+bufferText);else -{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.J!==undefined||modifiers.K!==undefined||modifiers.L!==undefined||modifiers.N!==undefined||modifiers.P!==undefined) -{modifierValue=null;var jm=null,km=null,lm=null,nm=null,pm=null;if(modifiers.J!==undefined) -jm=modifiers[ModifiersUnits.J_EVALUATION_RATING];if(modifiers.K!==undefined) -km=modifiers[ModifiersUnits.K_COMBAT_EFFECTIVENESS];if(modifiers.L!==undefined) -lm=modifiers[ModifiersUnits.L_SIGNATURE_EQUIP];if(modifiers.N!==undefined) -nm=modifiers[ModifiersUnits.N_HOSTILE];if(modifiers.P!==undefined) -pm=modifiers[ModifiersUnits.P_IFF_SIF];modifierValue="";if(jm!==null&&jm!==("")) -modifierValue=modifierValue+jm;if(km!==null&&km!==("")) -modifierValue=modifierValue+" "+km;if(lm!==null&&lm!==("")) -modifierValue=modifierValue+" "+lm;if(nm!==null&&nm!==("")) -modifierValue=modifierValue+" "+nm;if(pm!==null&&pm!==("")) -modifierValue=modifierValue+" "+pm;if(modifierValue.charAt(0)===" ") -modifierValue=modifierValue.substring(1);tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) -y=Math.round(bounds.y+bounds.height+labelHeight+bufferText);else -{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) -cpofNameX=x+labelWidth+3;} -if(modifiers.W!==undefined) -{modifierValue=modifiers[ModifiersUnits.W_DTG_1];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) -{x=bounds.x-labelWidth-bufferXL;y=bounds.y-bufferY-descent;} -else -{x=bounds.x-labelWidth-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText)*2);y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.F!==undefined||modifiers.E!==undefined) -{modifierValue=null;var E=null,F=null;if(modifiers.E!==undefined) -E=modifiers[ModifiersUnits.E_FRAME_SHAPE_MODIFIER];if(modifiers.F!==undefined) -F=modifiers[ModifiersUnits.F_REINFORCED_REDUCED];if(E!==null&&E!==("")) -modifierValue=E;if(F!==null&&F!==("")) -{if(F.toUpperCase()===("R")) -F="(+)";else if(F.toUpperCase()===("D")) -F="(-)";else if(F.toUpperCase()===("RD")) -F="("+String.fromCharCode(177)+")";else -F=null;} -if(F!==null&&F!==("")) -{if(modifierValue!==null&&modifierValue!==("")) -modifierValue=modifierValue+" "+F;else -modifierValue=F;} -tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) -{x=bounds.x+bounds.width+bufferXR;y=bounds.y-bufferY-descent;} -else -{x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText)*2);y=bounds.y+y;} -tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) -cpofNameX=x+labelWidth+3;} -if(modifiers.AA!==undefined) -{modifierValue=modifiers[ModifiersUnits.AA_SPECIAL_C2_HQ];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=(symbolBounds.x+(symbolBounds.width*0.5))-(labelWidth*0.5);y=(symbolBounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=symbolBounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -if(modifiers.CN!==undefined) -{modifierValue=modifiers[ModifiersUnits.CN_CPOF_NAME_LABEL];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=cpofNameX;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} -var modifierBounds=null;if(tiArray!==null&&tiArray.length>0) -{modifierBounds=tiArray[0].getTextOutlineBounds();var size=tiArray.length;var tempShape=null;for(var i=1;i2) -outlineOffset=(outlineOffset-1)/2;else -outlineOffset=0;var spli=SinglePointLookup.getSPLookupInfo(symbolID,symStd);if(spli===null) -{if(modifiers===null) -modifiers={};if(modifiers.H!==undefined) -modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2]=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];modifiers[ModifiersTG.H_ADDITIONAL_INFO_1]=symbolID.substring(0,10);symbolID="G"+SymbolUtilities.getAffiliation(symbolID)+"G"+SymbolUtilities.getStatus(symbolID)+"GPP---****X";spli=SinglePointLookup.getSPLookupInfo(symbolID,symStd);} -if(symbolID.charAt(1).toUpperCase()==="H") -{modifiers[ModifiersTG.N_HOSTILE]="ENY";} -var symbolBounds=null,rect=null;var ratio=1;if(pixelSize>0) -{symbolBounds=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);rect=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);if(keepUnitRatio===true) -{if(fontSize===80) -{scale=pixelSize/35.0;} -else if(fontSize===60) -{scale=pixelSize/35.0;} -else if(fontSize===100) -{scale=pixelSize/35.0;} -else if(fontSize===120) -{scale=pixelSize/35.0;} -else -{scale=pixelSize/35.0;}} -ratio=Math.min((pixelSize/rect.getHeight()),(pixelSize/rect.getWidth()));} -if(scale!==-999) -{ratio=scale;} -if(ratio>0) -{fontSize=fontSize*ratio;} -if(pixelSize>0) -{symbolBounds=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);fontSize=(((fontSize)/96)*72);strSPFont=fontSize+"pt SinglePoint";} -else -{symbolBounds=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);fontSize=((fontSize/96)*72);strSPFont=fontSize+"pt SinglePoint";} -this.checkModifierFont();intFrame=SinglePointLookup.getCharCodeFromSymbol(symbolID,symStd);var fillID=null;if(SymbolUtilities.hasDefaultFill(symbolID)&&fillColor===null) -{fillColor=SymbolUtilities.getFillColorOfAffiliation(symbolID).toHexString(false);} -if(SymbolUtilities.isTGSPWithFill(symbolID)) -{fillID=SymbolUtilities.getTGFillSymbolCode(symbolID);if(fillID!==null) -intFill=SinglePointLookup.getCharCodeFromSymbol(fillID,symStd);} -else if(SymbolUtilities.isWeatherSPWithFill(symbolID)) -{intFill=intFrame+1;fillColor=SymbolUtilities.getFillColorOfWeather(symbolID).toHexString(false);} -if(intFill>0) -fill=String.fromCharCode(intFill);frame=String.fromCharCode(intFrame);var symbolWidth=Math.round(symbolBounds.getWidth())+(outlineOffset*2),symbolHeight=Math.round(symbolBounds.getHeight())+(outlineOffset*2);if(render===true) -{if(hasDisplayModifiers===true||hasTextModifiers===true) -{buffer=_bufferSymbol;ctx=buffer.getContext('2d');ctx.clearRect(0,0,_bufferSymbolSize,_bufferSymbolSize);} -else -{buffer=this.createBuffer(symbolWidth,symbolHeight);ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;} -ctx.font=strSPFont;} -var x=Math.round(symbolBounds.getWidth()/2),y=Math.round(symbolBounds.getHeight()/2);var centerPoint=SymbolDimensions.getSymbolCenter(symbolID,symbolBounds);x=centerPoint.getX();y=centerPoint.getY();if(outlineOffset>0) -{x+=outlineOffset;y+=outlineOffset;symbolBounds.shift(outlineOffset,outlineOffset);symbolBounds.grow(outlineOffset);} -if(render===true) -{if(frame!==null&&frame!=="") -{if(outlineOffset>0) -{ctx.lineWidth=symbolOutlineWidth;ctx.strokeStyle=RendererUtilities.getIdealOutlineColor(lineColor);ctx.strokeText(frame,x,y);}} -if(fill!==null&&fill!==""&&fillColor!==null) -{ctx.fillStyle=fillColor;ctx.fillText(fill,x,y);} -if(frame!==null&&frame!=="") -{ctx.fillStyle=lineColor;ctx.fillText(frame,x,y);}} -var imageBounds=new SO.Rectangle(0,0,symbolWidth,symbolHeight);var ii=new ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);var iiNew=null;if(icon===false&&(hasTextModifiers||hasDisplayModifiers||SymbolUtilities.isTGSPWithIntegralText(symbolID))) -{if(SymbolUtilities.isTGSPWithSpecialModifierLayout(symbolID)||SymbolUtilities.isTGSPWithIntegralText(symbolID)) -{iiNew=this.ProcessTGSPWithSpecialModifierLayout(ii,symbolID,modifiers);} -else -{iiNew=this.ProcessTGSPModifiers(ii,symbolID,modifiers);}} -if(iiNew) -ii=iiNew;ctx=null;buffer=null;if(icon) -return ii.getSquareImageInfo();else -return ii;},ProcessTGSPWithSpecialModifierLayout:function(ii,symbolID,modifiers){var render=true;if(modifiers["RENDER"]!==undefined) -render=modifiers["RENDER"];var bufferXL=6,bufferXR=4,bufferY=2,bufferText=2,centerOffset=1,x=0,y=0,x2=0,y2=0,symStd=modifiers[MilStdAttributes.SymbologyStandard]||RendererSettings.getSymbologyStandard(),outlineOffset=RendererSettings.getTextOutlineWidth(),labelHeight=0,labelWidth=0,newii=null;var arrMods=new Array();var duplicate=false;var symbolBounds=ii.getSymbolBounds().clone(),bounds=ii.getSymbolBounds().clone(),imageBounds=ii.getImageBounds().clone(),centerPoint=ii.getCenterPoint().clone();centerPoint=new SO.Point(Math.round(ii.getCenterPoint().getX()),Math.round(ii.getCenterPoint().getY()));var byLabelHeight=false;labelHeight=RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle()).fullHeight;labelHeight=Math.round(labelHeight);var maxHeight=(symbolBounds.getHeight());if((labelHeight*3)>maxHeight) -byLabelHeight=true;var descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj");var yForY=-1;var labelBounds1=null,labelBounds2=null,strText="",strText1="",strText2="",text1=null,text2=null;var basicID=SymbolUtilities.getBasicSymbolID(symbolID);if(outlineOffset>2) -outlineOffset=((outlineOffset-1)/2);else -outlineOffset=0;if(basicID===("G*G*GPRD--****X")) -{strText1="D";text1=new TextInfo(strText1,0,0,textInfoContext);labelBounds1=text1.getTextBounds();if(symStd===RendererSettings.Symbology_2525Bch2_USAS_13_14) -{y=symbolBounds.getY()+symbolBounds.getHeight();x=symbolBounds.getX()-labelBounds1.getWidth()-bufferXL;text1.setLocation(Math.round(x),Math.round(y));} -else -{text1=null;}} -else if(basicID===("G*G*APU---****X")) -{strText1="PUP";text1=new TextInfo(strText1,0,0,textInfoContext);labelBounds1=text1.getTextBounds();y=symbolBounds.getCenterY()+((labelBounds1.getHeight()-descent)/2);x=symbolBounds.getX()+symbolBounds.getWidth()+bufferXR;text1.setLocation(Math.round(x),Math.round(y));} -else if(basicID===("G*M*NZ----****X")) -{} -else if(basicID===("G*M*NF----****X")) -{} -else if(basicID===("G*M*NEB---****X")) -{var offset=1;strText2="BIO";text2=new TextInfo(strText2,0,0,textInfoContext);labelBounds2=text2.getTextBounds();y2=symbolBounds.getCenterY()+((labelBounds2.getHeight()-descent)*0.5);x2=symbolBounds.getX()-labelBounds2.getWidth()-bufferXL;text2.setLocation(Math.round(x2),Math.round(y2-offset));} -else if(basicID===("G*M*NEC---****X")) -{var offset=1;strText2="CML";text2=new TextInfo(strText2,0,0,textInfoContext);labelBounds2=text2.getTextBounds();y2=symbolBounds.getCenterY()+((labelBounds2.getHeight()-descent)/2);x2=symbolBounds.getX()-labelBounds2.getWidth()-bufferXL;text2.setLocation(Math.round(x2),Math.round(y2-offset));} -if(text1!==null) -{arrMods.push(text1);} -if(text2!==null) -{arrMods.push(text2);} -var ti=null;if(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")) -{if((labelHeight*3)>bounds.getHeight()) -byLabelHeight=true;} -if(basicID===("G*G*GPH---****X")||basicID===("G*G*GPPC--****X")||basicID===("G*G*GPPD--****X")) -{if(modifiers.H!==undefined) -{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*G*GPRI--****X")) -{if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.25);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*G*GPPW--****X")||basicID===("G*F*PCF---****X")) -{if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+(bounds.width*0.75);y=bounds.y+(bounds.height*0.5);y=y+((labelHeight-descent)*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*G*APP---****X")||basicID===("G*G*APC---****X")) -{if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);var labelWidth=ti.getTextBounds().getWidth();x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y+(((bounds.height*0.5)-labelHeight)/2)+labelHeight-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*G*DPT---****X")||basicID===("G*F*PTS---****X")||basicID===("G*F*PTN---****X")) -{if(modifiers.H!==undefined&&basicID===("G*F*PTS---****X")) -{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.getCenterX()+(bounds.width*0.15);y=bounds.y+(bounds.height*0.75);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.H1!==undefined&&basicID===("G*F*PTS---****X")) -{strText=modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.getCenterX()-(bounds.width*0.15);x=x-(labelWidth);y=bounds.y+(bounds.height*0.75);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.getCenterX()+(bounds.width*0.15);y=bounds.y+(bounds.height*0.25);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")) -{if(modifiers.N!==undefined) -{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) -{y=bounds.y+bounds.height;} -else -{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+(labelHeight-descent+bufferText));} -ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.H!==undefined) -{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) -{y=bounds.y+labelHeight-descent;} -else -{y=bounds.y+((bounds.height*0.5)-((labelHeight-descent)*0.5)+(-descent-bufferText));} -ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.W!==undefined) -{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) -{y=bounds.y+labelHeight-descent;} -else -{y=bounds.y+((bounds.height*0.5)-((labelHeight-descent)*0.5)+(-descent-bufferText));} -ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.V!==undefined&&basicID===("G*M*NZ----****X")) -{strText=modifiers[ModifiersTG.V_EQUIP_TYPE];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5));ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) -{y=bounds.y+bounds.height;} -else -{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+(labelHeight-descent+bufferText));} -ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.Y!==undefined) -{strText=modifiers[ModifiersTG.Y_LOCATION];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);if(!byLabelHeight) -{y=bounds.y+bounds.height+labelHeight-descent+bufferY;} -else -{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+((labelHeight+bufferText)*2)-descent);} -yForY=y+descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.C!==undefined) -{strText=modifiers[ModifiersTG.C_QUANTITY];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} -else if(basicID===("G*M*OFS---****X")) -{if(modifiers.H!==undefined) -{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.W!==undefined) -{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height);y=y+(labelHeight);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} -if(modifiers.N!==undefined) -{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);var ti2=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width)+bufferXR;duplicate=true;x2=bounds.x;x2=x2-labelWidth-bufferXL;y=bounds.y+(bounds.height*0.5);y=y+((labelHeight-descent)*0.5);y2=y;ti.setLocation(Math.round(x),Math.round(y));ti2.setLocation(Math.round(x2),Math.round(y2));arrMods.push(ti);arrMods.push(ti2);}} -var domPoints=null,domBounds=null;if(modifiers[ModifiersTG.Q_DIRECTION_OF_MOVEMENT]!==undefined&&(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X"))) -{var q=modifiers[ModifiersTG.Q_DIRECTION_OF_MOVEMENT];var tempBounds=bounds.clone();tempBounds.unionPoint(new SO.Point(bounds.getCenterX(),yForY));domPoints=this.createDOMArrowPoints(symbolID,tempBounds,ii.getCenterPoint(),q,false);domBounds=new SO.Rectangle(domPoints[0].getX(),domPoints[0].getY(),1,1);var temp=null;for(var i=1;i<6;i++) -{temp=domPoints[i];if(temp!==null) -domBounds.unionPoint(temp);} -imageBounds.union(domBounds);} -var modifierBounds=null;if(arrMods!==null&&arrMods.length>0) -{modifierBounds=arrMods[0].getTextOutlineBounds();var size=arrMods.length;var tempShape=null;for(var i=1;imaxHeight) -byLabelHeight=true;var descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj");var yForY=-1;var labelBounds1=null,labelBounds2=null,strText="",strText1="",strText2="",text1=null,text2=null;var basicID=SymbolUtilities.getBasicSymbolID(symbolID);if(outlineOffset>2) -outlineOffset=((outlineOffset-1)/2);else -outlineOffset=0;var ti=null;{if(modifiers.N!==undefined) -{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) -{y=((bounds.height/3)*2);y=bounds.y+y;} -else -{y=bounds.y+bounds.height;} -ti.setLocation(x,y);arrMods.push(ti);} -if(modifiers.H!==undefined) -{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(x,y);arrMods.push(ti);} -if(modifiers.H1!==undefined) -{strText=modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+labelHeight+(bounds.height*0.2);ti.setLocation(x,y);arrMods.push(ti);} -if(modifiers.W!==undefined) -{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=bounds.y+labelHeight-descent;ti.setLocation(x,y);arrMods.push(ti);} -if(modifiers.W1!==undefined) -{strText=modifiers[ModifiersTG.W1_DTG_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=((labelHeight-descent+bufferText)*2);y=bounds.y+y;ti.setLocation(x,y);arrMods.push(ti);} -if(modifiers.T!==undefined) -{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;y=bounds.y+labelHeight-descent;ti.setLocation(x,y);arrMods.push(ti);} -if((modifiers.T1!==undefined)&&(basicID===("G*O*ES----****X")||basicID===("G*S*PP----****X")||basicID===("G*S*PX----****X"))) -{strText=modifiers[ModifiersTG.T1_UNIQUE_DESIGNATION_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=((bounds.height*0.60));y=bounds.y+y;ti.setLocation(x,y);arrMods.push(ti);}} -var modifierBounds=null;if(arrMods!==null&&arrMods.length>0) -{modifierBounds=arrMods[0].getTextOutlineBounds();var size=arrMods.length;var tempShape=null;for(var i=1;i0) -{ctx.lineWidth=RendererSettings.getTextOutlineWidth();ctx.fillStyle=outlineStyle;ctx.strokeStyle=outlineStyle;for(var i=0;i0) -ctx.lineWidth=(outlineWidth*2)+1;ctx.fillStyle=fillStyle;ctx.strokeStyle=outlineStyle;for(var i=0;i0) -{tempShape.strokeText(ctx);} -tempShape.fillText(ctx);}}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.MilStdIconRenderer=(function(){var MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,UnitDefTable=armyc2.c2sd.renderer.utilities.UnitDefTable,UnitFontLookup=armyc2.c2sd.renderer.utilities.UnitFontLookup,SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,SinglePointRenderer=armyc2.c2sd.renderer.SinglePointRenderer,TacticalGraphicIconRenderer=armyc2.c2sd.renderer.TacticalGraphicIconRenderer,initialized=false;try -{if(initialized===false) -{UnitDefTable.init();SymbolDefTable.init();armyc2.c2sd.renderer.utilities.SinglePointLookup.init();armyc2.c2sd.renderer.utilities.UnitFontLookup.init();armyc2.c2sd.renderer.utilities.TacticalGraphicLookup.init();if(UnitDefTable.hasSymbolMap(RendererSettings.Symbology_2525Bch2_USAS_13_14)===false) -{RendererSettings.setSymbologyStandard(RendererSettings.Symbology_2525C);} -initialized=true;}} -catch(err) -{err.message+=" - MilStdIconRenderer failed to initialize";armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdIconRenderer","Init",err);} -function renderTacticalMultipointIcon(symbolID,modifiers) -{var lineColor=SymbolUtilities.getLineColorOfAffiliation(symbolID);if(modifiers[MilStdAttributes.LineColor]!==undefined) -{lineColor=modifiers[MilStdAttributes.LineColor];} -var size=RendererSettings.getDefaultPixelSize();if(modifiers[MilStdAttributes.PixelSize]!==undefined) -{size=modifiers[MilStdAttributes.PixelSize];} -var ii=TacticalGraphicIconRenderer.getIcon(symbolID,size,lineColor);return ii;} -return{CanRender:function(){},Render:function(symbolID,modifiers){if(!(modifiers)) -{modifiers={};} -var symStd=0;if(modifiers[MilStdAttributes.SymbologyStandard]) -{symStd=modifiers[MilStdAttributes.SymbologyStandard];} -else -{symStd=RendererSettings.getSymbologyStandard();modifiers[MilStdAttributes.SymbologyStandard]=symStd;} -var basicID=SymbolUtilities.getBasicSymbolID(symbolID);if(SymbolUtilities.isTacticalGraphic(symbolID)) -{var sd=SymbolDefTable.getSymbolDef(basicID,symStd);if(sd===null) -{symbolID=SymbolUtilities.reconcileSymbolID(symbolID);basicID=SymbolUtilities.getBasicSymbolID(symbolID);sd=SymbolDefTable.getSymbolDef(basicID);} -if(sd!==null&&sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_POINT) -{return armyc2.c2sd.renderer.SinglePointRenderer.renderSPTG(symbolID,modifiers);} -else -{return renderTacticalMultipointIcon(symbolID,modifiers);}} -else if(UnitFontLookup.hasUnitLookup(basicID,symStd)) -{return SinglePointRenderer.renderUnit(symbolID,modifiers);} -else if(SymbolUtilities.is3dAirspace(symbolID)) -{return renderTacticalMultipointIcon(symbolID,modifiers);} -else -{symbolID=SymbolUtilities.reconcileSymbolID(symbolID,false);return SinglePointRenderer.renderUnit(symbolID,modifiers);}}};}());var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.utilities=sec.web.renderer.utilities||{};sec.web.renderer.utilities.JavaRendererUtilities={};sec.web.renderer.utilities.JavaRendererUtilities.getBrowserEngine=function() -{var ua=navigator.userAgent;if(ua.indexOf("Trident")>0) -return"Trident";else if(ua.indexOf("AppleWebKit")>0) -return"AppleWebKit";else if(ua.indexOf("Gecko")>0&&ua.indexOf("Firefox")>0) -return"Gecko";else -return"Other";};sec.web.renderer.utilities.JavaRendererUtilities.ARGBtoABGR=function(rgbString) -{var c=rgbString.split('');var temp1=c[2];var temp2=c[3];c[2]=c[6];c[3]=c[7];c[6]=temp1;c[7]=temp2;var returnVal=c.join("");return returnVal;};sec.web.renderer.utilities.JavaRendererUtilities.normalizeSymbolCode=function(symbolCode) -{var newSymbolCode=symbolCode;if(symbolCode.charAt(0)==="G"||symbolCode.charAt(0)==="S"){newSymbolCode=newSymbolCode.substring(0,1)+'*'+newSymbolCode.substring(2);newSymbolCode=newSymbolCode.substring(0,3)+'*'+newSymbolCode.substring(4);newSymbolCode=newSymbolCode.substring(0,10)+"****"+newSymbolCode.substring(14);} -if(symbolCode.charAt(0)===("S")){newSymbolCode=newSymbolCode.substring(0,14)+'*';} -return newSymbolCode;};sec.web.renderer.utilities.JavaRendererUtilities.ReconcileSymbolID=function(symbolID) -{var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;var sb="";var codingScheme=symbolID.charAt(0);if(symbolID!==null&&symbolID.length===15) -{if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') -{sb+=(codingScheme);if(SymbolUtilities.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));if(SymbolUtilities.hasValidBattleDimension(symbolID)===false) -{sb+=('Z');sb="S"+sb.substring(1);} -else -sb+=(symbolID.charAt(2));if(SymbolUtilities.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));} -else if(codingScheme==='G') -{sb+=(codingScheme);if(SymbolUtilities.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));sb+=('G');if(SymbolUtilities.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));sb+=("GPP---");sb+=(symbolID.substring(10,15));} -else if(codingScheme==='W') -{return"SUZP-----------";} -else -{sb+=('S');if(SymbolUtilities.hasValidAffiliation(symbolID)===false) -sb+=('U');else -sb+=(symbolID.charAt(1));if(SymbolUtilities.hasValidBattleDimension(symbolID)===false) -{sb+=('Z');sb="S"+sb.substring(1);} -else -sb+=(symbolID.charAt(2));if(SymbolUtilities.hasValidStatus(symbolID)===false) -sb+=('P');else -sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));}} -else -{return"SUZP-----------";} -return sb;};sec.web.renderer.utilities.JavaRendererUtilities.is3dSymbol=function(symbolCode,modifiers) -{var returnValue=false;try -{var symbolId=symbolCode.substring(4,10);if(symbolId===("ACAI--")||symbolId===("ACAR--")||symbolId===("ACAC--")||symbolId===("AKPC--")||symbolId===("AKPI--")||symbolId===("AKPR--")||symbolId===("AKPI--")||symbolId===("ALC---")||symbolId===("ALM---")||symbolId===("ALS---")||symbolId===("ALU---")||symbolId===("ALL---")||symbolId===("AAR---")||symbolId===("AAF---")||symbolId===("AAH---")||symbolId===("AAM---")||symbolId===("AAF---")||symbolId===("AAML--")||symbolId===("AAMH--")) -{try -{if(modifiers) -{if(modifiers.modifiers) -{modifiers=modifiers.modifiers;} -var jsonAltitudeArray=null;if(modifiers.X) -{jsonAltitudeArray=modifiers.X;} -else if(modifiers.altitudeDepth) -{jsonAltitudeArray=modifiers.altitudeDepth;} -if(jsonAltitudeArray&&jsonAltitudeArray.length>=2) -{returnValue=true;} -else -{returnValue=false;}}} -catch(je) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("JavaRendererUtilities","is3DSymbol()",je);}}} -catch(err) -{returnValue=false;} -return returnValue;};sec.web.renderer.utilities.JavaRendererUtilities.isNumber=function(text){var re=new RegExp("((-|\\+)?[0-9]+(\\.[0-9]+)?)+");return(re.test(text));};sec.web.renderer.utilities.JavaRendererUtilities.createParameterMapFromURL=function(SymbolInfo) -{var modifiers={},symbolID=null,parameters=null,key=null,value=null,arrParameters=null,arrKeyValue=null,temp=null,questionIndex=SymbolInfo.indexOf('?');if(this.be==="") -{this.be=this.getBrowserEngine();} -var be=this.be,tSpace=String.fromCharCode(8196),gSpace=String.fromCharCode(8192);if(questionIndex===-1) -symbolID=SymbolInfo;else -symbolID=SymbolInfo.substring(0,questionIndex);if(questionIndex>0&&(questionIndex+1180){longRem-=360;} -if(longRem<-180){longRem+=360;} -var metersPerDeg=this.GetMetersPerDegAtLat(latitude);var pixDis=(longRem*metersPerDeg)/metPerPix;return pixDis;},x2long:function(xPosition,scale,longOrigin,latitude,metPerPix){var metersPerDeg=this.GetMetersPerDegAtLat(latitude);var longitude=longOrigin+((xPosition*metPerPix)/metersPerDeg);if(longitude<-180){longitude+=360;}else if(longitude>180){longitude-=360;} -return longitude;},Deg2Rad:function(deg){var conv_factor=(2.0*Math.PI)/360.0;return(deg*conv_factor);},GetMetersPerDegAtLat:function(lat){lat=this.Deg2Rad(lat);var p1=111412.84;var p2=-93.5;var p3=0.118;var longlen=(p1*Math.cos(lat))+(p2*Math.cos(3*lat))+(p3*Math.cos(5*lat));return longlen;}};}());var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.MultiPointHandler=(function(){var ErrorLogger=armyc2.c2sd.renderer.utilities.ErrorLogger;var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;var ModifiersTG=armyc2.c2sd.renderer.utilities.ModifiersTG;var MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes;var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;var _appletChecked=false;var _appletUrl=null;var baseURL="http:"+"//"+location.hostname+":8080/",baseSURL=location.protocol+"//"+location.host+"/";var _decimalAccuracy=7;function hasRequiredModifiers(symbolID,dc,AM,AN) -{var message="";if((dc>=16&&dc<=20)) -{if(dc===SymbolDefTable.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE) -{if(AM!==null&&AM.length>0) -return{hasRequiredModifiers:true,message:true};else -{message+=symbolID+" requires a modifiers object that has 1 distance/AM value.";return{hasRequiredModifiers:false,message:message};}} -else if(dc===SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE) -{if(AM!==null&&AM.length>=2&&AN!==null&&AN.length>=1) -return{hasRequiredModifiers:true,message:true};else -{message+=symbolID+" requires a modifiers object that has 2 distance/AM values and 1 azimuth/AN value.";return{hasRequiredModifiers:false,message:message};}} -else if(dc===SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE) -{if(AM!==null&&AM.length>=2&&AN!==null&&AN.length>=2) -return{hasRequiredModifiers:true,message:true};else -{message+=symbolID+" requires a modifiers object that has 2 distance/AM values and 2 azimuth/AN values per sector. The first sector can have just one AM value although it is recommended to always use 2 values for each sector.";return{hasRequiredModifiers:false,message:message};}} -else if(dc===SymbolDefTable.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE) -{if(AM!==null&&AM.length>0) -return{hasRequiredModifiers:true,message:true};else -{message+=symbolID+" requires a modifiers object that has at least 1 distance/AM value";return{hasRequiredModifiers:false,message:message};}} -else if(dc===SymbolDefTable.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE) -{if(AM!==null&&AM.length>0) -return{hasRequiredModifiers:true,message:true};else -{message+=symbolID+" requires a modifiers object that has 1 distance/AM value.";return{hasRequiredModifiers:false,message:message};}} -else -{return{hasRequiredModifiers:true,message:true};}} -else -{return{hasRequiredModifiers:true,message:true};}};return{MODIFIER_HEADER:"modifiers",QUANTITY:"quantity",REINFORCE_OR_REDUCED:"reinforcedOrReduced",STAFF_COMMENTS:"staffComments",ADDITIONAL_INFO_1:"additionalInfo1",ADDITIONAL_INFO_2:"additionalInfo2",ADDITIONAL_INFO_3:"additionalInfo3",EVALUATION_RATION:"evaluationRating",COMBAT_EFFECTIVENESS:"combatEffectiveness",SIGNATURE_EQUIPMENT:"signatureEquipment",HIGHER_FORMATION:"higherFormation",HOSTILE:"hostile",IFFSIFF:"iffSif",DIRECTION_OF_MOVEMENT:"directionOfMovement",UNIQUE_DESIGNATION_1:"uniqueDesignation1",UNIQUE_DESIGNATION_2:"uniqueDesignation2",EQUIPMENT_TYPE:"equipmentType",DATE_TIME_GROUP_1:"dateTimeGroup1",DATE_TIME_GROUP_2:"dateTimeGroup2",DATE_TIME_GROUP_3:"dateTimeGroup3",ALTITUDE_DEPTH:"altitudeDepth",LOCATION:"location",SPEED:"speed",SPECIAL_C2_HQ:"specialC2Headquarters",DISTANCE:"distance",AZIMUTH:"azimuth",FILL_COLOR:"fillColor",LINE_COLOR:"lineColor",LINE_THICKNESS:"lineThickness",SYMBOL_FILL_ICON_SIZE:"symbolFillIconSize",SYMBOL_FILL_IDS:"symbolFillIds",SYMBOL_LINE_IDS:"symbolLineIds",Symbology_2525Bch2_USAS_13_14:0,Symbology_2525C:1,NormalizeGECoordsToGEExtents:function(leftLongitude,rightLongitude,pts2d) -{try -{var j=0;var x=0,y=0;var pt2d=null;for(j=0;jrightLongitude) -x-=360;pt2d=new armyc2.c2sd.graphics2d.Point2D(x,y);pts2d[j]=pt2d;}} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","NormalizeGECoordsToGEExtents",err);}},NormalizeCoordToGECoord:function(pt2d) -{var ptGeo=null;try -{var x=pt2d.getX(),y=pt2d.getY();while(x<-180) -x+=360;while(x>180) -x-=360;ptGeo=new armyc2.c2sd.graphics2d.Point2D(x,y);} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","NormalizeCoordToGECoord",err);} -return ptGeo;},getBoundingRectangle:function(controlPoints,bbox) -{var bbox2="";try -{var left=0,right=0,top=0,bottom=0;var coordinates=controlPoints.split(" ");var len=coordinates.length;var i=0;left=Number.MAX_VALUE;right=Number.MIN_VALUE;top=Number.MIN_VALUE;bottom=Number.MAX_VALUE;for(i=0;iright) -right=longitude;if(latitude>top) -top=latitude;if(latituderight) -right=ptTemp.getX();if(ptTemp.getY()>top) -top=ptTemp.getY();if(ptTemp.getY()right) -right=pt.getX();if(pt.getY()>top) -top=pt.getY();if(pt.getY()180) -{left=geoCoords[0].x;for(j=1;j0&&pt.getX()180) -return true;} -return result;},ShouldClipSymbol:function(symbolID) -{var status=armyc2.c2sd.renderer.utilities.SymbolUtilities.getStatus(symbolID);if(symbolID.charAt(0)===("G")&&status===("A")){return true;} -if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isWeather(symbolID)) -return true;var id=armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolID(symbolID);if(id===("G*T*F-----****X")||id===("G*F*LCC---****X")||id===("G*G*GLB---****X")||id===("G*G*GLF---****X")||id===("G*G*GLC---****X")||id===("G*G*GAF---****X")||id===("G*G*AAW---****X")||id===("G*G*DABP--****X")||id===("G*G*OLP---****X")||id===("G*G*PY----****X")||id===("G*G*PM----****X")||id===("G*G*ALL---****X")||id===("G*G*ALU---****X")||id===("G*G*ALM---****X")||id===("G*G*ALC---****X")||id===("G*G*SLB---****X")||id===("G*G*SLH---****X")||id===("G*G*GAY---****X")||id===("G*G*ALS---****X")||id===("G*M*OFA---****X")||id===("G*M*OGB---****X")||id===("G*M*OGL---****X")||id===("G*M*OGZ---****X")||id===("G*M*OGF---****X")||id===("G*M*OGR---****X")||id===("G*M*OADU--****X")||id===("G*M*OADC--****X")||id===("G*M*OAR---****X")||id===("G*M*OAW---****X")||id===("G*M*OEF---****X")||id===("G*M*OMC---****X")||id===("G*M*OWU---****X")||id===("G*M*OWS---****X")||id===("G*M*OWD---****X")||id===("G*M*OWA---****X")||id===("G*M*OWL---****X")||id===("G*M*OWH---****X")||id===("G*M*OWCS--****X")||id===("G*M*OWCD--****X")||id===("G*M*OWCT--****X")||id===("G*M*OHO---****X")||id===("G*M*BDD---****X")||id===("G*M*BCD---****X")||id===("G*M*BCE---****X")||id===("G*M*SL----****X")||id===("G*M*SP----****X")||id===("G*M*NR----****X")||id===("G*M*NB----****X")||id===("G*M*NC----****X")||id===("G*F*ACNI--****X")||id===("G*F*ACNR--****X")||id===("G*F*ACNC--****X")||id===("G*F*AKBC--****X")||id===("G*F*AKBI--****X")||id===("G*F*AKBR--****X")||id===("G*F*AKPC--****X")||id===("G*F*AKPI--****X")||id===("G*F*AKPR--****X")||id===("G*F*LT----****X")||id===("G*F*LTS---****X")||id===("G*G*SAE---****X")||id===("G*S*LRA---****X")||id===("G*S*LRM---****X")||id===("G*S*LRO---****X")||id===("G*S*LRT---****X")||id===("G*S*LRW---****X")||id===("G*T*Q-----****X")||id===("G*T*E-----****X")||id===("G*T*F-----****X")||id===("G*T*K-----****X")||id===("G*T*KF----****X")||id===("G*T*A-----****X")||id===("G*G*PA----****X")) -{return true;} -else -return false;},RenderSymbol:function(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd) -{if(symStd===undefined) -{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} -var normalize=false,controlLat=0,controlLong=0,jsonOutput="",jsonContent="",rect=null,tgPoints=null,coordinates=controlPoints.split(" "),tgl=new armyc2.c2sd.JavaTacticalRenderer.TGLight(),shapes=new Array(),modifiers=new Array(),geoCoords=new Array(),len=coordinates.length,ipc=null,left=0,right=0,top=0,bottom=0,temp=null,ptGeoUL=null,width=0,height=0,leftX=0,topY=0,bottomY=0,rightX=0,j=0,bboxCoords=null;if(bbox!==null&&bbox!==("")){var bounds=null;if(bbox.contains(" ")) -{bboxCoords=new Array();var x=0;var y=0;var coords=bbox.split(" ");var coord;var arrCoord;var tempPt=null;for(var i=0;i180) -right-=360;else -if(right<-180) -right+=360;} -if(top===bottom) -{dist=1000.0*(1.0/96.0)*(1.0/39.37)*scale;var ptTop=new armyc2.c2sd.JavaLineArray.POINT2(left,top);var ptBottom=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTop,dist,180.0);bottom=ptBottom.y;} -var pt2d=null;if(bboxCoords===undefined||bboxCoords===null) -{pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(left,top);temp=ipc.GeoToPixels(pt2d);leftX=Math.round(temp.getX());topY=Math.round(temp.getY());pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(right,bottom);temp=ipc.GeoToPixels(pt2d);bottomY=Math.round(temp.getY());rightX=Math.round(temp.getX());width=Math.abs(rightX-leftX);height=Math.abs(bottomY-topY);rect=new armyc2.c2sd.graphics2d.Rectangle(leftX,topY,width,height);}} -else -{rect=null;} -var tempPt=null;for(var i=0;i0){symbol.setLineWidth(lineWidth);} -if(altitudes!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.X_ALTITUDE_DEPTH,altitudes);} -if(distances!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE,distances);} -if(azimuths!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH,azimuths);} -if(armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolID(symbol.getSymbolID())===("G*F*AXS---****X")){if(symbol.getModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH)!==null&&symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE)!==null){var anCount=symbol.getModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH).length;var amCount=symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE).length;var am=null;if(amCount<((Math.floor(anCount/2))+1)){am=symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE);if(am[0]!==0) -{am.splice(0,0,0);}}}}} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","populateModifiers",err);} -return true;},KMLize:function(id,name,description,symbolCode,shapes,modifiers,ipc,geMap,normalize) -{var kml="";var tempModifier=null;var cdataStart="";kml+=("");kml+=(""+cdataStart+name+cdataEnd+"");kml+=("1");try -{var len=shapes.size();for(var i=0;i0) -{jstr+=",";} -var shapesToAdd=sec.web.renderer.MultiPointHandler.ShapeToJSONString(shapes.get(i),ipc,geMap,normalize);if(shapesToAdd.length>0){if(shapesToAdd.substring(2,6)==="line") -{if(lines.length>0) -{lines+=",";} -lines+=shapesToAdd;} -else if(shapesToAdd.substring(2,6)==="poly") -{if(polygons.length>0) -{polygons+=",";} -polygons+=shapesToAdd;}}} -jstr+="\"polygons\": ["+polygons+"],"+"\"lines\": ["+lines+"],";var len2=modifiers.size();labels="";for(var j=0;j0){if(labels.length>0){labels+=",";} -labels+=labelsToAdd;}} -jstr+="\"labels\": ["+labels+"]";} -catch(err) -{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","JSONize",err);} -return jstr;},IsOnePointSymbolCode:function(symbolCode) -{var symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();var basicCode=SymbolUtilities.getBasicSymbolID(symbolCode);var sd=null;if(SymbolDefTable.hasSymbolDef(basicCode,symStd)) -{sd=SymbolDefTable.getSymbolDef(basicCode,symStd);if(symbolCode.charAt(0)==='G'&&sd.maxPoints===1) -return true;} -if(symbolCode.equals("CAKE-----------")) -return true;else if(symbolCode.equals("CYLINDER-------")) -return true;else if(symbolCode.equals("RADARC---------")) -return true;return false;},normalizePoints:function(shape,ipc) -{var geoCoords=new Array();for(var j=0;j");if(description) -{kml+=(""+cdataStart+description+cdataEnd+"");} -kml+=("");var shapesArray=shapeInfo.getPolylines();var len=shapesArray.size();kml+=("");for(var i=0;i");kml+=("1");kml+=("clampToGround");kml+=("");for(var j=0;j");kml+=("");} -if(fillColor!==null){if(i===0) -kml+=("");if(i===1&&len>1) -kml+=("");else -kml+=("");kml+=("");kml+=("clampToGround");kml+=("1");kml+=("");var lastLongitude=null;if(normalize===false&&this.IsOnePointSymbolCode(symbolCode)) -{for(var j=0;j180) -{normalize=true;break;}} -lastLongitude=longitude;}} -for(var j=0;j0) -{longitude-=360;}} -kml+=(longitude);kml+=(",");kml+=(latitude);kml+=(" ");} -kml+=("");kml+=("");if(i===1&&len>1) -kml+=("");else -kml+=("");if(i===len-1) -kml+=("");}} -kml+=("");kml+=("");return kml;},AdjustModifierPointToCenter:function(modifier) -{try{}catch(err){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","AdjustModifierPointToCenter",err);}},ShapeToJSONString:function(shapeInfo,ipc,geMap,normalize) -{var JSONed="";var fillColor=null;var lineColor=null;if(shapeInfo.getLineColor()!==null){lineColor=shapeInfo.getLineColor().toHexString();} -if(shapeInfo.getFillColor()!==null){fillColor=shapeInfo.getFillColor().toHexString();} -var stroke=null;stroke=shapeInfo.getStroke();var lineWidth=4;if(stroke!==null){lineWidth=Math.round(stroke.getLineWidth());} -var shapesArray=shapeInfo.getPolylines();for(var i=0;i0) -{longitude-=360;}} -coord.setLocation(longitude,latitude);shape[j]=coord;JSONed+=("[");JSONed+=(longitude);JSONed+=(",");JSONed+=(latitude);JSONed+=("]");if(j<(shape.size()-1)){JSONed+=(",");}} -JSONed+=("]");if(lineColor!==null){JSONed+=(",\"lineColor\":\"");JSONed+=(lineColor);JSONed+=("\"");} -if(fillColor!==null){JSONed+=(",\"fillColor\":\"");JSONed+=(fillColor);JSONed+=("\"");} -JSONed+=(",\"lineWidth\":\"");JSONed+=(lineWidth);JSONed+=("\"");JSONed+=("}");if(i<(shapesArray.size()-1)){JSONed+=(",");}} -return JSONed;},LabelToKMLString:function(id,i,shapeInfo,ipc,normalize) -{var cdataStart="";var kml="";var coord=new armyc2.c2sd.graphics2d.Point2D();coord.setLocation(shapeInfo.getGlyphPosition().getX(),shapeInfo.getGlyphPosition().getY());var geoCoord=ipc.PixelsToGeo(coord);if(normalize) -geoCoord=this.NormalizeCoordToGECoord(geoCoord);var latitude=geoCoord.getY().toFixed(_decimalAccuracy);var longitude=geoCoord.getX().toFixed(_decimalAccuracy);var angle=Math.round(shapeInfo.getModifierStringAngle());var text=shapeInfo.getModifierString();if(text!==null&&text!==("")){kml+=("");kml+=(""+cdataStart+text+cdataEnd+"");kml+=("");kml+=("");kml+=("1");kml+=("relativeToGround");kml+=("");kml+=(longitude);kml+=(",");kml+=(latitude);kml+=("");kml+=("");kml+=("");}else{return"";} -return kml;},LabelToJSONString:function(shapeInfo,ipc,normalize) -{var JSONed=("{\"label\":");var coord=new armyc2.c2sd.graphics2d.Point2D();coord.setLocation(shapeInfo.getGlyphPosition().getX(),shapeInfo.getGlyphPosition().getY());var geoCoord=ipc.PixelsToGeo(coord);if(normalize) -geoCoord=this.NormalizeCoordToGECoord(geoCoord);var latitude=geoCoord.getY().toFixed(_decimalAccuracy);var longitude=geoCoord.getX().toFixed(_decimalAccuracy);var angle=shapeInfo.getModifierStringAngle();coord.setLocation(longitude,latitude);shapeInfo.setGlyphPosition(coord);var text=shapeInfo.getModifierString();if(text!==null&&text!==("")){JSONed+=("[");JSONed+=(longitude);JSONed+=(",");JSONed+=(latitude);JSONed+=("]");JSONed+=(",\"text\":\"");JSONed+=(text);JSONed+=("\"");JSONed+=(",\"angle\":\"");JSONed+=(angle);JSONed+=("\"}");}else{return"";} -return JSONed;},getModififerKML:function(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd) -{var output="";var placemarks=new Array();try -{var maxAlt=0;var minAlt=0;output=this.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd);var pmiStart=output.indexOf("0) -{if(count>0) -{pmiEnd=output.indexOf("",pmiStart)+12;tempPlacemark=output.substring(pmiStart,pmiEnd);if(tempPlacemark.contains("")) -placemarks.push(output.substring(pmiStart,pmiEnd));pmiStart=output.indexOf("0) -{path.lineTo(temp.getX(),temp.getY());} -else if(i===0) -{path.moveTo(temp.getX(),temp.getY());}} -bounds=path.getBounds();height=bounds.getHeight();width=bounds.getWidth();if(bounds.getX()<0) -{offsetX=Math.round(bounds.getX()*-1);} -else if((bounds.getX()+bounds.getWidth())>width) -{offsetX=Math.round((bounds.getX()+bounds.getWidth())-width)*-1;} -if(bounds.getY()<0) -{offsetY=Math.round(bounds.getY()*-1);} -else if((bounds.getY()+bounds.getHeight())>height) -{offsetY=Math.round((bounds.getY()+bounds.getHeight())-height)*-1;} -if(clip!==null) -{var sbClip="";sbClip+=("&clip=");sbClip+=(clip.getX());sbClip+=(",");sbClip+=(clip.getY());sbClip+=(",");sbClip+=(clip.getWidth());sbClip+=(",");sbClip+=(clip.getHeight());strClip=sbClip;} -var sbCoords="";var sbUrl="";sbCoords+=("coords=");if(modifiers["symbolFillIds"]!==undefined) -{symbolFillIDs=modifiers["symbolFillIds"];} -if(modifiers["symbolLineIds"]!==undefined) -{symbolLineIDs=modifiers["symbolLineIds"];} -if(modifiers["symbolFillIconSize"]!==undefined) -{symbolSize=["symbolFillIconSize"];} -if(modifiers["clip"]) -{strClip=["clip"];} -for(var i=0;i0) -{sbCoords+=(",");} -point=pixels.get(i);x=Math.round(point.getX()+offsetX);y=Math.round(point.getY()+offsetY);sbCoords+=(x);sbCoords+=(",");sbCoords+=(y);} -sbUrl=this.GetImageServerURL();sbUrl+=("AREASYMBOLFILL?");sbUrl+=("renderer=AreaSymbolFillRenderer&");sbUrl+=sbCoords;if(symbolFillIDs!==null) -{sbUrl+=("&symbolFillIds=");sbUrl+=(symbolFillIDs);} -if(symbolLineIDs!==null) -{sbUrl+=("&symbolLineIds=");sbUrl+=(symbolLineIDs);} -if(symbolSize>0) -{sbUrl+=("&symbolFillIconSize=");sbUrl+=(symbolSize);} -if(strClip!==null) -{sbUrl+=(strClip);} -sbUrl+=("&height=");sbUrl+=parseInt(height);sbUrl+=("&width=");sbUrl+=parseInt(width);url=sbUrl;if(height0) -{path.lineTo(tpTemp.x,tpTemp.y);} -else -{path.moveTo(tpTemp.x,tpTemp.y);}} -var rect=path.getBounds();var goImageUrl=this.GenerateSymbolLineFillUrl(mSymbol.getModifierMap(),pixelPoints,rect);var goKML="";if(goImageUrl!==null) -{goKML=this.GenerateGroundOverlayKML(goImageUrl,ipc,rect,normalize);} -goKML+="";jsonContent=jsonContent.replace("",goKML);return jsonContent;},GenerateGroundOverlayKML:function(urlImage,ipc,symbolBounds,normalize) -{var x=0;var y=0;var height=0;var width=0;var sb="";var lineFill=false;var params={};var symbolSize=0;var imageOffset=0;try -{var index=-1;index=urlImage.indexOf(this.SYMBOL_LINE_IDS);if(index>0) -{lineFill=true;if(params[this.SYMBOL_FILL_ICON_SIZE]!==undefined) -{var size=params[this.SYMBOL_FILL_ICON_SIZE];symbolSize=parseInt(size);} -else -{symbolSize=25;} -imageOffset=(symbolSize/2)+3;} -var bounds=null;bounds=symbolBounds;height=bounds.getHeight()+(imageOffset*2);width=bounds.getWidth()+(imageOffset*2);x=bounds.getX()-imageOffset;y=bounds.getY()-imageOffset;var coord=new armyc2.c2sd.graphics2d.Point2D(x,y);var topLeft=ipc.PixelsToGeo(coord);coord=new armyc2.c2sd.graphics2d.Point2D(x+width,y+height);var bottomRight=ipc.PixelsToGeo(coord);if(normalize) -{topLeft=this.NormalizeCoordToGECoord(topLeft);bottomRight=this.NormalizeCoordToGECoord(bottomRight);if(topLeft.getX()>0) -{topLeft.x-=360;}} -var cdataStart="";sb+=("");sb+=("symbol fill");sb+=("symbol fill");sb+=("");sb+=("");sb+=(cdataStart);sb+=(urlImage);sb+=(cdataEnd);sb+=("");sb+=("");sb+=("");sb+=("");sb+=topLeft.getY();sb+=("");sb+=("");sb+=bottomRight.getY();sb+=("");sb+=("");sb+=bottomRight.getX();sb+=("");sb+=("");sb+=topLeft.getX();sb+=("");sb+=("");sb+=("0");sb+=("");sb+=("");sb+=("");} -catch(exc) -{ErrorLogger.LogException("MultiPointHandler","GenerateGroundOverlayKML",exc);} -var kml=sb;return kml;},GetImageServerURL:function() -{if(_appletUrl===null) -{_appletUrl=baseURL;_appletUrl+="mil-sym-service/renderer/image/";} -return _appletUrl;},SetImageServerURL:function(hostURL) -{_appletUrl=hostURL;_appletUrl+="mil-sym-service/renderer/image/";}};}());var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.Shape3DHandler=function(){};sec.web.renderer.Shape3DHandler.render3dSymbol=function(name,id,shapeType,description,color,altitudeMode,controlPoints,attributes){var result="";var convertedAltitudeMode=altitudeMode;if(shapeType.equals("CYLINDER-------")){result=sec.web.renderer.Shape3DHandler.buildCylinder(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("ORBIT----------")){result=sec.web.renderer.Shape3DHandler.buildOrbit(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("RADARC---------")){result=sec.web.renderer.Shape3DHandler.buildRadarc(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("POLYARC--------")){result=sec.web.renderer.Shape3DHandler.buildPolyArc(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("ROUTE----------")){result=sec.web.renderer.Shape3DHandler.buildRoute(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("POLYGON--------")){result=sec.web.renderer.Shape3DHandler.buildPolygon(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("CAKE-----------")){result=sec.web.renderer.Shape3DHandler.buildCake(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else if(shapeType.equals("TRACK----------")){result=sec.web.renderer.Shape3DHandler.buildTrack(controlPoints,id,name,description,color,convertedAltitudeMode,attributes);}else{var sb=new sec.geo.utilities.StringBuilder();sb.append("Given shape type \""+shapeType+"\" does not match any of the available shape types.");sb.append("\n");sb.append("Available Types: ");sb.append("CYLINDER-------\n");sb.append("ORBIT----------\n");sb.append("ROUTE----------\n");sb.append("POLYGON--------\n");sb.append("RADARC---------\n");sb.append("POLYARC--------\n");sb.append("CAKE-----------\n");sb.append("TRACK----------");} -if(!(description)) -{if(result.indexOf("undefined\n")>0) -result=result.replace("undefined\n","");else if(result.indexOf("null\n")>0) -result=result.replace("null\n","");} -return result;};sec.web.renderer.Shape3DHandler.buildPolygon=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";try{var latlons=controlPoints.$plit(" ");if(latlons.length>=2){pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getPolygonKml(latlons,id,name,description,color,altitudeMode,(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("Shape3DHandler","buildPolygon()",e);} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildCylinder=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.$plit(" ");if(latlons.length>0){var pivot=latlons[0].$plit(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} -pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getCircleKml(pivotx,pivoty,id,name,description,color,altitudeMode,(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildKml=function(coords,id,name,color){var kml=new sec.geo.utilities.StringBuilder();kml.append("");kml.append("");kml.append(name);kml.append("");kml.append("");kml.append(id);kml.append("");kml.append("");kml.append("");for(var s,$s=0,$$s=coords;$s<$$s.length&&((s=$$s[$s])||true);$s++){kml.append("");kml.append("0");kml.append("relativeToGround");kml.append("");kml.append("");kml.append("");kml.append(s);kml.append("");kml.append("");kml.append("");kml.append("");} -kml.append("");kml.append("");return kml.toString();};sec.web.renderer.Shape3DHandler.buildOrbit=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var point1x=0.0;var point1y=0.0;var point2x=0.0;var point2y=0.0;try{var latlons=controlPoints.$plit(" ");if(latlons.length>1){var point1=latlons[0].$plit(",");if(point1.length>=2){point1x=Double.parseDouble(point1[0]);point1y=Double.parseDouble(point1[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} -var point2=latlons[1].$plit(",");if(point2.length>=2){point2x=Double.parseDouble(point2[0]);point2y=Double.parseDouble(point2[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} -pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getOrbitKml(point1x,point1y,point2x,point2y,id,name,description,color,altitudeMode,(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildRadarc=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.$plit(" ");if(latlons.length>0){var pivot=latlons[0].$plit(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} -pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getRadarcKml(pivotx,pivoty,id,name,description,color,altitudeMode,(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.AM_DISTANCE.get(1)).doubleValue(),(attributes.AN_AZIMUTH.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(1)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildPolyArc=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.$plit(" ");if(latlons.length>=3){var pivot=latlons[0].$plit(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} -var length=latlons.length-1;var points=new Array(length);System.arraycopy(latlons,1,points,0,length);pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getPolyarcKml(points,pivotx,pivoty,id,name,description,color,altitudeMode,(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(1)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildRoute=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var width;var leftWidth;var rightWidth;try{var latlons=controlPoints.$plit(" ");if(latlons.length>=2){width=(attributes.AM_DISTANCE.get(0)).doubleValue();leftWidth=width/2;rightWidth=width/2;pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getRouteKml(latlons,id,name,description,color,altitudeMode,leftWidth,rightWidth,(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildCake=function(controlPoints,id,name,description,color,altitudeMode,attributes){var pointArrayStringList="";var letThemEat=new sec.geo.shape.Cake();var pivotx=0.0;var pivoty=0.0;var kmlRender=new sec.geo.kml.KmlRenderer();try{var latlons=controlPoints.$plit(" ");var numberOfPoints=latlons.length;if(numberOfPoints>0){var pivotString=latlons[0].$plit(",");if(pivotString.length>=2){pivotx=Double.parseDouble(pivotString[0]);pivoty=Double.parseDouble(pivotString[1]);letThemEat.setPivot(new sec.geo.GeoPoint(pivotx,pivoty));}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} -var attributesArrayLength=attributes.X_ALTITUDE_DEPTH.size();for(var i=0;i=2){var track=new sec.geo.shape.Track();for(var i=0;i=2){point1lon=Double.parseDouble(point1String[0]);point1lat=Double.parseDouble(point1String[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} -if(point2String.length>=2){point2lon=Double.parseDouble(point2String[0]);point2lat=Double.parseDouble(point2String[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} -route.addPoint(new sec.geo.GeoPoint(point1lon,point1lat));route.addPoint(new sec.geo.GeoPoint(point2lon,point2lat));route.setLeftWidth((attributes.AM_DISTANCE.get(2*i)).doubleValue());route.setRightWidth((attributes.AM_DISTANCE.get(2*i+1)).doubleValue());route.setMinAltitude((attributes.X_ALTITUDE_DEPTH.get(2*i)).doubleValue());route.setMaxAltitude((attributes.X_ALTITUDE_DEPTH.get(2*i+1)).doubleValue());track.addRoute(route);} -pointArrayStringList=kmlRender.getKml(track,id,name,description,color);}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} -return pointArrayStringList;};sec.web.renderer.Shape3DHandler.CYLINDER="CYLINDER-------";sec.web.renderer.Shape3DHandler.ORBIT="ORBIT----------";sec.web.renderer.Shape3DHandler.ROUTE="ROUTE----------";sec.web.renderer.Shape3DHandler.POLYGON="POLYGON--------";sec.web.renderer.Shape3DHandler.RADARC="RADARC---------";sec.web.renderer.Shape3DHandler.POLYARC="POLYARC--------";sec.web.renderer.Shape3DHandler.CAKE="CAKE-----------";sec.web.renderer.Shape3DHandler.TRACK="TRACK----------";sec.web.renderer.Shape3DHandler.ATTRIBUTES="attributes";sec.web.renderer.Shape3DHandler.MIN_ALT="minalt";sec.web.renderer.Shape3DHandler.MAX_ALT="maxalt";sec.web.renderer.Shape3DHandler.RADIUS1="radius1";sec.web.renderer.Shape3DHandler.RADIUS2="radius2";sec.web.renderer.Shape3DHandler.LEFT_AZIMUTH="leftazimuth";sec.web.renderer.Shape3DHandler.RIGHT_AZIMUTH="rightazimuth";sec.web.renderer.Shape3DHandler.MIN_ALT_DEFAULT=0.0;sec.web.renderer.Shape3DHandler.MAX_ALT_DEFAULT=100.0;sec.web.renderer.Shape3DHandler.RADIUS1_DEFAULT=50.0;sec.web.renderer.Shape3DHandler.RADIUS2_DEFAULT=100.0;sec.web.renderer.Shape3DHandler.LEFT_AZIMUTH_DEFAULT=0.0;sec.web.renderer.Shape3DHandler.RIGHT_AZIMUTH_DEFAULT=90.0;sec.web.renderer.Shape3DHandler.DEFAULT_ATTRIBUTES="[{radius1:50.0,radius2:100.0,minalt:0.0,maxalt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}]";sec.web.renderer.Shape3DHandler.ERR_ATRIBUTES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"The attribute paramaters are not formatted correctly";sec.web.renderer.Shape3DHandler.ERR_COORDINATES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"There was an error creating the Symbol - the coordinates were not formatted correctly";sec.web.renderer.Shape3DHandler.ERR_GENERAL_ERROR="{\"type\":\"error\",\"error\":\"There was an error creating the Symbol - An unknown error occurred. Please refer to the stack trace";sec.web.renderer.Shape3DHandler.ERR_INVALID_NUMBER_POINTS_ERROR="{\"type\":\"error\",\"error\":\"Not enough points were passed in to create a graphic.";var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.SECWebRenderer=(function(){var CYLINDER="CYLINDER-------",ORBIT="ORBIT----------",ROUTE="ROUTE----------",POLYGON="POLYGON--------",RADARC="RADARC---------",POLYARC="POLYARC--------",CAKE="CAKE-----------",TRACK="TRACK----------",CURTAIN="CURTAIN--------",ATTRIBUTES="attributes",MIN_ALT="minalt",MAX_ALT="maxalt",RADIUS1="radius1",RADIUS2="radius2",LEFT_AZIMUTH="leftAzimuth",RIGHT_AZIMUTH="rightAzimuth",MIN_ALT_DEFAULT=0.0,MAX_ALT_DEFAULT=100.0,RADIUS1_DEFAULT=50.0,RADIUS2_DEFAULT=100.0,LEFT_AZIMUTH_DEFAULT=0.0,RIGHT_AZIMUTH_DEFAULT=90.0,ERR_ATTRIBUTES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"The attribute paramaters are not formatted correctly",DEFAULT_ATTRIBUTES="[{radius1:50.0,radius2:100.0,minalt:0.0,maxalt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}]",spsPortNumber=-1,ErrorLogger=armyc2.c2sd.renderer.utilities.ErrorLogger,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,JavaRendererUtilities=sec.web.renderer.utilities.JavaRendererUtilities,Shape3DHandler=sec.web.renderer.Shape3DHandler,MilStdIconRenderer=null;if(armyc2.c2sd.renderer.MilStdIconRenderer) -{MilStdIconRenderer=armyc2.c2sd.renderer.MilStdIconRenderer;} -else -{armyc2.c2sd.renderer.utilities.SymbolDefTable.init();} -return{setLoggingLevel:function(level) -{ErrorLogger.setLevel(level);},RenderSymbol:function(id,name,description,symbolCode,controlPoints,altitudeMode,scale,bbox,modifiers,format,symStd) -{var output="";try -{if(JavaRendererUtilities.is3dSymbol(symbolCode,modifiers)) -{if(!(altitudeMode&&altitudeMode.length)) -altitudeMode="relativeToGround";output=this.RenderMilStd3dSymbol(name,id,symbolCode,description,altitudeMode,controlPoints,modifiers);var modifierKML=sec.web.renderer.MultiPointHandler.getModififerKML(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd);modifierKML+="";output=output.replace("",modifierKML);if(output===""){output=sec.web.renderer.MultiPointHandler.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd);}} -else -{output=sec.web.renderer.MultiPointHandler.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd);} -return output;} -catch(err) -{output="{\"type\":'error',error:'There was an error creating the MilStdSymbol - "+err.name+":"+err.message+"'}";ErrorLogger.LogException("SECWebRenderer","RenderSymbol",err,ErrorLogger.WARNING);} -return output;},RenderSymbol2D:function(id,name,description,symbolCode,controlPoints,pixelWidth,pixelHeight,bbox,modifiers,format,symStd) -{var output="";try -{output=sec.web.renderer.MultiPointHandler.RenderSymbol2D(id,name,description,symbolCode,controlPoints,pixelWidth,pixelHeight,bbox,modifiers,format,symStd);} -catch(exc) -{output="{\"type\":'error',error:'There was an error creating the MilStdSymbol: "+symbolCode+" - "+exc.toString()+"'}";ErrorLogger.LogException("SECWebRenderer","RenderSymbol2D",exc,ErrorLogger.WARNING);} -return output;},Render3dSymbol:function(name,id,shapeType,description,color,altitudeMode,controlPoints,AttributesArray) -{var returnValue="";try{var attributes={};attributes.AM_DISTANCE=new java.util.ArrayList();attributes.X_ALTITUDE_DEPTH=new java.util.ArrayList();attributes.AN_AZIMUTH=new java.util.ArrayList();if(AttributesArray===null||attributes===""){AttributesArray=[{innerRadius:50.0,radius:100.0,minAlt:0.0,maxAlt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}];} -var attributesArrayLength=AttributesArray.length;if(attributesArrayLength>0){for(var i=0;i0) -{sb+=(",");} -info=jsa[i];var modifiers=JavaRendererUtilities.createParameterMapFromURL(info);var symbolID=modifiers["SYMBOLID"];modifiers["RENDER"]=false;var ii=MilStdIconRenderer.Render(symbolID,modifiers);var anchor=ii.getCenterPoint();var symbolBounds=ii.getSymbolBounds();var iconSize=ii.getImageBounds();var item="";item+=("{\"x\":");item+=(anchor.getX());item+=(",\"y\":");item+=(anchor.getY());item+=(",\"boundsx\":");item+=(symbolBounds.getX());item+=(",\"boundsy\":");item+=(symbolBounds.getY());item+=(",\"boundswidth\":");item+=(symbolBounds.getWidth());item+=(",\"boundsheight\":");item+=(symbolBounds.getHeight());item+=(",\"iconwidth\":");item+=(iconSize.getWidth());item+=(",\"iconheight\":");item+=(iconSize.getHeight());item+=("}");sb+=(item);} -sb+=("]}");}} -catch(exc) -{ErrorLogger.LogException("SECWebRenderer","getSinglePointInfoBatch",exc);} -return sb;},setDefaultSymbologyStandard:function(symStd) -{armyc2.c2sd.renderer.utilities.RendererSettings.setSymbologyStandard(symStd);}};}()); \ No newline at end of file diff --git a/support/client/lib/vwf/model/mil-sym/sm-c.min.js b/support/client/lib/vwf/model/mil-sym/sm-c.min.js new file mode 100644 index 000000000..5e936fea1 --- /dev/null +++ b/support/client/lib/vwf/model/mil-sym/sm-c.min.js @@ -0,0 +1,9883 @@ + +var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SinglePointMappingsC={"SINGLEPOINTMAPPINGS":{"SYMBOL":[{"ID":"NBCNUCFILL****X","MP":"1900","MA":"1900","W":"30","H":"39"},{"ID":"NBCBIOFILL****X","MP":"1901","MA":"1901","W":"28","H":"39"},{"ID":"NBCCMLFILL****X","MP":"1902","MA":"1902","W":"22","H":"39"},{"ID":"SONOBYFILL****X","MP":"1904","MA":"1904","W":"24","H":"48"},{"ID":"CPOINTFILL****X","MP":"1903","MA":"1903","W":"30","H":"30"},{"ID":"CHKPNTFILL****X","MP":"1905","MA":"1905","W":"25","H":"45"},{"ID":"REFPNTFILL****X","MP":"1908","MA":"1908","W":"32","H":"31"},{"ID":"DECPNTFILL****X","MP":"1909","MA":"1909","W":"31","H":"30"},{"ID":"G*F*PTS---****X","MP":"2162","MA":"3162","W":"36","H":"36"},{"ID":"G*T*G-----****X","MP":"1999","MA":"1999","W":"62","H":"35"},{"ID":"G*G*GPPN--****X","MP":"2196","MA":"3196","W":"25","H":"45"},{"ID":"G*F*PTN---****X","MP":"2163","MA":"3163","W":"36","H":"36"},{"ID":"G*F*PTC---****X","MP":"34","MA":"34","W":"26","H":"43"},{"ID":"G*F*PTR---****X","MP":"35","MA":"35","W":"26","H":"43"},{"ID":"G*F*PCF---****X","MP":"2164","MA":"3164","W":"30","H":"30"},{"ID":"G*F*PCS---****X","MP":"2165","MA":"3165","W":"25","H":"45"},{"ID":"G*F*PCB---****X","MP":"2166","MA":"3166","W":"25","H":"45"},{"ID":"G*F*PCR---****X","MP":"2167","MA":"3167","W":"25","H":"45"},{"ID":"G*F*PCH---****X","MP":"2168","MA":"3168","W":"25","H":"45"},{"ID":"G*F*PCL---****X","MP":"2169","MA":"3169","W":"25","H":"45"},{"ID":"G*S*PX----****X","MP":"2170","MA":"3170","W":"25","H":"45"},{"ID":"G*S*PC----****X","MP":"2171","MA":"3171","W":"25","H":"45"},{"ID":"G*S*PY----****X","MP":"2172","MA":"3172","W":"25","H":"45"},{"ID":"G*S*PT----****X","MP":"2173","MA":"3173","W":"25","H":"45"},{"ID":"G*S*PD----****X","MP":"2174","MA":"3174","W":"25","H":"45"},{"ID":"G*S*PE----****X","MP":"2175","MA":"3175","W":"25","H":"45"},{"ID":"G*S*PL----****X","MP":"2176","MA":"3176","W":"25","H":"45"},{"ID":"G*S*PM----****X","MP":"2177","MA":"3177","W":"25","H":"45"},{"ID":"G*S*PR----****X","MP":"2178","MA":"3178","W":"25","H":"45"},{"ID":"G*S*PU----****X","MP":"2179","MA":"3179","W":"25","H":"45"},{"ID":"G*S*PO----****X","MP":"2180","MA":"3180","W":"25","H":"45"},{"ID":"G*S*PI----****X","MP":"2181","MA":"3181","W":"25","H":"45"},{"ID":"G*S*PN----****X","MP":"2182","MA":"3182","W":"25","H":"45"},{"ID":"G*S*PSZ---****X","MP":"2183","MA":"3183","W":"25","H":"45"},{"ID":"G*S*PSA---****X","MP":"2184","MA":"3184","W":"25","H":"45"},{"ID":"G*S*PSB---****X","MP":"2185","MA":"3185","W":"25","H":"45"},{"ID":"G*S*PSC---****X","MP":"2186","MA":"3186","W":"25","H":"45"},{"ID":"G*S*PSD---****X","MP":"2187","MA":"3187","W":"25","H":"45"},{"ID":"G*S*PSE---****X","MP":"2188","MA":"3188","W":"25","H":"45"},{"ID":"G*S*PSF---****X","MP":"2189","MA":"3189","W":"25","H":"45"},{"ID":"G*S*PSG---****X","MP":"2190","MA":"3190","W":"25","H":"45"},{"ID":"G*S*PSH---****X","MP":"2191","MA":"3191","W":"25","H":"45"},{"ID":"G*S*PSI---****X","MP":"2192","MA":"3192","W":"25","H":"45"},{"ID":"G*S*PSJ---****X","MP":"2193","MA":"3191","W":"25","H":"45"},{"ID":"G*S*PAS---****X","MP":"2194","MA":"3194","W":"25","H":"45"},{"ID":"G*S*PAT---****X","MP":"2195","MA":"3195","W":"25","H":"45"},{"ID":"G*S*PP----****X","MP":"2214","MA":"3214","W":"25","H":"45"},{"ID":"G*G*DPO---****X","MP":"2122","MA":"3122","W":"30","H":"31"},{"ID":"G*G*GPPK--****X","MP":"2081","MA":"3081","W":"25","H":"45"},{"ID":"G*G*GPPC--****X","MP":"2082","MA":"3082","W":"22","H":"31"},{"ID":"G*G*GPPO--****X","MP":"2083","MA":"3083","W":"30","H":"30"},{"ID":"G*G*GPPL--****X","MP":"2085","MA":"3085","W":"25","H":"45"},{"ID":"G*M*OAOF--****X","MP":"2129","MA":"2129","W":"30","H":"30"},{"ID":"G*M*OAOM--****X","MP":"2130","MA":"3130","W":"30","H":"31"},{"ID":"G*M*OAOP--****X","MP":"2131","MA":"3131","W":"30","H":"30"},{"ID":"G*G*APP---****X","MP":"2116","MA":"3116","W":"30","H":"30"},{"ID":"G*G*APC---****X","MP":"2117","MA":"3117","W":"30","H":"30"},{"ID":"G*G*GPPP--****X","MP":"2086","MA":"3086","W":"25","H":"45"},{"ID":"G*G*GPPE--****X","MP":"2088","MA":"3088","W":"25","H":"45"},{"ID":"G*G*GPPS--****X","MP":"2089","MA":"3089","W":"25","H":"45"},{"ID":"G*G*OPP---****X","MP":"2128","MA":"3128","W":"25","H":"45"},{"ID":"G*G*APU---****X","MP":"2118","MA":"3118","W":"30","H":"30"},{"ID":"G*G*APD---****X","MP":"2119","MA":"3119","W":"25","H":"45"},{"ID":"G*G*GPP---****X","MP":"2080","MA":"3080","W":"25","H":"45"},{"ID":"G*G*GPPD--****X","MP":"2084","MA":"3084","W":"31","H":"30"},{"ID":"G*G*GPPR--****X","MP":"2087","MA":"3087","W":"25","H":"45"},{"ID":"G*G*GPPW--****X","MP":"2090","MA":"3090","W":"30","H":"30"},{"ID":"G*M*NEB---****X","MP":"2149","MA":"3149","W":"28","H":"39"},{"ID":"G*M*NEC---****X","MP":"2150","MA":"3150","W":"22","H":"39"},{"ID":"G*M*NDP---****X","MP":"2151","MA":"3151","W":"25","H":"45"},{"ID":"G*M*NDT---****X","MP":"2153","MA":"3153","W":"25","H":"45"},{"ID":"G*M*NDE---****X","MP":"2154","MA":"3154","W":"25","H":"45"},{"ID":"G*M*NDB---****X","MP":"2155","MA":"3155","W":"25","H":"45"},{"ID":"G*M*NDD---****X","MP":"2157","MA":"3157","W":"25","H":"45"},{"ID":"G*M*NDA---****X","MP":"2152","MA":"3152","W":"25","H":"45"},{"ID":"G*M*NDO---****X","MP":"2156","MA":"3156","W":"25","H":"45"},{"ID":"G*T*D-----****X","MP":"2000","MA":"3000","W":"62","H":"36"},{"ID":"G*T*I-----****X","MP":"2001","MA":"3001","W":"60","H":"38"},{"ID":"G*T*N-----****X","MP":"2002","MA":"3002","W":"62","H":"36"},{"ID":"G*G*PN----****X","MP":"2120","MA":"3120","W":"48","H":"41"},{"ID":"G*G*DPT---****X","MP":"2121","MA":"3121","W":"36","H":"36"},{"ID":"G*G*DPOC--****X","MP":"2123","MA":"3123","W":"34","H":"34"},{"ID":"G*G*DPOR--****X","MP":"2124","MA":"3124","W":"30","H":"30"},{"ID":"G*G*DPOF--****X","MP":"2125","MA":"3125","W":"30","H":"30"},{"ID":"G*G*DPOS--****X","MP":"2126","MA":"3126","W":"30","H":"30"},{"ID":"G*G*DPON--****X","MP":"2127","MA":"3127","W":"30","H":"30"},{"ID":"G*M*OB----****X","MP":"2132","MA":"3132","W":"30","H":"39"},{"ID":"G*M*OMU---****X","MP":"2133","MA":"2133","W":"24","H":"24"},{"ID":"G*M*OMT---****X","MP":"2134","MA":"2134","W":"24","H":"24"},{"ID":"G*M*OMD---****X","MP":"2135","MA":"2135","W":"25","H":"51"},{"ID":"G*M*OME---****X","MP":"2136","MA":"2136","W":"24","H":"53"},{"ID":"G*M*OMP---****X","MP":"2137","MA":"2137","W":"40","H":"33"},{"ID":"G*M*OMW---****X","MP":"2138","MA":"2138","W":"54","H":"42"},{"ID":"G*M*OFS---****X","MP":"2139","MA":"3139","W":"48","H":"26"},{"ID":"G*M*OHTL--****X","MP":"2140","MA":"2140","W":"26","H":"33"},{"ID":"G*M*OHTH--****X","MP":"2141","MA":"2141","W":"26","H":"32"},{"ID":"G*M*BCP---****X","MP":"2142","MA":"3142","W":"25","H":"45"},{"ID":"G*M*SE----****X","MP":"2143","MA":"2143","W":"31","H":"30"},{"ID":"G*M*SF----****X","MP":"2144","MA":"3144","W":"44","H":"48"},{"ID":"G*M*SS----****X","MP":"2145","MA":"2145","W":"48","H":"30"},{"ID":"G*M*SU----****X","MP":"2146","MA":"2146","W":"48","H":"30"},{"ID":"G*M*NZ----****X","MP":"2147","MA":"3147","W":"31","H":"39"},{"ID":"G*M*NF----****X","MP":"2148","MA":"3148","W":"30","H":"39"},{"ID":"G*G*GPWI--****X","MP":"2038","MA":"2038","W":"42","H":"42"},{"ID":"WAS-PL----P----","MP":"5000","W":"24","H":"33"},{"ID":"WAS-PH----P----","MP":"5003","W":"26","H":"34"},{"ID":"WAS-TL----P----","MP":"5006","W":"38","H":"22"},{"ID":"WAS-TM----P----","MP":"5007","W":"46","H":"22"},{"ID":"WAS-TS----P----","MP":"5008","W":"46","H":"28"},{"ID":"WAS-TE----P----","MP":"5009","W":"46","H":"34"},{"ID":"WAS-ICL---P----","MP":"5011","W":"48","H":"30"},{"ID":"WAS-ICM---P----","MP":"5012","W":"48","H":"30"},{"ID":"WAS-ICS---P----","MP":"5013","W":"48","H":"30"},{"ID":"WAS-IRL---P----","MP":"5014","W":"48","H":"30"},{"ID":"WAS-IRM---P----","MP":"5015","W":"48","H":"30"},{"ID":"WAS-IRS---P----","MP":"5016","W":"48","H":"30"},{"ID":"WAS-IML---P----","MP":"5017","W":"48","H":"54"},{"ID":"WAS-IMM---P----","MP":"5018","W":"60","H":"35"},{"ID":"WAS-IMS---P----","MP":"5019","W":"60","H":"34"},{"ID":"WA--W----------","MP":"10136","MA":"10136","W":"26","H":"43"},{"ID":"WAS-WC----P----","MP":"5020","W":"30","H":"30"},{"ID":"WA--FI---------","MP":"10138","MA":"10138","W":"26","H":"43"},{"ID":"WAS-CCCSCSP----","MP":"5021","W":"38","H":"38"},{"ID":"WAS-CCCSBCP----","MP":"5024","W":"36","H":"36"},{"ID":"WAS-WST-FCP----","MP":"5072","W":"26","H":"48"},{"ID":"WAS-GSI---P----","MP":"5107","W":"46","H":"40"},{"ID":"WAS-WSDD--P----","MP":"5087","W":"26","H":"48"},{"ID":"WAS-WSFU--P----","MP":"5083","W":"26","H":"48"},{"ID":"WAS-WSDB--P----","MP":"5088","W":"28","H":"48"},{"ID":"WA-DBAFG----A--","MP":"170","MA":"170","W":"26","H":"43"},{"ID":"G*O*SS----****X","MP":"2210","MA":"2210","W":"39","H":"30"},{"ID":"G*O*SM----****X","MP":"2209","MA":"2209","W":"35","H":"12"},{"ID":"G*O*SBW---****X","MP":"2207","MA":"2207","W":"44","H":"24"},{"ID":"G*O*SBX---****X","MP":"2208","MA":"2208","W":"36","H":"22"},{"ID":"G*O*SBN---****X","MP":"2206","MA":"2206","W":"30","H":"22"},{"ID":"G*O*SBM---****X","MP":"2205","MA":"2205","W":"30","H":"22"},{"ID":"G*O*SB----****X","MP":"2204","MA":"2204","W":"30","H":"22"},{"ID":"G*O*HM----****X","MP":"2201","MA":"2201","W":"22","H":"21"},{"ID":"G*O*HO----****X","MP":"2203","MA":"2203","W":"30","H":"18"},{"ID":"G*O*HI----****X","MP":"2202","MA":"2202","W":"36","H":"27"},{"ID":"G*O*FO----****X","MP":"2213","MA":"2213","W":"30","H":"29"},{"ID":"G*O*FE----****X","MP":"2212","MA":"2212","W":"31","H":"29"},{"ID":"G*O*FA----****X","MP":"2211","MA":"2211","W":"28","H":"29"},{"ID":"G*O*EP----****X","MP":"2199","MA":"2199","W":"32","H":"20"},{"ID":"G*O*ED----****X","MP":"2198","MA":"2198","W":"44","H":"35"},{"ID":"G*O*ES----****X","MP":"2197","MA":"3197","W":"24","H":"45"},{"ID":"G*O*EV----****X","MP":"2200","MA":"2200","W":"52","H":"37"},{"ID":"G*G*GPWP--****X","MP":"2039","MA":"2039","W":"42","H":"42"},{"ID":"G*G*GPWM--****X","MP":"2037","MA":"3037","W":"46","H":"40"},{"ID":"G*G*GPWG--****X","MP":"2036","MA":"2036","W":"34","H":"43"},{"ID":"G*G*GPWE--****X","MP":"2035","MA":"3035","W":"62","H":"34"},{"ID":"G*G*GPWD--****X","MP":"2034","MA":"3034","W":"44","H":"38"},{"ID":"G*G*GPWA--****X","MP":"2033","MA":"3033","W":"47","H":"47"},{"ID":"G*G*GPUUS-****X","MP":"2006","MA":"2006","W":"30","H":"31"},{"ID":"G*G*GPUUL-****X","MP":"2005","MA":"2005","W":"24","H":"30"},{"ID":"G*G*GPUUD-****X","MP":"2003","MA":"2003","W":"38","H":"38"},{"ID":"G*G*GPUUB-****X","MP":"2004","MA":"2004","W":"24","H":"30"},{"ID":"G*G*GPUYV-****X","MP":"2015","MA":"3015","W":"24","H":"48"},{"ID":"G*G*GPUYR-****X","MP":"2017","MA":"3017","W":"24","H":"48"},{"ID":"G*G*GPUYP-****X","MP":"2008","MA":"3008","W":"24","H":"48"},{"ID":"G*G*GPUYL-****X","MP":"2010","MA":"3010","W":"24","H":"48"},{"ID":"G*G*GPUYC-****X","MP":"2011","MA":"3011","W":"24","H":"48"},{"ID":"G*G*GPUYK-****X","MP":"2018","MA":"3018","W":"24","H":"48"},{"ID":"G*G*GPUYX-****X","MP":"2019","MA":"3019","W":"50","H":"51"},{"ID":"G*G*GPUYD-****X","MP":"2009","MA":"3009","W":"24","H":"48"},{"ID":"G*G*GPUYS-****X","MP":"2012","MA":"3012","W":"25","H":"48"},{"ID":"G*G*GPUYB-****X","MP":"2013","MA":"3013","W":"24","H":"48"},{"ID":"G*G*GPUYT-****X","MP":"2016","MA":"3016","W":"24","H":"48"},{"ID":"G*G*GPUYA-****X","MP":"2014","MA":"3014","W":"24","H":"48"},{"ID":"G*G*GPUSC-****X","MP":"2023","MA":"2023","W":"36","H":"36"},{"ID":"G*G*GPUSA-****X","MP":"2021","MA":"2021","W":"39","H":"35"},{"ID":"G*G*GPUSD-****X","MP":"2022","MA":"2022","W":"39","H":"35"},{"ID":"G*G*GPOW--****X","MP":"2049","MA":"3049","W":"36","H":"33"},{"ID":"G*G*GPOZ--****X","MP":"2047","MA":"3047","W":"36","H":"34"},{"ID":"G*G*GPOR--****X","MP":"2051","MA":"3051","W":"36","H":"33"},{"ID":"G*G*GPOP--****X","MP":"2050","MA":"3050","W":"36","H":"34"},{"ID":"G*G*GPOD--****X","MP":"2048","MA":"3048","W":"36","H":"33"},{"ID":"G*G*GPRS--****X","MP":"2025","MA":"3025","W":"32","H":"31"},{"ID":"G*G*GPRI--****X","MP":"2032","MA":"2032","W":"24","H":"43"},{"ID":"G*G*GPR---****X","MP":"2024","MA":"2024","W":"32","H":"31"},{"ID":"G*G*GPRN--****X","MP":"2026","MA":"3026","W":"32","H":"31"},{"ID":"G*G*GPRD--****X","MP":"2027","MA":"3027","W":"32","H":"31"},{"ID":"G*G*GPRP--****X","MP":"2028","MA":"3028","W":"32","H":"31"},{"ID":"G*G*GPRM--****X","MP":"2029","MA":"3029","W":"32","H":"31"},{"ID":"G*G*GPRW--****X","MP":"2030","MA":"3030","W":"32","H":"31"},{"ID":"G*G*GPRC--****X","MP":"2031","MA":"3031","W":"32","H":"31"},{"ID":"G*G*GPHY--****X","MP":"2044","MA":"3044","W":"32","H":"23"},{"ID":"G*G*GPHX--****X","MP":"2045","MA":"3045","W":"32","H":"23"},{"ID":"G*G*GPHQ--****X","MP":"2042","MA":"3042","W":"32","H":"23"},{"ID":"G*G*GPHA--****X","MP":"2043","MA":"3043","W":"32","H":"23"},{"ID":"G*G*GPAO--****X","MP":"2059","MA":"3059","W":"29","H":"42"},{"ID":"G*G*GPAK--****X","MP":"2056","MA":"3056","W":"29","H":"42"},{"ID":"G*G*GPAT--****X","MP":"2055","MA":"3055","W":"29","H":"42"},{"ID":"G*G*GPAS--****X","MP":"2063","MA":"3063","W":"30","H":"42"},{"ID":"G*G*GPAB--****X","MP":"2065","MA":"3065","W":"29","H":"42"},{"ID":"G*G*GPAC--****X","MP":"2066","MA":"3066","W":"29","H":"42"},{"ID":"G*G*GPAD--****X","MP":"2067","MA":"3067","W":"29","H":"42"},{"ID":"G*G*GPAE--****X","MP":"2068","MA":"3068","W":"29","H":"42"},{"ID":"G*G*GPAF--****X","MP":"2069","MA":"3069","W":"30","H":"42"},{"ID":"G*G*GPAG--****X","MP":"2070","MA":"3070","W":"30","H":"42"},{"ID":"G*G*GPAI--****X","MP":"2071","MA":"3071","W":"29","H":"42"},{"ID":"G*G*GPAJ--****X","MP":"2072","MA":"3072","W":"29","H":"42"},{"ID":"G*G*GPAM--****X","MP":"2073","MA":"3073","W":"29","H":"42"},{"ID":"G*G*GPAN--****X","MP":"2074","MA":"3074","W":"29","H":"42"},{"ID":"G*G*GPAR--****X","MP":"2060","MA":"3060","W":"29","H":"42"},{"ID":"G*G*GPAL--****X","MP":"2061","MA":"3061","W":"29","H":"42"},{"ID":"G*G*GPA---****X","MP":"2052","MA":"3052","W":"29","H":"42"},{"ID":"G*G*GPAP--****X","MP":"2053","MA":"3053","W":"30","H":"42"},{"ID":"G*G*GPAH--****X","MP":"2058","MA":"3058","W":"29","H":"42"},{"ID":"G*G*GPAA--****X","MP":"2057","MA":"3057","W":"29","H":"42"},{"ID":"G*G*GPAW--****X","MP":"2054","MA":"3054","W":"30","H":"42"},{"ID":"WAS-PC----P----","MP":"5001","W":"26","H":"33"},{"ID":"WAS-PLT---P----","MP":"5002","W":"28","H":"26"},{"ID":"WAS-PA----P----","MP":"5004","W":"26","H":"33"},{"ID":"WAS-PHT---P----","MP":"5005","W":"28","H":"26"},{"ID":"WAS-T-MW--P----","MP":"5010","W":"24","H":"12"},{"ID":"WAS-CCCSFCP----","MP":"5022","W":"38","H":"38"},{"ID":"WAS-CCCSSCP----","MP":"5023","W":"36","H":"36"},{"ID":"WAS-CCCSOCP----","MP":"5025","W":"38","H":"38"},{"ID":"WAS-CCCSOBP----","MP":"5026","W":"38","H":"38"},{"ID":"WAS-WSR-LIP----","MP":"5027","W":"10","H":"10"},{"ID":"WAS-WSR-LCP----","MP":"5028","W":"36","H":"10"},{"ID":"WAS-WSR-MIP----","MP":"5029","W":"10","H":"27"},{"ID":"WAS-WSR-MCP----","MP":"5030","W":"26","H":"22"},{"ID":"WAS-WSR-HIP----","MP":"5031","W":"10","H":"30"},{"ID":"WAS-WSR-HCP----","MP":"5032","W":"34","H":"27"},{"ID":"WAS-WSRFL-P----","MP":"5033","W":"48","H":"26"},{"ID":"WAS-WSRFMHP----","MP":"5034","W":"48","H":"26"},{"ID":"WAS-WSRSL-P----","MP":"5035","W":"12","H":"27"},{"ID":"WAS-WSRSMHP----","MP":"5036","W":"12","H":"27"},{"ID":"WAS-WSRST-P----","MP":"5037","W":"12","H":"37"},{"ID":"WAS-WSD-LIP----","MP":"5038","W":"8","H":"14"},{"ID":"WAS-WSD-LCP----","MP":"5039","W":"21","H":"14"},{"ID":"WAS-WSD-MIP----","MP":"5040","W":"8","H":"32"},{"ID":"WAS-WSD-MCP----","MP":"5041","W":"21","H":"29"},{"ID":"WAS-WSD-HIP----","MP":"5042","W":"8","H":"44"},{"ID":"WAS-WSD-HCP----","MP":"5043","W":"27","H":"34"},{"ID":"WAS-WSDFL-P----","MP":"5044","W":"48","H":"26"},{"ID":"WAS-WSDFMHP----","MP":"5045","W":"48","H":"26"},{"ID":"WAS-WSM-L-P----","MP":"5046","W":"16","H":"33"},{"ID":"WAS-WSM-MHP----","MP":"5047","W":"16","H":"52"},{"ID":"WAS-WSMSL-P----","MP":"5048","W":"16","H":"53"},{"ID":"WAS-WSMSMHP----","MP":"5049","W":"16","H":"52"},{"ID":"WAS-WSS-LIP----","MP":"5050","W":"16","H":"18"},{"ID":"WAS-WSS-LCP----","MP":"5051","W":"35","H":"18"},{"ID":"WAS-WSS-MIP----","MP":"5052","W":"16","H":"39"},{"ID":"WAS-WSS-MCP----","MP":"5053","W":"35","H":"40"},{"ID":"WAS-WSS-HIP----","MP":"5054","W":"16","H":"60"},{"ID":"WAS-WSS-HCP----","MP":"5055","W":"35","H":"60"},{"ID":"WAS-WSSBLMP----","MP":"5056","W":"34","H":"34"},{"ID":"WAS-WSSBH-P----","MP":"5057","W":"34","H":"34"},{"ID":"WAS-WSSG--P----","MP":"5058","W":"42","H":"19"},{"ID":"WAS-WSSSL-P----","MP":"5059","W":"12","H":"27"},{"ID":"WAS-WSSSMHP----","MP":"5060","W":"12","H":"27"},{"ID":"WAS-WSGRL-P----","MP":"5061","W":"12","H":"28"},{"ID":"WAS-WSGRMHP----","MP":"5062","W":"12","H":"28"},{"ID":"WAS-WSIC--P----","MP":"5063","W":"50","H":"14"},{"ID":"WAS-WSPLL-P----","MP":"5064","W":"24","H":"19"},{"ID":"WAS-WSPLM-P----","MP":"5065","W":"33","H":"30"},{"ID":"WAS-WSPLH-P----","MP":"5066","W":"34","H":"41"},{"ID":"WAS-WST-NPP----","MP":"5067","W":"49","H":"42"},{"ID":"WAS-WSTMR-P----","MP":"5068","W":"26","H":"48"},{"ID":"WAS-WSTHR-P----","MP":"5069","W":"28","H":"48"},{"ID":"WAS-WSTMH-P----","MP":"5070","W":"24","H":"48"},{"ID":"WAS-WSTHH-P----","MP":"5071","W":"25","H":"48"},{"ID":"WAS-WST-SQP----","MP":"5073","W":"24","H":"28"},{"ID":"WAS-WST-LGP----","MP":"5074","W":"32","H":"42"},{"ID":"WAS-WSFGPSP----","MP":"5075","W":"28","H":"30"},{"ID":"WAS-WSFGCSP----","MP":"5076","MA":"7","W":"28","H":"30"},{"ID":"WAS-WSFGP-P----","MP":"5077","W":"28","H":"30"},{"ID":"WAS-WSFGSVP----","MP":"5078","W":"28","H":"30"},{"ID":"WAS-WSFGSOP----","MP":"5079","W":"28","H":"30"},{"ID":"WAS-WSFGFVP----","MP":"5080","W":"30","H":"30"},{"ID":"WAS-WSFGFOP----","MP":"5081","W":"30","H":"30"},{"ID":"WAS-WSBR--P----","MP":"5082","W":"26","H":"43"},{"ID":"WAS-WSHZ--P----","MP":"5084","W":"48","H":"22"},{"ID":"WAS-WSDSLMP----","MP":"5085","W":"42","H":"42"},{"ID":"WAS-WSDSS-P----","MP":"5086","W":"42","H":"42"},{"ID":"WAS-WSBD--P----","MP":"349","MA":"349","W":"26","H":"43"},{"ID":"WAS-WSTSD-P----","MP":"5089","W":"24","H":"24"},{"ID":"WAS-WSTSS-P----","MP":"5090","W":"32","H":"52"},{"ID":"WAS-WSTSH-P----","MP":"5091","W":"32","H":"52"},{"ID":"WAS-WSVE--P----","MP":"5092","W":"31","H":"37"},{"ID":"WAS-WSVA--P----","MP":"5093","W":"26","H":"27"},{"ID":"WAS-WST-LVP----","MP":"5094","W":"50","H":"28"},{"ID":"WAS-WSF-LVP----","MP":"5095","W":"50","H":"28"},{"ID":"WAS-WSUKP-P----","MP":"5096","W":"48","H":"25"},{"ID":"WAS-GND-NCP----","MP":"5097","W":"36","H":"39"},{"ID":"WAS-GNM---P----","MP":"5098","W":"36","H":"39"},{"ID":"WAS-GNW-SWP----","MP":"5099","W":"36","H":"39"},{"ID":"WAS-GNFL--P----","MP":"5100","W":"36","H":"39"},{"ID":"WAS-GNFZ--P----","MP":"5101","W":"36","H":"39"},{"ID":"WAS-GNG-TIP----","MP":"5102","W":"36","H":"39"},{"ID":"WAS-GNLDN-P----","MP":"5103","W":"36","H":"38"},{"ID":"WAS-GNLDTCP----","MP":"5104","W":"36","H":"39"},{"ID":"WAS-GNLDMCP----","MP":"5105","W":"36","H":"39"},{"ID":"WAS-GNDEWCP----","MP":"5106","W":"36","H":"39"},{"ID":"WAS-GSSCL-P----","MP":"5108","W":"33","H":"38"},{"ID":"WAS-GSSCH-P----","MP":"5109","W":"36","H":"38"},{"ID":"WAS-GSSCCEP----","MP":"5110","W":"36","H":"39"},{"ID":"WAS-GSSCCUP----","MP":"5111","W":"36","H":"39"},{"ID":"WAS-GSSLL-P----","MP":"5112","W":"33","H":"38"},{"ID":"WAS-GSSLH-P----","MP":"5113","W":"36","H":"38"},{"ID":"WAS-GSSLCEP----","MP":"5114","W":"36","H":"39"},{"ID":"WAS-GSSLCUP----","MP":"5115","W":"36","H":"39"},{"ID":"WAS-GSSDC-P----","MP":"5116","W":"36","H":"39"},{"ID":"WOS-IB----P----","MP":"5117","W":"36","H":"29"},{"ID":"WOS-IBM---P----","MP":"5118","W":"44","H":"22"},{"ID":"WOS-IBBS--P----","MP":"5119","W":"36","H":"10"},{"ID":"WOS-IBG---P----","MP":"5120","W":"36","H":"29"},{"ID":"WOS-IBMG--P----","MP":"5121","W":"36","H":"29"},{"ID":"WOS-IBBB--P----","MP":"5122","W":"30","H":"30"},{"ID":"WOS-IBBBM-P----","MP":"5123","W":"30","H":"30"},{"ID":"WOS-IBGL--P----","MP":"5124","W":"30","H":"24"},{"ID":"WOS-IBGLM-P----","MP":"5125","W":"30","H":"24"},{"ID":"WOS-IBF---P----","MP":"5126","W":"36","H":"36"},{"ID":"WOS-IBII--P----","MP":"5127","W":"36","H":"36"},{"ID":"WOS-ICWB--P----","MP":"5128","W":"48","H":"17"},{"ID":"WOS-ICWR--P----","MP":"5129","W":"48","H":"16"},{"ID":"WOS-ICIF--P----","MP":"5130","W":"36","H":"14"},{"ID":"WOS-IDC---P----","MP":"5131","W":"42","H":"8"},{"ID":"WOS-IDD---P----","MP":"5132","W":"42","H":"8"},{"ID":"WOS-IDS---P----","MP":"5133","W":"20","H":"18"},{"ID":"WO-DIDID---L---","MP":"5134","W":"20","H":"8"},{"ID":"WO-DIDID--P----","MP":"5134","W":"20","H":"8"},{"ID":"WOS-II----P----","MP":"5135","W":"25","H":"24"},{"ID":"WOS-IITM--P----","MP":"5136","W":"46","H":"40"},{"ID":"WOS-IITE--P----","MP":"5137","W":"45","H":"40"},{"ID":"WOS-IIP---P----","MP":"5138","W":"39","H":"14"},{"ID":"WOS-ISC---P----","MP":"5139","W":"17","H":"29"},{"ID":"WOS-ISS---P----","MP":"5140","W":"29","H":"44"},{"ID":"WOS-ITRH--P----","MP":"5141","W":"36","H":"18"},{"ID":"WOS-ITR---P----","MP":"5142","W":"36","H":"26"},{"ID":"WOS-ITBB--P----","MP":"5143","W":"36","H":"18"},{"ID":"WOS-HDS---P----","MP":"5144","MA":"404","W":"30","H":"32"},{"ID":"WOS-HPB-O-P----","MP":"5145","W":"36","H":"36"},{"ID":"WOS-HPB-A-P----","MP":"5146","W":"46","H":"44"},{"ID":"WOS-HPBA--P----","MP":"5147","W":"46","H":"44"},{"ID":"WOS-HPCP--P----","MP":"5148","W":"19","H":"36"},{"ID":"WOS-HPFH--P----","MP":"5149","W":"36","H":"34"},{"ID":"WOS-HPFS--P----","MP":"5150","W":"34","H":"32"},{"ID":"WOS-HPFS---L---","MP":"5151","W":"36","H":"31"},{"ID":"WOS-HPML--P----","MP":"5152","W":"36","H":"36"},{"ID":"WO-DHPMO--P----","MP":"5153","W":"35","H":"38"},{"ID":"WO-DHPMO---L---","MP":"5154","W":"36","H":"4"},{"ID":"WOS-HPM-R-P----","MP":"5155","MA":"5156","W":"36","H":"20"},{"ID":"WOS-HPM-FC-L---","MP":"5157","W":"38","H":"10"},{"ID":"WOS-HPM-CC-L---","MP":"5158","W":"38","H":"10"},{"ID":"WOS-HPD---P----","MP":"5159","MA":"5160","W":"36","H":"20"},{"ID":"WOS-HABA--P----","MP":"5161","W":"36","H":"39"},{"ID":"WOS-HABB--P----","MP":"5162","MA":"5163","W":"52","H":"34"},{"ID":"WOS-HABM--P----","MP":"5164","W":"24","H":"32"},{"ID":"WOS-HABP--P----","MP":"5165","W":"24","H":"24"},{"ID":"WOS-HAL---P----","MP":"5166","W":"40","H":"36"},{"ID":"WOS-HALV--P----","MP":"5167","W":"36","H":"32"},{"ID":"WOS-HALH--P----","MP":"5168","W":"28","H":"36"},{"ID":"WOS-HHRS--P----","MP":"5169","MA":"5170","W":"26","H":"26"},{"ID":"WOS-HHRA--P----","MP":"5171","W":"26","H":"36"},{"ID":"WOS-HHDF--P----","MP":"5172","W":"26","H":"36"},{"ID":"WO-DHHDK--P----","MP":"5173","W":"38","H":"13"},{"ID":"WOS-HHDMDBP----","MP":"5174","W":"24","H":"36"},{"ID":"WOS-HHDMDFP----","MP":"5175","W":"24","H":"36"},{"ID":"WOS-HHDS--P----","MP":"5176","MA":"5177","W":"36","H":"22"},{"ID":"WOS-HHDWA-P----","MP":"5178","W":"42","H":"29"},{"ID":"WOS-HHDWB-P----","MP":"5179","MA":"5180","W":"36","H":"22"},{"ID":"WOS-HHDE--P----","MP":"5181","W":"59","H":"20"},{"ID":"WOS-BFC-S-P----","MP":"5182","W":"28","H":"37"},{"ID":"WOS-BFC-M-P----","MP":"5183","W":"38","H":"26"},{"ID":"WOS-BFC-CLP----","MP":"5184","W":"36","H":"30"},{"ID":"WOS-BFC-SIP----","MP":"5185","W":"36","H":"33"},{"ID":"WOS-BFC-STP----","MP":"5186","W":"36","H":"33"},{"ID":"WOS-BFC-G-P----","MP":"5187","W":"40","H":"42"},{"ID":"WOS-BFC-P-P----","MP":"5188","W":"30","H":"30"},{"ID":"WOS-BFC-CBP----","MP":"5189","W":"36","H":"26"},{"ID":"WOS-BFC-R-P----","MP":"5190","W":"30","H":"34"},{"ID":"WOS-BFC-COP----","MP":"5191","W":"36","H":"25"},{"ID":"WOS-BFC-SHP----","MP":"5192","W":"36","H":"28"},{"ID":"WOS-BFQ-F-P----","MP":"5193","W":"26","H":"36"},{"ID":"WOS-BFQ-M-P----","MP":"5194","W":"36","H":"25"},{"ID":"WOS-BFQ-C-P----","MP":"5195","W":"32","H":"36"},{"ID":"WOS-TCCW--P----","MP":"5196","W":"60","H":"21"},{"ID":"WOS-TCCTD-P----","MP":"5197","W":"30","H":"36"},{"ID":"WOS-TCCTG-P----","MP":"5198","MA":"5199","W":"33","H":"20"},{"ID":"WOS-MF----P----","MP":"5200","W":"12","H":"34"},{"ID":"WOS-ML----P----","MP":"5201","W":"22","H":"26"},{"ID":"WOS-MOA---P----","MP":"5202","W":"31","H":"42"},{"ID":"WOS-MPA---P----","MP":"5203","W":"24","H":"24"},{"ID":"G*G*GPUY--****X","MP":"2007","MA":"3007","W":"24","H":"48"},{"ID":"G*G*GPUS--****X","MP":"2020","MA":"2020","W":"39","H":"35"},{"ID":"G*G*GPF---****X","MP":"2040","MA":"3040","W":"36","H":"36"},{"ID":"G*G*GPH---****X","MP":"2041","MA":"3041","W":"32","H":"23"},{"ID":"G*G*GPO---****X","MP":"2046","MA":"3046","W":"36","H":"24"},{"ID":"G*G*GPPA--****X","MP":"2091","MA":"3091","W":"25","H":"45"},{"ID":"G*G*GPC---****X","MP":"2092","MA":"3092","W":"42","H":"29"},{"ID":"G*G*GPCU--****X","MP":"2093","MA":"3093","W":"42","H":"29"},{"ID":"G*G*GPCUR-****X","MP":"2094","MA":"3094","W":"42","H":"29"},{"ID":"G*G*GPCUA-****X","MP":"2095","MA":"3095","W":"42","H":"29"},{"ID":"G*G*GPCUS-****X","MP":"2096","MA":"3096","W":"42","H":"29"},{"ID":"G*G*GPCUM-****X","MP":"2097","MA":"3097","W":"42","H":"29"},{"ID":"G*G*GPCA--****X","MP":"2098","MA":"3098","W":"42","H":"29"},{"ID":"G*G*GPCS--****X","MP":"2099","MA":"3099","W":"42","H":"29"},{"ID":"G*G*GPCM--****X","MP":"2100","MA":"3100","W":"42","H":"29"},{"ID":"G*G*GPCP--****X","MP":"2101","MA":"3101","W":"42","H":"29"},{"ID":"G*G*GPCR--****X","MP":"2102","MA":"3102","W":"42","H":"29"},{"ID":"G*G*GPCC--****X","MP":"2103","MA":"3103","W":"42","H":"29"},{"ID":"G*G*GPCE--****X","MP":"2104","MA":"3104","W":"42","H":"29"},{"ID":"G*G*GPCN--****X","MP":"2105","MA":"3105","W":"42","H":"29"},{"ID":"G*G*GPB---****X","MP":"2106","MA":"2106","W":"42","H":"29"},{"ID":"G*G*GPBU--****X","MP":"2107","MA":"2107","W":"42","H":"29"},{"ID":"G*G*GPBUA-****X","MP":"2108","MA":"2108","W":"42","H":"29"},{"ID":"G*G*GPBUS-****X","MP":"2109","MA":"2109","W":"42","H":"29"},{"ID":"G*G*GPBUM-****X","MP":"2110","MA":"2110","W":"42","H":"29"},{"ID":"G*G*GPBS--****X","MP":"2111","MA":"2111","W":"42","H":"29"},{"ID":"G*G*GPBSA-****X","MP":"2112","MA":"2112","W":"42","H":"29"},{"ID":"E*N*AA----*****","MA":"6000","MP":"6000","W":"34","H":"34"},{"ID":"E*N*AB----*****","MA":"6001","MP":"6001","W":"30","H":"35"},{"ID":"E*N*AC----*****","MA":"6002","MP":"6002","W":"38","H":"38"},{"ID":"E*N*AD----*****","MA":"6003","MP":"6003","W":"39","H":"31"},{"ID":"E*N*AE----*****","MA":"6004","MP":"6004","W":"42","H":"18"},{"ID":"E*N*AG----*****","MA":"6006","MP":"6006","W":"34","H":"31"},{"ID":"E*N*BB----*****","MA":"6007","MP":"6007","W":"36","H":"25"},{"ID":"E*N*BC----*****","MA":"6008","MP":"6008","W":"32","H":"27"},{"ID":"E*N*BF----*****","MA":"6009","MP":"6009","W":"30","H":"28"},{"ID":"E*N*BM----*****","MA":"6010","MP":"6010","W":"36","H":"26"},{"ID":"E*N*CA----*****","MA":"6011","MP":"6011","W":"40","H":"30"},{"ID":"E*N*CB----*****","MA":"6012","MP":"6012","W":"44","H":"26"},{"ID":"E*N*CC----*****","MA":"6013","MP":"6013","W":"40","H":"18"},{"ID":"E*N*CD----*****","MA":"6014","MP":"6014","W":"36","H":"22"},{"ID":"E*N*CE----*****","MA":"6015","MP":"6015","W":"38","H":"28"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.SymbolConstantsC={"SYMBOLCONSTANTS":{"SYMBOL":[{"ID":"BS_BASIC_SHAPES","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Basic Shapes","H":"0.X",},{"ID":"BS_LINE--------","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Line","H":"0.X.1",},{"ID":"BS_AREA--------","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Area","H":"0.X.2",},{"ID":"BS_CROSS--------","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Cross","H":"0.X.3",},{"ID":"BS_ELLIPSE-----","G":"area","DC":"2","MXP":"3","MNP":"3","D":"Ellipse","H":"0.X.4",},{"ID":"BS_RECTANGLE---","G":"area","DC":"15","MXP":"10000","MNP":"2","M":"T.","D":"Rectangle","H":"0.X.5",},{"ID":"BUFFERED_SHAPES","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Buffered Basic Shapes","H":"0.X.6",},{"ID":"BBS_LINE-------","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"AM.T.","D":"Buffered Line","H":"0.X.6.1",},{"ID":"BBS_AREA-------","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"AM.T.","D":"Buffered Area","H":"0.X.6.2",},{"ID":"BBS_POINT------","G":"point","DC":"16","MXP":"1","MNP":"1","M":"AM.T.","D":"Buffered Point","H":"0.X.6.3",},{"ID":"BBS_RECTANGLE--","G":"area","DC":"15","MXP":"10000","MNP":"2","M":"AM.T.","D":"Buffered Rectangle","H":"0.X.6.4",},{"ID":"PARAMETERED_BASIC_SHAPES","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Parametered Basic Shapes","H":"0.X.7",},{"ID":"PBS_CIRCLE-----","G":"area","DC":"16","MXP":"1","MNP":"1","M":"AM.","D":"Circle","H":"0.X.7.1",},{"ID":"PBS_ELLIPSE----","G":"area","DC":"17","MXP":"1","MNP":"1","M":"AM.AN.","D":"Ellipse","H":"0.X.7.2",},{"ID":"PBS_SQUARE-----","G":"area","DC":"16","MXP":"1","MNP":"1","M":"AM.AN.","D":"Square","H":"0.X.7.3",},{"ID":"PBS_RECTANGLE--","G":"area","DC":"17","MXP":"1","MNP":"1","M":"AM.AN.","D":"Rectangle","H":"0.X.7.4",},{"ID":"G*-*------****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Tactical Graphics","H":"2.X",},{"ID":"G*T*------****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Tasks","H":"2.X.1",},{"ID":"G*T*B-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Block Task","H":"2.X.1.1",},{"ID":"G*T*H-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Breach","H":"2.X.1.2",},{"ID":"G*T*Y-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Bypass","H":"2.X.1.3",},{"ID":"G*T*C-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Canalize","H":"2.X.1.4",},{"ID":"G*T*X-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Clear","H":"2.X.1.5",},{"ID":"G*T*J-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Contain","H":"2.X.1.6",},{"ID":"G*T*K-----****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Counterattack (CATK)","H":"2.X.1.7",},{"ID":"G*T*KF----****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Counterattack by Fire","H":"2.X.1.7.1",},{"ID":"G*T*L-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","M":"W.","D":"Delay","H":"2.X.1.8",},{"ID":"G*T*D-----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Destroy","H":"2.X.1.9",},{"ID":"G*T*T-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Disrupt Tasks","H":"2.X.1.10",},{"ID":"G*T*F-----****X","G":"line","DC":"9","MXP":"2","MNP":"2","D":"Fix Task","H":"2.X.1.11",},{"ID":"G*T*A-----****X","G":"line","DC":"9","MXP":"2","MNP":"2","M":"T.","D":"Follow and Assume","H":"2.X.1.12",},{"ID":"G*T*AS----****X","G":"line","DC":"9","MXP":"2","MNP":"2","M":"T.","D":"Follow and Support","H":"2.X.1.12.1",},{"ID":"G*T*I-----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Interdict","H":"2.X.1.13",},{"ID":"G*T*E-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Isolate","H":"2.X.1.14",},{"ID":"G*T*N-----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Neutralize","H":"2.X.1.15",},{"ID":"G*T*O-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Occupy","H":"2.X.1.16",},{"ID":"G*T*P-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Penetrate","H":"2.X.1.17",},{"ID":"G*T*R-----****X","G":"line","DC":"15","MXP":"4","MNP":"4","D":"Relief in Place","H":"2.X.1.18",},{"ID":"G*T*Q-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Retain","H":"2.X.1.19",},{"ID":"G*T*M-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Retirement","H":"2.X.1.20",},{"ID":"G*T*S-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Secure","H":"2.X.1.21",},{"ID":"G*T*U-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Security","H":"2.X.1.22",},{"ID":"G*T*US----****X","G":"line","DC":"2","MXP":"4","MNP":"3","M":"A.","D":"Screen","H":"2.X.1.22.1",},{"ID":"G*T*UG----****X","G":"line","DC":"2","MXP":"4","MNP":"3","M":"A.","D":"Guard","H":"2.X.1.22.2",},{"ID":"G*T*UC----****X","G":"line","DC":"2","MXP":"4","MNP":"3","M":"A.","D":"Cover","H":"2.X.1.22.3",},{"ID":"G*T*Z-----****X","G":"line","DC":"15","MXP":"4","MNP":"3","M":"A.","D":"Seize","H":"2.X.1.23",},{"ID":"G*T*W-----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Withdraw","H":"2.X.1.24",},{"ID":"G*T*WP----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Withdraw Under Pressure","H":"2.X.1.24.1",},{"ID":"G*T*V-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Cordon and Search","H":"2.X.1.25",},{"ID":"G*T*2-----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Cordon and Knock","H":"2.X.1.26",},{"ID":"G*T*G-----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Suppress","H":"2.X.1.27",},{"ID":"G*G*------****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Command and Control and General Maneuver","H":"2.X.2",},{"ID":"G*G*G-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"General","H":"2.X.2.1",},{"ID":"G*G*GP----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.2.1.1",},{"ID":"G*G*GPU---****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Under Sea Warfare","H":"2.X.2.1.1.1",},{"ID":"G*G*GPUU--****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Underwater","H":"2.X.2.1.1.1.1",},{"ID":"G*G*GPUUD-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Underwater Datum","H":"2.X.2.1.1.1.1.1",},{"ID":"G*G*GPUUB-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Underwater Brief Contact","H":"2.X.2.1.1.1.1.2",},{"ID":"G*G*GPUUL-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Underwater Lost Contact","H":"2.X.2.1.1.1.1.3",},{"ID":"G*G*GPUUS-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Underwater Sinker","H":"2.X.2.1.1.1.1.4",},{"ID":"G*G*GPUY--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy","H":"2.X.2.1.1.1.2",},{"ID":"G*G*GPUYP-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Pattern Center","H":"2.X.2.1.1.1.2.1",},{"ID":"G*G*GPUYD-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Directional Frequency Analyzing and Recording (DIFAR)","H":"2.X.2.1.1.1.2.2",},{"ID":"G*G*GPUYL-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Low Frequency Analyzing and Recording (LOFAR)","H":"2.X.2.1.1.1.2.3",},{"ID":"G*G*GPUYC-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Command Active Sonobuoy System (CASS)","H":"2.X.2.1.1.1.2.4",},{"ID":"G*G*GPUYS-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Directional Command Active Sonobuoy System (DICASS)","H":"2.X.2.1.1.1.2.5",},{"ID":"G*G*GPUYB-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Bathythermograph Transmitting (BT)","H":"2.X.2.1.1.1.2.6",},{"ID":"G*G*GPUYA-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy ANM","H":"2.X.2.1.1.1.2.7",},{"ID":"G*G*GPUYV-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Vertical Line Array DIFAR (VLAD)","H":"2.X.2.1.1.1.2.8",},{"ID":"G*G*GPUYT-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy ATAC","H":"2.X.2.1.1.1.2.9",},{"ID":"G*G*GPUYR-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Range Only (RO)","H":"2.X.2.1.1.1.2.10",},{"ID":"G*G*GPUYK-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Kingpin","H":"2.X.2.1.1.1.2.11",},{"ID":"G*G*GPUYX-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sonobuoy Expired","H":"2.X.2.1.1.1.2.12",},{"ID":"G*G*GPUS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Search","H":"2.X.2.1.1.1.3",},{"ID":"G*G*GPUSA-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Search Area","H":"2.X.2.1.1.1.3.1",},{"ID":"G*G*GPUSD-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Dip Position","H":"2.X.2.1.1.1.3.2",},{"ID":"G*G*GPUSC-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Search Center","H":"2.X.2.1.1.1.3.3",},{"ID":"G*G*GPR---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Reference Point","H":"2.X.2.1.1.2",},{"ID":"G*G*GPRS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Special Point","H":"2.X.2.1.1.2.1",},{"ID":"G*G*GPRN--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Navigational Reference Point","H":"2.X.2.1.1.2.2",},{"ID":"G*G*GPRD--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"DLRP","H":"2.X.2.1.1.2.3",},{"ID":"G*G*GPRI--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Point of Interest","H":"2.X.2.1.1.2.4",},{"ID":"G*G*GPRP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Point of Intended Movement (PIM)","H":"2.X.2.1.1.2.5",},{"ID":"G*G*GPRM--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Marshall Point","H":"2.X.2.1.1.2.6",},{"ID":"G*G*GPRW--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Waypoint (Reference Point)","H":"2.X.2.1.1.2.7",},{"ID":"G*G*GPRC--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Corridor Tab","H":"2.X.2.1.1.2.8",},{"ID":"G*G*GPW---****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Weapon","H":"2.X.2.1.1.3",},{"ID":"G*G*GPWA--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Aim Point","H":"2.X.2.1.1.3.1",},{"ID":"G*G*GPWD--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Drop Point","H":"2.X.2.1.1.3.2",},{"ID":"G*G*GPWE--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Entry Point","H":"2.X.2.1.1.3.3",},{"ID":"G*G*GPWG--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ground Zero","H":"2.X.2.1.1.3.4",},{"ID":"G*G*GPWM--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"MSL Detect Point","H":"2.X.2.1.1.3.5",},{"ID":"G*G*GPWI--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Impact Point","H":"2.X.2.1.1.3.6",},{"ID":"G*G*GPWP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Predicted Impact Point","H":"2.X.2.1.1.3.7",},{"ID":"G*G*GPF---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Formation","H":"2.X.2.1.1.4",},{"ID":"G*G*GPH---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.","D":"Harbor General","H":"2.X.2.1.1.5",},{"ID":"G*G*GPHQ--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Harbor Point Q","H":"2.X.2.1.1.5.1",},{"ID":"G*G*GPHA--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Harbor Point A","H":"2.X.2.1.1.5.2",},{"ID":"G*G*GPHY--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Harbor Point Y","H":"2.X.2.1.1.5.3",},{"ID":"G*G*GPHX--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Harbor Point X","H":"2.X.2.1.1.5.4",},{"ID":"G*G*GPO---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route","H":"2.X.2.1.1.6",},{"ID":"G*G*GPOZ--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route Rendezvous","H":"2.X.2.1.1.6.1",},{"ID":"G*G*GPOD--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route Diversions","H":"2.X.2.1.1.6.2",},{"ID":"G*G*GPOW--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route Waypoint","H":"2.X.2.1.1.6.3",},{"ID":"G*G*GPOP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route PIM","H":"2.X.2.1.1.6.4",},{"ID":"G*G*GPOR--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Route Point R","H":"2.X.2.1.1.6.5",},{"ID":"G*G*GPA---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control","H":"2.X.2.1.1.7",},{"ID":"G*G*GPAP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Combat Air Patrol (CAP)","H":"2.X.2.1.1.7.1",},{"ID":"G*G*GPAW--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Airborne Early Warning (AEW)","H":"2.X.2.1.1.7.2",},{"ID":"G*G*GPAT--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control TACAN","H":"2.X.2.1.1.7.3",},{"ID":"G*G*GPAK--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Tanking","H":"2.X.2.1.1.7.4",},{"ID":"G*G*GPAA--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Antisubmarine Warfare, Fixed Wing","H":"2.X.2.1.1.7.5",},{"ID":"G*G*GPAH--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Antisubmarine Warfare, Rotary Wing","H":"2.X.2.1.1.7.6",},{"ID":"G*G*GPAO--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Tomcat","H":"2.X.2.1.1.7.7",},{"ID":"G*G*GPAR--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Rescue","H":"2.X.2.1.1.7.8",},{"ID":"G*G*GPAL--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Replenish","H":"2.X.2.1.1.7.9",},{"ID":"G*G*GPAS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Strike IP","H":"2.X.2.1.1.7.11",},{"ID":"G*G*GPAB--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control SUCAP - Fixed Wing","H":"2.X.2.1.1.7.13",},{"ID":"G*G*GPAC--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control SUCAP - Rotary Wing","H":"2.X.2.1.1.7.14",},{"ID":"G*G*GPAD--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control MIW - Fixed Wing","H":"2.X.2.1.1.7.15",},{"ID":"G*G*GPAE--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control MIW - Rotary Wing","H":"2.X.2.1.1.7.16",},{"ID":"G*G*GPAF--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Unmanned Aerial System (UAS/UA)","H":"2.X.2.1.1.7.17",},{"ID":"G*G*GPAG--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control VTUA","H":"2.X.2.1.1.7.18",},{"ID":"G*G*GPAI--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Orbit","H":"2.X.2.1.1.7.19",},{"ID":"G*G*GPAJ--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Orbit - Figure Eight","H":"2.X.2.1.1.7.20",},{"ID":"G*G*GPAM--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Orbit - Race Track","H":"2.X.2.1.1.7.21",},{"ID":"G*G*GPAN--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Air Control Orbit - Random, Closed","H":"2.X.2.1.1.7.22",},{"ID":"G*G*GPP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.H1.T.W.W1.N.","D":"Action Point","H":"2.X.2.1.1.8",},{"ID":"G*G*GPPK--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Check Point","H":"2.X.2.1.1.8.1",},{"ID":"G*G*GPPC--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Contact Point","H":"2.X.2.1.1.8.2",},{"ID":"G*G*GPPO--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Coordination Point","H":"2.X.2.1.1.8.3",},{"ID":"G*G*GPPD--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Decision Point","H":"2.X.2.1.1.8.4",},{"ID":"G*G*GPPL--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Linkup Point","H":"2.X.2.1.1.8.5",},{"ID":"G*G*GPPP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Passage Point","H":"2.X.2.1.1.8.6",},{"ID":"G*G*GPPR--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Rally Point","H":"2.X.2.1.1.8.7",},{"ID":"G*G*GPPE--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Release Point (RP)","H":"2.X.2.1.1.8.8",},{"ID":"G*G*GPPS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Start Point (SP)","H":"2.X.2.1.1.8.9",},{"ID":"G*G*GPPW--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Waypoint","H":"2.X.2.1.1.8.10",},{"ID":"G*G*GPPA--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Amnesty Point","H":"2.X.2.1.1.8.11",},{"ID":"G*G*GPPN--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.H.W.W1.N.","D":"Entry Control Point","H":"2.X.2.1.1.8.12",},{"ID":"G*G*GPC---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sea Surface Control Station","H":"2.X.2.1.1.9",},{"ID":"G*G*GPCU--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Unmanned Surface Vehicle (USV) Control Station","H":"2.X.2.1.1.9.1",},{"ID":"G*G*GPCUR-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Remote Multimission Vehicle (RMV) USV Control Station","H":"2.X.2.1.1.9.1.1",},{"ID":"G*G*GPCUA-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"USV - Antisubmarine Warfare Control Station","H":"2.X.2.1.1.9.1.2",},{"ID":"G*G*GPCUS-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"USV - Surface Warfare Control Station","H":"2.X.2.1.1.9.1.3",},{"ID":"G*G*GPCUM-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"USV - Mine Warfare Control Station","H":"2.X.2.1.1.9.1.4",},{"ID":"G*G*GPCA--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"ASW Control Station","H":"2.X.2.1.1.9.2",},{"ID":"G*G*GPCS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"SUW Control Station","H":"2.X.2.1.1.9.3",},{"ID":"G*G*GPCM--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"MIW Control Station","H":"2.X.2.1.1.9.4",},{"ID":"G*G*GPCP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Picket Control Station","H":"2.X.2.1.1.9.5",},{"ID":"G*G*GPCR--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rendezvous Control Point","H":"2.X.2.1.1.9.6",},{"ID":"G*G*GPCC--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rescue Control Point","H":"2.X.2.1.1.9.7",},{"ID":"G*G*GPCE--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Replenishment Control Point","H":"2.X.2.1.1.9.8",},{"ID":"G*G*GPCN--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Noncombatant Control Station","H":"2.X.2.1.1.9.9",},{"ID":"G*G*GPB---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Subsurface Control Station","H":"2.X.2.1.1.10",},{"ID":"G*G*GPBU--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Unmanned Underwater Vehicle (UUV) Control Station","H":"2.X.2.1.1.10.1",},{"ID":"G*G*GPBUA-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"UUV - Antisubmarine Warfare Control Station","H":"2.X.2.1.1.10.1.1",},{"ID":"G*G*GPBUS-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"UUV - Surface Warfare Control Station","H":"2.X.2.1.1.10.1.2",},{"ID":"G*G*GPBUM-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"UUV - Mine Warfare Control Station","H":"2.X.2.1.1.10.1.3",},{"ID":"G*G*GPBS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Submarine Control Station","H":"2.X.2.1.1.10.2",},{"ID":"G*G*GPBSA-****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"ASW Submarine Control Station","H":"2.X.2.1.1.10.2.1",},{"ID":"G*G*GL----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.2.1.2",},{"ID":"G*G*GLB---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"B.N.T.T1.","D":"Boundary","H":"2.X.2.1.2.1",},{"ID":"G*G*GLF---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Forward Line of Own Troops","H":"2.X.2.1.2.2",},{"ID":"G*G*GLC---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"N.","D":"Line of Contact (LC)","H":"2.X.2.1.2.3",},{"ID":"G*G*GLP---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Phase Line","H":"2.X.2.1.2.4",},{"ID":"G*G*GLL---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Light Line","H":"2.X.2.1.2.5",},{"ID":"G*G*GA----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Areas","H":"2.X.2.1.3",},{"ID":"G*G*GAG---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"General Area","H":"2.X.2.1.3.1",},{"ID":"G*G*GAA---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Assembly Area","H":"2.X.2.1.3.2",},{"ID":"G*G*GAE---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Engagement Area (General)","H":"2.X.2.1.3.3",},{"ID":"G*G*GAF---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Fortified Area","H":"2.X.2.1.3.4",},{"ID":"G*G*GAD---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Drop Zone","H":"2.X.2.1.3.5",},{"ID":"G*G*GAX---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Extraction Zone","H":"2.X.2.1.3.6",},{"ID":"G*G*GAL---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Landing Zone (LZ)","H":"2.X.2.1.3.7",},{"ID":"G*G*GAP---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.T.","D":"Pickup Zone (PZ)","H":"2.X.2.1.3.8",},{"ID":"G*G*GAS---****X","G":"line","DC":"2","MXP":"3","MNP":"3","M":"A.","D":"Search Area/Reconnaissance Area","H":"2.X.2.1.3.9",},{"ID":"G*G*GAY---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"A.","D":"Limited Access Area","H":"2.X.2.1.3.10",},{"ID":"G*G*GAZ---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Airfield Zone","H":"2.X.2.1.3.11",},{"ID":"G*G*A-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Aviation","H":"2.X.2.2",},{"ID":"G*G*AP----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.2.2.1",},{"ID":"G*G*APP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Air Control Point (ACP)","H":"2.X.2.2.1.1",},{"ID":"G*G*APC---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Communications Checkpoint (CCP)","H":"2.X.2.2.1.2",},{"ID":"G*G*APU---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Pull-Up Point (PUP)","H":"2.X.2.2.1.3",},{"ID":"G*G*APD---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"N.","D":"Downed Aircrew Pickup Point","H":"2.X.2.2.1.4",},{"ID":"G*G*AL----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.2.2.2",},{"ID":"G*G*ALC---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"X.X1.T.W.W1.AM.","D":"Air Corridor","H":"2.X.2.2.2.1",},{"ID":"G*G*ALM---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"X.X1.T.W.W1.AM.","D":"Minimum Risk Route (MRR)","H":"2.X.2.2.2.2",},{"ID":"G*G*ALS---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"X.X1.T.W.W1.AM.","D":"Standard-Use Army Aircraft Flight Route (SAAFR)","H":"2.X.2.2.2.3",},{"ID":"G*G*ALU---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"X.X1.T.W.W1.AM.","D":"Unmanned Aircraft (UA) Route","H":"2.X.2.2.2.4",},{"ID":"G*G*ALL---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"X.X1.T.W.W1.AM.","D":"Low Level Transit Route (LLTR)","H":"2.X.2.2.2.5",},{"ID":"G*G*AA----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Areas","H":"2.X.2.2.3",},{"ID":"G*G*AAR---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"Restricted Operations Zone (ROZ)","H":"2.X.2.2.3.1",},{"ID":"G*G*AAF---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"Short-Range Air Defense Engagement Zone (SHORADEZ)","H":"2.X.2.2.3.2",},{"ID":"G*G*AAH---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"High Density Airspace Control Zone (HIDACZ)","H":"2.X.2.2.3.3",},{"ID":"G*G*AAM---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"Missile Engagement Zone (MEZ)","H":"2.X.2.2.3.4",},{"ID":"G*G*AAML--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"Low Altitude MEZ","H":"2.X.2.2.3.4.1",},{"ID":"G*G*AAMH--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.T.W.W1.","D":"High Altitude MEZ","H":"2.X.2.2.3.4.2",},{"ID":"G*G*AAW---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Weapons Free Zone","H":"2.X.2.2.3.5",},{"ID":"G*G*P-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Deception","H":"2.X.2.3",},{"ID":"G*G*PD----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Dummy (Deception/Decoy)","H":"2.X.2.3.1",},{"ID":"G*G*PA----****X","G":"line","DC":"5","MXP":"10000","MNP":"3","M":"T.","D":"Axis of Advance for Feint","H":"2.X.2.3.2",},{"ID":"G*G*PF----****X","G":"line","DC":"4","MXP":"10000","MNP":"2","M":"T.","D":"Direction of Attack for Feint","H":"2.X.2.3.3",},{"ID":"G*G*PM----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Decoy Mined Area","H":"2.X.2.3.4",},{"ID":"G*G*PY----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Decoy Mined Area, Fenced","H":"2.X.2.3.5",},{"ID":"G*G*PN----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Dummy Minefield - Static","H":"2.X.2.3.6",},{"ID":"G*G*PC----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"H.N.","D":"Dummy Minefield - Dynamic","H":"2.X.2.3.7",},{"ID":"G*G*D-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Defense","H":"2.X.2.4",},{"ID":"G*G*DP----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.2.4.1",},{"ID":"G*G*DPT---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Target Reference","H":"2.X.2.4.1.1",},{"ID":"G*G*DPO---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Observation Post (OP)/Outpost","H":"2.X.2.4.1.2",},{"ID":"G*G*DPOC--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Combat Outpost","H":"2.X.2.4.1.2.1",},{"ID":"G*G*DPOR--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Observation Post Occupied Dismounted Recon","H":"2.X.2.4.1.2.2",},{"ID":"G*G*DPOF--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Forward Observer Position Outpost","H":"2.X.2.4.1.2.3",},{"ID":"G*G*DPOS--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sensor Outpost/Listening Post (OP/LP)","H":"2.X.2.4.1.2.4",},{"ID":"G*G*DPON--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"CBRN Observation Post Dismounted","H":"2.X.2.4.1.2.5",},{"ID":"G*G*DL----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.2.4.2",},{"ID":"G*G*DLF---****X","G":"line","DC":"1","MXP":"2","MNP":"2","D":"Forward Edge of Battle Area","H":"2.X.2.4.2.1",},{"ID":"G*G*DLP---****X","G":"line","DC":"15","MXP":"3","MNP":"3","M":"A.","D":"Principal Direction of Fire (PDF)","H":"2.X.2.4.2.2",},{"ID":"G*G*DA----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Areas","H":"2.X.2.4.3",},{"ID":"G*G*DAB---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"B.N.T.","D":"Battle Position","H":"2.X.2.4.3.1",},{"ID":"G*G*DABP--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"B.N.T.","D":"Battle Position Prepared but not Occupied","H":"2.X.2.4.3.1.1",},{"ID":"G*G*DAE---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Engagement Area (Defense)","H":"2.X.2.4.3.2",},{"ID":"G*G*O-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Offense","H":"2.X.2.5",},{"ID":"G*G*OP----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.2.5.1",},{"ID":"G*G*OPP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Point of Departure","H":"2.X.2.5.1.1",},{"ID":"G*G*OL----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.2.5.2",},{"ID":"G*G*OLA---****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Axis of Advance","H":"2.X.2.5.2.1",},{"ID":"G*G*OLAV--****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Axis of Advance Aviation","H":"2.X.2.5.2.1.1",},{"ID":"G*G*OLAA--****X","G":"line","DC":"5","MXP":"10000","MNP":"3","M":"A.","D":"Axis of Advance Airborne","H":"2.X.2.5.2.1.2",},{"ID":"G*G*OLAR--****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Axis of Advance Attack, Rotary Wing","H":"2.X.2.5.2.1.3",},{"ID":"G*G*OLAG--****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Axis of Advance Ground","H":"2.X.2.5.2.1.4",},{"ID":"G*G*OLAGM-****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Axis of Advance Ground Main Attack","H":"2.X.2.5.2.1.4.1",},{"ID":"G*G*OLAGS-****X","G":"line","DC":"5","MXP":"10000","MNP":"3","D":"Axis of Advance Ground Supporting Attack","H":"2.X.2.5.2.1.4.2",},{"ID":"G*G*OLK---****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Direction of Attack","H":"2.X.2.5.2.2",},{"ID":"G*G*OLKA--****X","G":"line","DC":"4","MXP":"10000","MNP":"2","M":"N.","D":"Direction of Attack Aviation","H":"2.X.2.5.2.2.1",},{"ID":"G*G*OLKG--****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Direction of Attack Ground","H":"2.X.2.5.2.2.2",},{"ID":"G*G*OLKGM-****X","G":"line","DC":"4","MXP":"10000","MNP":"2","D":"Direction of Attack Ground Main Attack","H":"2.X.2.5.2.2.2.1",},{"ID":"G*G*OLKGS-****X","G":"line","DC":"4","MXP":"10000","MNP":"2","D":"Direction of Attack Ground Supporting Attack","H":"2.X.2.5.2.2.2.2",},{"ID":"G*G*OLF---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Final Coordination Line","H":"2.X.2.5.2.3",},{"ID":"G*G*OLI---****X","G":"line","DC":"15","MXP":"3","MNP":"3","M":"T.","D":"Infiltration Lane","H":"2.X.2.5.2.4",},{"ID":"G*G*OLL---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Limit Of Advance (LOA)","H":"2.X.2.5.2.5",},{"ID":"G*G*OLT---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Line of Departure (LD)","H":"2.X.2.5.2.6",},{"ID":"G*G*OLC---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Line of Departure/Line of Contact (LD/LC)","H":"2.X.2.5.2.7",},{"ID":"G*G*OLP---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Probable Line of Deployment (PLD)","H":"2.X.2.5.2.8",},{"ID":"G*G*OA----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Areas","H":"2.X.2.5.3",},{"ID":"G*G*OAA---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Assault Position","H":"2.X.2.5.3.1",},{"ID":"G*G*OAK---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Attack Position","H":"2.X.2.5.3.2",},{"ID":"G*G*OAF---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Attack by Fire Position","H":"2.X.2.5.3.3",},{"ID":"G*G*OAS---****X","G":"line","DC":"15","MXP":"4","MNP":"4","D":"Support by Fire Position","H":"2.X.2.5.3.4",},{"ID":"G*G*OAO---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Objective","H":"2.X.2.5.3.5",},{"ID":"G*G*OAP---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Penetration Box","H":"2.X.2.5.3.6",},{"ID":"G*G*S-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Special","H":"2.X.2.6",},{"ID":"G*G*SL----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Line","H":"2.X.2.6.1",},{"ID":"G*G*SLA---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Ambush","H":"2.X.2.6.1.1",},{"ID":"G*G*SLH---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Holding Line","H":"2.X.2.6.1.2",},{"ID":"G*G*SLR---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Release Line","H":"2.X.2.6.1.3",},{"ID":"G*G*SLB---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Bridgehead","H":"2.X.2.6.1.4",},{"ID":"G*G*SA----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Area","H":"2.X.2.6.2",},{"ID":"G*G*SAO---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Area of Operations (AO)","H":"2.X.2.6.2.1",},{"ID":"G*G*SAA---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Airhead","H":"2.X.2.6.2.2",},{"ID":"G*G*SAE---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Encirclement","H":"2.X.2.6.2.3",},{"ID":"G*G*SAN---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Named Area of Interest (NAI)","H":"2.X.2.6.2.4",},{"ID":"G*G*SAT---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Targeted Area of Interest (TAI)","H":"2.X.2.6.2.5",},{"ID":"G*M*------****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Mobility/Survivability","H":"2.X.3",},{"ID":"G*M*O-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Obstacles","H":"2.X.3.1",},{"ID":"G*M*OG----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"General (Obstacles)","H":"2.X.3.1.1",},{"ID":"G*M*OGB---****X","G":"area","DC":"3","MXP":"10000","MNP":"2","M":"T.T1.","D":"Obstacle Belt","H":"2.X.3.1.1.1",},{"ID":"G*M*OGL---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Obstacle Line","H":"2.X.3.1.1.2",},{"ID":"G*M*OGZ---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Obstacle Zone","H":"2.X.3.1.1.3",},{"ID":"G*M*OGF---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Obstacle Free Area","H":"2.X.3.1.1.4",},{"ID":"G*M*OGR---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Obstacle Restricted Area","H":"2.X.3.1.1.5",},{"ID":"G*M*OS----****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Abatis","H":"2.X.3.1.2",},{"ID":"G*M*OA----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Antitank Obstacles","H":"2.X.3.1.3",},{"ID":"G*M*OAD---****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Antitank Ditch","H":"2.X.3.1.3.1",},{"ID":"G*M*OADU--****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Antitank Ditch Under Construction","H":"2.X.3.1.3.1.1",},{"ID":"G*M*OADC--****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Antitank Ditch Complete","H":"2.X.3.1.3.1.2",},{"ID":"G*M*OAR---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Antitank Ditch Reinforced with Antitank Mines","H":"2.X.3.1.3.2",},{"ID":"G*M*OAO---****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Antitank Obstacles, Tetrahedrons, Dragons Teeth, and Other Similar Obstacles","H":"2.X.3.1.3.3",},{"ID":"G*M*OAOF--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Obstacles Fixed and Prefabricated","H":"2.X.3.1.3.3.1",},{"ID":"G*M*OAOM--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Obstacles Moveable","H":"2.X.3.1.3.3.2",},{"ID":"G*M*OAOP--****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Obstacles Moveable and Prefabricated","H":"2.X.3.1.3.3.3",},{"ID":"G*M*OAW---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Antitank Wall","H":"2.X.3.1.3.4",},{"ID":"G*M*OB----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Booby Trap","H":"2.X.3.1.4",},{"ID":"G*M*OM----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Mines","H":"2.X.3.1.5",},{"ID":"G*M*OMU---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Unspecified Mine","H":"2.X.3.1.5.1",},{"ID":"G*M*OMT---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Mine","H":"2.X.3.1.5.2",},{"ID":"G*M*OMD---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Mine With Antihandling Device","H":"2.X.3.1.5.3",},{"ID":"G*M*OME---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antitank Mine, Directional","H":"2.X.3.1.5.4",},{"ID":"G*M*OMP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Antipersonnel Mine","H":"2.X.3.1.5.5",},{"ID":"G*M*OMW---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Wide Area Mines","H":"2.X.3.1.5.6",},{"ID":"G*M*OMC---****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Mine Cluster","H":"2.X.3.1.5.7",},{"ID":"G*M*OF----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Minefields","H":"2.X.3.1.6",},{"ID":"G*M*OFS---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.N.W.A.","D":"Minefield (Static)","H":"2.X.3.1.6.1",},{"ID":"G*M*OFD---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"H.N.W.","D":"Minefield (Dynamic)","H":"2.X.3.1.6.2",},{"ID":"G*M*OFG---****X","G":"line","DC":"15","MXP":"4","MNP":"4","M":"W.W1.","D":"Minefields Gap","H":"2.X.3.1.6.3",},{"ID":"G*M*OFA---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"N.","D":"Mined Area","H":"2.X.3.1.6.4",},{"ID":"G*M*OE----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Obstacle Effect","H":"2.X.3.1.7",},{"ID":"G*M*OEB---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Block Obstacle Effect","H":"2.X.3.1.7.1",},{"ID":"G*M*OEF---****X","G":"line","DC":"9","MXP":"2","MNP":"2","D":"Fix (Obstacle Effect)","H":"2.X.3.1.7.2",},{"ID":"G*M*OET---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Turn","H":"2.X.3.1.7.3",},{"ID":"G*M*OED---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Disrupt Obstacle Effect","H":"2.X.3.1.7.4",},{"ID":"G*M*OU----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Unexploded Ordnance Area (UXO)","H":"2.X.3.1.8",},{"ID":"G*M*OR----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Roadblocks, Craters, and Blown Bridges","H":"2.X.3.1.9",},{"ID":"G*M*ORP---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"RCBB Planned","H":"2.X.3.1.9.1",},{"ID":"G*M*ORS---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"RCBB Explosives State of Readiness 1 (Safe)","H":"2.X.3.1.9.2",},{"ID":"G*M*ORA---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"RCBB Explosives State of Readiness 2 (Armed - but Passable)","H":"2.X.3.1.9.3",},{"ID":"G*M*ORC---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"RCBB Roadblock Complete (Executed)","H":"2.X.3.1.9.4",},{"ID":"G*M*OT----****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Trip Wire","H":"2.X.3.1.10",},{"ID":"G*M*OW----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Wire Obstacle","H":"2.X.3.1.11",},{"ID":"G*M*OWU---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Unspecified","H":"2.X.3.1.11.1",},{"ID":"G*M*OWS---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Single Fence","H":"2.X.3.1.11.2",},{"ID":"G*M*OWD---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Double Fence","H":"2.X.3.1.11.3",},{"ID":"G*M*OWA---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Double Apron Fence","H":"2.X.3.1.11.4",},{"ID":"G*M*OWL---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Low Wire Fence","H":"2.X.3.1.11.5",},{"ID":"G*M*OWH---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle High Wire Fence","H":"2.X.3.1.11.6",},{"ID":"G*M*OWC---****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Concertina","H":"2.X.3.1.11.7",},{"ID":"G*M*OWCS--****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Single Concertina","H":"2.X.3.1.11.7.1",},{"ID":"G*M*OWCD--****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Double Strand Concertina","H":"2.X.3.1.11.7.2",},{"ID":"G*M*OWCT--****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Wire Obstacle Triple Strand Concertina","H":"2.X.3.1.11.7.3",},{"ID":"G*M*OH----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Aviation","H":"2.X.3.1.12",},{"ID":"G*M*OHT---****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Tower","H":"2.X.3.1.12.1",},{"ID":"G*M*OHTL--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Aviation Tower Low","H":"2.X.3.1.12.1.1",},{"ID":"G*M*OHTH--****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Aviation Tower High","H":"2.X.3.1.12.1.2",},{"ID":"G*M*OHO---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Overhead Wire","H":"2.X.3.1.12.2",},{"ID":"G*M*B-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Obstacle Bypass","H":"2.X.3.2",},{"ID":"G*M*BD----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Obstacle Bypass Difficulty","H":"2.X.3.2.1",},{"ID":"G*M*BDE---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Bypass Easy","H":"2.X.3.2.1.1",},{"ID":"G*M*BDD---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Bypass Difficult","H":"2.X.3.2.1.2",},{"ID":"G*M*BDI---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Bypass Impossible","H":"2.X.3.2.1.3",},{"ID":"G*M*BC----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Crossing Site/Water Crossing","H":"2.X.3.2.2",},{"ID":"G*M*BCA---****X","G":"line","DC":"15","MXP":"4","MNP":"4","D":"Assault Crossing Area","H":"2.X.3.2.2.1",},{"ID":"G*M*BCB---****X","G":"line","DC":"15","MXP":"4","MNP":"4","D":"Bridge or Gap","H":"2.X.3.2.2.2",},{"ID":"G*M*BCF---****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Ferry","H":"2.X.3.2.2.3",},{"ID":"G*M*BCE---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Ford Easy","H":"2.X.3.2.2.4",},{"ID":"G*M*BCD---****X","G":"line","DC":"15","MXP":"3","MNP":"3","D":"Ford Difficult","H":"2.X.3.2.2.5",},{"ID":"G*M*BCL---****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Lane","H":"2.X.3.2.2.6",},{"ID":"G*M*BCR---****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Raft Site","H":"2.X.3.2.2.7",},{"ID":"G*M*BCP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Engineer Regulating Point","H":"2.X.3.2.2.8",},{"ID":"G*M*S-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Survivability","H":"2.X.3.3",},{"ID":"G*M*SE----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Earthwork, Small Trench or Fortification","H":"2.X.3.3.1",},{"ID":"G*M*SF----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fort","H":"2.X.3.3.2",},{"ID":"G*M*SL----****X","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Fortified Line","H":"2.X.3.3.3",},{"ID":"G*M*SW----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Foxhole, Emplacement or Weapon Site","H":"2.X.3.3.4",},{"ID":"G*M*SP----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"B.T.","D":"Strong Point","H":"2.X.3.3.5",},{"ID":"G*M*SS----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Surface Shelter","H":"2.X.3.3.6",},{"ID":"G*M*SU----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Underground Shelter","H":"2.X.3.3.7",},{"ID":"G*M*N-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Nuclear, Biological, and Chemical","H":"2.X.3.4",},{"ID":"G*M*NM----****X","G":"line","DC":"2","MXP":"4","MNP":"4","D":"Minimum Safe Distance Zones","H":"2.X.3.4.1",},{"ID":"G*M*NZ----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"C.H.N.Q.T.V.W.Y.","D":"Nuclear Detonations Ground Zero","H":"2.X.3.4.2",},{"ID":"G*M*NF----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fallout Producing","H":"2.X.3.4.3",},{"ID":"G*M*NR----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Radioactive Area","H":"2.X.3.4.4",},{"ID":"G*M*NB----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Biologically Contaminated Area","H":"2.X.3.4.5",},{"ID":"G*M*NC----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Chemically Contaminated Area","H":"2.X.3.4.6",},{"ID":"G*M*NE----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Release Events","H":"2.X.3.4.7",},{"ID":"G*M*NEB---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.N.Q.T.W.Y.","D":"Biological Event","H":"2.X.3.4.7.1",},{"ID":"G*M*NEC---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.N.Q.T.W.Y.","D":"Chemical Event","H":"2.X.3.4.7.2",},{"ID":"G*M*ND----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Decontamination (DECON) Points","H":"2.X.3.4.8",},{"ID":"G*M*NDP---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Unspecified","H":"2.X.3.4.8.1",},{"ID":"G*M*NDA---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Alternate Decon Site/Point Unspecified","H":"2.X.3.4.8.2",},{"ID":"G*M*NDT---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Troops","H":"2.X.3.4.8.3",},{"ID":"G*M*NDE---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Equipment","H":"2.X.3.4.8.4",},{"ID":"G*M*NDB---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Equipment and Troops","H":"2.X.3.4.8.5",},{"ID":"G*M*NDO---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Operational Decontamination","H":"2.X.3.4.8.6",},{"ID":"G*M*NDD---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Decon Site/Point Thorough Decontamination","H":"2.X.3.4.8.7",},{"ID":"G*M*NL----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Dose Rate Contour Lines","H":"2.X.3.4.9",},{"ID":"G*F*------****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Fire Support","H":"2.X.4",},{"ID":"G*F*P-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.4.1",},{"ID":"G*F*PT----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Target","H":"2.X.4.1.1",},{"ID":"G*F*PTS---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.H1.T.","D":"Point/Single Target","H":"2.X.4.1.1.1",},{"ID":"G*F*PTN---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Nuclear Target","H":"2.X.4.1.1.2",},{"ID":"G*F*PC----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Command and Control","H":"2.X.4.1.2",},{"ID":"G*F*PCF---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.","D":"Fire Support Station","H":"2.X.4.1.2.1",},{"ID":"G*F*PCS---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Survey Control Point","H":"2.X.4.1.2.2",},{"ID":"G*F*PCB---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Firing Point","H":"2.X.4.1.2.3",},{"ID":"G*F*PCR---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Reload Point","H":"2.X.4.1.2.4",},{"ID":"G*F*PCH---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Hide Point","H":"2.X.4.1.2.5",},{"ID":"G*F*PCL---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Launch Point","H":"2.X.4.1.2.6",},{"ID":"G*F*L-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.4.2",},{"ID":"G*F*LT----****X","G":"line","DC":"6","MXP":"2","MNP":"2","M":"T.","D":"Linear Target","H":"2.X.4.2.1",},{"ID":"G*F*LTS---****X","G":"line","DC":"6","MXP":"2","MNP":"2","M":"T.","D":"Linear Smoke Target","H":"2.X.4.2.1.1",},{"ID":"G*F*LTF---****X","G":"line","DC":"6","MXP":"2","MNP":"2","M":"T.T1.","D":"Final Protective Fire","H":"2.X.4.2.1.2",},{"ID":"G*F*LC----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Command and Control Lines","H":"2.X.4.2.2",},{"ID":"G*F*LCF---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.W.W1.","D":"Fire Support Coordination Line","H":"2.X.4.2.2.1",},{"ID":"G*F*LCC---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.W.W1.","D":"Coordinated Fire Line (CFL)","H":"2.X.4.2.2.2",},{"ID":"G*F*LCN---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"No-Fire Line (NFL)","H":"2.X.4.2.2.3",},{"ID":"G*F*LCR---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.W.W1.","D":"Restrictive Fire Line (RFL)","H":"2.X.4.2.2.4",},{"ID":"G*F*LCM---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"W.W1.","D":"Munition Flight Path (MFP)","H":"2.X.4.2.2.5",},{"ID":"G*F*A-----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Areas","H":"2.X.4.3",},{"ID":"G*F*AT----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Area Target","H":"2.X.4.3.1",},{"ID":"G*F*ATR---****X","G":"area","DC":"17","MXP":"1","MNP":"1","M":"T.AM.AN.","D":"Rectangular Target","H":"2.X.4.3.1.1",},{"ID":"G*F*ATC---****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.AM.","D":"Circular Target","H":"2.X.4.3.1.2",},{"ID":"G*F*ATG---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Group of Targets","H":"2.X.4.3.1.3",},{"ID":"G*F*ATS---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.","D":"Smoke Area","H":"2.X.4.3.1.4",},{"ID":"G*F*ATB---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bomb Area","H":"2.X.4.3.1.5",},{"ID":"G*F*AC----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Command and Control Areas","H":"2.X.4.3.2",},{"ID":"G*F*ACS---****X","G":"area","DC":"0","MXP":"0","MNP":"0","M":"T.W.W1.","D":"Fire Support Area (FSA)","H":"2.X.4.3.2.1",},{"ID":"G*F*ACSI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Fire Support Area (FSA) Irregular","H":"2.X.4.3.2.1.1",},{"ID":"G*F*ACSR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Fire Support Area (FSA) Rectangular","H":"2.X.4.3.2.1.2",},{"ID":"G*F*ACSC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Fire Support Area (FSA) Circular","H":"2.X.4.3.2.1.3",},{"ID":"G*F*ACA---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Airspace Coordination Area (ACA)","H":"2.X.4.3.2.2",},{"ID":"G*F*ACAI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"X.X1.H2.T.W.W1.","D":"Airspace Coordination Area (ACA) Irregular","H":"2.X.4.3.2.2.1",},{"ID":"G*F*ACAR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.X.X1.H2.W.W1.AM.","D":"Airspace Coordination Area (ACA) Rectangular","H":"2.X.4.3.2.2.2",},{"ID":"G*F*ACAC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.X.X1.H2.W.W1.AM.","D":"Airspace Coordination Area (ACA) Circular","H":"2.X.4.3.2.2.3",},{"ID":"G*F*ACF---****X","G":"area","DC":"0","MXP":"0","MNP":"0","M":"T.W.W1.","D":"Free Fire Area (FFA)","H":"2.X.4.3.2.3",},{"ID":"G*F*ACFI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Free Fire Area (FFA) Irregular","H":"2.X.4.3.2.3.1",},{"ID":"G*F*ACFR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Free Fire Area (FFA) Rectangular","H":"2.X.4.3.2.3.2",},{"ID":"G*F*ACFC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Free Fire Area (FFA) Circular","H":"2.X.4.3.2.3.3",},{"ID":"G*F*ACN---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"No-Fire Area (NFA)","H":"2.X.4.3.2.4",},{"ID":"G*F*ACNI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"No-Fire Area (NFA) Irregular","H":"2.X.4.3.2.4.1",},{"ID":"G*F*ACNR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"No-Fire Area (NFA) Rectangular","H":"2.X.4.3.2.4.2",},{"ID":"G*F*ACNC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"No-Fire Area (NFA) Circular","H":"2.X.4.3.2.4.3",},{"ID":"G*F*ACR---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Restrictive Fire Area (RFA)","H":"2.X.4.3.2.5",},{"ID":"G*F*ACRI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Restrictive Fire Area (RFA) Irregular","H":"2.X.4.3.2.5.1",},{"ID":"G*F*ACRR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Restrictive Fire Area (RFA) Rectangular","H":"2.X.4.3.2.5.2",},{"ID":"G*F*ACRC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Restrictive Fire Area (RFA) Circular","H":"2.X.4.3.2.5.3",},{"ID":"G*F*ACP---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Position Area for Artillery (PAA)","H":"2.X.4.3.2.6",},{"ID":"G*F*ACPR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"AM.","D":"Position Area for Artillery (PAA) Rectangular","H":"2.X.4.3.2.6.1",},{"ID":"G*F*ACPC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"AM.","D":"Position Area For Artillery (PAA) Circular","H":"2.X.4.3.2.6.2",},{"ID":"G*F*ACE---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Sensor Zone","H":"2.X.4.3.2.7",},{"ID":"G*F*ACEI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Sensor Zone Irregular","H":"2.X.4.3.2.7.1",},{"ID":"G*F*ACER--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Sensor Zone Rectangular","H":"2.X.4.3.2.7.2",},{"ID":"G*F*ACEC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Sensor Zone Circular","H":"2.X.4.3.2.7.3",},{"ID":"G*F*ACD---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Dead Space Area (DA)","H":"2.X.4.3.2.8",},{"ID":"G*F*ACDI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Dead Space Area (DA) Irregular","H":"2.X.4.3.2.8.1",},{"ID":"G*F*ACDR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Dead Space Area (DA) Rectangular","H":"2.X.4.3.2.8.2",},{"ID":"G*F*ACDC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Dead Space Area (DA) Circular","H":"2.X.4.3.2.8.3",},{"ID":"G*F*ACZ---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Zone of Responsibility (ZOR)","H":"2.X.4.3.2.9",},{"ID":"G*F*ACZI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Zone of Responsibility (ZOR) Irregular","H":"2.X.4.3.2.9.1",},{"ID":"G*F*ACZR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Zone of Responsibility (ZOR) Rectangular","H":"2.X.4.3.2.9.2",},{"ID":"G*F*ACZC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Zone of Responsibility (ZOR) Circular","H":"2.X.4.3.2.9.3",},{"ID":"G*F*ACB---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Target Build-Up Area (TBA)","H":"2.X.4.3.2.10",},{"ID":"G*F*ACBI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Target Build-Up Area (TBA) Irregular","H":"2.X.4.3.2.10.1",},{"ID":"G*F*ACBR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Target Build-Up Area (TBA) Rectangular","H":"2.X.4.3.2.10.2",},{"ID":"G*F*ACBC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Target Build-Up Area (TBA) Circular","H":"2.X.4.3.2.10.3",},{"ID":"G*F*ACV---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Target Value Area (TVAR)","H":"2.X.4.3.2.11",},{"ID":"G*F*ACVI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Target Value Area (TVAR) Irregular","H":"2.X.4.3.2.11.1",},{"ID":"G*F*ACVR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Target Value Area (TVAR) Rectangular","H":"2.X.4.3.2.11.2",},{"ID":"G*F*ACVC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Target Value Area (TVAR) Circular","H":"2.X.4.3.2.11.3",},{"ID":"G*F*ACT---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Terminally Guided Munition Footprint (TGMF)","H":"2.X.4.3.2.12",},{"ID":"G*F*AZ----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Target Acquisition Zones","H":"2.X.4.3.3",},{"ID":"G*F*AZI---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Artillery Target Intelligence (ATI)","H":"2.X.4.3.3.1",},{"ID":"G*F*AZII--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Artillery Target Intelligence (ATI) Zone Irregular","H":"2.X.4.3.3.1.1",},{"ID":"G*F*AZIR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Artillery Target Intelligence (ATI) Zone Rectangular","H":"2.X.4.3.3.1.2",},{"ID":"G*F*AZIC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Artillery Target Intelligence (ATI) Zone Circular","H":"2.X.4.3.3.1.3",},{"ID":"G*F*AZX---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Call for Fire Zone (CFFZ)","H":"2.X.4.3.3.2",},{"ID":"G*F*AZXI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Call For Fire Zone (CFFZ) Irregular","H":"2.X.4.3.3.2.1",},{"ID":"G*F*AZXR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Call For Fire Zone (CFFZ) Rectangular","H":"2.X.4.3.3.2.2",},{"ID":"G*F*AZXC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM","D":"Call For Fire Zone (CFFZ) Circular","H":"2.X.4.3.3.2.3",},{"ID":"G*F*AZC---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Censor Zone","H":"2.X.4.3.3.4",},{"ID":"G*F*AZCI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Censor Zone Irregular","H":"2.X.4.3.3.4.1",},{"ID":"G*F*AZCR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM","D":"Censor Zone Rectangular","H":"2.X.4.3.3.4.2",},{"ID":"G*F*AZCC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Censor Zone Circular","H":"2.X.4.3.3.4.3",},{"ID":"G*F*AZF---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Critical Friendly Zone (CFZ)","H":"2.X.4.3.3.6",},{"ID":"G*F*AZFI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.W.W1.","D":"Critical Friendly Zone (CFZ) Irregular","H":"2.X.4.3.3.6.1",},{"ID":"G*F*AZFR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"T.W.W1.AM.","D":"Critical Friendly Zone (CFZ) Rectangular","H":"2.X.4.3.3.6.2",},{"ID":"G*F*AZFC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"T.W.W1.AM.","D":"Critical Friendly Zone (CFZ) Circular","H":"2.X.4.3.3.6.3",},{"ID":"G*F*AX----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Radar Range Fans","H":"2.X.4.3.4",},{"ID":"G*F*AXC---****X","G":"area","DC":"19","MXP":"1","MNP":"1","M":"X.AM.","D":"Circular Range Fan","H":"2.X.4.3.4.1",},{"ID":"G*F*AXS---****X","G":"area","DC":"18","MXP":"1","MNP":"1","M":"X.AM.AN.","D":"Sector Range Fan","H":"2.X.4.3.4.2",},{"ID":"G*F*AK----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Kill Box","H":"2.X.4.3.5",},{"ID":"G*F*AKB---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Blue","H":"2.X.4.3.5.1",},{"ID":"G*F*AKBC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.","D":"Kill Box Blue Circular","H":"2.X.4.3.5.1.1",},{"ID":"G*F*AKBI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.","D":"Kill Box Blue Irregular","H":"2.X.4.3.5.1.2",},{"ID":"G*F*AKBR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.","D":"Kill Box Blue Rectangular","H":"2.X.4.3.5.1.3",},{"ID":"G*F*AKP---****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Purple","H":"2.X.4.3.5.2",},{"ID":"G*F*AKPC--****X","G":"area","DC":"16","MXP":"1","MNP":"1","M":"W.W1.T.AM.X.","D":"Kill Box Purple Circular","H":"2.X.4.3.5.2.1",},{"ID":"G*F*AKPI--****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"W.W1.T.X.","D":"Kill Box Purple Irregular","H":"2.X.4.3.5.2.2",},{"ID":"G*F*AKPR--****X","G":"area","DC":"20","MXP":"2","MNP":"2","M":"W.W1.T.AM.X.","D":"Kill Box Purple Rectangular","H":"2.X.4.3.5.2.3",},{"ID":"G*S*------****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Combat Service Support","H":"2.X.5",},{"ID":"G*S*P-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Points","H":"2.X.5.1",},{"ID":"G*S*PX----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.T1.W.W1.N.>","D":"Ambulance Exchange Point","H":"2.X.5.1.1",},{"ID":"G*S*PC----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Cannibalization Point","H":"2.X.5.1.2",},{"ID":"G*S*PY----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Casualty Collection Point","H":"2.X.5.1.3",},{"ID":"G*S*PT----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Civilian Collection Point","H":"2.X.5.1.4",},{"ID":"G*S*PD----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Detainee Collection Point","H":"2.X.5.1.5",},{"ID":"G*S*PE----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Enemy Prisoner of War Collection Point","H":"2.X.5.1.6",},{"ID":"G*S*PL----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Logistics Release Point","H":"2.X.5.1.7",},{"ID":"G*S*PM----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Maintenance Collection Point","H":"2.X.5.1.8",},{"ID":"G*S*PR----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Rearm, Refuel and Resupply Point","H":"2.X.5.1.9",},{"ID":"G*S*PU----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Refuel on the Move Point","H":"2.X.5.1.10",},{"ID":"G*S*PO----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Traffic Control Post (TCP)","H":"2.X.5.1.11",},{"ID":"G*S*PI----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Trailer Transfer Point","H":"2.X.5.1.12",},{"ID":"G*S*PN----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Unit Maintenance Collection Point","H":"2.X.5.1.13",},{"ID":"G*S*PS----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Supply Points","H":"2.X.5.1.14",},{"ID":"G*S*PSZ---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point General","H":"2.X.5.1.14.1",},{"ID":"G*S*PSA---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class I","H":"2.X.5.1.14.2",},{"ID":"G*S*PSB---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class II","H":"2.X.5.1.14.3",},{"ID":"G*S*PSC---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class III","H":"2.X.5.1.14.4",},{"ID":"G*S*PSD---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class IV","H":"2.X.5.1.14.5",},{"ID":"G*S*PSE---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class V","H":"2.X.5.1.14.6",},{"ID":"G*S*PSF---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class VI","H":"2.X.5.1.14.7",},{"ID":"G*S*PSG---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class VII","H":"2.X.5.1.14.8",},{"ID":"G*S*PSH---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class VIII","H":"2.X.5.1.14.9",},{"ID":"G*S*PSI---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class IX","H":"2.X.5.1.14.10",},{"ID":"G*S*PSJ---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Supply Point Class X","H":"2.X.5.1.14.11",},{"ID":"G*S*PA----****X","G":"point","DC":"0","MXP":"0","MNP":"0","M":"N.","D":"Ammunition Points","H":"2.X.5.1.15",},{"ID":"G*S*PAS---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Ammunition Supply Point (ASP)","H":"2.X.5.1.15.1",},{"ID":"G*S*PAT---****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.W.W1.N.","D":"Ammunition Transfer Point (ATP)","H":"2.X.5.1.15.2",},{"ID":"G*S*PP----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"H.T.T1.W.W1.","D":"Medevac Pick-Up Point","H":"2.X.5.1.16",},{"ID":"G*S*L-----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"2.X.5.2",},{"ID":"G*S*LC----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Convoys","H":"2.X.5.2.1",},{"ID":"G*S*LCM---****X","G":"line","DC":"9","MXP":"2","MNP":"2","M":"A.H.H1.W.W1.","D":"Moving Convoy","H":"2.X.5.2.1.1",},{"ID":"G*S*LCH---****X","G":"line","DC":"9","MXP":"2","MNP":"2","M":"A.H.H1.W.W1.","D":"Halted Convoy","H":"2.X.5.2.1.2",},{"ID":"G*S*LR----****X","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Supply Routes","H":"2.X.5.2.2",},{"ID":"G*S*LRM---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Main Supply Route","H":"2.X.5.2.2.1",},{"ID":"G*S*LRA---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Alternate Supply Route","H":"2.X.5.2.2.2",},{"ID":"G*S*LRO---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Supply Route One-Way Traffic","H":"2.X.5.2.2.3",},{"ID":"G*S*LRT---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Supply Route Alternating Traffic","H":"2.X.5.2.2.4",},{"ID":"G*S*LRW---****X","G":"line","DC":"1","MXP":"10000","MNP":"2","M":"T.","D":"Supply Route Two-Way Traffic","H":"2.X.5.2.2.5",},{"ID":"G*S*A-----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Area","H":"2.X.5.3",},{"ID":"G*S*AD----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Detainee Holding Area","H":"2.X.5.3.1",},{"ID":"G*S*AE----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Enemy Prisoner of War Holding Area","H":"2.X.5.3.2",},{"ID":"G*S*AR----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Forward Arming and Refueling Area","H":"2.X.5.3.3",},{"ID":"G*S*AH----****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Refugee Holding Area","H":"2.X.5.3.4",},{"ID":"G*S*AS----****X","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Support Areas","H":"2.X.5.3.5",},{"ID":"G*S*ASB---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Brigade Support Area (BSA)","H":"2.X.5.3.5.1",},{"ID":"G*S*ASD---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Division Support Area (DSA)","H":"2.X.5.3.5.2",},{"ID":"G*S*ASR---****X","G":"area","DC":"3","MXP":"10000","MNP":"3","M":"T.","D":"Regimental Support Area (RSA)","H":"2.X.5.3.5.3",},{"ID":"G*O*------****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Other","H":"2.X.6",},{"ID":"G*O*E-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Emergency","H":"2.X.6.1",},{"ID":"G*O*ED----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ditched Aircraft","H":"2.X.6.1.1",},{"ID":"G*O*EP----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Person in Water","H":"2.X.6.1.2",},{"ID":"G*O*ES----****X","G":"point","DC":"8","MXP":"1","MNP":"1","M":"T.T1.H.W.W1.N.","D":"Emergency Distress Call","H":"2.X.6.1.4",},{"ID":"G*O*EV----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Distressed Vessel","H":"2.X.6.1.3",},{"ID":"G*O*H-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Hazard","H":"2.X.6.2",},{"ID":"G*O*HM----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sea Mine-Like Hazard","H":"2.X.6.2.1",},{"ID":"G*O*HN----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Navigational Hazard","H":"2.X.6.2.2",},{"ID":"G*O*HI----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Iceberg Hazard","H":"2.X.6.2.3",},{"ID":"G*O*HO----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Oil Rig Hazard","H":"2.X.6.2.4",},{"ID":"G*O*S-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Sea Subsurface Returns","H":"2.X.6.3",},{"ID":"G*O*SB----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Bottom Return/Non-Milco","H":"2.X.6.3.1",},{"ID":"G*O*SBM---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sea Installation/Manmade","H":"2.X.6.3.1.1",},{"ID":"G*O*SBN---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Seabed Rock/Stone Obstacle","H":"2.X.6.3.1.2",},{"ID":"G*O*SBW---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Wreck, Nondangerous","H":"2.X.6.3.1.3",},{"ID":"G*O*SBX---****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Wreck, Dangerous","H":"2.X.6.3.1.4",},{"ID":"G*O*SM----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Marine Life","H":"2.X.6.3.2",},{"ID":"G*O*SS----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sea Anomaly","H":"2.X.6.3.3",},{"ID":"G*O*B-----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Bearing Line","H":"2.X.6.4",},{"ID":"G*O*BE----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Bearing Line Electronic","H":"2.X.6.4.1",},{"ID":"G*O*BA----****X","G":"line","DC":"2","MXP":"2","MNP":"2","D":"Bearing Line Acoustic","H":"2.X.6.4.2",},{"ID":"G*O*BT----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Bearing Line Torpedo","H":"2.X.6.4.3",},{"ID":"G*O*BO----****X","G":"line","DC":"6","MXP":"2","MNP":"2","D":"Bearing Line Electro-Optical Intercept","H":"2.X.6.4.4",},{"ID":"G*O*F-----****X","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Fix","H":"2.X.6.5",},{"ID":"G*O*FA----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fix Acoustic","H":"2.X.6.5.1",},{"ID":"G*O*FE----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fix Electro-Magnetic","H":"2.X.6.5.2",},{"ID":"G*O*FO----****X","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fix Electro-Optical","H":"2.X.6.5.3",},{"ID":"W--------------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"METOC","H":"3.X",},{"ID":"WA-------------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Atmospheric","H":"3.X.1",},{"ID":"WA--P----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Pressure Systems","H":"3.X.1.1",},{"ID":"WAS-PL----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Low Pressure Center","H":"3.X.1.1.1",},{"ID":"WAS-PC----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Cyclone Center","H":"3.X.1.1.1.1",},{"ID":"WAS-PLT---P----","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Tropopause Low","H":"3.X.1.1.1.2",},{"ID":"WAS-PH----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"High Pressure Center","H":"3.X.1.1.2",},{"ID":"WAS-PA----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Anticyclone Center","H":"3.X.1.1.2.1",},{"ID":"WAS-PHT---P----","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Tropopause High","H":"3.X.1.1.2.2",},{"ID":"WA-DPF-----L---","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Frontal Systems","H":"3.X.1.1.3",},{"ID":"WA-DPFC----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cold Front","H":"3.X.1.1.3.1",},{"ID":"WA-DPFCU---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Upper Cold Front","H":"3.X.1.1.3.1.1",},{"ID":"WA-DPFC-FG-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cold Frontogenisis","H":"3.X.1.1.3.1.2",},{"ID":"WA-DPFC-FY-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cold Frontolysis","H":"3.X.1.1.3.1.3",},{"ID":"WA-DPFW----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Warm Front","H":"3.X.1.1.3.2",},{"ID":"WA-DPFWU---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Upper Warm Front","H":"3.X.1.1.3.2.1",},{"ID":"WA-DPFW-FG-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Warm Frontogenisis","H":"3.X.1.1.3.2.2",},{"ID":"WA-DPFW-FY-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Warm Frontolysis","H":"3.X.1.1.3.2.3",},{"ID":"WA-DPFO----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Occluded Front","H":"3.X.1.1.3.3",},{"ID":"WA-DPFOU---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Upper Occluded Front","H":"3.X.1.1.3.3.1",},{"ID":"WA-DPFO-FY-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Occluded Frontolysis","H":"3.X.1.1.3.3.2",},{"ID":"WA-DPFS----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Stationary Front","H":"3.X.1.1.3.4",},{"ID":"WA-DPFSU---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Upper Stationary Front","H":"3.X.1.1.3.4.1",},{"ID":"WA-DPFS-FG-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Stationary Frontogenesis","H":"3.X.1.1.3.4.2",},{"ID":"WA-DPFS-FY-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Stationary Frontolysis","H":"3.X.1.1.3.4.3",},{"ID":"WA--PX---------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Lines","H":"3.X.1.1.4",},{"ID":"WA-DPXT----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Trough Axis","H":"3.X.1.1.4.1",},{"ID":"WA-DPXR----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ridge Axis","H":"3.X.1.1.4.2",},{"ID":"WA-DPXSQ---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Severe Squall Line","H":"3.X.1.1.4.3",},{"ID":"WA-DPXIL---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Instability Line","H":"3.X.1.1.4.4",},{"ID":"WA-DPXSH---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Shear Line","H":"3.X.1.1.4.5",},{"ID":"WA-DPXITCZ-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Inter-Tropical Convergance Zone","H":"3.X.1.1.4.6",},{"ID":"WA-DPXCV---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Convergance Line","H":"3.X.1.1.4.7",},{"ID":"WA-DPXITD--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Inter-Tropical Discontinuity","H":"3.X.1.1.4.8",},{"ID":"WAS-T----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Turbulence","H":"3.X.1.2",},{"ID":"WAS-TL----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Turbulence","H":"3.X.1.2.1",},{"ID":"WAS-TM----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Turbulence","H":"3.X.1.2.2",},{"ID":"WAS-TS----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Severe Turbulence","H":"3.X.1.2.3",},{"ID":"WAS-TE----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Extreme Turbulence","H":"3.X.1.2.4",},{"ID":"WAS-T-MW--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Mountain Waves","H":"3.X.1.2.5",},{"ID":"WAS-I----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Icing","H":"3.X.1.3",},{"ID":"WAS-IC----P----","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Clear Icing","H":"3.X.1.3.1",},{"ID":"WAS-ICL---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Clear Icing","H":"3.X.1.3.1.1",},{"ID":"WAS-ICM---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Clear Icing","H":"3.X.1.3.1.2",},{"ID":"WAS-ICS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Severe Clear Icing","H":"3.X.1.3.1.3",},{"ID":"WAS-IR-----P---","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Rime Icing","H":"3.X.1.3.2",},{"ID":"WAS-IRL---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Rime Icing","H":"3.X.1.3.2.1",},{"ID":"WAS-IRM---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Rime Icing","H":"3.X.1.3.2.2",},{"ID":"WAS-IRS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Severe Rime Icing","H":"3.X.1.3.2.3",},{"ID":"WAS-IM-----P---","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Mixed Icing","H":"3.X.1.3.3",},{"ID":"WAS-IML---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Mixed Icing","H":"3.X.1.3.3.1",},{"ID":"WAS-IMM---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Mixed Icing","H":"3.X.1.3.3.2",},{"ID":"WAS-IMS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Severe Mixed Icing","H":"3.X.1.3.3.3",},{"ID":"WA--W----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Winds","H":"3.X.1.4",},{"ID":"WAS-WC----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Calm Winds","H":"3.X.1.4.1",},{"ID":"WAS-WP----P----","G":"point","DC":"0","MXP":"2","MNP":"2","M":"Z.Q.","D":"Wind Plot","H":"3.X.1.4.2",},{"ID":"WA-DWJ-----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Jet Stream","H":"3.X.1.4.3",},{"ID":"WA-DWS-----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Stream Line","H":"3.X.1.4.4",},{"ID":"WA--CC---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Cloud Coverage","H":"3.X.1.5",},{"ID":"WA--CCCS-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Cloud Coverage Symbols","H":"3.X.1.5.1",},{"ID":"WAS-CCCSCSP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Clear Sky","H":"3.X.1.5.1.1",},{"ID":"WAS-CCCSFCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Few Coverage","H":"3.X.1.5.1.2",},{"ID":"WAS-CCCSSCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Scattered Coverage","H":"3.X.1.5.1.3",},{"ID":"WAS-CCCSBCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Broken Coverage","H":"3.X.1.5.1.4",},{"ID":"WAS-CCCSOCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Overcast Coverage","H":"3.X.1.5.1.5",},{"ID":"WAS-CCCSOBP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sky Totally or Partially Obscured","H":"3.X.1.5.1.6",},{"ID":"WA--WS---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Weather Symbols","H":"3.X.1.6",},{"ID":"WAS-WSR--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Rain","H":"3.X.1.6.1",},{"ID":"WAS-WSR-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Light Rain","H":"3.X.1.6.1.1",},{"ID":"WAS-WSR-LCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Light Rain","H":"3.X.1.6.1.1.1",},{"ID":"WAS-WSR-MIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Moderate Rain","H":"3.X.1.6.1.2",},{"ID":"WAS-WSR-MCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Moderate Rain","H":"3.X.1.6.1.2.1",},{"ID":"WAS-WSR-HIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Heavy Rain","H":"3.X.1.6.1.3",},{"ID":"WAS-WSR-HCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Heavy Rain","H":"3.X.1.6.1.3.1",},{"ID":"WAS-WSRF-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Freezing Rain","H":"3.X.1.6.2",},{"ID":"WAS-WSRFL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Freezing Rain","H":"3.X.1.6.2.1",},{"ID":"WAS-WSRFMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Heavy Freezing Rain","H":"3.X.1.6.2.2",},{"ID":"WAS-WSRS-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Rain Showers","H":"3.X.1.6.3",},{"ID":"WAS-WSRSL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Rain Showers","H":"3.X.1.6.3.1",},{"ID":"WAS-WSRSMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Heavy Rain Showers","H":"3.X.1.6.3.2",},{"ID":"WAS-WSRST-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Torrential Rain Showers","H":"3.X.1.6.3.3",},{"ID":"WAS-WSD--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Drizzle","H":"3.X.1.6.4",},{"ID":"WAS-WSD-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Light Drizzle","H":"3.X.1.6.4.1",},{"ID":"WAS-WSD-LCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Light Drizzle","H":"3.X.1.6.4.1.1",},{"ID":"WAS-WSD-MIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Moderate Drizzle","H":"3.X.1.6.4.2",},{"ID":"WAS-WSD-MCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Moderate Drizzle","H":"3.X.1.6.4.2.1",},{"ID":"WAS-WSD-HIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Heavy Drizzle","H":"3.X.1.6.4.3",},{"ID":"WAS-WSD-HCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Heavy Drizzle","H":"3.X.1.6.4.3.1",},{"ID":"WAS-WSDF-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Freezing Drizzle","H":"3.X.1.6.5",},{"ID":"WAS-WSDFL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Freezing Drizzle","H":"3.X.1.6.5.1",},{"ID":"WAS-WSDFMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Heavy Freezing Drizzle","H":"3.X.1.6.5.2",},{"ID":"WAS-WSM--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Rain and Snow Mixed","H":"3.X.1.6.6",},{"ID":"WAS-WSM-L-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Rain or Drizzle and Snow","H":"3.X.1.6.6.1",},{"ID":"WAS-WSM-MHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Heavy Rain or Drizzle and Snow","H":"3.X.1.6.6.2",},{"ID":"WAS-WSMSL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Rain and Snow Showers","H":"3.X.1.6.6.3",},{"ID":"WAS-WSMSMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Heavy Rain and Snow Showers","H":"3.X.1.6.6.4",},{"ID":"WAS-WSS--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Snow","H":"3.X.1.6.7",},{"ID":"WAS-WSS-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Light Snow","H":"3.X.1.6.7.1",},{"ID":"WAS-WSS-LCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Light Snow","H":"3.X.1.6.7.1.1",},{"ID":"WAS-WSS-MIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Moderate Snow","H":"3.X.1.6.7.2",},{"ID":"WAS-WSS-MCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Moderate Snow","H":"3.X.1.6.7.2.1",},{"ID":"WAS-WSS-HIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Intermittent Heavy Snow","H":"3.X.1.6.7.3",},{"ID":"WAS-WSS-HCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Continuous Heavy Snow","H":"3.X.1.6.7.3.1",},{"ID":"WAS-WSSBLMP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light/Moderate Blowing Snow","H":"3.X.1.6.7.4",},{"ID":"WAS-WSSBH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Heavy Blowing Snow","H":"3.X.1.6.7.5",},{"ID":"WAS-WSSG--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Snow Grains","H":"3.X.1.6.8",},{"ID":"WAS-WSSS-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Snow Showers","H":"3.X.1.6.9",},{"ID":"WAS-WSSSL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Snow Showers","H":"3.X.1.6.9.1",},{"ID":"WAS-WSSSMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Heavy Snow Showers","H":"3.X.1.6.9.2",},{"ID":"WAS-WSGR-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Hail","H":"3.X.1.6.10",},{"ID":"WAS-WSGRL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Hail - Light not Associated With Thunder","H":"3.X.1.6.10.1",},{"ID":"WAS-WSGRMHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Hail - Moderate/Heavy not Associated With Thunder","H":"3.X.1.6.10.2",},{"ID":"WAS-WSIC--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Crystals","H":"3.X.1.6.11",},{"ID":"WAS-WSPL-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Ice Pellets","H":"3.X.1.6.12",},{"ID":"WAS-WSPLL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Ice Pellets","H":"3.X.1.6.12.1",},{"ID":"WAS-WSPLM-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate Ice Pellets","H":"3.X.1.6.12.2",},{"ID":"WAS-WSPLH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Heavy Ice Pellets","H":"3.X.1.6.12.3",},{"ID":"WAS-WST--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Storms","H":"3.X.1.6.13",},{"ID":"WAS-WST-NPP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunderstorm - No Precipitation","H":"3.X.1.6.13.1",},{"ID":"WAS-WSTMR-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunderstorm Light to Moderate With Rain/Snow - No Hail","H":"3.X.1.6.13.2",},{"ID":"WAS-WSTHR-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunderstorm Heavy With Rain/Snow - No Hail","H":"3.X.1.6.13.3",},{"ID":"WAS-WSTMH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunderstorm Light to Moderate - With Hail","H":"3.X.1.6.13.4",},{"ID":"WAS-WSTHH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunderstorm Heavy - With Hail","H":"3.X.1.6.13.5",},{"ID":"WAS-WST-FCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Funnel Cloud (Tornado/Waterspout)","H":"3.X.1.6.13.6",},{"ID":"WAS-WST-SQP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Squall","H":"3.X.1.6.13.7",},{"ID":"WAS-WST-LGP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Lightning","H":"3.X.1.6.13.8",},{"ID":"WAS-WSFG-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Fog","H":"3.X.1.6.14",},{"ID":"WAS-WSFGPSP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Shallow Patches","H":"3.X.1.6.14.1",},{"ID":"WAS-WSFGCSP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Shallow Continuous","H":"3.X.1.6.14.2",},{"ID":"WAS-WSFGP-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Patchy","H":"3.X.1.6.14.3",},{"ID":"WAS-WSFGSVP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Sky Visible","H":"3.X.1.6.14.4",},{"ID":"WAS-WSFGSOP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Sky Obscured","H":"3.X.1.6.14.5",},{"ID":"WAS-WSFGFVP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Freezing, Sky Visible","H":"3.X.1.6.14.6",},{"ID":"WAS-WSFGFOP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog - Freezing, Sky Not Visible","H":"3.X.1.6.14.7",},{"ID":"WAS-WSBR--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Mist","H":"3.X.1.6.15",},{"ID":"WAS-WSFU--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Smoke Point","H":"3.X.1.6.16",},{"ID":"WAS-WSHZ--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Haze","H":"3.X.1.6.17",},{"ID":"WAS--SD--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Dust or Sand","H":"3.X.1.6.18",},{"ID":"WAS-WSDSLMP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light to Moderate Dust/Sand Storm","H":"3.X.1.6.18.1",},{"ID":"WAS-WSDSS-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Severe Dust/Sand Storm","H":"3.X.1.6.18.2",},{"ID":"WAS-WSDD--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Dust Devil","H":"3.X.1.6.18.3",},{"ID":"WAS-WSDB--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Blowing Dust or Sand","H":"3.X.1.6.18.4",},{"ID":"WAS-WSTS-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Tropical Storm Systems","H":"3.X.1.6.19",},{"ID":"WAS-WSTSD-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tropical Depression","H":"3.X.1.6.19.1",},{"ID":"WAS-WSTSS-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tropical Storm","H":"3.X.1.6.19.2",},{"ID":"WAS-WSTSH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Hurricane/Typhoon","H":"3.X.1.6.19.3",},{"ID":"WA-DWSTSWA--A--","G":"point","DC":"0","MXP":"1","MNP":"1","D":"Tropical Storm Wind Areas and Date/Time Labels","H":"3.X.1.6.19.4",},{"ID":"WAS-WSVE--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Volcanic Eruption","H":"3.X.1.6.20",},{"ID":"WAS-WSVA--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Volcanic Ash","H":"3.X.1.6.20.1",},{"ID":"WAS-WST-LVP----","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Tropopause Level","H":"3.X.1.6.21",},{"ID":"WAS-WSF-LVP----","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Freezing Level","H":"3.X.1.6.22",},{"ID":"WAS-WSUKP-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Precipiation of Unknown Type and Intensity","H":"3.X.1.6.23",},{"ID":"WA--BA---------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Bounded Areas of Weather","H":"3.X.1.7",},{"ID":"WA-DBAIF----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"IFR","H":"3.X.1.7.1",},{"ID":"WA-DBAMV----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"MVFR","H":"3.X.1.7.2",},{"ID":"WA-DBATB----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Turbulence","H":"3.X.1.7.3",},{"ID":"WA-DBAI-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Icing","H":"3.X.1.7.4",},{"ID":"WA-DBALPNC--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Precipiation Non-Convective","H":"3.X.1.7.5",},{"ID":"WA-DBALPC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Precipitation Convective","H":"3.X.1.7.5.1",},{"ID":"WA-DBAFP----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Frozen Precipitation","H":"3.X.1.7.6",},{"ID":"WA-DBAT-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Thunderstorm","H":"3.X.1.7.7",},{"ID":"WA-DBAFG----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Fog","H":"3.X.1.7.8",},{"ID":"WA-DBAD-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Sand","H":"3.X.1.7.9",},{"ID":"WA-DBAFF----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Weather Freeform","H":"3.X.1.7.10",},{"ID":"WA--IP---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Isopleths","H":"3.X.1.8",},{"ID":"WA-DIPIB---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Isobar Surface","H":"3.X.1.8.1",},{"ID":"WA-DIPCO---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Upper Air","H":"3.X.1.8.2",},{"ID":"WA-DIPIS---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Isotherm","H":"3.X.1.8.3",},{"ID":"WA-DIPIT---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Isotach","H":"3.X.1.8.4",},{"ID":"WA-DIPID---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Isodrosotherm","H":"3.X.1.8.5",},{"ID":"WA-DIPTH---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Isopleths Thickness","H":"3.X.1.8.6",},{"ID":"WA-DIPFF---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Operator Freeform","H":"3.X.1.8.7",},{"ID":"WAS-G----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"State of the Ground","H":"3.X.1.9",},{"ID":"WAS-GN---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Without Snow or Measureable Ice Cover","H":"3.X.1.9.1",},{"ID":"WAS-GND-NCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Loose Sand","H":"3.X.1.9.1.1",},{"ID":"WAS-GNM---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Surface Moist","H":"3.X.1.9.1.2",},{"ID":"WAS-GNW-SWP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Surface Wet, Standing Water in Small or Large Pools","H":"3.X.1.9.1.3",},{"ID":"WAS-GNFL--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Surface Flooded","H":"3.X.1.9.1.4",},{"ID":"WAS-GNFZ--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Surface Frozen","H":"3.X.1.9.1.5",},{"ID":"WAS-GNG-TIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Glaze (Thin Ice) on Ground","H":"3.X.1.9.1.6",},{"ID":"WAS-GNLDN-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Loose Dry Dust or Sand not Covering Ground Completely","H":"3.X.1.9.1.7",},{"ID":"WAS-GNLDTCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thin Loose Dry Dust or Sand Covering Ground Completely","H":"3.X.1.9.1.8",},{"ID":"WAS-GNLDMCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Moderate/Thick Loose Dry Dust or Sand Covering Ground Completely","H":"3.X.1.9.1.9",},{"ID":"WAS-GNDEWCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Extremely Dry With Cracks","H":"3.X.1.9.1.10",},{"ID":"WAS-GS---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"With Snow or Measureable Ice Cover","H":"3.X.1.9.2",},{"ID":"WAS-GSI---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Predominately Ice Covered","H":"3.X.1.9.2.1",},{"ID":"WAS-GSSCL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Compact or Wet Snow (With or Without Ice) Covering Less than One-Half of Ground","H":"3.X.1.9.2.2",},{"ID":"WAS-GSSCH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Compact or Wet Snow Covering At Least One-Half Ground, but Ground not Completely Covered","H":"3.X.1.9.2.3",},{"ID":"WAS-GSSCCEP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Even Layer of Compact or Wet Snow Covering Ground Completely","H":"3.X.1.9.2.4",},{"ID":"WAS-GSSCCUP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Uneven Layer of Compact or Wet Snow Covering Ground Completely","H":"3.X.1.9.2.5",},{"ID":"WAS-GSSLL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Loose Dry Snow Covering Less than One-Half of Ground","H":"3.X.1.9.2.6",},{"ID":"WAS-GSSLH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Loose Dry Snow Covering at Least One-Half Ground, but not Completely Covered","H":"3.X.1.9.2.7",},{"ID":"WAS-GSSLCEP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Even Layer of Loose Dry Snow Covering Ground Completely","H":"3.X.1.9.2.8",},{"ID":"WAS-GSSLCUP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Uneven Layer of Loose Dry Snow Covering Ground Completely","H":"3.X.1.9.2.9",},{"ID":"WAS-GSSDC-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Snow Covering Ground Completely, Deep Drifts","H":"3.X.1.9.2.10",},{"ID":"WO-------------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Oceanic","H":"3.X.2",},{"ID":"WO--I----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Ice Systems","H":"3.X.2.1",},{"ID":"WOS-IB----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Icebergs","H":"3.X.2.1.1",},{"ID":"WOS-IBM---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Many Icebergs","H":"3.X.2.1.1.1",},{"ID":"WOS-IBBS--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Belts and Strips","H":"3.X.2.1.1.2",},{"ID":"WOS-IBG---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Iceberg - General","H":"3.X.2.1.1.3",},{"ID":"WOS-IBMG--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Many Icebergs - General","H":"3.X.2.1.1.4",},{"ID":"WOS-IBBB--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Bergy Bit","H":"3.X.2.1.1.5",},{"ID":"WOS-IBBBM-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Many Bergy Bits","H":"3.X.2.1.1.6",},{"ID":"WOS-IBGL--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Growler","H":"3.X.2.1.1.7",},{"ID":"WOS-IBGLM-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Many Growlers","H":"3.X.2.1.1.8",},{"ID":"WOS-IBF---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Floeberg","H":"3.X.2.1.1.9",},{"ID":"WOS-IBII--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Island","H":"3.X.2.1.1.10",},{"ID":"WO--IC---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Ice Concentration","H":"3.X.2.1.2",},{"ID":"WOS-ICWB--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Bergy Water","H":"3.X.2.1.2.1",},{"ID":"WOS-ICWR--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Water With Radar Targets","H":"3.X.2.1.2.2",},{"ID":"WOS-ICIF--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Free","H":"3.X.2.1.2.3",},{"ID":"WOS-ID---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Dynamic Processes","H":"3.X.2.1.3",},{"ID":"WOS-IDC---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Convergence","H":"3.X.2.1.3.1",},{"ID":"WOS-IDD---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Divergence","H":"3.X.2.1.3.2",},{"ID":"WOS-IDS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Shearing or Shear Zone","H":"3.X.2.1.3.3",},{"ID":"WO-DIDID--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Drift (Direction)","H":"3.X.2.1.3.4",},{"ID":"WO-DIDID---L---","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Drift (Direction)","H":"3.X.2.1.3.5",},{"ID":"WOS-II----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sea Ice","H":"3.X.2.1.4",},{"ID":"WOS-IITM--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Thickness (Observed)","H":"3.X.2.1.4.1",},{"ID":"WOS-IITE--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ice Thickness (Estimated)","H":"3.X.2.1.4.2",},{"ID":"WOS-IIP---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Melt Puddles or Flooded Ice","H":"3.X.2.1.4.3",},{"ID":"WO--IL---------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Limits","H":"3.X.2.1.5",},{"ID":"WO-DILOV---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Limit of Visual Observation","H":"3.X.2.1.5.1",},{"ID":"WO-DILUC---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Limit of Undercast","H":"3.X.2.1.5.2",},{"ID":"WO-DILOR---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Limit of Radar Observation","H":"3.X.2.1.5.3",},{"ID":"WO-DILIEO--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Observed Ice Edge","H":"3.X.2.1.5.4",},{"ID":"WO-DILIEE--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Estimated Ice Edge","H":"3.X.2.1.5.5",},{"ID":"WO-DILIER--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ice Edge From Radar","H":"3.X.2.1.5.6",},{"ID":"WO--IO---------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Openings in the Ice","H":"3.X.2.1.6",},{"ID":"WO-DIOC----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cracks","H":"3.X.2.1.6.1",},{"ID":"WO-DIOCS---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cracks Specific-Location","H":"3.X.2.1.6.2",},{"ID":"WO-DIOL----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ice Openings-Lead","H":"3.X.2.1.6.3",},{"ID":"WO-DIOLF---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Frozen Lead","H":"3.X.2.1.6.4",},{"ID":"WOS-ISC---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Snow Cover","H":"3.X.2.1.7",},{"ID":"WOS-ISS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sastrugi","H":"3.X.2.1.7.1",},{"ID":"WOS-IT---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Topographical Features","H":"3.X.2.1.8",},{"ID":"WOS-ITRH--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ridges or Hummocks","H":"3.X.2.1.8.1",},{"ID":"WOS-ITR---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rafting","H":"3.X.2.1.8.2",},{"ID":"WOS-ITBB--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Jammed Brash Barrier","H":"3.X.2.1.8.3",},{"ID":"WO--H----------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Hydrography","H":"3.X.2.2",},{"ID":"WO--HD---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Depth","H":"3.X.2.2.1",},{"ID":"WOS-HDS---P----","G":"point","DC":"8","MXP":"1","MNP":"1","M":"X.","D":"Soundings","H":"3.X.2.2.1.1",},{"ID":"WO-DHDDL---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Depth Curve","H":"3.X.2.2.1.2",},{"ID":"WO-DHDDC---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Depth Contour","H":"3.X.2.2.1.3",},{"ID":"WO-DHDDA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Depth Area","H":"3.X.2.2.1.4",},{"ID":"WO--HC---------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Coastal Hydrography","H":"3.X.2.2.2",},{"ID":"WO-DHCC----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Coastline","H":"3.X.2.2.2.1",},{"ID":"WO-DHCI-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Island","H":"3.X.2.2.2.2",},{"ID":"WO-DHCB-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Beach","H":"3.X.2.2.2.3",},{"ID":"WO-DHCW-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Water","H":"3.X.2.2.2.4",},{"ID":"WO-DHCF--------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Foreshore","H":"3.X.2.2.2.5",},{"ID":"WO-DHCF----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Foreshore Line","H":"3.X.2.2.2.5.1",},{"ID":"WO-DHCF-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Foreshore Area","H":"3.X.2.2.2.5.2",},{"ID":"WO-DHP---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Ports and Harbors","H":"3.X.2.2.3",},{"ID":"WO--HPB--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Ports","H":"3.X.2.2.3.1",},{"ID":"WOS-HPB-O-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Berths (Onshore)","H":"3.X.2.2.3.1.1",},{"ID":"WOS-HPB-A-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Berths (Anchor)","H":"3.X.2.2.3.1.2",},{"ID":"WOS-HPBA--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Anchorage","H":"3.X.2.2.3.1.3",},{"ID":"WO-DHPBA---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Anchorage Line","H":"3.X.2.2.3.1.4",},{"ID":"WO-DHPBA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Anchorage Area","H":"3.X.2.2.3.1.5",},{"ID":"WOS-HPCP--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Call in Point","H":"3.X.2.2.3.1.6",},{"ID":"WO-DHPBP---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Pier","H":"3.X.2.2.3.1.7",},{"ID":"WOS-HPF--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Fishing","H":"3.X.2.2.3.2",},{"ID":"WOS-HPFH--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fishing Harbor","H":"3.X.2.2.3.2.1",},{"ID":"WOS-HPFS--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fish Stakes/Traps/Weirs","H":"3.X.2.2.3.2.2",},{"ID":"WOS-HPFS---L---","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fish Stakes/Traps/Weirs","H":"3.X.2.2.3.2.3",},{"ID":"WOS-HPFF----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Fish Stakes/Traps/Weirs","H":"3.X.2.2.3.2.4",},{"ID":"WO--HPM--------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Facilities","H":"3.X.2.2.3.3",},{"ID":"WO-DHPMD----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Drydock","H":"3.X.2.2.3.3.1",},{"ID":"WOS-HPML--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Landing Place","H":"3.X.2.2.3.3.2",},{"ID":"WO-DHPMO--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Offshore Loading Facility Point","H":"3.X.2.2.3.3.3",},{"ID":"WO-DHPMO---L---","G":"line","DC":"1","MXP":"10000","MNP":"1","D":"Offshore Loading Facility Line","H":"3.X.2.2.3.3.4",},{"ID":"WO-DHPMO----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Offshore Loading Facility Area","H":"3.X.2.2.3.3.5",},{"ID":"WO-DHPMRA--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ramp Above Water","H":"3.X.2.2.3.3.6",},{"ID":"WO-DHPMRB--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ramp Below Water","H":"3.X.2.2.3.3.7",},{"ID":"WOS-HPM-R-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Landing Ring","H":"3.X.2.2.3.3.8",},{"ID":"WOS-HPM-FC-L---","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ferry Crossing","H":"3.X.2.2.3.3.9",},{"ID":"WOS-HPM-CC-L---","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Cable Ferry Crossing","H":"3.X.2.2.3.3.10",},{"ID":"WOS-HPD---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Dolphin","H":"3.X.2.2.3.3.11",},{"ID":"WO-DHPSP-------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Shoreline Protection","H":"3.X.2.2.3.4",},{"ID":"WO-DHPSPA--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Jetty Above Water","H":"3.X.2.2.3.4.1",},{"ID":"WO-DHPSPB--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Jetty Below Water","H":"3.X.2.2.3.4.2",},{"ID":"WO-DHPSPS--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Seawall","H":"3.X.2.2.3.4.3",},{"ID":"WO--HA---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Aids to Navigation","H":"3.X.2.2.4",},{"ID":"WOS-HABA--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Beacon","H":"3.X.2.2.4.1",},{"ID":"WOS-HABB--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Buoy Default","H":"3.X.2.2.4.2",},{"ID":"WOS-HABM--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Marker","H":"3.X.2.2.4.3",},{"ID":"WOS-HABP-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Perches/Stakes","H":"3.X.2.2.4.4",},{"ID":"WOS-HABP--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Perches/Stakes","H":"3.X.2.2.4.4.1",},{"ID":"WO-DHABP----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Perches/Stakes","H":"3.X.2.2.4.4.2",},{"ID":"WOS-HAL---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light","H":"3.X.2.2.4.5",},{"ID":"WO-DHALLA--L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Leading Line","H":"3.X.2.2.4.6",},{"ID":"WOS-HALV--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Light Vessel/Lightship","H":"3.X.2.2.4.7",},{"ID":"WOS-HALH--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Lighthouse","H":"3.X.2.2.4.8",},{"ID":"WO--HH---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Dangers/Hazards","H":"3.X.2.2.5",},{"ID":"WOS-HHRS--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rock Submerged","H":"3.X.2.2.5.1",},{"ID":"WOS-HHRA--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rock Awashed","H":"3.X.2.2.5.2",},{"ID":"WO-DHHD-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Underwater Hazard","H":"3.X.2.2.5.3",},{"ID":"WOS-HHDF-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Foul Ground","H":"3.X.2.2.5.4",},{"ID":"WOS-HHDF--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Foul Ground Point","H":"3.X.2.2.5.4.1",},{"ID":"WO-DHHDF----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Foul Ground Area","H":"3.X.2.2.5.4.2",},{"ID":"WO-DHHDK-------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Kelp/Seaweed","H":"3.X.2.2.5.5",},{"ID":"WO-DHHDK--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Kelp/Seaweed Point","H":"3.X.2.2.5.5.1",},{"ID":"WO-DHHDK----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Kelp/Seaweed Area","H":"3.X.2.2.5.5.2",},{"ID":"WOS-HHDMD------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Mine-Naval","H":"3.X.2.2.5.6",},{"ID":"WOS-HHDMDBP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Mine-Naval (Doubtful)","H":"3.X.2.2.5.6.1",},{"ID":"WOS-HHDMDFP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Mine-Naval (Definite)","H":"3.X.2.2.5.6.2",},{"ID":"WOS-HHDS--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Snags/Stumps","H":"3.X.2.2.5.7",},{"ID":"WOS-HHDW--P----","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Wreck","H":"3.X.2.2.5.8",},{"ID":"WOS-HHDWA-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Wreck (Uncovers)","H":"3.X.2.2.5.8.1",},{"ID":"WOS-HHDWB-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Wreck (Submerged)","H":"3.X.2.2.5.8.2",},{"ID":"WO-DHHDB---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Breaker","H":"3.X.2.2.5.9",},{"ID":"WOS-HHDR---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Reef","H":"3.X.2.2.5.10",},{"ID":"WOS-HHDE--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Eddies/Overfalls/Tide Rips","H":"3.X.2.2.5.11",},{"ID":"WO-DHHDD----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Discolored Water","H":"3.X.2.2.5.12",},{"ID":"WO--BF---------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Bottom Features","H":"3.X.2.2.6",},{"ID":"WOS-BFC--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Bottom Characteristics","H":"3.X.2.2.6.1",},{"ID":"WOS-BFC-S-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sand","H":"3.X.2.2.6.1.1",},{"ID":"WOS-BFC-M-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Mud","H":"3.X.2.2.6.1.2",},{"ID":"WOS-BFC-CLP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Clay","H":"3.X.2.2.6.1.3",},{"ID":"WOS-BFC-SIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Silt","H":"3.X.2.2.6.1.4",},{"ID":"WOS-BFC-STP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Stones","H":"3.X.2.2.6.1.5",},{"ID":"WOS-BFC-G-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Gravel","H":"3.X.2.2.6.1.6",},{"ID":"WOS-BFC-P-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Pebbles","H":"3.X.2.2.6.1.7",},{"ID":"WOS-BFC-CBP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Cobbles","H":"3.X.2.2.6.1.8",},{"ID":"WOS-BFC-R-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rock","H":"3.X.2.2.6.1.9",},{"ID":"WOS-BFC-COP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Coral","H":"3.X.2.2.6.1.10",},{"ID":"WOS-BFC-SHP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Shell","H":"3.X.2.2.6.1.11",},{"ID":"WOS-BFQ--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Qualifying Terms","H":"3.X.2.2.6.2",},{"ID":"WOS-BFQ-F-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fine","H":"3.X.2.2.6.2.1",},{"ID":"WOS-BFQ-M-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Medium","H":"3.X.2.2.6.2.2",},{"ID":"WOS-BFQ-C-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Coarse","H":"3.X.2.2.6.2.3",},{"ID":"WO--TCC--------","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Tide and Current","H":"3.X.2.2.7",},{"ID":"WOS-TCCW--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Water Turbulence","H":"3.X.2.2.7.1",},{"ID":"WO-DTCCCFE-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Ebb Tide","H":"3.X.2.2.7.2",},{"ID":"WO-DTCCCFF-L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Flood Tide","H":"3.X.2.2.7.3",},{"ID":"WOS-TCCTD-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tide Data Point","H":"3.X.2.2.7.4",},{"ID":"WOS-TCCTG-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tide Gauge","H":"3.X.2.2.7.5",},{"ID":"WO--O----------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Oceanography","H":"3.X.2.3",},{"ID":"WO--OB---------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Bioluminescence","H":"3.X.2.3.1",},{"ID":"WO-DOBVA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 1-2","H":"3.X.2.3.1.1",},{"ID":"WO-DOBVB----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 2-3","H":"3.X.2.3.1.2",},{"ID":"WO-DOBVC----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 3-4","H":"3.X.2.3.1.3",},{"ID":"WO-DOBVD----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 4-5","H":"3.X.2.3.1.4",},{"ID":"WO-DOBVE----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 5-6","H":"3.X.2.3.1.5",},{"ID":"WO-DOBVF----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 6-7","H":"3.X.2.3.1.6",},{"ID":"WO-DOBVG----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 7-8","H":"3.X.2.3.1.7",},{"ID":"WO-DOBVH----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 8-9","H":"3.X.2.3.1.8",},{"ID":"WO-DOBVI----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"VDR Level 9-10","H":"3.X.2.3.1.9",},{"ID":"WO--BS---------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Beach Slope","H":"3.X.2.3.2",},{"ID":"WO-DBSF-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Beach Slope Flat","H":"3.X.2.3.2.1",},{"ID":"WO-DBSG-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Beach Slope Gentle","H":"3.X.2.3.2.2",},{"ID":"WO-DBSM-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Beach Slope Moderate","H":"3.X.2.3.2.3",},{"ID":"WO-DBST-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Beach Slope Steep","H":"3.X.2.3.2.4",},{"ID":"WO--G----------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Geophysics/Acoustics","H":"3.X.2.4",},{"ID":"WO--GM---------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Mine Warefare Bottom Descriptors","H":"3.X.2.4.1",},{"ID":"WO--GMS--------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Miw-Bottom Sediments","H":"3.X.2.4.1.1",},{"ID":"WO-DGMSR----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Solid Rock","H":"3.X.2.4.1.1.1",},{"ID":"WO-DGMSC----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Clay","H":"3.X.2.4.1.1.2",},{"ID":"WO-DGMSSVS--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Very Course Sand","H":"3.X.2.4.1.1.3",},{"ID":"WO-DGMSSC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Coarse Sand","H":"3.X.2.4.1.1.4",},{"ID":"WO-DGMSSM---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Medium Sand","H":"3.X.2.4.1.1.5",},{"ID":"WO-DGMSSF---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Fine Sand","H":"3.X.2.4.1.1.6",},{"ID":"WO-DGMSSVF--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Very Fine Sand","H":"3.X.2.4.1.1.7",},{"ID":"WO-DGMSIVF--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Very Fine Silt","H":"3.X.2.4.1.1.8",},{"ID":"WO-DGMSIF---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Fine Silt","H":"3.X.2.4.1.1.9",},{"ID":"WO-DGMSIM---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Medium Silt","H":"3.X.2.4.1.1.10",},{"ID":"WO-DGMSIC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Coarse Silt","H":"3.X.2.4.1.1.11",},{"ID":"WO-DGMSB----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Boulders","H":"3.X.2.4.1.1.12",},{"ID":"WO-DGMS-CO--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Oyster Shells","H":"3.X.2.4.1.1.13",},{"ID":"WO-DGMS-PH--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Pebbles Shells","H":"3.X.2.4.1.1.14",},{"ID":"WO-DGMS-SH--A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Sand and Shells","H":"3.X.2.4.1.1.15",},{"ID":"WO-DGML-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Sediments Land","H":"3.X.2.4.1.1.16",},{"ID":"WO-DGMN-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Sediments No Data","H":"3.X.2.4.1.1.17",},{"ID":"WO-DGMR--------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Bottom Roughness","H":"3.X.2.4.1.2",},{"ID":"WO-DGMRS----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Roughness Smooth","H":"3.X.2.4.1.2.1",},{"ID":"WO-DGMRM----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Roughness Moderate","H":"3.X.2.4.1.2.2",},{"ID":"WO-DGMRR----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Roughness Rough","H":"3.X.2.4.1.2.3",},{"ID":"WO-DGMC--------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Clutter (Bottom)","H":"3.X.2.4.1.3",},{"ID":"WO-DGMCL----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Clutter Low","H":"3.X.2.4.1.3.1",},{"ID":"WO-DGMCM----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Clutter Medium","H":"3.X.2.4.1.3.2",},{"ID":"WO-DGMCH----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Clutter High","H":"3.X.2.4.1.3.3",},{"ID":"WO-DGMIB-------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Impact Burial","H":"3.X.2.4.1.4",},{"ID":"WO-DGMIBA---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Impact Burial 0","H":"3.X.2.4.1.4.1",},{"ID":"WO-DGMIBB---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Impact Burial 10","H":"3.X.2.4.1.4.2",},{"ID":"WO-DGMIBC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Impact Burial 20","H":"3.X.2.4.1.4.3",},{"ID":"WO-DGMIBD---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Impact Burial 75","H":"3.X.2.4.1.4.4",},{"ID":"WO-DGMIBE---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Impact Burial 75-100","H":"3.X.2.4.1.4.5",},{"ID":"WO-DGMBC-------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Miw Bottom Category","H":"3.X.2.4.1.5",},{"ID":"WO-DGMBCA---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Category A","H":"3.X.2.4.1.5.1",},{"ID":"WO-DGMBCB---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Category B","H":"3.X.2.4.1.5.2",},{"ID":"WO-DGMBCC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Category C","H":"3.X.2.4.1.5.3",},{"ID":"WO-DGMBT-------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Miw Bottom Type","H":"3.X.2.4.1.6",},{"ID":"WO-DGMBTA---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type A1","H":"3.X.2.4.1.6.1",},{"ID":"WO-DGMBTB---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type A2","H":"3.X.2.4.1.6.2",},{"ID":"WO-DGMBTC---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type A3","H":"3.X.2.4.1.6.3",},{"ID":"WO-DGMBTD---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type B1","H":"3.X.2.4.1.6.4",},{"ID":"WO-DGMBTE---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type B2","H":"3.X.2.4.1.6.5",},{"ID":"WO-DGMBTF---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type B3","H":"3.X.2.4.1.6.6",},{"ID":"WO-DGMBTG---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type C1","H":"3.X.2.4.1.6.7",},{"ID":"WO-DGMBTH---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type C2","H":"3.X.2.4.1.6.8",},{"ID":"WO-DGMBTI---A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Bottom Type C3","H":"3.X.2.4.1.6.9",},{"ID":"WO--L----------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Limits","H":"3.X.2.5",},{"ID":"WO-DL-ML---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Maritime Limit Boundary","H":"3.X.2.5.1",},{"ID":"WO-DL-MA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Maritime Area","H":"3.X.2.5.2",},{"ID":"WO-DL-RA---L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Restricted Area","H":"3.X.2.5.3",},{"ID":"WO-DL-SA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Swept Area","H":"3.X.2.5.4",},{"ID":"WO-DL-TA----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Training Area","H":"3.X.2.5.5",},{"ID":"WO-DL-O-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Operator Defined","H":"3.X.2.5.6",},{"ID":"WO--M----------","G":"line","DC":"0","MXP":"0","MNP":"0","D":"Man-Made Structures","H":"3.X.2.6",},{"ID":"WO-DMCA----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Cable","H":"3.X.2.6.1",},{"ID":"WO-DMCC-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Submerged Crib","H":"3.X.2.6.2",},{"ID":"WO-DMCD----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Canal","H":"3.X.2.6.3",},{"ID":"WOS-MF----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Ford","H":"3.X.2.6.4",},{"ID":"WOS-ML----P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Lock","H":"3.X.2.6.5",},{"ID":"WOS-MOA---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Oil/Gas Rig","H":"3.X.2.6.6",},{"ID":"WO-DMOA-----A--","G":"area","DC":"3","MXP":"10000","MNP":"3","D":"Oil Rig Field","H":"3.X.2.6.7",},{"ID":"WO-DMPA----L---","G":"line","DC":"1","MXP":"10000","MNP":"2","D":"Pipelines/Pipe","H":"3.X.2.6.8",},{"ID":"WOS-MPA---P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Pile/Piling/Post","H":"3.X.2.6.9",},{"ID":"WS-------------","G":"area","DC":"0","MXP":"0","MNP":"0","D":"Space","H":"3.X.3",},{"ID":"E*N*------*****","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Natural Events","H":"6.X.2",},{"ID":"E*N*A-----*****","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Geologic","H":"6.X.2.1",},{"ID":"E*N*AA----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Aftershock","H":"6.X.2.1.1",},{"ID":"E*N*AB----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Avalanche","H":"6.X.2.1.2",},{"ID":"E*N*AC----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Earthquake Epicenter","H":"6.X.2.1.3",},{"ID":"E*N*AD----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Landslide","H":"6.X.2.1.4",},{"ID":"E*N*AE----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Subsidence","H":"6.X.2.1.5",},{"ID":"WAS-WSVE--P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Volcanic Eruption","H":"6.X.2.1.6",},{"ID":"E*N*AG----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Volcanic Threat","H":"6.X.2.1.7",},{"ID":"E*N*B-----*****","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Hydro-Meteorological","H":"6.X.2.2",},{"ID":"WAS-WSD-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Drizzle","H":"6.X.2.2.1",},{"ID":"E*N*BB----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Drought","H":"6.X.2.2.2",},{"ID":"E*N*BC----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Flood","H":"6.X.2.2.3",},{"ID":"WAS-WSFGSOP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Fog","H":"6.X.2.2.4",},{"ID":"WAS-WSGRL-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Hail","H":"6.X.2.2.5",},{"ID":"E*N*BF----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Inversion","H":"6.X.2.2.6",},{"ID":"WAS-WSR-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rain","H":"6.X.2.2.7",},{"ID":"WAS-WSDSLMP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Sand Dust Storm","H":"6.X.2.2.8",},{"ID":"WAS-WSS-LIP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Snow","H":"6.X.2.2.9",},{"ID":"WAS-WSTMH-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Thunder Storm","H":"6.X.2.2.9",},{"ID":"WAS-WST-FCP----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tornado","H":"6.X.2.2.10",},{"ID":"WAS-WSTSS-P----","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tropical Cyclone","H":"6.X.2.2.11",},{"ID":"E*N*BM----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Tsunami","H":"6.X.2.2.12",},{"ID":"E*N*C-----*****","G":"point","DC":"0","MXP":"0","MNP":"0","D":"Infestation","H":"6.X.2.3",},{"ID":"E*N*CA----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Bird Infestation","H":"6.X.2.3.1",},{"ID":"E*N*CB----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Insect Infestation","H":"6.X.2.3.2",},{"ID":"E*N*CC----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Microbial Infestation","H":"6.X.2.3.3",},{"ID":"E*N*CD----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Reptile Infestation","H":"6.X.2.3.4",},{"ID":"E*N*CE----*****","G":"point","DC":"8","MXP":"1","MNP":"1","D":"Rodent Infestation","H":"6.X.2.3.5",}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitFontMappingsC={"UNITFONTMAPPINGS":{"SYMBOL":[{"ID":"S***------*****",},{"ID":"S*P*------*****",},{"ID":"S*P*S-----*****","M1U":"1000","M1F":"1000","M1N":"1000","M1H":"1000"},{"ID":"S*P*V-----*****","M1U":"1001","M1F":"1001","M1N":"1001","M1H":"1001"},{"ID":"S*P*T-----*****","M1U":"1002","M1F":"1002","M1N":"1002","M1H":"1002","M2":"1003","M2C":"#FFFFFF"},{"ID":"S*P*L-----*****","M1U":"1004","M1F":"1004","M1N":"1004","M1H":"1004"},{"ID":"S*A*------*****",},{"ID":"S*A*M-----*****","M1U":"1005","M1F":"1005","M1N":"1005","M1H":"1005"},{"ID":"S*A*MF----*****","M1U":"1006","M1F":"1006","M1N":"1006","M1H":"1006"},{"ID":"S*A*MFB---*****","M1U":"1007","M1F":"1007","M1N":"1007","M1H":"1007"},{"ID":"S*A*MFF---*****","M1U":"1008","M1F":"1008","M1N":"1008","M1H":"1008"},{"ID":"S*A*MFFI--*****","M1U":"1009","M1F":"1009","M1N":"1009","M1H":"1009"},{"ID":"S*A*MFT---*****","M1U":"1010","M1F":"1010","M1N":"1010","M1H":"1010"},{"ID":"S*A*MFA---*****","M1U":"1011","M1F":"1011","M1N":"1011","M1H":"1011"},{"ID":"S*A*MFL---*****","M1U":"1012","M1F":"1012","M1N":"1012","M1H":"1012"},{"ID":"S*A*MFK---*****","M1U":"1013","M1F":"1013","M1N":"1013","M1H":"1013"},{"ID":"S*A*MFKB--*****","M1U":"1014","M1F":"1014","M1N":"1014","M1H":"1014"},{"ID":"S*A*MFKD--*****","M1U":"1015","M1F":"1015","M1N":"1015","M1H":"1015"},{"ID":"S*A*MFC---*****","M1U":"1016","M1F":"1016","M1N":"1016","M1H":"1016"},{"ID":"S*A*MFCL--*****","M1U":"1017","M1F":"1017","M1N":"1017","M1H":"1017"},{"ID":"S*A*MFCM--*****","M1U":"1018","M1F":"1018","M1N":"1018","M1H":"1018"},{"ID":"S*A*MFCH--*****","M1U":"1019","M1F":"1019","M1N":"1019","M1H":"1019"},{"ID":"S*A*MFJ---*****","M1U":"1020","M1F":"1020","M1N":"1020","M1H":"1020"},{"ID":"S*A*MFO---*****","M1U":"1021","M1F":"1021","M1N":"1021","M1H":"1021"},{"ID":"S*A*MFR---*****","M1U":"1022","M1F":"1022","M1N":"1022","M1H":"1022"},{"ID":"S*A*MFRW--*****","M1U":"1023","M1F":"1023","M1N":"1023","M1H":"1023"},{"ID":"S*A*MFRZ--*****","M1U":"1024","M1F":"1024","M1N":"1024","M1H":"1024"},{"ID":"S*A*MFRX--*****","M1U":"1025","M1F":"1025","M1N":"1025","M1H":"1025"},{"ID":"S*A*MFP---*****","M1U":"1026","M1F":"1026","M1N":"1026","M1H":"1026"},{"ID":"S*A*MFPN--*****","M1U":"1027","M1F":"1027","M1N":"1027","M1H":"1027"},{"ID":"S*A*MFPM--*****","M1U":"1028","M1F":"1028","M1N":"1028","M1H":"1028"},{"ID":"S*A*MFU---*****","M1U":"1029","M1F":"1029","M1N":"1029","M1H":"1029"},{"ID":"S*A*MFUL--*****","M1U":"1030","M1F":"1030","M1N":"1030","M1H":"1030"},{"ID":"S*A*MFUM--*****","M1U":"1031","M1F":"1031","M1N":"1031","M1H":"1031"},{"ID":"S*A*MFUH--*****","M1U":"1032","M1F":"1032","M1N":"1032","M1H":"1032"},{"ID":"S*A*MFY---*****","M1U":"1033","M1F":"1033","M1N":"1033","M1H":"1033"},{"ID":"S*A*MFH---*****","M1U":"1034","M1F":"1034","M1N":"1034","M1H":"1034"},{"ID":"S*A*MFD---*****","M1U":"1035","M1F":"1035","M1N":"1035","M1H":"1035"},{"ID":"S*A*MFQ---*****","M1U":"1036","M1F":"1036","M1N":"1036","M1H":"1036"},{"ID":"S*A*MFQA--*****","M1U":"1037","M1F":"1037","M1N":"1037","M1H":"1037"},{"ID":"S*A*MFQB--*****","M1U":"1038","M1F":"1038","M1N":"1038","M1H":"1038"},{"ID":"S*A*MFQC--*****","M1U":"1039","M1F":"1039","M1N":"1039","M1H":"1039"},{"ID":"S*A*MFQD--*****","M1U":"1040","M1F":"1040","M1N":"1040","M1H":"1040"},{"ID":"S*A*MFQF--*****","M1U":"1041","M1F":"1041","M1N":"1041","M1H":"1041"},{"ID":"S*A*MFQH--*****","M1U":"1042","M1F":"1042","M1N":"1042","M1H":"1042"},{"ID":"S*A*MFQJ--*****","M1U":"1043","M1F":"1043","M1N":"1043","M1H":"1043"},{"ID":"S*A*MFQK--*****","M1U":"1044","M1F":"1044","M1N":"1044","M1H":"1044"},{"ID":"S*A*MFQL--*****","M1U":"1045","M1F":"1045","M1N":"1045","M1H":"1045"},{"ID":"S*A*MFQM--*****","M1U":"1046","M1F":"1046","M1N":"1046","M1H":"1046"},{"ID":"S*A*MFQI--*****","M1U":"1047","M1F":"1047","M1N":"1047","M1H":"1047"},{"ID":"S*A*MFQN--*****","M1U":"1048","M1F":"1048","M1N":"1048","M1H":"1048"},{"ID":"S*A*MFQP--*****","M1U":"1049","M1F":"1049","M1N":"1049","M1H":"1049"},{"ID":"S*A*MFQR--*****","M1U":"1050","M1F":"1050","M1N":"1050","M1H":"1050"},{"ID":"S*A*MFQRW-*****","M1U":"1051","M1F":"1051","M1N":"1051","M1H":"1051"},{"ID":"S*A*MFQRZ-*****","M1U":"1052","M1F":"1052","M1N":"1052","M1H":"1052"},{"ID":"S*A*MFQRX-*****","M1U":"1053","M1F":"1053","M1N":"1053","M1H":"1053"},{"ID":"S*A*MFQS--*****","M1U":"1054","M1F":"1054","M1N":"1054","M1H":"1054"},{"ID":"S*A*MFQT--*****","M1U":"1055","M1F":"1055","M1N":"1055","M1H":"1055"},{"ID":"S*A*MFQU--*****","M1U":"1056","M1F":"1056","M1N":"1056","M1H":"1056"},{"ID":"S*A*MFQY--*****","M1U":"1057","M1F":"1057","M1N":"1057","M1H":"1057"},{"ID":"S*A*MFQO--*****","M1U":"1058","M1F":"1058","M1N":"1058","M1H":"1058"},{"ID":"S*A*MFS---*****","M1U":"1059","M1F":"1059","M1N":"1059","M1H":"1059"},{"ID":"S*A*MFM---*****","M1U":"1060","M1F":"1060","M1N":"1060","M1H":"1060"},{"ID":"S*A*MH----*****","M1U":"1061","M1F":"1061","M1N":"1061","M1H":"1061"},{"ID":"S*A*MHA---*****","M1U":"1062","M1F":"1062","M1N":"1062","M1H":"1062"},{"ID":"S*A*MHS---*****","M1U":"1063","M1F":"1063","M1N":"1063","M1H":"1063"},{"ID":"S*A*MHU---*****","M1U":"1064","M1F":"1064","M1N":"1064","M1H":"1064"},{"ID":"S*A*MHUL--*****","M1U":"1065","M1F":"1065","M1N":"1065","M1H":"1065"},{"ID":"S*A*MHUM--*****","M1U":"1066","M1F":"1066","M1N":"1066","M1H":"1066"},{"ID":"S*A*MHUH--*****","M1U":"1067","M1F":"1067","M1N":"1067","M1H":"1067"},{"ID":"S*A*MHI---*****","M1U":"1068","M1F":"1068","M1N":"1068","M1H":"1068"},{"ID":"S*A*MHH---*****","M1U":"1069","M1F":"1069","M1N":"1069","M1H":"1069"},{"ID":"S*A*MHR---*****","M1U":"1070","M1F":"1070","M1N":"1070","M1H":"1070"},{"ID":"S*A*MHQ---*****","M1U":"1071","M1F":"1071","M1N":"1071","M1H":"1071"},{"ID":"S*A*MHC---*****","M1U":"1072","M1F":"1072","M1N":"1072","M1H":"1072"},{"ID":"S*A*MHCL--*****","M1U":"1073","M1F":"1073","M1N":"1073","M1H":"1073"},{"ID":"S*A*MHCM--*****","M1U":"1074","M1F":"1074","M1N":"1074","M1H":"1074"},{"ID":"S*A*MHCH--*****","M1U":"1075","M1F":"1075","M1N":"1075","M1H":"1075"},{"ID":"S*A*MHT---*****","M1U":"1076","M1F":"1076","M1N":"1076","M1H":"1076"},{"ID":"S*A*MHO---*****","M1U":"1077","M1F":"1077","M1N":"1077","M1H":"1077"},{"ID":"S*A*MHM---*****","M1U":"1078","M1F":"1078","M1N":"1078","M1H":"1078"},{"ID":"S*A*MHD---*****","M1U":"1079","M1F":"1079","M1N":"1079","M1H":"1079"},{"ID":"S*A*MHK---*****","M1U":"1080","M1F":"1080","M1N":"1080","M1H":"1080"},{"ID":"S*A*MHJ---*****","M1U":"1081","M1F":"1081","M1N":"1081","M1H":"1081"},{"ID":"S*A*ML----*****","M1U":"1082","M1F":"1082","M1N":"1082","M1H":"1082"},{"ID":"S*A*MV----*****","M1U":"2167","M1F":"2167","M1N":"2167","M1H":"2167"},{"ID":"S*A*ME----*****","M1U":"2168","M1F":"2168","M1N":"2168","M1H":"2168"},{"ID":"S*A*W-----*****","M1U":"1083","M1F":"1083","M1N":"1083","M1H":"1083","M2":"1084","M2C":"#FFFF00"},{"ID":"S*A*WM----*****","M1U":"1083","M1F":"1083","M1N":"1083","M1H":"1083","M2":"1084","M2C":"#FFFF00"},{"ID":"S*A*WMS---*****","M1U":"1085","M1F":"1085","M1N":"1085","M1H":"1085","M2":"1084","M2C":"#FFFF00"},{"ID":"S*A*WMSS--*****","M1U":"1086","M1F":"1086","M1N":"1086","M1H":"1086","M2":"1084","M2C":"#FFFF00"},{"ID":"S*A*WMSA--*****","M1U":"1087","M1F":"1087","M1N":"1087","M1H":"1087","M2":"1084","M2C":"#FFFF00"},{"ID":"S*A*WMSU--*****","M1U":"1088","M1F":"1088","M1N":"1088","M1H":"1088","M2":"401","M2C":"#FFFF00"},{"ID":"S*A*WMSB--*****","M1U":"1089","M1F":"1089","M1N":"1089","M1H":"1089","M2":"401","M2C":"#FFFF00"},{"ID":"S*A*WMA---*****","M1U":"1090","M1F":"1090","M1N":"1090","M1H":"1090","M2":"400","M2C":"#FFFF00"},{"ID":"S*A*WMAS--*****","M1U":"1091","M1F":"1091","M1N":"1091","M1H":"1091","M2":"400","M2C":"#FFFF00"},{"ID":"S*A*WMAA--*****","M1U":"1093","M1F":"1093","M1N":"1093","M1H":"1093","M2":"400","M2C":"#FFFF00"},{"ID":"S*A*WMAP--*****","M1U":"1094","M1F":"1094","M1N":"1094","M1H":"1094","M2":"401","M2C":"#FFFF00"},{"ID":"S*A*WMU---*****","M1U":"1095","M1F":"1095","M1N":"1095","M1H":"1095","M2":"401","M2C":"#FFFF00"},{"ID":"S*A*WMCM--*****","M1U":"1096","M1F":"1096","M1N":"1096","M1H":"1096","M2":"400","M2C":"#FFFF00"},{"ID":"S*A*WMB---*****","M1U":"1097","M1F":"1097","M1N":"1097","M1H":"1097","M2":"400","M2C":"#FFFF00"},{"ID":"S*A*WD----*****","M1U":"1099","M1F":"1099","M1N":"1099","M1H":"1099"},{"ID":"S*A*WB----*****","M1U":"1098","M1F":"1098","M1N":"1098","M1H":"1098"},{"ID":"S*A*C-----*****","M1U":"1100","M1F":"1100","M1N":"1100","M1H":"1100"},{"ID":"S*A*CF----*****","M1U":"1101","M1F":"1101","M1N":"1101","M1H":"1101","M2":"402","M2C":"#FFFFFF"},{"ID":"S*A*CH----*****","M1U":"1102","M1F":"1102","M1N":"1102","M1H":"1102","M2":"403","M2C":"#FFFFFF"},{"ID":"S*A*CL----*****","M1U":"1103","M1F":"1103","M1N":"1103","M1H":"1103","M2":"404","M2C":"#FFFFFF"},{"ID":"S*G*------*****",},{"ID":"S*G*U-----*****",},{"ID":"S*G*UC----*****","M1U":"1104","M1F":"1104","M1N":"1104","M1H":"1104"},{"ID":"S*G*UCD---*****","M1U":"1105","M1F":"1106","M1N":"1107","M1H":"1108"},{"ID":"S*G*UCDS--*****","M1U":"1109","M1F":"1110","M1N":"1111","M1H":"1112"},{"ID":"S*G*UCDSC-*****","M1U":"1113","M1F":"1114","M1N":"1115","M1H":"1116"},{"ID":"S*G*UCDSS-*****","M1U":"1117","M1F":"1118","M1N":"1119","M1H":"1120"},{"ID":"S*G*UCDSV-*****","M1U":"1121","M1F":"1122","M1N":"1123","M1H":"1124"},{"ID":"S*G*UCDM--*****","M1U":"1125","M1F":"1126","M1N":"1127","M1H":"1128"},{"ID":"S*G*UCDML-*****","M1U":"1129","M1F":"1130","M1N":"1131","M1H":"1132"},{"ID":"S*G*UCDMLA*****","M1U":"1133","M1F":"1134","M1N":"1135","M1H":"1136"},{"ID":"S*G*UCDMM-*****","M1U":"1137","M1F":"1138","M1N":"1139","M1H":"1140"},{"ID":"S*G*UCDMH-*****","M1U":"1141","M1F":"1142","M1N":"1143","M1H":"1144"},{"ID":"S*G*UCDH--*****","M1U":"1145","M1F":"1146","M1N":"1147","M1H":"1148"},{"ID":"S*G*UCDHH-*****","M1U":"1149","M1F":"1150","M1N":"1151","M1H":"1152"},{"ID":"S*G*UCDHP-*****","M1U":"1153","M1F":"1154","M1N":"1155","M1H":"1156"},{"ID":"S*G*UCDG--*****","M1U":"1157","M1F":"1158","M1N":"1159","M1H":"1160"},{"ID":"S*G*UCDC--*****","M1U":"1161","M1F":"1162","M1N":"1163","M1H":"1164"},{"ID":"S*G*UCDT--*****","M1U":"1165","M1F":"1166","M1N":"1167","M1H":"1168"},{"ID":"S*G*UCDO--*****","M1U":"1169","M1F":"1170","M1N":"1171","M1H":"1172"},{"ID":"S*G*UCA---*****","M1U":"1173","M1F":"1173","M1N":"1173","M1H":"1173"},{"ID":"S*G*UCAT--*****","M1U":"1173","M1F":"1173","M1N":"1173","M1H":"1173"},{"ID":"S*G*UCATA-*****","M1U":"1174","M1F":"1174","M1N":"1174","M1H":"1174"},{"ID":"S*G*UCATW-*****","M1U":"1175","M1F":"1176","M1N":"1177","M1H":"1178"},{"ID":"S*G*UCATWR*****","M1U":"1179","M1F":"1180","M1N":"1181","M1H":"1182"},{"ID":"S*G*UCATL-*****","M1U":"1183","M1F":"1183","M1N":"1183","M1H":"1183"},{"ID":"S*G*UCATM-*****","M1U":"1184","M1F":"1184","M1N":"1184","M1H":"1184"},{"ID":"S*G*UCATH-*****","M1U":"1185","M1F":"1185","M1N":"1185","M1H":"1185"},{"ID":"S*G*UCATR-*****","M1U":"1186","M1F":"1186","M1N":"1186","M1H":"1186"},{"ID":"S*G*UCAW--*****","M1U":"1187","M1F":"1187","M1N":"1187","M1H":"1187"},{"ID":"S*G*UCAWS-*****","M1U":"1188","M1F":"1188","M1N":"1188","M1H":"1188"},{"ID":"S*G*UCAWA-*****","M1U":"1189","M1F":"1189","M1N":"1189","M1H":"1189"},{"ID":"S*G*UCAWW-*****","M1U":"1190","M1F":"1191","M1N":"1192","M1H":"1193"},{"ID":"S*G*UCAWWR*****","M1U":"1194","M1F":"1195","M1N":"1196","M1H":"1197"},{"ID":"S*G*UCAWL-*****","M1U":"1198","M1F":"1198","M1N":"1198","M1H":"1198"},{"ID":"S*G*UCAWM-*****","M1U":"1199","M1F":"1199","M1N":"1199","M1H":"1199"},{"ID":"S*G*UCAWH-*****","M1U":"1200","M1F":"1200","M1N":"1200","M1H":"1200"},{"ID":"S*G*UCAWR-*****","M1U":"1201","M1F":"1201","M1N":"1201","M1H":"1201"},{"ID":"S*G*UCAA--*****","M1U":"1202","M1F":"1203","M1N":"1204","M1H":"1205"},{"ID":"S*G*UCAAD-*****","M1U":"1202","M1F":"1203","M1N":"1204","M1H":"1205"},{"ID":"S*G*UCAAL-*****","M1U":"1206","M1F":"1207","M1N":"1208","M1H":"1209"},{"ID":"S*G*UCAAM-*****","M1U":"1210","M1F":"1211","M1N":"1212","M1H":"1213"},{"ID":"S*G*UCAAS-*****","M1U":"1214","M1F":"1215","M1N":"1216","M1H":"1217"},{"ID":"S*G*UCAAU-*****","M1U":"1218","M1F":"1219","M1N":"1220","M1H":"1221"},{"ID":"S*G*UCAAC-*****","M1U":"1222","M1F":"1223","M1N":"1224","M1H":"1225"},{"ID":"S*G*UCAAA-*****","M1U":"1226","M1F":"1227","M1N":"1228","M1H":"1229"},{"ID":"S*G*UCAAAT*****","M1U":"1226","M1F":"1227","M1N":"1228","M1H":"1229"},{"ID":"S*G*UCAAAW*****","M1U":"1230","M1F":"1231","M1N":"1232","M1H":"1233"},{"ID":"S*G*UCAAAS*****","M1U":"1234","M1F":"1235","M1N":"1236","M1H":"1237"},{"ID":"S*G*UCAAO-*****","M1U":"1238","M1F":"1239","M1N":"1240","M1H":"1241"},{"ID":"S*G*UCAAOS*****","M1U":"1242","M1F":"1243","M1N":"1244","M1H":"1245"},{"ID":"S*G*UCV---*****","M1U":"1246","M1F":"1246","M1N":"1246","M1H":"1246"},{"ID":"S*G*UCVF--*****","M1U":"1247","M1F":"1247","M1N":"1247","M1H":"1247"},{"ID":"S*G*UCVFU-*****","M1U":"1248","M1F":"1248","M1N":"1248","M1H":"1248"},{"ID":"S*G*UCVFA-*****","M1U":"1249","M1F":"1249","M1N":"1249","M1H":"1249"},{"ID":"S*G*UCVFR-*****","M1U":"1250","M1F":"1250","M1N":"1250","M1H":"1250"},{"ID":"S*G*UCVR--*****","M1U":"1251","M1F":"1251","M1N":"1251","M1H":"1251"},{"ID":"S*G*UCVRA-*****","M1U":"1252","M1F":"1252","M1N":"1252","M1H":"1252"},{"ID":"S*G*UCVRS-*****","M1U":"1253","M1F":"1253","M1N":"1253","M1H":"1253"},{"ID":"S*G*UCVRW-*****","M1U":"1254","M1F":"1254","M1N":"1254","M1H":"1254"},{"ID":"S*G*UCVRU-*****","M1U":"1255","M1F":"1255","M1N":"1255","M1H":"1255"},{"ID":"S*G*UCVRUL*****","M1U":"1256","M1F":"1256","M1N":"1256","M1H":"1256"},{"ID":"S*G*UCVRUM*****","M1U":"1257","M1F":"1257","M1N":"1257","M1H":"1257"},{"ID":"S*G*UCVRUH*****","M1U":"1258","M1F":"1258","M1N":"1258","M1H":"1258"},{"ID":"S*G*UCVRUC*****","M1U":"1259","M1F":"1259","M1N":"1259","M1H":"1259"},{"ID":"S*G*UCVRUE*****","M1U":"1260","M1F":"1260","M1N":"1260","M1H":"1260"},{"ID":"S*G*UCVRM-*****","M1U":"1261","M1F":"1261","M1N":"1261","M1H":"1261"},{"ID":"S*G*UCVS--*****","M1U":"1262","M1F":"1262","M1N":"1262","M1H":"1262"},{"ID":"S*G*UCVC--*****","M1U":"1263","M1F":"1263","M1N":"1263","M1H":"1263"},{"ID":"S*G*UCVV--*****","M1U":"1264","M1F":"1264","M1N":"1264","M1H":"1264"},{"ID":"S*G*UCVU--*****","M1U":"1265","M1F":"1265","M1N":"1265","M1H":"1265"},{"ID":"S*G*UCVUF-*****","M1U":"1266","M1F":"1266","M1N":"1266","M1H":"1266"},{"ID":"S*G*UCVUR-*****","M1U":"1267","M1F":"1267","M1N":"1267","M1H":"1267"},{"ID":"S*G*UCI---*****","M1U":"1268","M1F":"1269","M1N":"1270","M1H":"1271"},{"ID":"S*G*UCIL--*****","M1U":"1272","M1F":"1273","M1N":"1274","M1H":"1275"},{"ID":"S*G*UCIM--*****","M1U":"1276","M1F":"1277","M1N":"1278","M1H":"1279"},{"ID":"S*G*UCIO--*****","M1U":"1280","M1F":"1281","M1N":"1282","M1H":"1283"},{"ID":"S*G*UCIA--*****","M1U":"1284","M1F":"1285","M1N":"1286","M1H":"1287"},{"ID":"S*G*UCIS--*****","M1U":"1288","M1F":"1289","M1N":"1290","M1H":"1291"},{"ID":"S*G*UCIZ--*****","M1U":"1292","M1F":"1293","M1N":"1294","M1H":"1295"},{"ID":"S*G*UCIN--*****","M1U":"1296","M1F":"1297","M1N":"1298","M1H":"1299"},{"ID":"S*G*UCII--*****","M1U":"1300","M1F":"1301","M1N":"1302","M1H":"1303"},{"ID":"S*G*UCIC--*****","M1U":"604","M1F":"605","M1N":"606","M1H":"607","M2":"1092"},{"ID":"S*G*UCE---*****","M1U":"1304","M1F":"1304","M1N":"1304","M1H":"1304"},{"ID":"S*G*UCEC--*****","M1U":"1305","M1F":"1305","M1N":"1305","M1H":"1305"},{"ID":"S*G*UCECS-*****","M1U":"1306","M1F":"1306","M1N":"1306","M1H":"1306"},{"ID":"S*G*UCECA-*****","M1U":"1307","M1F":"1307","M1N":"1307","M1H":"1307"},{"ID":"S*G*UCECC-*****","M1U":"1308","M1F":"1308","M1N":"1308","M1H":"1308"},{"ID":"S*G*UCECL-*****","M1U":"1309","M1F":"1309","M1N":"1309","M1H":"1309"},{"ID":"S*G*UCECM-*****","M1U":"1310","M1F":"1310","M1N":"1310","M1H":"1310"},{"ID":"S*G*UCECH-*****","M1U":"1311","M1F":"1311","M1N":"1311","M1H":"1311"},{"ID":"S*G*UCECT-*****","M1U":"1312","M1F":"1312","M1N":"1312","M1H":"1312"},{"ID":"S*G*UCECW-*****","M1U":"1313","M1F":"1314","M1N":"1315","M1H":"1316"},{"ID":"S*G*UCECO-*****","M1U":"1317","M1F":"1317","M1N":"1317","M1H":"1317"},{"ID":"S*G*UCECR-*****","M1U":"1318","M1F":"1319","M1N":"1320","M1H":"1321"},{"ID":"S*G*UCEN--*****","M1U":"1322","M1F":"1322","M1N":"1322","M1H":"1322"},{"ID":"S*G*UCENN-*****","M1U":"1323","M1F":"1323","M1N":"1323","M1H":"1323"},{"ID":"S*G*UCF---*****","M1U":"1324","M1F":"1324","M1N":"1324","M1H":"1324"},{"ID":"S*G*UCFH--*****","M1U":"1324","M1F":"1324","M1N":"1324","M1H":"1324"},{"ID":"S*G*UCFHE-*****","M1U":"1325","M1F":"1325","M1N":"1325","M1H":"1325"},{"ID":"S*G*UCFHS-*****","M1U":"1326","M1F":"1326","M1N":"1326","M1H":"1326"},{"ID":"S*G*UCFHA-*****","M1U":"1327","M1F":"1327","M1N":"1327","M1H":"1327"},{"ID":"S*G*UCFHC-*****","M1U":"1328","M1F":"1328","M1N":"1328","M1H":"1328"},{"ID":"S*G*UCFHO-*****","M1U":"1329","M1F":"1329","M1N":"1329","M1H":"1329"},{"ID":"S*G*UCFHL-*****","M1U":"1330","M1F":"1330","M1N":"1330","M1H":"1330"},{"ID":"S*G*UCFHM-*****","M1U":"1331","M1F":"1331","M1N":"1331","M1H":"1331"},{"ID":"S*G*UCFHH-*****","M1U":"1332","M1F":"1332","M1N":"1332","M1H":"1332"},{"ID":"S*G*UCFHX-*****","M1U":"1333","M1F":"1334","M1N":"1335","M1H":"1336"},{"ID":"S*G*UCFR--*****","M1U":"1337","M1F":"1337","M1N":"1337","M1H":"1337"},{"ID":"S*G*UCFRS-*****","M1U":"1338","M1F":"1338","M1N":"1338","M1H":"1338"},{"ID":"S*G*UCFRSS*****","M1U":"1339","M1F":"1339","M1N":"1339","M1H":"1339"},{"ID":"S*G*UCFRSR*****","M1U":"1340","M1F":"1340","M1N":"1340","M1H":"1340"},{"ID":"S*G*UCFRST*****","M1U":"1341","M1F":"1341","M1N":"1341","M1H":"1341"},{"ID":"S*G*UCFRM-*****","M1U":"1342","M1F":"1342","M1N":"1342","M1H":"1342"},{"ID":"S*G*UCFRMS*****","M1U":"1343","M1F":"1343","M1N":"1343","M1H":"1343"},{"ID":"S*G*UCFRMR*****","M1U":"1344","M1F":"1344","M1N":"1344","M1H":"1344"},{"ID":"S*G*UCFRMT*****","M1U":"1345","M1F":"1345","M1N":"1345","M1H":"1345"},{"ID":"S*G*UCFT--*****","M1U":"1346","M1F":"1346","M1N":"1346","M1H":"1346"},{"ID":"S*G*UCFTR-*****","M1U":"1347","M1F":"1347","M1N":"1347","M1H":"1347"},{"ID":"S*G*UCFTS-*****","M1U":"1348","M1F":"1349","M1N":"1350","M1H":"1351","M2":"405","M2C":"#FFFFFF"},{"ID":"S*G*UCFTF-*****","M1U":"1352","M1F":"1352","M1N":"1352","M1H":"1352"},{"ID":"S*G*UCFTC-*****","M1U":"1353","M1F":"1354","M1N":"1355","M1H":"1356"},{"ID":"S*G*UCFTCD*****","M1U":"1357","M1F":"1358","M1N":"1359","M1H":"1360"},{"ID":"S*G*UCFTCM*****","M1U":"1361","M1F":"1362","M1N":"1363","M1H":"1364"},{"ID":"S*G*UCFTA-*****","M1U":"1365","M1F":"1366","M1N":"1367","M1H":"1368"},{"ID":"S*G*UCFM--*****","M1U":"1369","M1F":"1369","M1N":"1369","M1H":"1369"},{"ID":"S*G*UCFMS-*****","M1U":"1370","M1F":"1370","M1N":"1370","M1H":"1370"},{"ID":"S*G*UCFMW-*****","M1U":"1371","M1F":"1371","M1N":"1371","M1H":"1371"},{"ID":"S*G*UCFMT-*****","M1U":"1372","M1F":"1372","M1N":"1372","M1H":"1372"},{"ID":"S*G*UCFMTA*****","M1U":"1373","M1F":"1373","M1N":"1373","M1H":"1373"},{"ID":"S*G*UCFMTS*****","M1U":"1374","M1F":"1374","M1N":"1374","M1H":"1374"},{"ID":"S*G*UCFMTC*****","M1U":"1375","M1F":"1375","M1N":"1375","M1H":"1375"},{"ID":"S*G*UCFMTO*****","M1U":"1376","M1F":"1376","M1N":"1376","M1H":"1376"},{"ID":"S*G*UCFML-*****","M1U":"1377","M1F":"1378","M1N":"1379","M1H":"1380"},{"ID":"S*G*UCFS--*****","M1U":"1381","M1F":"1381","M1N":"1381","M1H":"1381","M2":"1382","M2C":"#FFFFFF"},{"ID":"S*G*UCFSS-*****","M1U":"1383","M1F":"1383","M1N":"1383","M1H":"1383","M2":"1384","M2C":"#FFFFFF"},{"ID":"S*G*UCFSA-*****","M1U":"1385","M1F":"1385","M1N":"1385","M1H":"1385","M2":"1386","M2C":"#FFFFFF"},{"ID":"S*G*UCFSL-*****","M1U":"1387","M1F":"1387","M1N":"1387","M1H":"1387","M2":"1388","M2C":"#FFFFFF"},{"ID":"S*G*UCFSO-*****","M1U":"1389","M1F":"1389","M1N":"1389","M1H":"1389","M2":"1390","M2C":"#FFFFFF"},{"ID":"S*G*UCFO--*****","M1U":"1391","M1F":"1391","M1N":"1391","M1H":"1391"},{"ID":"S*G*UCFOS-*****","M1U":"1392","M1F":"1392","M1N":"1392","M1H":"1392"},{"ID":"S*G*UCFOA-*****","M1U":"1393","M1F":"1393","M1N":"1393","M1H":"1393"},{"ID":"S*G*UCFOL-*****","M1U":"1394","M1F":"1394","M1N":"1394","M1H":"1394"},{"ID":"S*G*UCFOO-*****","M1U":"1395","M1F":"1395","M1N":"1395","M1H":"1395"},{"ID":"S*G*UCR---*****","M1U":"1396","M1F":"1397","M1N":"1398","M1H":"1399"},{"ID":"S*G*UCRH--*****","M1U":"1400","M1F":"1400","M1N":"1400","M1H":"1400"},{"ID":"S*G*UCRV--*****","M1U":"1401","M1F":"1402","M1N":"1403","M1H":"1404"},{"ID":"S*G*UCRVA-*****","M1U":"1405","M1F":"1406","M1N":"1407","M1H":"1408"},{"ID":"S*G*UCRVM-*****","M1U":"1409","M1F":"1410","M1N":"1411","M1H":"1412"},{"ID":"S*G*UCRVG-*****","M1U":"1413","M1F":"1414","M1N":"1415","M1H":"1416"},{"ID":"S*G*UCRVO-*****","M1U":"1417","M1F":"1418","M1N":"1419","M1H":"1420"},{"ID":"S*G*UCRC--*****","M1U":"1421","M1F":"1422","M1N":"1423","M1H":"1424"},{"ID":"S*G*UCRS--*****","M1U":"1425","M1F":"1426","M1N":"1427","M1H":"1428"},{"ID":"S*G*UCRA--*****","M1U":"1429","M1F":"1430","M1N":"1431","M1H":"1432"},{"ID":"S*G*UCRO--*****","M1U":"1433","M1F":"1434","M1N":"1435","M1H":"1436"},{"ID":"S*G*UCRL--*****","M1U":"1437","M1F":"1438","M1N":"1439","M1H":"1440"},{"ID":"S*G*UCRR--*****","M1U":"1441","M1F":"1442","M1N":"1443","M1H":"1444"},{"ID":"S*G*UCRRD-*****","M1U":"1445","M1F":"1446","M1N":"1447","M1H":"1448"},{"ID":"S*G*UCRRF-*****","M1U":"1449","M1F":"1450","M1N":"1451","M1H":"1452"},{"ID":"S*G*UCRRL-*****","M1U":"1453","M1F":"1454","M1N":"1455","M1H":"1456"},{"ID":"S*G*UCRX--*****","M1U":"1457","M1F":"1458","M1N":"1459","M1H":"1460"},{"ID":"S*G*UCM---*****","M1U":"1461","M1F":"1461","M1N":"1461","M1H":"1461"},{"ID":"S*G*UCMT--*****","M1U":"1462","M1F":"1462","M1N":"1462","M1H":"1462"},{"ID":"S*G*UCMS--*****","M1U":"1463","M1F":"1463","M1N":"1463","M1H":"1463"},{"ID":"S*G*UCS---*****","M1U":"1464","M1F":"1464","M1N":"1464","M1H":"1464"},{"ID":"S*G*UCSW--*****","M1U":"1465","M1F":"1466","M1N":"1467","M1H":"1468"},{"ID":"S*G*UCSG--*****","M1U":"1469","M1F":"1469","M1N":"1469","M1H":"1469"},{"ID":"S*G*UCSGD-*****","M1U":"1470","M1F":"1471","M1N":"1472","M1H":"1473"},{"ID":"S*G*UCSGM-*****","M1U":"1474","M1F":"1475","M1N":"1476","M1H":"1477"},{"ID":"S*G*UCSGA-*****","M1U":"1478","M1F":"1478","M1N":"1478","M1H":"1478"},{"ID":"S*G*UCSM--*****","M1U":"1479","M1F":"1479","M1N":"1479","M1H":"1479"},{"ID":"S*G*UCSR--*****","M1U":"1480","M1F":"1480","M1N":"1480","M1H":"1480"},{"ID":"S*G*UCSA--*****","M1U":"1481","M1F":"1481","M1N":"1481","M1H":"1481"},{"ID":"S*G*UCL---*****","M1U":"1890","M1F":"1890","M1N":"1890","M1H":"1890"},{"ID":"S*G*UU----*****","M1U":"1482","M1F":"1482","M1N":"1482","M1H":"1482"},{"ID":"S*G*UUA---*****","M1U":"1483","M1F":"1483","M1N":"1483","M1H":"1483"},{"ID":"S*G*UUAC--*****","M1U":"1484","M1F":"1484","M1N":"1484","M1H":"1484"},{"ID":"S*G*UUACC-*****","M1U":"1485","M1F":"1485","M1N":"1485","M1H":"1485"},{"ID":"S*G*UUACCK*****","M1U":"1486","M1F":"1486","M1N":"1486","M1H":"1486"},{"ID":"S*G*UUACCM*****","M1U":"1487","M1F":"1488","M1N":"1489","M1H":"1490"},{"ID":"S*G*UUACS-*****","M1U":"1491","M1F":"1491","M1N":"1491","M1H":"1491"},{"ID":"S*G*UUACSM*****","M1U":"1492","M1F":"1493","M1N":"1494","M1H":"1495"},{"ID":"S*G*UUACSA*****","M1U":"1496","M1F":"1496","M1N":"1496","M1H":"1496"},{"ID":"S*G*UUACR-*****","M1U":"1497","M1F":"1498","M1N":"1499","M1H":"1500"},{"ID":"S*G*UUACRW*****","M1U":"1501","M1F":"1502","M1N":"1503","M1H":"1504"},{"ID":"S*G*UUACRS*****","M1U":"1505","M1F":"1506","M1N":"1507","M1H":"1508"},{"ID":"S*G*UUAN--*****","M1U":"1509","M1F":"1509","M1N":"1509","M1H":"1509"},{"ID":"S*G*UUAB--*****","M1U":"1510","M1F":"1510","M1N":"1510","M1H":"1510"},{"ID":"S*G*UUABR-*****","M1U":"1511","M1F":"1512","M1N":"1513","M1H":"1514"},{"ID":"S*G*UUAD--*****","M1U":"1515","M1F":"1515","M1N":"1515","M1H":"1515"},{"ID":"S*G*UUM---*****","M1U":"1516","M1F":"1516","M1N":"1516","M1H":"1516"},{"ID":"S*G*UUMA--*****","M1U":"1517","M1F":"1517","M1N":"1517","M1H":"1517"},{"ID":"S*G*UUMS--*****","M1U":"1518","M1F":"1518","M1N":"1518","M1H":"1518"},{"ID":"S*G*UUMSE-*****","M1U":"1519","M1F":"1519","M1N":"1519","M1H":"1519"},{"ID":"S*G*UUMSEA*****","M1U":"600","M1F":"601","M1N":"602","M1H":"603","M2":"1520","M2C":"#000000"},{"ID":"S*G*UUMSED*****","M1U":"1521","M1F":"1521","M1N":"1521","M1H":"1521"},{"ID":"S*G*UUMSEI*****","M1U":"1522","M1F":"1522","M1N":"1522","M1H":"1522"},{"ID":"S*G*UUMSEJ*****","M1U":"1523","M1F":"1524","M1N":"1525","M1H":"1526"},{"ID":"S*G*UUMSET*****","M1U":"1527","M1F":"1528","M1N":"1529","M1H":"1530"},{"ID":"S*G*UUMSEC*****","M1U":"1531","M1F":"1532","M1N":"1533","M1H":"1534"},{"ID":"S*G*UUMC--*****","M1U":"1535","M1F":"1535","M1N":"1535","M1H":"1535"},{"ID":"S*G*UUMR--*****","M1U":"1536","M1F":"1536","M1N":"1536","M1H":"1536"},{"ID":"S*G*UUMRG-*****","M1U":"1537","M1F":"1537","M1N":"1537","M1H":"1537"},{"ID":"S*G*UUMRS-*****","M1U":"1538","M1F":"1539","M1N":"1540","M1H":"1541","M2":"1542","M2C":"#FFFFFF"},{"ID":"S*G*UUMRSS*****","M1U":"1543","M1F":"1544","M1N":"1545","M1H":"1546","M2":"1542","M2C":"#FFFFFF"},{"ID":"S*G*UUMRX-*****","M1U":"1547","M1F":"1547","M1N":"1547","M1H":"1547"},{"ID":"S*G*UUMMO-*****","M1U":"1548","M1F":"1548","M1N":"1548","M1H":"1548"},{"ID":"S*G*UUMO--*****","M1U":"1549","M1F":"1549","M1N":"1549","M1H":"1549"},{"ID":"S*G*UUMT--*****","M1U":"1550","M1F":"1550","M1N":"1550","M1H":"1550"},{"ID":"S*G*UUMQ--*****","M1U":"1551","M1F":"1551","M1N":"1551","M1H":"1551"},{"ID":"S*G*UUMJ--*****","M1U":"1552","M1F":"1552","M1N":"1552","M1H":"1552"},{"ID":"S*G*UUL---*****","M1U":"1553","M1F":"1553","M1N":"1553","M1H":"1553"},{"ID":"S*G*UULS--*****","M1U":"1554","M1F":"1554","M1N":"1554","M1H":"1554"},{"ID":"S*G*UULM--*****","M1U":"1555","M1F":"1555","M1N":"1555","M1H":"1555"},{"ID":"S*G*UULC--*****","M1U":"1556","M1F":"1556","M1N":"1556","M1H":"1556"},{"ID":"S*G*UULF--*****","M1U":"1557","M1F":"1557","M1N":"1557","M1H":"1557"},{"ID":"S*G*UULD--*****","M1U":"1558","M1F":"1558","M1N":"1558","M1H":"1558"},{"ID":"S*G*UUS---*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562"},{"ID":"S*G*UUSA--*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1563","M2C":"#000000"},{"ID":"S*G*UUSC--*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1564","M2C":"#000000"},{"ID":"S*G*UUSCL-*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1565","M2C":"#000000"},{"ID":"S*G*UUSO--*****","M1U":"1559","M2":"1566","M2C":"#000000"},{"ID":"S*G*UUSF--*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1567","M2C":"#000000"},{"ID":"S*G*UUSM--*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1568","M2C":"#000000"},{"ID":"S*G*UUSMS-*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1569","M2C":"#000000"},{"ID":"S*G*UUSML-*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1570","M2C":"#000000"},{"ID":"S*G*UUSMN-*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1571","M2C":"#000000"},{"ID":"S*G*UUSR--*****","M1U":"1572","M1F":"1573","M1N":"1574","M1H":"1575"},{"ID":"S*G*UUSRS-*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1576","M2C":"#000000"},{"ID":"S*G*UUSRT-*****","M1U":"1577","M1F":"1578","M1N":"1579","M1H":"1580"},{"ID":"S*G*UUSRW-*****","M1U":"1581","M1F":"1582","M1N":"1583","M1H":"1584"},{"ID":"S*G*UUSS--*****","M1U":"1559","M1F":"1560","M1N":"1561","M1H":"1562","M2":"1585","M2C":"#000000"},{"ID":"S*G*UUSW--*****","M1U":"1586","M1F":"1587","M1N":"1588","M1H":"1589"},{"ID":"S*G*UUSX--*****","M1U":"1590","M1F":"1590","M1N":"1590","M1H":"1590","M2":"1591","M2C":"#FFFFFF"},{"ID":"S*G*UUI---*****","M1U":"1592","M1F":"1592","M1N":"1592","M1H":"1592"},{"ID":"S*G*UUP---*****","M1U":"612","M1F":"613","M1N":"614","M1H":"615","M2":"1593","M2C":"#000000"},{"ID":"S*G*UUE---*****","M1U":"1594","M1F":"1594","M1N":"1594","M1H":"1594"},{"ID":"S*G*US----*****","M1U":"1595","M1F":"1595","M1N":"1595","M1H":"1595"},{"ID":"S*G*USA---*****","M1U":"1596","M1F":"1596","M1N":"1596","M1H":"1596"},{"ID":"S*G*USAT--*****","M1U":"1597","M1F":"1598","M1N":"1599","M1H":"1600"},{"ID":"S*G*USAC--*****","M1U":"1601","M1F":"1602","M1N":"1603","M1H":"1604"},{"ID":"S*G*USAJ--*****","M1U":"1605","M1F":"1605","M1N":"1605","M1H":"1605"},{"ID":"S*G*USAJT-*****","M1U":"1606","M1F":"1607","M1N":"1608","M1H":"1609"},{"ID":"S*G*USAJC-*****","M1U":"1610","M1F":"1611","M1N":"1612","M1H":"1613"},{"ID":"S*G*USAO--*****","M1U":"1614","M1F":"1614","M1N":"1614","M1H":"1614"},{"ID":"S*G*USAOT-*****","M1U":"1615","M1F":"1616","M1N":"1617","M1H":"1618"},{"ID":"S*G*USAOC-*****","M1U":"1619","M1F":"1620","M1N":"1621","M1H":"1622"},{"ID":"S*G*USAF--*****","M1U":"1623","M1F":"1623","M1N":"1623","M1H":"1623"},{"ID":"S*G*USAFT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1623","M2C":"#000000"},{"ID":"S*G*USAFC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1623","M2C":"#000000"},{"ID":"S*G*USAS--*****","M1U":"1624","M1F":"1624","M1N":"1624","M1H":"1624"},{"ID":"S*G*USAST-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1624","M2C":"#000000"},{"ID":"S*G*USASC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1624","M2C":"#000000"},{"ID":"S*G*USAM--*****","M1U":"1625","M1F":"1625","M1N":"1625","M1H":"1625"},{"ID":"S*G*USAMT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1625","M2C":"#000000"},{"ID":"S*G*USAMC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1625","M2C":"#000000"},{"ID":"S*G*USAR--*****","M1U":"1626","M1F":"1626","M1N":"1626","M1H":"1626"},{"ID":"S*G*USART-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1626","M2C":"#000000"},{"ID":"S*G*USARC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1626","M2C":"#000000"},{"ID":"S*G*USAP--*****","M1U":"1627","M1F":"1627","M1N":"1627","M1H":"1627"},{"ID":"S*G*USAPT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1627","M2C":"#000000"},{"ID":"S*G*USAPC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1627","M2C":"#000000"},{"ID":"S*G*USAPB-*****","M1U":"1628","M1F":"1628","M1N":"1628","M1H":"1628"},{"ID":"S*G*USAPBT*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1628","M2C":"#000000"},{"ID":"S*G*USAPBC*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1628","M2C":"#000000"},{"ID":"S*G*USAPM-*****","M1U":"1630","M1F":"1630","M1N":"1630","M1H":"1630"},{"ID":"S*G*USAPMT*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1630","M2C":"#000000"},{"ID":"S*G*USAPMC*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1630","M2C":"#000000"},{"ID":"S*G*USAX--*****","M1U":"1631","M1F":"1631","M1N":"1631","M1H":"1631"},{"ID":"S*G*USAXT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1631","M2C":"#000000"},{"ID":"S*G*USAXC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1631","M2C":"#000000"},{"ID":"S*G*USAL--*****","M1U":"1633","M1F":"1633","M1N":"1633","M1H":"1633"},{"ID":"S*G*USALT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1633","M2C":"#000000"},{"ID":"S*G*USALC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1633","M2C":"#000000"},{"ID":"S*G*USAW--*****","M1U":"1634","M1F":"1634","M1N":"1634","M1H":"1634"},{"ID":"S*G*USAWT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1634","M2C":"#000000"},{"ID":"S*G*USAWC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1634","M2C":"#000000"},{"ID":"S*G*USAQ--*****","M1U":"1636","M1F":"1636","M1N":"1636","M1H":"1636"},{"ID":"S*G*USAQT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1636","M2C":"#000000"},{"ID":"S*G*USAQC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1636","M2C":"#000000"},{"ID":"S*G*USM---*****","M1U":"1637","M1F":"1638","M1N":"1639","M1H":"1640"},{"ID":"S*G*USMT--*****","M1U":"1641","M1F":"1642","M1N":"1643","M1H":"1644"},{"ID":"S*G*USMC--*****","M1U":"1645","M1F":"1646","M1N":"1647","M1H":"1648"},{"ID":"S*G*USMM--*****","M1U":"1637","M1F":"1638","M1N":"1639","M1H":"1640","M2":"1649","M2C":"#000000"},{"ID":"S*G*USMMT-*****","M1U":"1641","M1F":"1642","M1N":"1643","M1H":"1644","M2":"1649","M2C":"#000000"},{"ID":"S*G*USMMC-*****","M1U":"1645","M1F":"1646","M1N":"1647","M1H":"1648","M2":"1649","M2C":"#000000"},{"ID":"S*G*USMV--*****","M1U":"1637","M1F":"1638","M1N":"1639","M1H":"1640","M2":"1650","M2C":"#000000"},{"ID":"S*G*USMVT-*****","M1U":"1641","M1F":"1642","M1N":"1643","M1H":"1644","M2":"1650","M2C":"#000000"},{"ID":"S*G*USMVC-*****","M1U":"1645","M1F":"1646","M1N":"1647","M1H":"1648","M2":"1650","M2C":"#000000"},{"ID":"S*G*USMD--*****","M1U":"1637","M1F":"1638","M1N":"1639","M1H":"1640","M2":"1651","M2C":"#000000"},{"ID":"S*G*USMDT-*****","M1U":"1641","M1F":"1642","M1N":"1643","M1H":"1644","M2":"1651","M2C":"#000000"},{"ID":"S*G*USMDC-*****","M1U":"1645","M1F":"1646","M1N":"1647","M1H":"1648","M2":"1651","M2C":"#000000"},{"ID":"S*G*USMP--*****","M1U":"1637","M1F":"1638","M1N":"1639","M1H":"1640","M2":"1652","M2C":"#000000"},{"ID":"S*G*USMPT-*****","M1U":"1641","M1F":"1642","M1N":"1643","M1H":"1644","M2":"1652","M2C":"#000000"},{"ID":"S*G*USMPC-*****","M1U":"1645","M1F":"1646","M1N":"1647","M1H":"1648","M2":"1652","M2C":"#000000"},{"ID":"S*G*USS---*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656"},{"ID":"S*G*USST--*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660"},{"ID":"S*G*USSC--*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664"},{"ID":"S*G*USS1--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1665","M2C":"#000000"},{"ID":"S*G*USS1T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1665","M2C":"#000000"},{"ID":"S*G*USS1C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1665","M2C":"#000000"},{"ID":"S*G*USS2--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1666","M2C":"#000000"},{"ID":"S*G*USS2T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1666","M2C":"#000000"},{"ID":"S*G*USS2C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1666","M2C":"#000000"},{"ID":"S*G*USS3--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1667","M2C":"#000000"},{"ID":"S*G*USS3T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1667","M2C":"#000000"},{"ID":"S*G*USS3C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1667","M2C":"#000000"},{"ID":"S*G*USS3A-*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1668","M2C":"#000000"},{"ID":"S*G*USS3AT*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1668","M2C":"#000000"},{"ID":"S*G*USS3AC*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1668","M2C":"#000000"},{"ID":"S*G*USS4--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1669","M2C":"#000000"},{"ID":"S*G*USS4T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1669","M2C":"#000000"},{"ID":"S*G*USS4C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1669","M2C":"#000000"},{"ID":"S*G*USS5--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1670","M2C":"#000000"},{"ID":"S*G*USS5T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1670","M2C":"#000000"},{"ID":"S*G*USS5C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1670","M2C":"#000000"},{"ID":"S*G*USS6--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1671","M2C":"#000000"},{"ID":"S*G*USS6T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1671","M2C":"#000000"},{"ID":"S*G*USS6C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1671","M2C":"#000000"},{"ID":"S*G*USS7--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1672","M2C":"#000000"},{"ID":"S*G*USS7T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1672","M2C":"#000000"},{"ID":"S*G*USS7C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1672","M2C":"#000000"},{"ID":"S*G*USS8--*****","M1U":"1673","M1F":"1674","M1N":"1675","M1H":"1676"},{"ID":"S*G*USS8T-*****","M1U":"1677","M1F":"1678","M1N":"1679","M1H":"1680"},{"ID":"S*G*USS8C-*****","M1U":"1681","M1F":"1682","M1N":"1683","M1H":"1684"},{"ID":"S*G*USS9--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1685","M2C":"#000000"},{"ID":"S*G*USS9T-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1685","M2C":"#000000"},{"ID":"S*G*USS9C-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1685","M2C":"#000000"},{"ID":"S*G*USSX--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1686","M2C":"#000000"},{"ID":"S*G*USSXT-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1686","M2C":"#000000"},{"ID":"S*G*USSXC-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1686","M2C":"#000000"},{"ID":"S*G*USSL--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1687","M2C":"#000000"},{"ID":"S*G*USSLT-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1687","M2C":"#000000"},{"ID":"S*G*USSLC-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1687","M2C":"#000000"},{"ID":"S*G*USSW--*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1688","M2C":"#000000"},{"ID":"S*G*USSWT-*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1688","M2C":"#000000"},{"ID":"S*G*USSWC-*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1688","M2C":"#000000"},{"ID":"S*G*USSWP-*****","M1U":"1653","M1F":"1654","M1N":"1655","M1H":"1656","M2":"1689","M2C":"#000000"},{"ID":"S*G*USSWPT*****","M1U":"1657","M1F":"1658","M1N":"1659","M1H":"1660","M2":"1689","M2C":"#000000"},{"ID":"S*G*USSWPC*****","M1U":"1661","M1F":"1662","M1N":"1663","M1H":"1664","M2":"1689","M2C":"#000000"},{"ID":"S*G*UST---*****","M1U":"1690","M1F":"1690","M1N":"1690","M1H":"1690"},{"ID":"S*G*USTT--*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1690","M2C":"#000000"},{"ID":"S*G*USTC--*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1690","M2C":"#000000"},{"ID":"S*G*USTM--*****","M1U":"1691","M1F":"1691","M1N":"1691","M1H":"1691"},{"ID":"S*G*USTMT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1691","M2C":"#000000"},{"ID":"S*G*USTMC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1691","M2C":"#000000"},{"ID":"S*G*USTR--*****","M1U":"1692","M1F":"1692","M1N":"1692","M1H":"1692"},{"ID":"S*G*USTRT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1692","M2C":"#000000"},{"ID":"S*G*USTRC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1692","M2C":"#000000"},{"ID":"S*G*USTS--*****","M1U":"1693","M1F":"1693","M1N":"1693","M1H":"1693"},{"ID":"S*G*USTST-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1693","M2C":"#000000"},{"ID":"S*G*USTSC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1693","M2C":"#000000"},{"ID":"S*G*USTA--*****","M1U":"1694","M1F":"1694","M1N":"1694","M1H":"1694"},{"ID":"S*G*USTAT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1694","M2C":"#000000"},{"ID":"S*G*USTAC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1694","M2C":"#000000"},{"ID":"S*G*USTI--*****","M1U":"1695","M1F":"1695","M1N":"1695","M1H":"1695"},{"ID":"S*G*USTIT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1695","M2C":"#000000"},{"ID":"S*G*USTIC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1695","M2C":"#000000"},{"ID":"S*G*USX---*****","M1U":"1696","M1F":"1696","M1N":"1696","M1H":"1696"},{"ID":"S*G*USXT--*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1696","M2C":"#000000"},{"ID":"S*G*USXC--*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1696","M2C":"#000000"},{"ID":"S*G*USXH--*****","M1U":"1697","M1F":"1697","M1N":"1697","M1H":"1697"},{"ID":"S*G*USXHT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1697","M2C":"#000000"},{"ID":"S*G*USXHC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1697","M2C":"#000000"},{"ID":"S*G*USXR--*****","M1U":"1698","M1F":"1698","M1N":"1698","M1H":"1698"},{"ID":"S*G*USXRT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1698","M2C":"#000000"},{"ID":"S*G*USXRC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1698","M2C":"#000000"},{"ID":"S*G*USXO--*****","M1U":"1699","M1F":"1699","M1N":"1699","M1H":"1699"},{"ID":"S*G*USXOT-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1699","M2C":"#000000"},{"ID":"S*G*USXOC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1699","M2C":"#000000"},{"ID":"S*G*USXOM-*****","M1U":"1700","M1F":"1700","M1N":"1700","M1H":"1700"},{"ID":"S*G*USXOMT*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1700","M2C":"#000000"},{"ID":"S*G*USXOMC*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1700","M2C":"#000000"},{"ID":"S*G*USXE--*****","M1U":"1701","M1F":"1701","M1N":"1701","M1H":"1701"},{"ID":"S*G*USXET-*****","M1U":"640","M1F":"641","M1N":"642","M1H":"643","M2":"1701","M2C":"#000000"},{"ID":"S*G*USXEC-*****","M1U":"648","M1F":"649","M1N":"650","M1H":"651","M2":"1701","M2C":"#000000"},{"ID":"S*G*UH----*****",},{"ID":"S*G*E-----*****",},{"ID":"S*G*EW----*****",},{"ID":"S*G*EWM---*****","M1U":"1702","M1F":"1702","M1N":"1702","M1H":"1702"},{"ID":"S*G*EWMA--*****","M1U":"1703","M1F":"1703","M1N":"1703","M1H":"1703"},{"ID":"S*G*EWMAS-*****","M1U":"1704","M1F":"1704","M1N":"1704","M1H":"1704"},{"ID":"S*G*EWMASR*****","M1U":"1705","M1F":"1705","M1N":"1705","M1H":"1705"},{"ID":"S*G*EWMASE*****","M1U":"1706","M1F":"1706","M1N":"1706","M1H":"1706"},{"ID":"S*G*EWMAI-*****","M1U":"1707","M1F":"1707","M1N":"1707","M1H":"1707"},{"ID":"S*G*EWMAIR*****","M1U":"1708","M1F":"1708","M1N":"1708","M1H":"1708"},{"ID":"S*G*EWMAIE*****","M1U":"1709","M1F":"1709","M1N":"1709","M1H":"1709"},{"ID":"S*G*EWMAL-*****","M1U":"1710","M1F":"1710","M1N":"1710","M1H":"1710"},{"ID":"S*G*EWMALR*****","M1U":"1711","M1F":"1711","M1N":"1711","M1H":"1711"},{"ID":"S*G*EWMALE*****","M1U":"1712","M1F":"1712","M1N":"1712","M1H":"1712"},{"ID":"S*G*EWMAT-*****","M1U":"1713","M1F":"1713","M1N":"1713","M1H":"1713"},{"ID":"S*G*EWMATR*****","M1U":"1714","M1F":"1714","M1N":"1714","M1H":"1714"},{"ID":"S*G*EWMATE*****","M1U":"1715","M1F":"1715","M1N":"1715","M1H":"1715"},{"ID":"S*G*EWMS--*****","M1U":"1716","M1F":"1716","M1N":"1716","M1H":"1716"},{"ID":"S*G*EWMSS-*****","M1U":"1717","M1F":"1717","M1N":"1717","M1H":"1717"},{"ID":"S*G*EWMSI-*****","M1U":"1718","M1F":"1718","M1N":"1718","M1H":"1718"},{"ID":"S*G*EWMSL-*****","M1U":"1719","M1F":"1719","M1N":"1719","M1H":"1719"},{"ID":"S*G*EWMT--*****","M1U":"1720","M1F":"1720","M1N":"1720","M1H":"1720"},{"ID":"S*G*EWMTL-*****","M1U":"1721","M1F":"1721","M1N":"1721","M1H":"1721"},{"ID":"S*G*EWMTM-*****","M1U":"1722","M1F":"1722","M1N":"1722","M1H":"1722"},{"ID":"S*G*EWMTH-*****","M1U":"1723","M1F":"1723","M1N":"1723","M1H":"1723"},{"ID":"S*G*EWS---*****","M1U":"1724","M1F":"1724","M1N":"1724","M1H":"1724"},{"ID":"S*G*EWSL--*****","M1U":"1725","M1F":"1725","M1N":"1725","M1H":"1725"},{"ID":"S*G*EWSM--*****","M1U":"1726","M1F":"1726","M1N":"1726","M1H":"1726"},{"ID":"S*G*EWSH--*****","M1U":"1727","M1F":"1727","M1N":"1727","M1H":"1727"},{"ID":"S*G*EWX---*****","M1U":"1728","M1F":"1728","M1N":"1728","M1H":"1728"},{"ID":"S*G*EWXL--*****","M1U":"1729","M1F":"1729","M1N":"1729","M1H":"1729"},{"ID":"S*G*EWXM--*****","M1U":"1730","M1F":"1730","M1N":"1730","M1H":"1730"},{"ID":"S*G*EWXH--*****","M1U":"1731","M1F":"1731","M1N":"1731","M1H":"1731"},{"ID":"S*G*EWT---*****","M1U":"1732","M1F":"1732","M1N":"1732","M1H":"1732"},{"ID":"S*G*EWTL--*****","M1U":"1733","M1F":"1733","M1N":"1733","M1H":"1733"},{"ID":"S*G*EWTM--*****","M1U":"1734","M1F":"1734","M1N":"1734","M1H":"1734"},{"ID":"S*G*EWTH--*****","M1U":"1735","M1F":"1735","M1N":"1735","M1H":"1735"},{"ID":"S*G*EWR---*****","M1U":"1736","M1F":"1736","M1N":"1736","M1H":"1736"},{"ID":"S*G*EWRR--*****","M1U":"1737","M1F":"1737","M1N":"1737","M1H":"1737"},{"ID":"S*G*EWRL--*****","M1U":"1738","M1F":"1738","M1N":"1738","M1H":"1738"},{"ID":"S*G*EWRH--*****","M1U":"1739","M1F":"1739","M1N":"1739","M1H":"1739"},{"ID":"S*G*EWZ---*****","M1U":"1740","M1F":"1740","M1N":"1740","M1H":"1740"},{"ID":"S*G*EWZL--*****","M1U":"1741","M1F":"1741","M1N":"1741","M1H":"1741"},{"ID":"S*G*EWZM--*****","M1U":"1742","M1F":"1742","M1N":"1742","M1H":"1742"},{"ID":"S*G*EWZH--*****","M1U":"1743","M1F":"1743","M1N":"1743","M1H":"1743"},{"ID":"S*G*EWO---*****","M1U":"1744","M1F":"1744","M1N":"1744","M1H":"1744"},{"ID":"S*G*EWOL--*****","M1U":"1745","M1F":"1745","M1N":"1745","M1H":"1745"},{"ID":"S*G*EWOM--*****","M1U":"1746","M1F":"1746","M1N":"1746","M1H":"1746"},{"ID":"S*G*EWOH--*****","M1U":"1747","M1F":"1747","M1N":"1747","M1H":"1747"},{"ID":"S*G*EWH---*****","M1U":"1748","M1F":"1748","M1N":"1748","M1H":"1748"},{"ID":"S*G*EWHL--*****","M1U":"1749","M1F":"1749","M1N":"1749","M1H":"1749"},{"ID":"S*G*EWHLS-*****","M1U":"1750","M1F":"1750","M1N":"1750","M1H":"1750"},{"ID":"S*G*EWHM--*****","M1U":"1751","M1F":"1751","M1N":"1751","M1H":"1751"},{"ID":"S*G*EWHMS-*****","M1U":"1752","M1F":"1752","M1N":"1752","M1H":"1752"},{"ID":"S*G*EWHH--*****","M1U":"1753","M1F":"1753","M1N":"1753","M1H":"1753"},{"ID":"S*G*EWHHS-*****","M1U":"1754","M1F":"1754","M1N":"1754","M1H":"1754"},{"ID":"S*G*EWG---*****","M1U":"1755","M1F":"1755","M1N":"1755","M1H":"1755"},{"ID":"S*G*EWGL--*****","M1U":"1756","M1F":"1756","M1N":"1756","M1H":"1756"},{"ID":"S*G*EWGM--*****","M1U":"1757","M1F":"1757","M1N":"1757","M1H":"1757"},{"ID":"S*G*EWGH--*****","M1U":"1758","M1F":"1758","M1N":"1758","M1H":"1758"},{"ID":"S*G*EWGR--*****","M1U":"1759","M1F":"1759","M1N":"1759","M1H":"1759"},{"ID":"S*G*EWD---*****","M1U":"1760","M1F":"1760","M1N":"1760","M1H":"1760"},{"ID":"S*G*EWDL--*****","M1U":"1761","M1F":"1761","M1N":"1761","M1H":"1761"},{"ID":"S*G*EWDLS-*****","M1U":"1762","M1F":"1762","M1N":"1762","M1H":"1762"},{"ID":"S*G*EWDM--*****","M1U":"1763","M1F":"1763","M1N":"1763","M1H":"1763"},{"ID":"S*G*EWDMS-*****","M1U":"1764","M1F":"1764","M1N":"1764","M1H":"1764"},{"ID":"S*G*EWDH--*****","M1U":"1765","M1F":"1765","M1N":"1765","M1H":"1765"},{"ID":"S*G*EWDHS-*****","M1U":"1766","M1F":"1766","M1N":"1766","M1H":"1766"},{"ID":"S*G*EWA---*****","M1U":"1767","M1F":"1767","M1N":"1767","M1H":"1767"},{"ID":"S*G*EWAL--*****","M1U":"1768","M1F":"1768","M1N":"1768","M1H":"1768"},{"ID":"S*G*EWAM--*****","M1U":"1769","M1F":"1769","M1N":"1769","M1H":"1769"},{"ID":"S*G*EWAH--*****","M1U":"1770","M1F":"1770","M1N":"1770","M1H":"1770"},{"ID":"S*G*EV----*****","M1U":"1771","M1F":"1771","M1N":"1771","M1H":"1771"},{"ID":"S*G*EVA---*****","M1U":"1772","M1F":"1772","M1N":"1772","M1H":"1772"},{"ID":"S*G*EVAT--*****","M1U":"1773","M1F":"1773","M1N":"1773","M1H":"1773"},{"ID":"S*G*EVATL-*****","M1U":"1774","M1F":"1774","M1N":"1774","M1H":"1774"},{"ID":"S*G*EVATLR*****","M1U":"1775","M1F":"1775","M1N":"1775","M1H":"1775"},{"ID":"S*G*EVATM-*****","M1U":"1776","M1F":"1776","M1N":"1776","M1H":"1776"},{"ID":"S*G*EVATMR*****","M1U":"1777","M1F":"1777","M1N":"1777","M1H":"1777"},{"ID":"S*G*EVATH-*****","M1U":"1778","M1F":"1778","M1N":"1778","M1H":"1778"},{"ID":"S*G*EVATHR*****","M1U":"1779","M1F":"1779","M1N":"1779","M1H":"1779"},{"ID":"S*G*EVAA--*****","M1U":"1780","M1F":"1780","M1N":"1780","M1H":"1780"},{"ID":"S*G*EVAAR-*****","M1U":"1781","M1F":"1781","M1N":"1781","M1H":"1781"},{"ID":"S*G*EVAI--*****","M1U":"1782","M1F":"1782","M1N":"1782","M1H":"1782"},{"ID":"S*G*EVAC--*****","M1U":"1783","M1F":"1783","M1N":"1783","M1H":"1783"},{"ID":"S*G*EVAS--*****","M1U":"1784","M1F":"1784","M1N":"1784","M1H":"1784"},{"ID":"S*G*EVAL--*****","M1U":"1785","M1F":"1785","M1N":"1785","M1H":"1785"},{"ID":"S*G*EVU---*****","M1U":"1786","M1F":"1786","M1N":"1786","M1H":"1786"},{"ID":"S*G*EVUB--*****","M1U":"1787","M1F":"1787","M1N":"1787","M1H":"1787"},{"ID":"S*G*EVUS--*****","M1U":"1788","M1F":"1788","M1N":"1788","M1H":"1788"},{"ID":"S*G*EVUSL-*****","M1U":"1789","M1F":"1789","M1N":"1789","M1H":"1789"},{"ID":"S*G*EVUSM-*****","M1U":"1790","M1F":"1790","M1N":"1790","M1H":"1790"},{"ID":"S*G*EVUSH-*****","M1U":"1791","M1F":"1791","M1N":"1791","M1H":"1791"},{"ID":"S*G*EVUL--*****","M1U":"1792","M1F":"1792","M1N":"1792","M1H":"1792"},{"ID":"S*G*EVUX--*****","M1U":"1793","M1F":"1793","M1N":"1793","M1H":"1793"},{"ID":"S*G*EVUR--*****","M1U":"1794","M1F":"1794","M1N":"1794","M1H":"1794"},{"ID":"S*G*EVUT--*****","M1U":"1795","M1F":"1795","M1N":"1795","M1H":"1795"},{"ID":"S*G*EVUTL-*****","M1U":"1796","M1F":"1796","M1N":"1796","M1H":"1796"},{"ID":"S*G*EVUTH-*****","M1U":"1797","M1F":"1797","M1N":"1797","M1H":"1797"},{"ID":"S*G*EVUA--*****","M1U":"1798","M1F":"1798","M1N":"1798","M1H":"1798"},{"ID":"S*G*EVUAA-*****","M1U":"1799","M1F":"1799","M1N":"1799","M1H":"1799"},{"ID":"S*G*EVE---*****","M1U":"1800","M1F":"1800","M1N":"1800","M1H":"1800"},{"ID":"S*G*EVEB--*****","M1U":"1894","M1F":"1894","M1N":"1894","M1H":"1894"},{"ID":"S*G*EVEE--*****","M1U":"1801","M1F":"1801","M1N":"1801","M1H":"1801"},{"ID":"S*G*EVEC--*****","M1U":"1802","M1F":"1802","M1N":"1802","M1H":"1802"},{"ID":"S*G*EVEM--*****","M1U":"1803","M1F":"1803","M1N":"1803","M1H":"1803"},{"ID":"S*G*EVEMV-*****","M1U":"1804","M1F":"1804","M1N":"1804","M1H":"1804"},{"ID":"S*G*EVEML-*****","M1U":"1805","M1F":"1805","M1N":"1805","M1H":"1805"},{"ID":"S*G*EVEA--*****","M1U":"1806","M1F":"1806","M1N":"1806","M1H":"1806"},{"ID":"S*G*EVEAA-*****","M1U":"1807","M1F":"1807","M1N":"1807","M1H":"1807"},{"ID":"S*G*EVEAT-*****","M1U":"1808","M1F":"1808","M1N":"1808","M1H":"1808"},{"ID":"S*G*EVED--*****","M1U":"1809","M1F":"1809","M1N":"1809","M1H":"1809"},{"ID":"S*G*EVEDA-*****","M1U":"1810","M1F":"1810","M1N":"1810","M1H":"1810"},{"ID":"S*G*EVES--*****","M1U":"1811","M1F":"1811","M1N":"1811","M1H":"1811"},{"ID":"S*G*EVER--*****","M1U":"1812","M1F":"1812","M1N":"1812","M1H":"1812"},{"ID":"S*G*EVEH--*****","M1U":"1813","M1F":"1813","M1N":"1813","M1H":"1813"},{"ID":"S*G*EVEF--*****","M1U":"1814","M1F":"1814","M1N":"1814","M1H":"1814"},{"ID":"S*G*EVT---*****","M1U":"1815","M1F":"1815","M1N":"1815","M1H":"1815"},{"ID":"S*G*EVC---*****","M1U":"1816","M1F":"1816","M1N":"1816","M1H":"1816"},{"ID":"S*G*EVCA--*****","M1U":"1817","M1F":"1817","M1N":"1817","M1H":"1817","M2":"1818","M2C":"#FFFFFF"},{"ID":"S*G*EVCAL-*****","M1U":"1819","M1F":"1819","M1N":"1819","M1H":"1819","M2":"1820","M2C":"#FFFFFF"},{"ID":"S*G*EVCAM-*****","M1U":"1821","M1F":"1821","M1N":"1821","M1H":"1821","M2":"1822","M2C":"#FFFFFF"},{"ID":"S*G*EVCAH-*****","M1U":"1823","M1F":"1823","M1N":"1823","M1H":"1823","M2":"1824","M2C":"#FFFFFF"},{"ID":"S*G*EVCO--*****","M1U":"1825","M1F":"1825","M1N":"1825","M1H":"1825","M2":"1826","M2C":"#FFFFFF"},{"ID":"S*G*EVCOL-*****","M1U":"1827","M1F":"1827","M1N":"1827","M1H":"1827","M2":"1828","M2C":"#FFFFFF"},{"ID":"S*G*EVCOM-*****","M1U":"1829","M1F":"1829","M1N":"1829","M1H":"1829","M2":"1830","M2C":"#FFFFFF"},{"ID":"S*G*EVCOH-*****","M1U":"1831","M1F":"1831","M1N":"1831","M1H":"1831","M2":"1832","M2C":"#FFFFFF"},{"ID":"S*G*EVCM--*****","M1U":"1833","M1F":"1833","M1N":"1833","M1H":"1833","M2":"1834","M2C":"#FFFFFF"},{"ID":"S*G*EVCML-*****","M1U":"1835","M1F":"1835","M1N":"1835","M1H":"1835","M2":"1836","M2C":"#FFFFFF"},{"ID":"S*G*EVCMM-*****","M1U":"1837","M1F":"1837","M1N":"1837","M1H":"1837","M2":"1838","M2C":"#FFFFFF"},{"ID":"S*G*EVCMH-*****","M1U":"1839","M1F":"1839","M1N":"1839","M1H":"1839","M2":"1840","M2C":"#FFFFFF"},{"ID":"S*G*EVCU--*****","M1U":"1841","M1F":"1841","M1N":"1841","M1H":"1841","M2":"1842","M2C":"#FFFFFF"},{"ID":"S*G*EVCUL-*****","M1U":"1843","M1F":"1843","M1N":"1843","M1H":"1843","M2":"1844","M2C":"#FFFFFF"},{"ID":"S*G*EVCUM-*****","M1U":"1845","M1F":"1845","M1N":"1845","M1H":"1845","M2":"1846","M2C":"#FFFFFF"},{"ID":"S*G*EVCUH-*****","M1U":"1847","M1F":"1847","M1N":"1847","M1H":"1847","M2":"1848","M2C":"#FFFFFF"},{"ID":"S*G*EVCJ--*****","M1U":"1849","M1F":"1849","M1N":"1849","M1H":"1849","M2":"1850","M2C":"#FFFFFF"},{"ID":"S*G*EVCJL-*****","M1U":"1851","M1F":"1851","M1N":"1851","M1H":"1851","M2":"1852","M2C":"#FFFFFF"},{"ID":"S*G*EVCJM-*****","M1U":"1853","M1F":"1853","M1N":"1853","M1H":"1853","M2":"1854","M2C":"#FFFFFF"},{"ID":"S*G*EVCJH-*****","M1U":"1855","M1F":"1855","M1N":"1855","M1H":"1855","M2":"1856","M2C":"#FFFFFF"},{"ID":"S*G*EVCT--*****","M1U":"1857","M1F":"1857","M1N":"1857","M1H":"1857","M2":"1858","M2C":"#FFFFFF"},{"ID":"S*G*EVCTL-*****","M1U":"1859","M1F":"1859","M1N":"1859","M1H":"1859","M2":"1860","M2C":"#FFFFFF"},{"ID":"S*G*EVCTM-*****","M1U":"1861","M1F":"1861","M1N":"1861","M1H":"1861","M2":"1862","M2C":"#FFFFFF"},{"ID":"S*G*EVCTH-*****","M1U":"1863","M1F":"1863","M1N":"1863","M1H":"1863","M2":"1864","M2C":"#FFFFFF"},{"ID":"S*G*EVCF--*****","M1U":"1865","M1F":"1865","M1N":"1865","M1H":"1865","M2":"1866","M2C":"#FFFFFF"},{"ID":"S*G*EVCFL-*****","M1U":"1867","M1F":"1867","M1N":"1867","M1H":"1867","M2":"1868","M2C":"#FFFFFF"},{"ID":"S*G*EVCFM-*****","M1U":"1869","M1F":"1869","M1N":"1869","M1H":"1869","M2":"1870","M2C":"#FFFFFF"},{"ID":"S*G*EVCFH-*****","M1U":"1871","M1F":"1871","M1N":"1871","M1H":"1871","M2":"1872","M2C":"#FFFFFF"},{"ID":"S*G*EVS---*****","M1U":"1874","M1F":"1874","M1N":"1874","M1H":"1874"},{"ID":"S*G*EVST--*****","M1U":"1875","M1F":"1875","M1N":"1875","M1H":"1875"},{"ID":"S*G*EVSR--*****","M1U":"1876","M1F":"1876","M1N":"1876","M1H":"1876"},{"ID":"S*G*EVSC--*****","M1U":"1877","M1F":"1877","M1N":"1877","M1H":"1877"},{"ID":"S*G*EVSP--*****","M1U":"1878","M1F":"1878","M1N":"1878","M1H":"1878"},{"ID":"S*G*EVSW--*****","M1U":"1879","M1F":"1879","M1N":"1879","M1H":"1879"},{"ID":"S*G*EVM---*****","M1U":"1873","M1F":"1873","M1N":"1873","M1H":"1873"},{"ID":"S*G*ES----*****","M1U":"1880","M1F":"1880","M1N":"1880","M1H":"1880"},{"ID":"S*G*ESR---*****","M1U":"1881","M1F":"1881","M1N":"1881","M1H":"1881"},{"ID":"S*G*ESE---*****","M1U":"1882","M1F":"1882","M1N":"1882","M1H":"1882"},{"ID":"S*G*EX----*****",},{"ID":"S*G*EXL---*****","M1U":"1884","M1F":"1884","M1N":"1884","M1H":"1884"},{"ID":"S*G*EXN---*****","M1U":"1885","M1F":"1885","M1N":"1885","M1H":"1885"},{"ID":"S*G*EXF---*****","M1U":"1886","M1F":"1886","M1N":"1886","M1H":"1886"},{"ID":"S*G*EXM---*****","M1U":"1887","M1F":"1887","M1N":"1887","M1H":"1887"},{"ID":"S*G*EXMC--*****","M1U":"1888","M1F":"1888","M1N":"1888","M1H":"1888"},{"ID":"S*G*EXML--*****","M1U":"1889","M1F":"1889","M1N":"1889","M1H":"1889"},{"ID":"S*G*EXI---*****","M1U":"1883","M1F":"1883","M1N":"1883","M1H":"1883"},{"ID":"S*G*EXI---*****","M1U":"1883","M1F":"1883","M1N":"1883","M1H":"1883"},{"ID":"S*G*I-----*****",},{"ID":"S*G*IR----*****","M1U":"1897","M1F":"1897","M1N":"1897","M1H":"1897"},{"ID":"S*G*IRM---*****","M1U":"1898","M1F":"1898","M1N":"1898","M1H":"1898"},{"ID":"S*G*IRP---*****","M1U":"1899","M1F":"1899","M1N":"1899","M1H":"1899"},{"ID":"S*G*IRN---*****","M1U":"1900","M1F":"1900","M1N":"1900","M1H":"1900"},{"ID":"S*G*IRNB--*****","M1U":"1901","M1F":"1901","M1N":"1901","M1H":"1901"},{"ID":"S*G*IRNC--*****","M1U":"1902","M1F":"1902","M1N":"1902","M1H":"1902"},{"ID":"S*G*IRNN--*****","M1U":"1903","M1F":"1903","M1N":"1903","M1H":"1903"},{"ID":"S*G*IP----*****","M1U":"1904","M1F":"1904","M1N":"1904","M1H":"1904"},{"ID":"S*G*IPD---*****","M1U":"1905","M1F":"1905","M1N":"1905","M1H":"1905"},{"ID":"S*G*IE----*****","M1U":"1906","M1F":"1906","M1N":"1906","M1H":"1906"},{"ID":"S*G*IU----*****","M1U":"1907","M1F":"1907","M1N":"1907","M1H":"1907"},{"ID":"S*G*IUR---*****","M1U":"1908","M1F":"1908","M1N":"1908","M1H":"1908"},{"ID":"S*G*IUT---*****","M1U":"1909","M1F":"1909","M1N":"1909","M1H":"1909"},{"ID":"S*G*IUE---*****","M1U":"1910","M1F":"1910","M1N":"1910","M1H":"1910"},{"ID":"S*G*IUEN--*****","M1U":"1911","M1F":"1911","M1N":"1911","M1H":"1911"},{"ID":"S*G*IUED--*****","M1U":"1912","M1F":"1912","M1N":"1912","M1H":"1912"},{"ID":"S*G*IUEF--*****","M1U":"1913","M1F":"1913","M1N":"1913","M1H":"1913"},{"ID":"S*G*IUP---*****","M1U":"1914","M1F":"1914","M1N":"1914","M1H":"1914"},{"ID":"S*G*IM----*****",},{"ID":"S*G*IMF---*****","M1U":"1915","M1F":"1915","M1N":"1915","M1H":"1915"},{"ID":"S*G*IMFA--*****","M1U":"1916","M1F":"1916","M1N":"1916","M1H":"1916"},{"ID":"S*G*IMFP--*****","M1U":"1917","M1F":"1917","M1N":"1917","M1H":"1917"},{"ID":"S*G*IMFPW-*****","M1U":"1918","M1F":"1918","M1N":"1918","M1H":"1918"},{"ID":"S*G*IMFS--*****","M1U":"1919","M1F":"1919","M1N":"1919","M1H":"1919"},{"ID":"S*G*IMA---*****","M1U":"1920","M1F":"1920","M1N":"1920","M1H":"1920"},{"ID":"S*G*IME---*****","M1U":"1921","M1F":"1921","M1N":"1921","M1H":"1921"},{"ID":"S*G*IMG---*****","M1U":"1922","M1F":"1922","M1N":"1922","M1H":"1922"},{"ID":"S*G*IMV---*****","M1U":"1923","M1F":"1923","M1N":"1923","M1H":"1923"},{"ID":"S*G*IMN---*****","M1U":"1924","M1F":"1924","M1N":"1924","M1H":"1924"},{"ID":"S*G*IMNB--*****","M1U":"1925","M1F":"1925","M1N":"1925","M1H":"1925"},{"ID":"S*G*IMC---*****","M1U":"1926","M1F":"1926","M1N":"1926","M1H":"1926"},{"ID":"S*G*IMS---*****","M1U":"1927","M1F":"1927","M1N":"1927","M1H":"1927"},{"ID":"S*G*IMM---*****","M1U":"1928","M1F":"1928","M1N":"1928","M1H":"1928"},{"ID":"S*G*IG----*****","M1U":"1929","M1F":"1929","M1N":"1929","M1H":"1929"},{"ID":"S*G*IB----*****","M1U":"1930","M1F":"1930","M1N":"1930","M1H":"1930"},{"ID":"S*G*IBA---*****","M1U":"1931","M1F":"1931","M1N":"1931","M1H":"1931"},{"ID":"S*G*IBN---*****","M1U":"1932","M1F":"1932","M1N":"1932","M1H":"1932"},{"ID":"S*G*IT----*****","M1U":"1933","M1F":"1933","M1N":"1933","M1H":"1933"},{"ID":"S*G*IX----*****","M1U":"660","M1F":"661","M1N":"662","M1H":"663"},{"ID":"S*G*IXH---*****","M1U":"660","M1F":"661","M1N":"662","M1H":"663","M2":"1935","M2C":"#000000"},{"ID":"S*G*IC----*****","M1U":"1891","M1F":"1891","M1N":"1891","M1H":"1891"},{"ID":"S*G*ICD---*****","M1U":"1892","M1F":"1892","M1N":"1892","M1H":"1892"},{"ID":"S*G*ICT---*****","M1U":"1893","M1F":"1893","M1N":"1893","M1H":"1893"},{"ID":"S*G*IW----*****","M1U":"1895","M1F":"1895","M1N":"1895","M1H":"1895"},{"ID":"S*S*------*****",},{"ID":"S*S*C-----*****","M1U":"1936","M1F":"1936","M1N":"1936","M1H":"1936","M2":"1937","M2C":"#FFFFFF"},{"ID":"S*S*CL----*****","M1U":"1938","M1F":"1938","M1N":"1938","M1H":"1938"},{"ID":"S*S*CLCV--*****","M1U":"1939","M1F":"1939","M1N":"1939","M1H":"1939"},{"ID":"S*S*CLBB--*****","M1U":"1940","M1F":"1940","M1N":"1940","M1H":"1940"},{"ID":"S*S*CLCC--*****","M1U":"1941","M1F":"1941","M1N":"1941","M1H":"1941"},{"ID":"S*S*CLDD--*****","M1U":"1942","M1F":"1942","M1N":"1942","M1H":"1942"},{"ID":"S*S*CLFF--*****","M1U":"1943","M1F":"1943","M1N":"1943","M1H":"1943"},{"ID":"S*S*CLLL--*****","M1U":"1944","M1F":"1944","M1N":"1944","M1H":"1944"},{"ID":"S*S*CLLLAS*****","M1U":"1945","M1F":"1945","M1N":"1945","M1H":"1945"},{"ID":"S*S*CLLLMI*****","M1U":"1946","M1F":"1946","M1N":"1946","M1H":"1946"},{"ID":"S*S*CLLLSU*****","M1U":"1947","M1F":"1947","M1N":"1947","M1H":"1947"},{"ID":"S*S*CA----*****","M1U":"1948","M1F":"1948","M1N":"1948","M1H":"1948"},{"ID":"S*S*CALA--*****","M1U":"1949","M1F":"1949","M1N":"1949","M1H":"1949"},{"ID":"S*S*CALS--*****","M1U":"1950","M1F":"1950","M1N":"1950","M1H":"1950"},{"ID":"S*S*CALSM-*****","M1U":"1951","M1F":"1951","M1N":"1951","M1H":"1951"},{"ID":"S*S*CALST-*****","M1U":"1952","M1F":"1952","M1N":"1952","M1H":"1952"},{"ID":"S*S*CALC--*****","M1U":"1953","M1F":"1953","M1N":"1953","M1H":"1953"},{"ID":"S*S*CM----*****","M1U":"1954","M1F":"1954","M1N":"1954","M1H":"1954"},{"ID":"S*S*CMML--*****","M1U":"1955","M1F":"1955","M1N":"1955","M1H":"1955"},{"ID":"S*S*CMMS--*****","M1U":"1956","M1F":"1956","M1N":"1956","M1H":"1956"},{"ID":"S*S*CMMH--*****","M1U":"1957","M1F":"1957","M1N":"1957","M1H":"1957"},{"ID":"S*S*CMMA--*****","M1U":"1958","M1F":"1958","M1N":"1958","M1H":"1958"},{"ID":"S*S*CP----*****","M1U":"1959","M1F":"1959","M1N":"1959","M1H":"1959"},{"ID":"S*S*CPSB--*****","M1U":"1960","M1F":"1960","M1N":"1960","M1H":"1960"},{"ID":"S*S*CPSU--*****","M1U":"1961","M1F":"1961","M1N":"1961","M1H":"1961"},{"ID":"S*S*CPSUM-*****","M1U":"1962","M1F":"1962","M1N":"1962","M1H":"1962"},{"ID":"S*S*CPSUT-*****","M1U":"1963","M1F":"1963","M1N":"1963","M1H":"1963"},{"ID":"S*S*CPSUG-*****","M1U":"1964","M1F":"1964","M1N":"1964","M1H":"1964"},{"ID":"S*S*CH----*****","M1U":"1965","M1F":"1965","M1N":"1965","M1H":"1965"},{"ID":"S*S*S-----*****","M1U":"1966","M1F":"1966","M1N":"1966","M1H":"1966"},{"ID":"S*S*SP----*****","M1U":"1967","M1F":"1967","M1N":"1967","M1H":"1967"},{"ID":"S*S*SA----*****","M1U":"1968","M1F":"1968","M1N":"1968","M1H":"1968"},{"ID":"S*S*G-----*****","M1U":"1969","M1F":"1969","M1N":"1969","M1H":"1969"},{"ID":"S*S*GT----*****","M1U":"1970","M1F":"1970","M1N":"1970","M1H":"1970"},{"ID":"S*S*GG----*****","M1U":"1971","M1F":"1971","M1N":"1971","M1H":"1971"},{"ID":"S*S*GU----*****","M1U":"1972","M1F":"1972","M1N":"1972","M1H":"1972"},{"ID":"S*S*GC----*****","M1U":"1973","M1F":"1973","M1N":"1973","M1H":"1973"},{"ID":"S*S*CD----*****","M1U":"1974","M1F":"1974","M1N":"1974","M1H":"1974"},{"ID":"S*S*CU----*****","M1U":"1975","M1F":"1975","M1N":"1975","M1H":"1975"},{"ID":"S*S*CUM---*****","M1U":"1976","M1F":"1976","M1N":"1976","M1H":"1976"},{"ID":"S*S*CUS---*****","M1U":"1977","M1F":"1977","M1N":"1977","M1H":"1977"},{"ID":"S*S*CUN---*****","M1U":"1978","M1F":"1978","M1N":"1978","M1H":"1978"},{"ID":"S*S*CUR---*****","M1U":"1979","M1F":"1979","M1N":"1979","M1H":"1979"},{"ID":"S*S*N-----*****","M1U":"1980","M1F":"1980","M1N":"1980","M1H":"1980"},{"ID":"S*S*NR----*****","M1U":"1981","M1F":"1981","M1N":"1981","M1H":"1981"},{"ID":"S*S*NF----*****","M1U":"1982","M1F":"1982","M1N":"1982","M1H":"1982"},{"ID":"S*S*NI----*****","M1U":"1983","M1F":"1983","M1N":"1983","M1H":"1983"},{"ID":"S*S*NS----*****","M1U":"1984","M1F":"1984","M1N":"1984","M1H":"1984"},{"ID":"S*S*NM----*****","M1U":"1985","M1F":"1985","M1N":"1985","M1H":"1985"},{"ID":"S*S*NH----*****","M1U":"1986","M1F":"1986","M1N":"1986","M1H":"1986","M2":"1987","M2C":"#FFFFFF"},{"ID":"S*S*NN----*****","M1U":"1988","M1F":"1988","M1N":"1988","M1H":"1988"},{"ID":"S*S*NNR---*****","M1U":"1989","M1F":"1989","M1N":"1989","M1H":"1989"},{"ID":"S*S*X-----*****",},{"ID":"S*S*XM----*****","M1U":"1990","M1F":"1990","M1N":"1990","M1H":"1990","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMC---*****","M1U":"1992","M1F":"1992","M1N":"1992","M1H":"1992","MAPPING1COLOR":"#000000","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMR---*****","M1U":"1993","M1F":"1993","M1N":"1993","M1H":"1993","MAPPING1COLOR":"#000000","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMO---*****","M1U":"1994","M1F":"1994","M1N":"1994","M1H":"1994","MAPPING1COLOR":"#000000","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMTU--*****","M1U":"1995","M1F":"1995","M1N":"1995","M1H":"1995","MAPPING1COLOR":"#000000","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMF---*****","M1U":"1996","M1F":"1996","M1N":"1996","M1H":"1996","MAPPING1COLOR":"#000000","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMP---*****","M1U":"1997","M1F":"1997","M1N":"1997","M1H":"1997","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMH---*****","M1U":"1998","M1F":"1998","M1N":"1998","M1H":"1998","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XMTO--*****","M1U":"1999","M1F":"1999","M1N":"1999","M1H":"1999","M2":"1991","M2C":"#FFFFFF"},{"ID":"S*S*XF----*****","M1U":"2000","M1F":"2000","M1N":"2000","M1H":"2000","M2":"2001","M2C":"#FFFFFF"},{"ID":"S*S*XFDF--*****","M1U":"2002","M1F":"2002","M1N":"2002","M1H":"2002","M2":"2001","M2C":"#FFFFFF"},{"ID":"S*S*XFDR--*****","M1U":"2003","M1F":"2003","M1N":"2003","M1H":"2003","M2":"2001","M2C":"#FFFFFF"},{"ID":"S*S*XFTR--*****","M1U":"2004","M1F":"2004","M1N":"2004","M1H":"2004","M2":"2001","M2C":"#FFFFFF"},{"ID":"S*S*XR----*****","M1U":"2005","M1F":"2005","M1N":"2005","M1H":"2005","M2":"2006","M2C":"#FFFFFF"},{"ID":"S*S*XL----*****","M1U":"2007","M1F":"2007","M1N":"2007","M1H":"2007","M2":"2008","M2C":"#FFFFFF"},{"ID":"S*S*XH----*****","M1U":"2009","M1F":"2009","M1N":"2009","M1H":"2009","M2":"2010","M2C":"#FFFFFF"},{"ID":"S*S*XA----*****","M1U":"2011","M1F":"2011","M1N":"2011","M1H":"2011","M2":"2012","M2C":"#FFFFFF"},{"ID":"S*S*XAR---*****","M1U":"2013","M1F":"2013","M1N":"2013","M1H":"2013","M2":"2012","M2C":"#FFFFFF"},{"ID":"S*S*XAS---*****","M1U":"2014","M1F":"2014","M1N":"2014","M1H":"2014","M2":"2012","M2C":"#FFFFFF"},{"ID":"S*S*XP----*****","M1U":"2015","M1F":"2015","M1N":"2015","M1H":"2015","M2":"2112","M2C":"#FFFFFF"},{"ID":"S*S*O-----*****",},{"ID":"S*U*------*****",},{"ID":"S*U*S-----*****","M1U":"2017","M1F":"2017","M1N":"2017","M1H":"2017"},{"ID":"S*U*SN----*****","M1U":"2022","M1F":"2022","M1N":"2022","M1H":"2022"},{"ID":"S*U*SNF---*****","M1U":"2023","M1F":"2023","M1N":"2023","M1H":"2023"},{"ID":"S*U*SNA---*****","M1U":"2024","M1F":"2024","M1N":"2024","M1H":"2024","M2":"2025","M2C":"#FFFFFF"},{"ID":"S*U*SNM---*****","M1U":"2026","M1F":"2026","M1N":"2026","M1H":"2026","M2":"2027","M2C":"#FFFFFF"},{"ID":"S*U*SNG---*****","M1U":"2028","M1F":"2028","M1N":"2028","M1H":"2028","M2":"2029","M2C":"#FFFFFF"},{"ID":"S*U*SNB---*****","M1U":"2030","M1F":"2030","M1N":"2030","M1H":"2030","M2":"2031","M2C":"#FFFFFF"},{"ID":"S*U*SC----*****","M1U":"2032","M1F":"2032","M1N":"2032","M1H":"2032"},{"ID":"S*U*SCF---*****","M1U":"2033","M1F":"2033","M1N":"2033","M1H":"2033"},{"ID":"S*U*SCA---*****","M1U":"2034","M1F":"2034","M1N":"2034","M1H":"2034","M2":"2035","M2C":"#FFFFFF"},{"ID":"S*U*SCM---*****","M1U":"2036","M1F":"2036","M1N":"2036","M1H":"2036","M2":"2037","M2C":"#FFFFFF"},{"ID":"S*U*SCG---*****","M1U":"2038","M1F":"2038","M1N":"2038","M1H":"2038","M2":"2039","M2C":"#FFFFFF"},{"ID":"S*U*SCB---*****","M1U":"2040","M1F":"2040","M1N":"2040","M1H":"2040","M2":"2041","M2C":"#FFFFFF"},{"ID":"S*U*SO----*****","M1U":"2042","M1F":"2042","M1N":"2042","M1H":"2042"},{"ID":"S*U*SOF---*****","M1U":"2043","M1F":"2043","M1N":"2043","M1H":"2043"},{"ID":"S*U*SU----*****","M1U":"2046","M1F":"2046","M1N":"2046","M1H":"2046"},{"ID":"S*U*SUM---*****","M1U":"2047","M1F":"2047","M1N":"2047","M1H":"2047"},{"ID":"S*U*SUS---*****","M1U":"2048","M1F":"2048","M1N":"2048","M1H":"2048"},{"ID":"S*U*SUN---*****","M1U":"2049","M1F":"2049","M1N":"2049","M1H":"2049"},{"ID":"S*U*SF----*****","M1U":"2018","M1F":"2018","M1N":"2018","M1H":"2018"},{"ID":"S*U*SB----*****","M1U":"2019","M1F":"2019","M1N":"2019","M1H":"2019"},{"ID":"S*U*SR----*****","M1U":"2020","M1F":"2020","M1N":"2020","M1H":"2020"},{"ID":"S*U*SX----*****","M1U":"2021","M1F":"2021","M1N":"2021","M1H":"2021"},{"ID":"S*U*S1----*****","M1U":"2050","M1F":"2050","M1N":"2050","M1H":"2050"},{"ID":"S*U*S2----*****","M1U":"2051","M1F":"2051","M1N":"2051","M1H":"2051"},{"ID":"S*U*S3----*****","M1U":"2052","M1F":"2052","M1N":"2052","M1H":"2052"},{"ID":"S*U*S4----*****","M1U":"2053","M1F":"2053","M1N":"2053","M1H":"2053"},{"ID":"S*U*SL----*****","M1U":"2054","M1F":"2054","M1N":"2054","M1H":"2054"},{"ID":"S*U*SK----*****","M1U":"2055","M1F":"2055","M1N":"2055","M1H":"2055"},{"ID":"S*U*W-----*****","M1U":"2056","M1F":"2056","M1N":"2056","M1H":"2056"},{"ID":"S*U*WT----*****","M1U":"2057","M1F":"2057","M1N":"2057","M1H":"2057"},{"ID":"S*U*WM----*****","M1U":"2058","M1F":"2058","M1N":"2058","M1H":"2058","M2":"2059","M2C":"FF0000"},{"ID":"S*U*WMD---*****","M1U":"2060","M1F":"2060","M1N":"2060","M1H":"2060","M2":"2059","M2C":"00FF00"},{"ID":"S*U*WMG---*****","M1U":"2061","M1F":"2061","M1N":"2061","M1H":"2061","M2":"2062","M2C":"FF0000"},{"ID":"S*U*WMGD--*****","M1U":"2063","M1F":"2063","M1N":"2063","M1H":"2063","M2":"2064","M2C":"00FF00"},{"ID":"S*U*WMGX--*****","M1U":"2065","M1F":"2065","M1N":"2065","M1H":"2065","M2":"2062","M2C":"008000"},{"ID":"S*U*WMGE--*****","M1U":"2066","M1F":"2066","M1N":"2066","M1H":"2066","M2":"2070","M2C":"FFFF00"},{"ID":"S*U*WMGC--*****","M1U":"2067","M1F":"2067","M1N":"2067","M1H":"2067","M2":"2070","M2C":"FFA500"},{"ID":"S*U*WMGR--*****","M1U":"2068","M1F":"2068","M1N":"2068","M1H":"2068","M2":"2070","M2C":"FFFF00"},{"ID":"S*U*WMGO--*****","M1U":"2069","M1F":"2069","M1N":"2069","M1H":"2069","M2":"2070","M2C":"008000"},{"ID":"S*U*WMM---*****","M1U":"2072","M1F":"2072","M1N":"2072","M1H":"2072","M2":"2073","M2C":"FF0000"},{"ID":"S*U*WMMD--*****","M1U":"2074","M1F":"2074","M1N":"2074","M1H":"2074","M2":"2075","M2C":"00FF00"},{"ID":"S*U*WMMX--*****","M1U":"2076","M1F":"2076","M1N":"2076","M1H":"2076","M2":"2073","M2C":"008000"},{"ID":"S*U*WMME--*****","M1U":"2077","M1F":"2077","M1N":"2077","M1H":"2077","M2":"2081","M2C":"FFFF00"},{"ID":"S*U*WMMC--*****","M1U":"2078","M1F":"2078","M1N":"2078","M1H":"2078","M2":"2081","M2C":"FFA500"},{"ID":"S*U*WMMR--*****","M1U":"2079","M1F":"2079","M1N":"2079","M1H":"2079","M2":"2081","M2C":"FFFF00"},{"ID":"S*U*WMMO--*****","M1U":"2080","M1F":"2080","M1N":"2080","M1H":"2080","M2":"2081","M2C":"008000"},{"ID":"S*U*WMF---*****","M1U":"2083","M1F":"2083","M1N":"2083","M1H":"2083","M2":"2084","M2C":"FF0000"},{"ID":"S*U*WMFD--*****","M1U":"2085","M1F":"2085","M1N":"2085","M1H":"2085","M2":"2086","M2C":"00FF00"},{"ID":"S*U*WMFX--*****","M1U":"2087","M1F":"2087","M1N":"2087","M1H":"2087","M2":"2084","M2C":"008000"},{"ID":"S*U*WMFE--*****","M1U":"2088","M1F":"2088","M1N":"2088","M1H":"2088","M2":"2092","M2C":"FFFF00"},{"ID":"S*U*WMFC--*****","M1U":"2089","M1F":"2089","M1N":"2089","M1H":"2089","M2":"2092","M2C":"FFA500"},{"ID":"S*U*WMFR--*****","M1U":"2090","M1F":"2090","M1N":"2090","M1H":"2090","M2":"2092","M2C":"FFFF00"},{"ID":"S*U*WMFO--*****","M1U":"2091","M1F":"2091","M1N":"2091","M1H":"2091","M2":"2092","M2C":"008000"},{"ID":"S*U*WMO---*****","M1U":"2093","M1F":"2093","M1N":"2093","M1H":"2093","M2":"2094","M2C":"FF0000"},{"ID":"S*U*WMOD--*****","M1U":"2095","M1F":"2095","M1N":"2095","M1H":"2095","M2":"2094","M2C":"00FF00"},{"ID":"S*U*WMX---*****","M1U":"2096","M1F":"2096","M1N":"2096","M1H":"2096","M2":"2094","M2C":"008000"},{"ID":"S*U*WME---*****","M1U":"2097","M1F":"2097","M1N":"2097","M1H":"2097","M2":"2104","M2C":"FFFF00"},{"ID":"S*U*WMA---*****","M1U":"2098","M1F":"2098","M1N":"2098","M1H":"2098","M2":"2104","M2C":"008000"},{"ID":"S*U*WMC---*****","M1U":"2099","M1F":"2099","M1N":"2099","M1H":"2099","M2":"2104","M2C":"FFA500"},{"ID":"S*U*WMR---*****","M1U":"2100","M1F":"2100","M1N":"2100","M1H":"2100","M2":"2104","M2C":"FFFF00"},{"ID":"S*U*WMB---*****","M1U":"2101","M1F":"2101","M1N":"2101","M1H":"2101","M2":"2104","M2C":"FFFF00"},{"ID":"S*U*WMBD--*****","M1U":"2102","M1F":"2102","M1N":"2102","M1H":"2102","M2":"2104","M2C":"00FF00"},{"ID":"S*U*WMN---*****","M1U":"2103","M1F":"2103","M1N":"2103","M1H":"2103","M2":"2104","M2C":"008000"},{"ID":"S*U*WMS---*****","M1U":"2106","M1F":"2106","M1N":"2106","M1H":"2106","M2":"2105","M2C":"FF0000"},{"ID":"S*U*WMSX--*****","M1U":"2107","M1F":"2107","M1N":"2107","M1H":"2107","M2":"2105","M2C":"008000"},{"ID":"S*U*WMSD--*****","M1U":"2108","M1F":"2108","M1N":"2108","M1H":"2108","M2":"2105","M2C":"00FF00"},{"ID":"S*U*WD----*****","M1U":"2113","M1F":"2113","M1N":"2113","M1H":"2113"},{"ID":"S*U*WDM---*****","M1U":"2114","M1F":"2114","M1N":"2114","M1H":"2114","M2":"2115","M2C":"008000"},{"ID":"S*U*WDMG--*****","M1U":"2116","M1F":"2116","M1N":"2116","M1H":"2116","M2":"2117","M2C":"008000"},{"ID":"S*U*WDMM--*****","M1U":"2118","M1F":"2118","M1N":"2118","M1H":"2118","M2":"2119","M2C":"008000"},{"ID":"S*U*N-----*****",},{"ID":"S*U*ND----*****","M1U":"2120","M1F":"2120","M1N":"2120","M1H":"2120"},{"ID":"S*U*E-----*****","M2":"2124","M2C":"00FF00"},{"ID":"S*U*V-----*****","M2":"2125","M2C":"00FF00"},{"ID":"S*U*X-----*****","M2":"2126","M2C":"#FF0000"},{"ID":"S*F*------*****","M1U":"2131","M1F":"2131","M1N":"2131","M1H":"2131"},{"ID":"S*F*A-----*****","M1U":"2132","M1F":"2132","M1N":"2132","M1H":"2132"},{"ID":"S*F*AF----*****","M1U":"2133","M1F":"2133","M1N":"2133","M1H":"2133"},{"ID":"S*F*AFA---*****","M1U":"2134","M1F":"2134","M1N":"2134","M1H":"2134"},{"ID":"S*F*AFK---*****","M1U":"2135","M1F":"2135","M1N":"2135","M1H":"2135"},{"ID":"S*F*AFU---*****","M1U":"2136","M1F":"2136","M1N":"2136","M1H":"2136"},{"ID":"S*F*AFUL--*****","M1U":"2137","M1F":"2137","M1N":"2137","M1H":"2137"},{"ID":"S*F*AFUM--*****","M1U":"2138","M1F":"2138","M1N":"2138","M1H":"2138"},{"ID":"S*F*AFUH--*****","M1U":"2139","M1F":"2139","M1N":"2139","M1H":"2139"},{"ID":"S*F*AV----*****","M1U":"2140","M1F":"2140","M1N":"2140","M1H":"2140"},{"ID":"S*F*AH----*****","M1U":"2141","M1F":"2141","M1N":"2141","M1H":"2141"},{"ID":"S*F*AHH---*****","M1U":"2142","M1F":"2142","M1N":"2142","M1H":"2142"},{"ID":"S*F*AHA---*****","M1U":"2143","M1F":"2143","M1N":"2143","M1H":"2143"},{"ID":"S*F*AHU---*****","M1U":"2144","M1F":"2144","M1N":"2144","M1H":"2144"},{"ID":"S*F*AHUL--*****","M1U":"2145","M1F":"2145","M1N":"2145","M1H":"2145"},{"ID":"S*F*AHUM--*****","M1U":"2146","M1F":"2146","M1N":"2146","M1H":"2146"},{"ID":"S*F*AHUH--*****","M1U":"2147","M1F":"2147","M1N":"2147","M1H":"2147"},{"ID":"S*F*N-----*****","M1U":"2148","M1F":"2148","M1N":"2148","M1H":"2148"},{"ID":"S*F*NS----*****","M1U":"2149","M1F":"2149","M1N":"2149","M1H":"2149"},{"ID":"S*F*NU----*****","M1U":"2150","M1F":"2150","M1N":"2150","M1H":"2150"},{"ID":"S*F*NB----*****","M1U":"2151","M1F":"2151","M1N":"2151","M1H":"2151","M2":"2152","M2C":"#FFFFFF"},{"ID":"S*F*NN----*****","M1U":"2153","M1F":"2153","M1N":"2153","M1H":"2153"},{"ID":"S*F*G-----*****","M1U":"604","M1F":"605","M1N":"606","M1H":"607","M2":"2154","M2C":"#000000"},{"ID":"S*F*GS----*****","M1U":"2158","M1F":"2158","M1N":"2158","M1H":"2158"},{"ID":"S*F*GR----*****","M1U":"604","M1F":"605","M1N":"606","M1H":"607","M2":"2159","M2C":"#000000"},{"ID":"S*F*GP----*****","M1U":"2161","M1F":"2161","M1N":"2161","M1H":"2161","M2":"2162","M2C":"#FFFFFF"},{"ID":"S*F*GPA---*****","M1U":"2163","M1F":"2163","M1N":"2163","M1H":"2163","M2":"2164","M2C":"#FFFFFF"},{"ID":"S*F*GC----*****","M1U":"2165","M1F":"2165","M1N":"2165","M1H":"2165"},{"ID":"S*F*B-----*****","M1U":"2166","M1F":"2166","M1N":"2166","M1H":"2166"},{"ID":"S*Z*------*****","M1U":"999","M1F":"999","M1N":"999","M1H":"999"},{"ID":"I*-*------*****",},{"ID":"I*P*------*****",},{"ID":"I*P*S-----*****",},{"ID":"I*P*SC----*****",},{"ID":"I*P*SCD---*****","M1U":"3000","M1F":"3000","M1N":"3000","M1H":"3000"},{"ID":"I*P*SR----*****",},{"ID":"I*P*SRD---*****","M1U":"3001","M1F":"3001","M1N":"3001","M1H":"3001"},{"ID":"I*P*SRE---*****","M1U":"3002","M1F":"3002","M1N":"3002","M1H":"3002"},{"ID":"I*P*SRI---*****","M1U":"3003","M1F":"3003","M1N":"3003","M1H":"3003"},{"ID":"I*P*SRM---*****","M1U":"3004","M1F":"3004","M1N":"3004","M1H":"3004"},{"ID":"I*P*SRT---*****","M1U":"3005","M1F":"3005","M1N":"3005","M1H":"3005"},{"ID":"I*P*SRS---*****","M1U":"3006","M1F":"3006","M1N":"3006","M1H":"3006"},{"ID":"I*P*SRU---*****","M1U":"3007","M1F":"3007","M1N":"3007","M1H":"3007"},{"ID":"I*A*------*****",},{"ID":"I*A*S-----*****",},{"ID":"I*A*SC----*****",},{"ID":"I*A*SCC---*****","M1U":"3008","M1F":"3008","M1N":"3008","M1H":"3008"},{"ID":"I*A*SCO---*****","M1U":"3009","M1F":"3009","M1N":"3009","M1H":"3009"},{"ID":"I*A*SCP---*****","M1U":"3010","M1F":"3010","M1N":"3010","M1H":"3010"},{"ID":"I*A*SCS---*****","M1U":"3011","M1F":"3011","M1N":"3011","M1H":"3011"},{"ID":"I*A*SR----*****",},{"ID":"I*A*SRAI--*****","M1U":"3012","M1F":"3012","M1N":"3012","M1H":"3012"},{"ID":"I*A*SRAS--*****","M1U":"3013","M1F":"3013","M1N":"3013","M1H":"3013"},{"ID":"I*A*SRC---*****","M1U":"3014","M1F":"3014","M1N":"3014","M1H":"3014"},{"ID":"I*A*SRD---*****","M1U":"3015","M1F":"3015","M1N":"3015","M1H":"3015"},{"ID":"I*A*SRE---*****","M1U":"3016","M1F":"3016","M1N":"3016","M1H":"3016"},{"ID":"I*A*SRF---*****","M1U":"3017","M1F":"3017","M1N":"3017","M1H":"3017"},{"ID":"I*A*SRI---*****","M1U":"3018","M1F":"3018","M1N":"3018","M1H":"3018"},{"ID":"I*A*SRMA--*****","M1U":"3019","M1F":"3019","M1N":"3019","M1H":"3019"},{"ID":"I*A*SRMD--*****","M1U":"3020","M1F":"3020","M1N":"3020","M1H":"3020"},{"ID":"I*A*SRMG--*****","M1U":"3021","M1F":"3021","M1N":"3021","M1H":"3021"},{"ID":"I*A*SRMT--*****","M1U":"3022","M1F":"3022","M1N":"3022","M1H":"3022"},{"ID":"I*A*SRMF--*****","M1U":"3023","M1F":"3023","M1N":"3023","M1H":"3023"},{"ID":"I*A*SRTI--*****","M1U":"3024","M1F":"3024","M1N":"3024","M1H":"3024"},{"ID":"I*A*SRTA--*****","M1U":"3025","M1F":"3025","M1N":"3025","M1H":"3025"},{"ID":"I*A*SRTT--*****","M1U":"3026","M1F":"3026","M1N":"3026","M1H":"3026"},{"ID":"I*A*SRU---*****","M1U":"3027","M1F":"3027","M1N":"3027","M1H":"3027"},{"ID":"I*G*------*****",},{"ID":"I*G*S-----*****",},{"ID":"I*G*SC----*****",},{"ID":"I*G*SCC---*****","M1U":"3028","M1F":"3028","M1N":"3028","M1H":"3028"},{"ID":"I*G*SCO---*****","M1U":"3029","M1F":"3029","M1N":"3029","M1H":"3029"},{"ID":"I*G*SCP---*****","M1U":"3030","M1F":"3030","M1N":"3030","M1H":"3030"},{"ID":"I*G*SCS---*****","M1U":"3031","M1F":"3031","M1N":"3031","M1H":"3031"},{"ID":"I*G*SCT---*****","M1U":"3032","M1F":"3032","M1N":"3032","M1H":"3032"},{"ID":"I*G*SR----*****",},{"ID":"I*G*SRAT--*****","M1U":"3033","M1F":"3033","M1N":"3033","M1H":"3033"},{"ID":"I*G*SRAA--*****","M1U":"3034","M1F":"3034","M1N":"3034","M1H":"3034"},{"ID":"I*G*SRB---*****","M1U":"3035","M1F":"3035","M1N":"3035","M1H":"3035"},{"ID":"I*G*SRCS--*****","M1U":"3036","M1F":"3036","M1N":"3036","M1H":"3036"},{"ID":"I*G*SRCA--*****","M1U":"3037","M1F":"3037","M1N":"3037","M1H":"3037"},{"ID":"I*G*SRD---*****","M1U":"3038","M1F":"3038","M1N":"3038","M1H":"3038"},{"ID":"I*G*SRE---*****","M1U":"3039","M1F":"3039","M1N":"3039","M1H":"3039"},{"ID":"I*G*SRF---*****","M1U":"3040","M1F":"3040","M1N":"3040","M1H":"3040"},{"ID":"I*G*SRH---*****","M1U":"3041","M1F":"3041","M1N":"3041","M1H":"3041"},{"ID":"I*G*SRI---*****","M1U":"3042","M1F":"3042","M1N":"3042","M1H":"3042"},{"ID":"I*G*SRMM--*****","M1U":"3043","M1F":"3043","M1N":"3043","M1H":"3043"},{"ID":"I*G*SRMA--*****","M1U":"3044","M1F":"3044","M1N":"3044","M1H":"3044"},{"ID":"I*G*SRMG--*****","M1U":"3045","M1F":"3045","M1N":"3045","M1H":"3045"},{"ID":"I*G*SRMT--*****","M1U":"3046","M1F":"3046","M1N":"3046","M1H":"3046"},{"ID":"I*G*SRMF--*****","M1U":"3047","M1F":"3047","M1N":"3047","M1H":"3047"},{"ID":"I*G*SRS---*****","M1U":"3048","M1F":"3048","M1N":"3048","M1H":"3048"},{"ID":"I*G*SRTA--*****","M1U":"3049","M1F":"3049","M1N":"3049","M1H":"3049"},{"ID":"I*G*SRTI--*****","M1U":"3050","M1F":"3050","M1N":"3050","M1H":"3050"},{"ID":"I*G*SRTT--*****","M1U":"3051","M1F":"3051","M1N":"3051","M1H":"3051"},{"ID":"I*G*SRU---*****","M1U":"3052","M1F":"3052","M1N":"3052","M1H":"3052"},{"ID":"I*S*------*****",},{"ID":"I*S*S-----*****",},{"ID":"I*S*SC----*****",},{"ID":"I*S*SCC---*****","M1U":"3053","M1F":"3053","M1N":"3053","M1H":"3053"},{"ID":"I*S*SCO---*****","M1U":"3054","M1F":"3054","M1N":"3054","M1H":"3054"},{"ID":"I*S*SCP---*****","M1U":"3055","M1F":"3055","M1N":"3055","M1H":"3055"},{"ID":"I*S*SCS---*****","M1U":"3056","M1F":"3056","M1N":"3056","M1H":"3056"},{"ID":"I*S*SR----*****",},{"ID":"I*S*SRAT--*****","M1U":"3057","M1F":"3057","M1N":"3057","M1H":"3057"},{"ID":"I*S*SRAA--*****","M1U":"3058","M1F":"3058","M1N":"3058","M1H":"3058"},{"ID":"I*S*SRCA--*****","M1U":"3059","M1F":"3059","M1N":"3059","M1H":"3059"},{"ID":"I*S*SRCI--*****","M1U":"3060","M1F":"3060","M1N":"3060","M1H":"3060"},{"ID":"I*S*SRD---*****","M1U":"3061","M1F":"3061","M1N":"3061","M1H":"3061"},{"ID":"I*S*SRE---*****","M1U":"3062","M1F":"3062","M1N":"3062","M1H":"3062"},{"ID":"I*S*SRF---*****","M1U":"3063","M1F":"3063","M1N":"3063","M1H":"3063"},{"ID":"I*S*SRH---*****","M1U":"3064","M1F":"3064","M1N":"3064","M1H":"3064"},{"ID":"I*S*SRI---*****","M1U":"3065","M1F":"3065","M1N":"3065","M1H":"3065"},{"ID":"I*S*SRMM--*****","M1U":"3066","M1F":"3066","M1N":"3066","M1H":"3066"},{"ID":"I*S*SRMA--*****","M1U":"3067","M1F":"3067","M1N":"3067","M1H":"3067"},{"ID":"I*S*SRMG--*****","M1U":"3068","M1F":"3068","M1N":"3068","M1H":"3068"},{"ID":"I*S*SRMT--*****","M1U":"3069","M1F":"3069","M1N":"3069","M1H":"3069"},{"ID":"I*S*SRMF--*****","M1U":"3070","M1F":"3070","M1N":"3070","M1H":"3070"},{"ID":"I*S*SRS---*****","M1U":"3071","M1F":"3071","M1N":"3071","M1H":"3071"},{"ID":"I*S*SRTA--*****","M1U":"3072","M1F":"3072","M1N":"3072","M1H":"3072"},{"ID":"I*S*SRTI--*****","M1U":"3073","M1F":"3073","M1N":"3073","M1H":"3073"},{"ID":"I*S*SRTT--*****","M1U":"3074","M1F":"3074","M1N":"3074","M1H":"3074"},{"ID":"I*S*SRU---*****","M1U":"3075","M1F":"3075","M1N":"3075","M1H":"3075"},{"ID":"I*U*------*****",},{"ID":"I*U*S-----*****",},{"ID":"I*U*SC----*****",},{"ID":"I*U*SCO---*****","M1U":"3076","M1F":"3076","M1N":"3076","M1H":"3076"},{"ID":"I*U*SCP---*****","M1U":"3077","M1F":"3077","M1N":"3077","M1H":"3077"},{"ID":"I*U*SCS---*****","M1U":"3078","M1F":"3078","M1N":"3078","M1H":"3078"},{"ID":"I*U*SR----*****",},{"ID":"I*U*SRD---*****","M1U":"3079","M1F":"3079","M1N":"3079","M1H":"3079"},{"ID":"I*U*SRE---*****","M1U":"3080","M1F":"3080","M1N":"3080","M1H":"3080"},{"ID":"I*U*SRM---*****","M1U":"3081","M1F":"3081","M1N":"3081","M1H":"3081"},{"ID":"I*U*SRS---*****","M1U":"3082","M1F":"3082","M1N":"3082","M1H":"3082"},{"ID":"I*U*SRT---*****","M1U":"3083","M1F":"3083","M1N":"3083","M1H":"3083"},{"ID":"I*U*SRU---*****","M1U":"3084","M1F":"3084","M1N":"3084","M1H":"3084"},{"ID":"O*-*------*****",},{"ID":"O*V*------*****",},{"ID":"O*V*A-----*****","M1U":"4000","M1F":"4000","M1N":"4000","M1H":"4000"},{"ID":"O*V*M-----*****","M1U":"4001","M1F":"4002","M1N":"4003","M1H":"4004"},{"ID":"O*V*MA----*****","M1U":"4005","M1F":"4006","M1N":"4007","M1H":"4008"},{"ID":"O*V*MB----*****","M1U":"4009","M1F":"4010","M1N":"4011","M1H":"4012"},{"ID":"O*V*MC----*****","M1U":"4013","M1F":"4014","M1N":"4015","M1H":"4016"},{"ID":"O*V*B-----*****","M1U":"4017","M1F":"4017","M1N":"4017","M1H":"4017"},{"ID":"O*V*Y-----*****","M1U":"4018","M1F":"4018","M1N":"4018","M1H":"4018"},{"ID":"O*V*D-----*****","M1U":"4019","M1F":"4019","M1N":"4019","M1H":"4019"},{"ID":"O*V*S-----*****","M1U":"4020","M1F":"4020","M1N":"4020","M1H":"4020"},{"ID":"O*V*P-----*****","M1U":"4021","M1F":"4021","M1N":"4021","M1H":"4021"},{"ID":"O*V*E-----*****","M1U":"4022","M1F":"4022","M1N":"4022","M1H":"4022","M2":"406","M2C":"#FFFF00"},{"ID":"O*V*EI----*****","M1U":"4023","M1F":"4023","M1N":"4023","M1H":"4023"},{"ID":"O*V*EG----*****","M1U":"4508","M1F":"4508","M1N":"4508","M1H":"4508"},{"ID":"O*V*EN----*****","M1U":"4509","M1F":"4509","M1N":"4509","M1H":"4509"},{"ID":"O*V*EM----*****","M1U":"4510","M1F":"4510","M1N":"4510","M1H":"4510"},{"ID":"O*V*EO----*****","M1U":"4511","M1F":"4511","M1N":"4511","M1H":"4511"},{"ID":"O*V*ER----*****","M1U":"4512","M1F":"4512","M1N":"4512","M1H":"4512"},{"ID":"O*V*EV----*****","M1U":"4513","M1F":"4513","M1N":"4513","M1H":"4513"},{"ID":"O*L*------*****",},{"ID":"O*L*B-----*****","M1U":"4024","M1F":"4024","M1N":"4024","M1H":"4024"},{"ID":"O*L*G-----*****","M1U":"4025","M1F":"4025","M1N":"4025","M1H":"4025"},{"ID":"O*L*W-----*****","M1U":"4026","M1F":"4026","M1N":"4026","M1H":"4026"},{"ID":"O*L*M-----*****","M1U":"4027","M1F":"4027","M1N":"4027","M1H":"4027"},{"ID":"O*L*E-----*****","M1U":"4505","M1F":"4505","M1N":"4505","M1H":"4505"},{"ID":"O*L*H-----*****","M1U":"4521","M1F":"4521","M1N":"4521","M1H":"4521"},{"ID":"O*L*N-----*****","M1U":"4503","M1F":"4503","M1N":"4503","M1H":"4503"},{"ID":"O*L*H-----*****","M1U":"4521","M1F":"4521","M1N":"4521","M1H":"4521"},{"ID":"O*L*F-----*****","M1U":"4522","M1F":"4522","M1N":"4522","M1H":"4522"},{"ID":"O*O*------*****",},{"ID":"O*O*P-----*****","M1U":"4028","M1F":"4028","M1N":"4028","M1H":"4028"},{"ID":"O*O*R-----*****",},{"ID":"O*O*RW----*****","M1U":"4029","M1F":"4029","M1N":"4029","M1H":"4029"},{"ID":"O*O*RC----*****","M1U":"4030","M1F":"4030","M1N":"4030","M1H":"4030"},{"ID":"O*O*D-----*****","M1U":"4031","M1F":"4031","M1N":"4031","M1H":"4031"},{"ID":"O*O*M-----*****","M1U":"4032","M1F":"4032","M1N":"4032","M1H":"4032"},{"ID":"O*O*Y-----*****","M1U":"4033","M1F":"4033","M1N":"4033","M1H":"4033","M2":"4034","M2C":"#FFFFFF"},{"ID":"O*O*YT----*****","M1U":"4035","M1F":"4036","M1N":"4037","M1H":"4038","M2":"4039","M2C":"#FFFFFF"},{"ID":"O*O*YW----*****","M1U":"4043","M1F":"4043","M1N":"4043","M1H":"4043","M2":"4045","M2C":"#FFFFFF"},{"ID":"O*O*YH----*****","M1U":"4044","M1F":"4044","M1N":"4044","M1H":"4044","M2":"4045","M2C":"#FFFFFF"},{"ID":"O*O*F-----*****","M1U":"4046","M1F":"4046","M1N":"4046","M1H":"4046"},{"ID":"O*O*S-----*****","M1U":"4047","M1F":"4047","M1N":"4047","M1H":"4047"},{"ID":"O*O*O-----*****","M1U":"4048","M1F":"4049","M1N":"4050","M1H":"4051"},{"ID":"O*O*E-----*****","M1U":"4052","M1F":"4052","M1N":"4052","M1H":"4052"},{"ID":"O*O*H-----*****",},{"ID":"O*O*HT----*****","M1U":"4053","M1F":"4053","M1N":"4053","M1H":"4053"},{"ID":"O*O*HA----*****","M1U":"4054","M1F":"4054","M1N":"4054","M1H":"4054","M2":"4055","M2C":"#FFFFFF"},{"ID":"O*O*HV----*****","M1U":"4056","M1F":"4056","M1N":"4056","M1H":"4056","M2":"4057","M2C":"#FFFFFF"},{"ID":"O*O*K-----*****","M1U":"4058","M1F":"4058","M1N":"4058","M1H":"4058"},{"ID":"O*O*KA----*****","M1U":"4059","M1F":"4059","M1N":"4059","M1H":"4059"},{"ID":"O*O*A-----*****","M1U":"4060","M1F":"4060","M1N":"4060","M1H":"4060"},{"ID":"O*O*U-----*****","M1U":"4061","M1F":"4061","M1N":"4061","M1H":"4061"},{"ID":"O*O*UT----*****","M1U":"4506","M1F":"4506","M1N":"4506","M1H":"4506"},{"ID":"O*O*C-----*****","M1U":"4062","M1F":"4062","M1N":"4062","M1H":"4062"},{"ID":"O*O*CA----*****","M1U":"4063","M1F":"4063","M1N":"4063","M1H":"4063"},{"ID":"O*O*CB----*****","M1U":"4064","M1F":"4064","M1N":"4064","M1H":"4064"},{"ID":"O*O*CC----*****","M1U":"4065","M1F":"4065","M1N":"4065","M1H":"4065"},{"ID":"O*O*N-----*****","M1U":"4500","M1F":"4500","M1N":"4500","M1H":"4500"},{"ID":"O*O*2-----*****","M1U":"4502","M1F":"4502","M1N":"4502","M1H":"4502"},{"ID":"O*O*V-----*****","M1U":"4514","M1F":"4514","M1N":"4514","M1H":"4514"},{"ID":"O*O*I-----*****","M1U":"4516","M1F":"4516","M1N":"4516","M1H":"4516"},{"ID":"O*O*J-----*****","M1U":"4518","M1F":"4518","M1N":"4518","M1H":"4518","M2":"4519","M2C":"#FFFFFF"},{"ID":"O*O*B-----*****","M1U":"4524","M1F":"4524","M1N":"4524","M1H":"4524"},{"ID":"O*O*G-----*****","M1U":"4526","M1F":"4526","M1N":"4526","M1H":"4526"},{"ID":"O*O*X-----*****","M1U":"4527","M1F":"4527","M1N":"4527","M1H":"4527"},{"ID":"O*O*W-----*****","M1U":"4525","M1F":"4525","M1N":"4525","M1H":"4525"},{"ID":"O*O*Z-----*****","M1U":"4529","M1F":"4529","M1N":"4529","M1H":"4529"},{"ID":"O*O*T-----*****","M1U":"4531","M1F":"4531","M1N":"4531","M1H":"4531"},{"ID":"O*O*TV----*****","M1U":"4533","M1F":"4533","M1N":"4533","M1H":"4533"},{"ID":"O*O*Q-----*****","M1U":"4532","M1F":"4532","M1N":"4532","M1H":"4532"},{"ID":"O*I*------*****",},{"ID":"O*I*R-----*****","M1U":"4066","M1F":"4066","M1N":"4066","M1H":"4066"},{"ID":"O*I*S-----*****","M1U":"4067","M1F":"4067","M1N":"4067","M1H":"4067"},{"ID":"O*I*G-----*****","M1U":"4068","M1F":"4068","M1N":"4068","M1H":"4068"},{"ID":"O*I*V-----*****","M1U":"4069","M1F":"4069","M1N":"4069","M1H":"4069"},{"ID":"O*I*I-----*****","M1U":"4070","M1F":"4070","M1N":"4070","M1H":"4070"},{"ID":"O*I*D-----*****","M1U":"4071","M1F":"4071","M1N":"4071","M1H":"4071"},{"ID":"O*I*F-----*****","M1U":"4072","M1F":"4072","M1N":"4072","M1H":"4072"},{"ID":"O*I*M-----*****","M1U":"4520","M1F":"4520","M1N":"4520","M1H":"4520"},{"ID":"O*I*T-----*****","M1U":"4530","M1F":"4530","M1N":"4530","M1H":"4530"},{"ID":"O*P*------*****","M1U":"4073","M1F":"4073","M1N":"4073","M1H":"4073"},{"ID":"O*P*A-----*****","M1U":"4074","M1F":"4074","M1N":"4074","M1H":"4074"},{"ID":"O*P*AR----*****","M1U":"4523","M1F":"4523","M1N":"4523","M1H":"4523"},{"ID":"O*P*B-----*****","M1U":"4075","M1F":"4075","M1N":"4075","M1H":"4075"},{"ID":"O*P*C-----*****","M1U":"4076","M1F":"4076","M1N":"4076","M1H":"4076"},{"ID":"O*P*D-----*****","M1U":"4504","M1F":"4504","M1N":"4504","M1H":"4504"},{"ID":"O*P*E-----*****","M1U":"4528","M1F":"4528","M1N":"4528","M1H":"4528"},{"ID":"O*P*F-----*****","M1U":"4501","M1F":"4501","M1N":"4501","M1H":"4501"},{"ID":"O*P*G-----*****","M1U":"4507","M1F":"4507","M1N":"4507","M1H":"4507"},{"ID":"O*P*H-----*****","M1U":"4517","M1F":"4517","M1N":"4517","M1H":"4517"},{"ID":"O*G*------*****","M1U":"4077","M1F":"4077","M1N":"4077","M1H":"4077"},{"ID":"O*G*B-----*****","M1U":"4079","M1F":"4079","M1N":"4079","M1H":"4079"},{"ID":"O*G*C-----*****","M1U":"4080","M1F":"4080","M1N":"4080","M1H":"4080"},{"ID":"O*G*D-----*****","M1U":"4081","M1F":"4081","M1N":"4081","M1H":"4081"},{"ID":"O*G*E-----*****","M1U":"4082","M1F":"4082","M1N":"4082","M1H":"4082"},{"ID":"O*G*F-----*****","M1U":"4083","M1F":"4083","M1N":"4083","M1H":"4083"},{"ID":"O*R*------*****","M1U":"4084","M1F":"4084","M1N":"4084","M1H":"4084"},{"ID":"O*R*A-----*****","M1U":"4085","M1F":"4085","M1N":"4085","M1H":"4085"},{"ID":"O*E*------*****",},{"ID":"O*E*A-----*****","M1U":"9004","M1F":"9004","M1N":"9004","M1H":"9004"},{"ID":"O*E*B-----*****","M1U":"9005","M1F":"9005","M1N":"9005","M1H":"9005"},{"ID":"O*E*C-----*****","M1U":"9006","M1F":"9006","M1N":"9006","M1H":"9006"},{"ID":"O*E*D-----*****","M1U":"9007","M1F":"9007","M1N":"9007","M1H":"9007"},{"ID":"O*E*E-----*****","M1U":"9008","M1F":"9008","M1N":"9008","M1H":"9008"},{"ID":"O*E*F-----*****","M1U":"9009","M1F":"9009","M1N":"9009","M1H":"9009"},{"ID":"O*E*G-----*****","M1U":"9010","M1F":"9010","M1N":"9010","M1H":"9010"},{"ID":"O*E*H-----*****","M1U":"9011","M1F":"9011","M1N":"9011","M1H":"9011"},{"ID":"O*E*I-----*****","M1U":"9012","M1F":"9012","M1N":"9012","M1H":"9012"},{"ID":"O*E*J-----*****","M1U":"9013","M1F":"9013","M1N":"9013","M1H":"9013"},{"ID":"O*E*K-----*****","M1U":"9014","M1F":"9014","M1N":"9014","M1H":"9014"},{"ID":"O*E*L-----*****","M1U":"9015","M1F":"9015","M1N":"9015","M1H":"9015"},{"ID":"O*E*M-----*****","M1U":"9016","M1F":"9016","M1N":"9016","M1H":"9016"},{"ID":"O*E*N-----*****","M1U":"9017","M1F":"9017","M1N":"9017","M1H":"9017"},{"ID":"O*E*O-----*****","M1U":"9018","M1F":"9018","M1N":"9018","M1H":"9018"},{"ID":"O*E*P-----*****","M1U":"9019","M1F":"9019","M1N":"9019","M1H":"9019"},{"ID":"O*E*Q-----*****","M1U":"9020","M1F":"9020","M1N":"9020","M1H":"9020"},{"ID":"O*E*R-----*****","M1U":"9021","M1F":"9021","M1N":"9021","M1H":"9021"},{"ID":"O*E*S-----*****","M1U":"9022","M1F":"9022","M1N":"9022","M1H":"9022"},{"ID":"O*E*T-----*****","M1U":"9023","M1F":"9023","M1N":"9023","M1H":"9023"},{"ID":"O*E*U-----*****","M1U":"9024","M1F":"9024","M1N":"9024","M1H":"9024"},{"ID":"O*E*V-----*****","M1U":"9025","M1F":"9025","M1N":"9025","M1H":"9025"},{"ID":"O*E*W-----*****","M1U":"9026","M1F":"9026","M1N":"9026","M1H":"9026"},{"ID":"O*E*X-----*****","M1U":"9027","M1F":"9027","M1N":"9027","M1H":"9027"},{"ID":"O*E*Y-----*****","M1U":"9028","M1F":"9028","M1N":"9028","M1H":"9028"},{"ID":"O*E*Z-----*****","M1U":"9029","M1F":"9029","M1N":"9029","M1H":"9029"},{"ID":"O*E*AA----*****","M1U":"9030","M1F":"9030","M1N":"9030","M1H":"9030"},{"ID":"O*E*AB----*****","M1U":"9031","M1F":"9031","M1N":"9031","M1H":"9031"},{"ID":"O*E*AC----*****","M1U":"9032","M1F":"9032","M1N":"9032","M1H":"9032"},{"ID":"O*E*AD----*****",},{"ID":"O*E*ADA---*****","M1U":"9033","M1F":"9033","M1N":"9033","M1H":"9033"},{"ID":"O*E*ADB---*****","M1U":"9034","M1F":"9034","M1N":"9034","M1H":"9034"},{"ID":"O*E*ADC---*****","M1U":"9035","M1F":"9035","M1N":"9035","M1H":"9035"},{"ID":"O*E*ADD---*****","M1U":"9036","M1F":"9036","M1N":"9036","M1H":"9036"},{"ID":"O*E*AE----*****",},{"ID":"O*E*AEA---*****","M1U":"9037","M1F":"9037","M1N":"9037","M1H":"9037"},{"ID":"O*E*AEB---*****","M1U":"9038","M1F":"9038","M1N":"9038","M1H":"9038"},{"ID":"O*E*AEC---*****","M1U":"9039","M1F":"9039","M1N":"9039","M1H":"9039"},{"ID":"O*E*AED---*****","M1U":"9040","M1F":"9040","M1N":"9040","M1H":"9040"},{"ID":"O*E*AEE---*****","M1U":"9041","M1F":"9041","M1N":"9041","M1H":"9041"},{"ID":"O*E*AEF---*****","M1U":"9042","M1F":"9042","M1N":"9042","M1H":"9042"},{"ID":"O*E*AEG---*****","M1U":"9043","M1F":"9043","M1N":"9043","M1H":"9043"},{"ID":"O*E*AEH---*****","M1U":"9044","M1F":"9044","M1N":"9044","M1H":"9044"},{"ID":"O*E*AEI---*****","M1U":"9045","M1F":"9045","M1N":"9045","M1H":"9045"},{"ID":"O*E*AEJ---*****","M1U":"9046","M1F":"9046","M1N":"9046","M1H":"9046"},{"ID":"O*E*AF----*****",},{"ID":"O*E*AFA---*****","M1U":"9047","M1F":"9047","M1N":"9047","M1H":"9047"},{"ID":"O*E*AFB---*****","M1U":"9048","M1F":"9048","M1N":"9048","M1H":"9048"},{"ID":"O*E*AFC---*****","M1U":"9049","M1F":"9049","M1N":"9049","M1H":"9049"},{"ID":"O*E*AG----*****","M1U":"9050","M1F":"9050","M1N":"9050","M1H":"9050"},{"ID":"O*E*AH----*****","M1U":"9051","M1F":"9051","M1N":"9051","M1H":"9051"},{"ID":"O*E*AI----*****","M1U":"9052","M1F":"9052","M1N":"9052","M1H":"9052"},{"ID":"O*E*AJ----*****","M1U":"9053","M1F":"9053","M1N":"9053","M1H":"9053"},{"ID":"O*E*AK----*****","M1U":"9054","M1F":"9054","M1N":"9054","M1H":"9054"},{"ID":"O*E*AL----*****","M1U":"9055","M1F":"9055","M1N":"9055","M1H":"9055"},{"ID":"O*E*AM----*****","M1U":"9056","M1F":"9057","M1N":"9058","M1H":"9059"},{"ID":"O*E*AN----*****","M1U":"9060","M1F":"9061","M1N":"9062","M1H":"9063"},{"ID":"O*E*AO----*****","M1U":"9064","M1F":"9064","M1N":"9064","M1H":"9064"},{"ID":"O*E*AP----*****","M1U":"9065","M1F":"9066","M1N":"9067","M1H":"9068"},{"ID":"O*E*AQ----*****","M1U":"9069","M1F":"9070","M1N":"9071","M1H":"9072"},{"ID":"O*E*AR----*****","M1U":"9073","M1F":"9074","M1N":"9075","M1H":"9076"},{"ID":"O*E*AS----*****","M1U":"9077","M1F":"9078","M1N":"9079","M1H":"9080"},{"ID":"O*E*AT----*****","M1U":"9081","M1F":"9082","M1N":"9083","M1H":"9084"},{"ID":"O*E*AU----*****","M1U":"9085","M1F":"9085","M1N":"9085","M1H":"9085"},{"ID":"O*E*AV----*****","M1U":"9086","M1F":"9086","M1N":"9086","M1H":"9086"},{"ID":"O*E*AW----*****","M1U":"9087","M1F":"9087","M1N":"9087","M1H":"9087"},{"ID":"O*E*AX----*****","M1U":"9088","M1F":"9088","M1N":"9088","M1H":"9088"},{"ID":"O*Y*------*****",},{"ID":"O*Y*A-----*****","M1U":"9089","M1F":"9089","M1N":"9089","M1H":"9089"},{"ID":"O*Y*B-----*****","M1U":"9090","M1F":"9090","M1N":"9090","M1H":"9090"},{"ID":"O*Y*C-----*****","M1U":"9091","M1F":"9091","M1N":"9091","M1H":"9091"},{"ID":"O*Y*D-----*****","M1U":"9092","M1F":"9092","M1N":"9092","M1H":"9092"},{"ID":"O*Y*E-----*****","M1U":"9093","M1F":"9093","M1N":"9093","M1H":"9093"},{"ID":"O*Y*F-----*****","M1U":"9094","M1F":"9094","M1N":"9094","M1H":"9094"},{"ID":"O*Y*G-----*****","M1U":"9095","M1F":"9095","M1N":"9095","M1H":"9095"},{"ID":"O*Y*R-----*****",},{"ID":"O*Y*SP----*****",},{"ID":"O*Y*LP----*****",},{"ID":"O*Y*SH----*****",},{"ID":"O*Y*FM----*****",},{"ID":"O*Y*SA----*****",},{"ID":"O*Y*EP----*****",},{"ID":"O*Y*PD----*****",},{"ID":"O*S*------*****",},{"ID":"O*S*A-----*****","M1U":"9103","M1F":"9103","M1N":"9103","M1H":"9103"},{"ID":"O*S*B-----*****","M1U":"9104","M1F":"9104","M1N":"9104","M1H":"9104"},{"ID":"O*S*C-----*****","M1U":"9105","M1F":"9105","M1N":"9105","M1H":"9105"},{"ID":"O*S*D-----*****","M1U":"9106","M1F":"9106","M1N":"9106","M1H":"9106"},{"ID":"O*S*E-----*****","M1U":"9107","M1F":"9107","M1N":"9107","M1H":"9107"},{"ID":"O*S*F-----*****","M1U":"9108","M1F":"9108","M1N":"9108","M1H":"9108"},{"ID":"O*S*G-----*****","M1U":"9109","M1F":"9109","M1N":"9109","M1H":"9109"},{"ID":"O*S*H-----*****","M1U":"9110","M1F":"9110","M1N":"9110","M1H":"9110"},{"ID":"O*S*I-----*****","M1U":"9111","M1F":"9111","M1N":"9111","M1H":"9111"},{"ID":"O*S*J-----*****","M1U":"9112","M1F":"9112","M1N":"9112","M1H":"9112"},{"ID":"O*S*K-----*****",},{"ID":"O*S*KA----*****","M1U":"9114","M1F":"9114","M1N":"9114","M1H":"9114"},{"ID":"O*S*KB----*****","M1U":"9115","M1F":"9115","M1N":"9115","M1H":"9115"},{"ID":"O*S*KC----*****","M1U":"9116","M1F":"9116","M1N":"9116","M1H":"9116"},{"ID":"O*S*L-----*****","M1U":"9117","M1F":"9117","M1N":"9117","M1H":"9117"},{"ID":"O*S*M-----*****","M1U":"9118","M1F":"9118","M1N":"9118","M1H":"9118"},{"ID":"O*S*N-----*****","M1U":"9119","M1F":"9119","M1N":"9119","M1H":"9119"},{"ID":"O*Q*------*****",},{"ID":"O*Q*A-----*****","M1U":"9121","M1F":"9121","M1N":"9121","M1H":"9121"},{"ID":"O*Q*B-----*****","M1U":"9122","M1F":"9122","M1N":"9122","M1H":"9122"},{"ID":"O*Q*C-----*****","M1U":"9123","M1F":"9123","M1N":"9123","M1H":"9123"},{"ID":"O*Q*D-----*****","M1U":"9124","M1F":"9124","M1N":"9124","M1H":"9124"},{"ID":"O*Q*E-----*****","M1U":"9125","M1F":"9125","M1N":"9125","M1H":"9125"},{"ID":"O*Q*F-----*****","M1U":"9126","M1F":"9126","M1N":"9126","M1H":"9126"},{"ID":"O*Q*G-----*****","M1U":"9127","M1F":"9127","M1N":"9127","M1H":"9127"},{"ID":"O*Q*H-----*****","M1U":"9128","M1F":"9128","M1N":"9128","M1H":"9128"},{"ID":"O*Q*I-----*****","M1U":"9129","M1F":"9129","M1N":"9129","M1H":"9129"},{"ID":"O*Q*J-----*****","M1U":"9130","M1F":"9130","M1N":"9130","M1H":"9130"},{"ID":"O*Q*K-----*****","M1U":"9131","M1F":"9131","M1N":"9131","M1H":"9131"},{"ID":"E*-*------*****",},{"ID":"E*I*------*****",},{"ID":"E*I*A-----*****","M1U":"5000","M1F":"5000","M1N":"5000","M1H":"5000"},{"ID":"E*I*AC----*****","M1U":"5001","M1F":"5001","M1N":"5001","M1H":"5001"},{"ID":"E*I*B-----*****","M1U":"5002","M1F":"5002","M1N":"5002","M1H":"5002"},{"ID":"E*I*BA----*****","M1U":"5003","M1F":"5003","M1N":"5003","M1H":"5003"},{"ID":"E*I*BC----*****","M1U":"5004","M1F":"5004","M1N":"5004","M1H":"5004"},{"ID":"E*I*BD----*****","M1U":"5005","M1F":"5005","M1N":"5005","M1H":"5005"},{"ID":"E*I*BF----*****","M1U":"5006","M1F":"5006","M1N":"5006","M1H":"5006"},{"ID":"E*I*C-----*****","M1U":"5007","M1F":"5007","M1N":"5007","M1H":"5007"},{"ID":"E*I*CA----*****","M1U":"5008","M1F":"5008","M1N":"5008","M1H":"5008","MAPPING1COLOR":"000000","M2":"5009","M2C":"FFFFFF"},{"ID":"E*I*CB----*****","M1U":"5010","M1F":"5010","M1N":"5010","M1H":"5010"},{"ID":"E*I*CC----*****","M1U":"5011","M1F":"5011","M1N":"5011","M1H":"5011","MAPPING1COLOR":"000000","M2":"5012","M2C":"FFFFFF"},{"ID":"E*I*CD----*****","M1U":"5013","M1F":"5013","M1N":"5013","M1H":"5013"},{"ID":"E*I*CE----*****","M1U":"5014","M1F":"5014","M1N":"5014","M1H":"5014"},{"ID":"E*I*CF----*****","M1U":"5015","M1F":"5015","M1N":"5015","M1H":"5015"},{"ID":"E*I*CG----*****","M1U":"5016","M1F":"5016","M1N":"5016","M1H":"5016"},{"ID":"E*I*CH----*****","M1U":"5017","M1F":"5017","M1N":"5017","M1H":"5017"},{"ID":"E*I*D-----*****","M1U":"5018","M1F":"5018","M1N":"5018","M1H":"5018","MAPPING1COLOR":"000000","M2":"5019","M2C":"FFFFFF"},{"ID":"E*I*DA----*****","M1U":"5020","M1F":"5020","M1N":"5020","M1H":"5020","MAPPING1COLOR":"000000","M2":"5021","M2C":"FFFF00"},{"ID":"E*I*DB----*****","M1U":"5022","M1F":"5022","M1N":"5022","M1H":"5022"},{"ID":"E*I*DC----*****","M1U":"5023","M1F":"5023","M1N":"5023","M1H":"5023","MAPPING1COLOR":"000000","M2":"5024","M2C":"FFFFFF"},{"ID":"E*I*DD----*****","M1U":"5025","M1F":"5025","M1N":"5025","M1H":"5025","MAPPING1COLOR":"000000","M2":"5026","M2C":"FFFFFF"},{"ID":"E*I*DE----*****","M1U":"5027","M1F":"5027","M1N":"5027","M1H":"5027","MAPPING1COLOR":"000000","M2":"5028","M2C":"FFFFFF"},{"ID":"E*I*DF----*****","M1U":"5029","M1F":"5029","M1N":"5029","M1H":"5029","MAPPING1COLOR":"000000","M2":"5030","M2C":"FFFFFF"},{"ID":"E*I*DG----*****","M1U":"5031","M1F":"5031","M1N":"5031","M1H":"5031","MAPPING1COLOR":"000000","M2":"5032","M2C":"FFFFFF"},{"ID":"E*I*DH----*****","M1U":"5033","M1F":"5033","M1N":"5033","M1H":"5033","MAPPING1COLOR":"000000","M2":"5034","M2C":"FFFFFF"},{"ID":"E*I*DI----*****","M1U":"5035","M1F":"5035","M1N":"5035","M1H":"5035","MAPPING1COLOR":"000000","M2":"5036","M2C":"FFFFFF"},{"ID":"E*I*DJ----*****","M1U":"5037","M1F":"5037","M1N":"5037","M1H":"5037","MAPPING1COLOR":"000000","M2":"5038","M2C":"FFFFFF"},{"ID":"E*I*DK----*****","M1U":"5039","M1F":"5039","M1N":"5039","M1H":"5039"},{"ID":"E*I*DL----*****","M1U":"5040","M1F":"5040","M1N":"5040","M1H":"5040"},{"ID":"E*I*DM----*****","M1U":"5041","M1F":"5041","M1N":"5041","M1H":"5041","MAPPING1COLOR":"000000","M2":"5042","M2C":"FFFFFF"},{"ID":"E*I*DN----*****","M1U":"5043","M1F":"5043","M1N":"5043","M1H":"5043"},{"ID":"E*I*DO----*****","M1U":"5044","M1F":"5044","M1N":"5044","M1H":"5044"},{"ID":"E*I*E-----*****","M1U":"5045","M1F":"5045","M1N":"5045","M1H":"5045","MAPPING1COLOR":"000000","M2":"5046","M2C":"FFFFFF"},{"ID":"E*I*EA----*****","M1U":"5047","M1F":"5047","M1N":"5047","M1H":"5047","MAPPING1COLOR":"000000","M2":"5048","M2C":"FFFFFF"},{"ID":"E*I*F-----*****","M1U":"5051","M1F":"5051","M1N":"5051","M1H":"5051","MAPPING1COLOR":"000000","M2":"5052","M2C":"FFFFFF"},{"ID":"E*I*FA----*****","M1U":"5053","M1F":"5053","M1N":"5053","M1H":"5053","MAPPING1COLOR":"000000","M2":"5054","M2C":"FFFFFF"},{"ID":"E*I*G-----*****","M1U":"5057","M1F":"5057","M1N":"5057","M1H":"5057","MAPPING1COLOR":"000000"},{"ID":"E*I*GA----*****","M1U":"5058","M1F":"5058","M1N":"5058","M1H":"5058","MAPPING1COLOR":"000000"},{"ID":"E*I*GB----*****","M1U":"5059","M1F":"5059","M1N":"5059","M1H":"5059","MAPPING1COLOR":"000000"},{"ID":"E*I*H-----*****","M1U":"5060","M1F":"5060","M1N":"5060","M1H":"5060","MAPPING1COLOR":"000000"},{"ID":"E*I*HA----*****","M1U":"5061","M1F":"5061","M1N":"5061","M1H":"5061","MAPPING1COLOR":"000000"},{"ID":"E*N*------*****",},{"ID":"E*O*------*****",},{"ID":"E*O*A-----*****","M1U":"5200","M1F":"5200","M1N":"5200","M1H":"5200"},{"ID":"E*O*AA----*****","M1U":"5200","M1F":"5200","M1N":"5200","M1H":"5200"},{"ID":"E*O*AB----*****","M1U":"5200","M1F":"5200","M1N":"5200","M1H":"5200"},{"ID":"E*O*AC----*****","M1U":"5200","M1F":"5200","M1N":"5200","M1H":"5200"},{"ID":"E*O*AD----*****","M1U":"5200","M1F":"5200","M1N":"5200","M1H":"5200"},{"ID":"E*O*AE----*****","M1U":"5201","M1F":"5201","M1N":"5201","M1H":"5201","MAPPING1COLOR":"000000","M2":"5202","M2C":"FFFFFF"},{"ID":"E*O*AF----*****","M1U":"5203","M1F":"5203","M1N":"5203","M1H":"5203","MAPPING1COLOR":"000000","M2":"5204","M2C":"FFFFFF"},{"ID":"E*O*AG----*****","M1U":"5205","M1F":"5205","M1N":"5205","M1H":"5205"},{"ID":"E*O*AJ----*****","M1U":"5206","M1F":"5206","M1N":"5206","M1H":"5206","MAPPING1COLOR":"000000","M2":"5207","M2C":"FFFFFF"},{"ID":"E*O*AK----*****","M1U":"5208","M1F":"5208","M1N":"5208","M1H":"5208","MAPPING1COLOR":"000000","M2":"5209","M2C":"FFFFFF"},{"ID":"E*O*AL----*****","M1U":"5210","M1F":"5210","M1N":"5210","M1H":"5210"},{"ID":"E*O*AM----*****","M1U":"5211","M1F":"5211","M1N":"5211","M1H":"5211","MAPPING1COLOR":"000000","M2":"5212","M2C":"FFFFFF"},{"ID":"E*O*B-----*****","M1U":"5213","M1F":"5213","M1N":"5213","M1H":"5213","MAPPING1COLOR":"000000","M2":"5214","M2C":"FFFFFF"},{"ID":"E*O*BA----*****","M1U":"5213","M1F":"5213","M1N":"5213","M1H":"5213","MAPPING1COLOR":"000000","M2":"5214","M2C":"FFFFFF"},{"ID":"E*O*BB----*****","M1U":"5213","M1F":"5213","M1N":"5213","M1H":"5213","MAPPING1COLOR":"000000","M2":"5214","M2C":"FFFFFF"},{"ID":"E*O*BC----*****","M1U":"5213","M1F":"5213","M1N":"5213","M1H":"5213","MAPPING1COLOR":"000000","M2":"5214","M2C":"FFFFFF"},{"ID":"E*O*BD----*****","M1U":"5215","M1F":"5215","M1N":"5215","M1H":"5215","MAPPING1COLOR":"000000","M2":"5216","M2C":"FFFFFF"},{"ID":"E*O*BE----*****","M1U":"5217","M1F":"5217","M1N":"5217","M1H":"5217","MAPPING1COLOR":"000000","M2":"5218","M2C":"FFFFFF"},{"ID":"E*O*BF----*****","M1U":"5219","M1F":"5219","M1N":"5219","M1H":"5219","MAPPING1COLOR":"000000","M2":"5220","M2C":"FFFFFF"},{"ID":"E*O*BG----*****","M1U":"5221","M1F":"5221","M1N":"5221","M1H":"5221","MAPPING1COLOR":"000000","M2":"5222","M2C":"FFFFFF"},{"ID":"E*O*BH----*****","M1U":"5223","M1F":"5223","M1N":"5223","M1H":"5223","MAPPING1COLOR":"000000","M2":"5224","M2C":"FFFFFF"},{"ID":"E*O*BI----*****","M1U":"5225","M1F":"5225","M1N":"5225","M1H":"5225","MAPPING1COLOR":"000000","M2":"5226","M2C":"FFFFFF"},{"ID":"E*O*BJ----*****","M1U":"5227","M1F":"5227","M1N":"5227","M1H":"5227","MAPPING1COLOR":"000000","M2":"5228","M2C":"FFFFFF"},{"ID":"E*O*BK----*****","M1U":"5229","M1F":"5230","M1N":"5231","M1H":"5232","MAPPING1COLOR":"000000"},{"ID":"E*O*BL----*****","M1U":"5233","M1F":"5234","M1N":"5235","M1H":"5236","MAPPING1COLOR":"000000"},{"ID":"E*O*C-----*****","M1U":"5237","M1F":"5237","M1N":"5237","M1H":"5237"},{"ID":"E*O*CA----*****","M1U":"5237","M1F":"5237","M1N":"5237","M1H":"5237"},{"ID":"E*O*CB----*****","M1U":"5237","M1F":"5237","M1N":"5237","M1H":"5237"},{"ID":"E*O*CC----*****","M1U":"5238","M1F":"5238","M1N":"5238","M1H":"5238","MAPPING1COLOR":"000000","M2":"5239","M2C":"FFFFFF"},{"ID":"E*O*CD----*****","M1U":"5240","M1F":"5240","M1N":"5240","M1H":"5240","MAPPING1COLOR":"000000","M2":"5241","M2C":"FFFFFF"},{"ID":"E*O*CE----*****","M1U":"5237","M1F":"5237","M1N":"5237","M1H":"5237"},{"ID":"E*O*D-----*****","M1U":"5242","M1F":"5242","M1N":"5242","M1H":"5242"},{"ID":"E*O*DA----*****","M1U":"5242","M1F":"5242","M1N":"5242","M1H":"5242"},{"ID":"E*O*DB----*****","M1U":"5242","M1F":"5242","M1N":"5242","M1H":"5242"},{"ID":"E*O*DC----*****","M1U":"5242","M1F":"5242","M1N":"5242","M1H":"5242"},{"ID":"E*O*DD----*****","M1U":"5243","M1F":"5243","M1N":"5243","M1H":"5243"},{"ID":"E*O*DDA---*****","M1U":"5243","M1F":"5243","M1N":"5243","M1H":"5243"},{"ID":"E*O*DDB---*****","M1U":"5243","M1F":"5243","M1N":"5243","M1H":"5243"},{"ID":"E*O*DDC---*****","M1U":"5243","M1F":"5243","M1N":"5243","M1H":"5243"},{"ID":"E*O*DE----*****","M1U":"5244","M1F":"5244","M1N":"5244","M1H":"5244","MAPPING1COLOR":"000000","M2":"5245","M2C":"FFFFFF"},{"ID":"E*O*DEA---*****","M1U":"5244","M1F":"5244","M1N":"5244","M1H":"5244","MAPPING1COLOR":"000000","M2":"5245","M2C":"FFFFFF"},{"ID":"E*O*DEB---*****","M1U":"5244","M1F":"5244","M1N":"5244","M1H":"5244","MAPPING1COLOR":"000000","M2":"5245","M2C":"FFFFFF"},{"ID":"E*O*DEC---*****","M1U":"5244","M1F":"5244","M1N":"5244","M1H":"5244","MAPPING1COLOR":"000000","M2":"5245","M2C":"FFFFFF"},{"ID":"E*O*DF----*****","M1U":"5246","M1F":"5246","M1N":"5246","M1H":"5246","MAPPING1COLOR":"000000","M2":"5247","M2C":"FFFFFF"},{"ID":"E*O*DFA---*****","M1U":"5246","M1F":"5246","M1N":"5246","M1H":"5246","MAPPING1COLOR":"000000","M2":"5247","M2C":"FFFFFF"},{"ID":"E*O*DFB---*****","M1U":"5246","M1F":"5246","M1N":"5246","M1H":"5246","MAPPING1COLOR":"000000","M2":"5247","M2C":"FFFFFF"},{"ID":"E*O*DFC---*****","M1U":"5246","M1F":"5246","M1N":"5246","M1H":"5246","MAPPING1COLOR":"000000","M2":"5247","M2C":"FFFFFF"},{"ID":"E*O*DG----*****","M1U":"5248","M1F":"5248","M1N":"5248","M1H":"5248"},{"ID":"E*O*DGA---*****","M1U":"5248","M1F":"5248","M1N":"5248","M1H":"5248"},{"ID":"E*O*DGB---*****","M1U":"5248","M1F":"5248","M1N":"5248","M1H":"5248"},{"ID":"E*O*DGC---*****","M1U":"5248","M1F":"5248","M1N":"5248","M1H":"5248"},{"ID":"E*O*DH----*****","M1U":"5249","M1F":"5249","M1N":"5249","M1H":"5249"},{"ID":"E*O*DHA---*****","M1U":"5249","M1F":"5249","M1N":"5249","M1H":"5249"},{"ID":"E*O*DHB---*****","M1U":"5249","M1F":"5249","M1N":"5249","M1H":"5249"},{"ID":"E*O*DHC---*****","M1U":"5249","M1F":"5249","M1N":"5249","M1H":"5249"},{"ID":"E*O*DI----*****","M1U":"5250","M1F":"5250","M1N":"5250","M1H":"5250"},{"ID":"E*O*DIA---*****","M1U":"5250","M1F":"5250","M1N":"5250","M1H":"5250"},{"ID":"E*O*DIB---*****","M1U":"5250","M1F":"5250","M1N":"5250","M1H":"5250"},{"ID":"E*O*DIC---*****","M1U":"5250","M1F":"5250","M1N":"5250","M1H":"5250"},{"ID":"E*O*DJ----*****","M1U":"5251","M1F":"5251","M1N":"5251","M1H":"5251"},{"ID":"E*O*DJB---*****","M1U":"5251","M1F":"5251","M1N":"5251","M1H":"5251"},{"ID":"E*O*DJC---*****","M1U":"5251","M1F":"5251","M1N":"5251","M1H":"5251"},{"ID":"E*O*DK----*****","M1U":"5252","M1F":"5252","M1N":"5252","M1H":"5252","MAPPING1COLOR":"000000","M2":"5253","M2C":"FFFFFF"},{"ID":"E*O*DL----*****","M1U":"5254","M1F":"5254","M1N":"5254","M1H":"5254"},{"ID":"E*O*DLA---*****","M1U":"5254","M1F":"5254","M1N":"5254","M1H":"5254"},{"ID":"E*O*DLB---*****","M1U":"5254","M1F":"5254","M1N":"5254","M1H":"5254"},{"ID":"E*O*DLC---*****","M1U":"5254","M1F":"5254","M1N":"5254","M1H":"5254"},{"ID":"E*O*DM----*****","M1U":"5255","M1F":"5255","M1N":"5255","M1H":"5255"},{"ID":"E*O*DMA---*****","M1U":"5255","M1F":"5255","M1N":"5255","M1H":"5255"},{"ID":"E*O*DMB---*****","M1U":"5255","M1F":"5255","M1N":"5255","M1H":"5255"},{"ID":"E*O*DMC---*****","M1U":"5255","M1F":"5255","M1N":"5255","M1H":"5255"},{"ID":"E*O*DN----*****","M1U":"2007","M1F":"2007","M1N":"2007","M1H":"2007","MAPPING1COLOR":"000000","M2":"2008","M2C":"FFFFFF"},{"ID":"E*O*DNA---*****","M1U":"2007","M1F":"2007","M1N":"2007","M1H":"2007","MAPPING1COLOR":"000000","M2":"2008","M2C":"FFFFFF"},{"ID":"E*O*DNC---*****","M1U":"2007","M1F":"2007","M1N":"2007","M1H":"2007","MAPPING1COLOR":"000000","M2":"2008","M2C":"FFFFFF"},{"ID":"E*O*DO----*****","M1U":"5257","M1F":"5257","M1N":"5257","M1H":"5257","MAPPING1COLOR":"000000","M2":"5258","M2C":"FFFFFF"},{"ID":"E*O*DOA---*****","M1U":"5257","M1F":"5257","M1N":"5257","M1H":"5257","MAPPING1COLOR":"000000","M2":"5258","M2C":"FFFFFF"},{"ID":"E*O*DOB---*****","M1U":"5257","M1F":"5257","M1N":"5257","M1H":"5257","MAPPING1COLOR":"000000","M2":"5258","M2C":"FFFFFF"},{"ID":"E*O*DOC---*****","M1U":"5257","M1F":"5257","M1N":"5257","M1H":"5257","MAPPING1COLOR":"000000","M2":"5258","M2C":"FFFFFF"},{"ID":"E*O*EA----*****","M1U":"5260","M1F":"5260","M1N":"5260","M1H":"5260"},{"ID":"E*O*EB----*****","M1U":"5261","M1F":"5261","M1N":"5261","M1H":"5261"},{"ID":"E*O*EC----*****","M1U":"5262","M1F":"5262","M1N":"5262","M1H":"5262"},{"ID":"E*O*ED----*****","M1U":"5263","M1F":"5263","M1N":"5263","M1H":"5263"},{"ID":"E*O*EE----*****","M1U":"5264","M1F":"5264","M1N":"5264","M1H":"5264"},{"ID":"E*F*------*****",},{"ID":"E*F*A-----*****","M1U":"5265","M1F":"5265","M1N":"5265","M1H":"5265","MAPPING1COLOR":"000000","M2":"5266","M2C":"FFFFFF"},{"ID":"E*F*AA----*****","M1U":"5267","M1F":"5267","M1N":"5267","M1H":"5267","MAPPING1COLOR":"000000","M2":"5268","M2C":"808080"},{"ID":"E*F*AB----*****","M1U":"5269","M1F":"5269","M1N":"5269","M1H":"5269","MAPPING1COLOR":"000000","M2":"5270","M2C":"FFFFFF"},{"ID":"E*F*AC----*****","M1U":"5271","M1F":"5272","M1N":"5273","M1H":"5274"},{"ID":"E*F*AD----*****","M1U":"5275","M1F":"5275","M1N":"5275","M1H":"5275","MAPPING1COLOR":"000000","M2":"5276","M2C":"FFFFFF"},{"ID":"E*F*AE----*****","M1U":"5277","M1F":"5278","M1N":"5279","M1H":"5280"},{"ID":"E*F*AF----*****","M1U":"5281","M1F":"5282","M1N":"5283","M1H":"5284"},{"ID":"E*F*AG----*****","M1U":"5285","M1F":"5285","M1N":"5285","M1H":"5285","M2":"5286","M2C":"FFFFFF"},{"ID":"E*F*B-----*****","M1U":"5287","M1F":"5287","M1N":"5287","M1H":"5287"},{"ID":"E*F*BA----*****","M1U":"5288","M1F":"5288","M1N":"5288","M1H":"5288","M2":"5289","M2C":"FFFFFF"},{"ID":"E*F*BB----*****","M1U":"5290","M1F":"5290","M1N":"5290","M1H":"5290","M2":"5291","M2C":"FFFFFF"},{"ID":"E*F*BC----*****","M1U":"5292","M1F":"5292","M1N":"5292","M1H":"5292","M2":"5293","M2C":"FFFFFF"},{"ID":"E*F*BD----*****","M1U":"5294","M1F":"5294","M1N":"5294","M1H":"5294","M2":"5295","M2C":"FFFFFF"},{"ID":"E*F*BE----*****","M1U":"5296","M1F":"5296","M1N":"5296","M1H":"5296"},{"ID":"E*F*BF----*****","M1U":"5297","M1F":"5297","M1N":"5297","M1H":"5297"},{"ID":"E*F*C-----*****","M1U":"5298","M1F":"5298","M1N":"5298","M1H":"5298","M2":"5299","M2C":"FFFFFF"},{"ID":"E*F*CA----*****","M1U":"5300","M1F":"5300","M1N":"5300","M1H":"5300","M2":"5299","M2C":"FFFFFF"},{"ID":"E*F*CB----*****","M1U":"5301","M1F":"5301","M1N":"5301","M1H":"5301","M2":"5299","M2C":"FFFFFF"},{"ID":"E*F*CC----*****","M1U":"5302","M1F":"5302","M1N":"5302","M1H":"5302","M2":"5303","M2C":"FFFFFF"},{"ID":"E*F*CD----*****","M1U":"5304","M1F":"5304","M1N":"5304","M1H":"5304","M2":"5299","M2C":"FFFFFF"},{"ID":"E*F*CE----*****","M1U":"5306","M1F":"5306","M1N":"5306","M1H":"5306","M2":"5307","M2C":"FFFFFF"},{"ID":"E*F*CF----*****","M1U":"5308","M1F":"5308","M1N":"5308","M1H":"5308","M2":"5299","M2C":"FFFFFF"},{"ID":"E*F*CG----*****","M1U":"5310","M1F":"5310","M1N":"5310","M1H":"5310","M2":"5311","M2C":"FFFFFF"},{"ID":"E*F*CH----*****","M1U":"5312","M1F":"5312","M1N":"5312","M1H":"5312","M2":"5313","M2C":"FFFFFF"},{"ID":"E*F*CI----*****","M1U":"5314","M1F":"5314","M1N":"5314","M1H":"5314","M2":"5315","M2C":"FFFFFF"},{"ID":"E*F*CJ----*****","M1U":"5316","M1F":"5316","M1N":"5316","M1H":"5316","M2":"5317","M2C":"FFFFFF"},{"ID":"E*F*D-----*****","M1U":"5318","M1F":"5318","M1N":"5318","M1H":"5318"},{"ID":"E*F*DA----*****","M1U":"5319","M1F":"5319","M1N":"5319","M1H":"5319"},{"ID":"E*F*DB----*****","M1U":"5320","M1F":"5320","M1N":"5320","M1H":"5320"},{"ID":"E*F*EA----*****","M1U":"5323","M1F":"5323","M1N":"5323","M1H":"5323"},{"ID":"E*F*EB----*****","M1U":"5325","M1F":"5325","M1N":"5325","M1H":"5325"},{"ID":"E*F*EE----*****","M1U":"5330","M1F":"5330","M1N":"5330","M1H":"5330","M2":"5331","M2C":"FFFFFF"},{"ID":"E*F*F-----*****","M1U":"5332","M1F":"5332","M1N":"5332","M1H":"5332","M2":"5333","M2C":"FFFFFF"},{"ID":"E*F*G-----*****","M1U":"5334","M1F":"5334","M1N":"5334","M1H":"5334","M2":"5335","M2C":"FFFFFF"},{"ID":"E*F*GA----*****","M1U":"5336","M1F":"5336","M1N":"5336","M1H":"5336"},{"ID":"E*F*H-----*****","M1U":"5338","M1F":"5338","M1N":"5338","M1H":"5338","M2":"5339","M2C":"FFFFFF"},{"ID":"E*F*HA----*****","M1U":"5340","M1F":"5340","M1N":"5340","M1H":"5340","M2":"5341","M2C":"FFFFFF"},{"ID":"E*F*HB----*****","M1U":"5342","M1F":"5342","M1N":"5342","M1H":"5342","M2":"5343","M2C":"FFFFFF"},{"ID":"E*F*I-----*****","M1U":"5344","M1F":"5344","M1N":"5344","M1H":"5344"},{"ID":"E*F*IA----*****","M1U":"5345","M1F":"5345","M1N":"5345","M1H":"5345","M2":"5346","M2C":"FFFFFF"},{"ID":"E*F*IB----*****","M1U":"5347","M1F":"5347","M1N":"5347","M1H":"5347"},{"ID":"E*F*IC----*****","M1U":"5348","M1F":"5348","M1N":"5348","M1H":"5348"},{"ID":"E*F*ID----*****","M1U":"5349","M1F":"5349","M1N":"5349","M1H":"5349","M2":"5350","M2C":"#FFFFFF"},{"ID":"E*F*J-----*****","M1U":"5351","M1F":"5351","M1N":"5351","M1H":"5351"},{"ID":"E*F*JA----*****","M1U":"5352","M1F":"5352","M1N":"5352","M1H":"5352"},{"ID":"E*F*JB----*****","M1U":"5353","M1F":"5353","M1N":"5353","M1H":"5353","M2":"5354","M2C":"FFFFFF"},{"ID":"E*F*JC----*****","M1U":"5355","M1F":"5355","M1N":"5355","M1H":"5355"},{"ID":"E*F*K-----*****","M1U":"5356","M1F":"5356","M1N":"5356","M1H":"5356"},{"ID":"E*F*KB----*****","M1U":"5358","M1F":"5358","M1N":"5358","M1H":"5358"},{"ID":"E*F*LA----*****","M1U":"5360","M1F":"5360","M1N":"5360","M1H":"5360"},{"ID":"E*F*LD----*****","M1U":"5363","M1F":"5363","M1N":"5363","M1H":"5363","M2":"5364","M2C":"FFFFFF"},{"ID":"E*F*LE----*****","M1U":"5365","M1F":"5365","M1N":"5365","M1H":"5365","M2":"5366","M2C":"FFFFFF"},{"ID":"E*F*LF----*****","M1U":"5367","M1F":"5367","M1N":"5367","M1H":"5367","M2":"5368","M2C":"FFFFFF"},{"ID":"E*F*LH----*****","M1U":"5370","M1F":"5370","M1N":"5370","M1H":"5370"},{"ID":"E*F*LJ----*****","M1U":"5372","M1F":"5372","M1N":"5372","M1H":"5372"},{"ID":"E*F*LK----*****","M1U":"5373","M1F":"5373","M1N":"5373","M1H":"5373"},{"ID":"E*F*LM----*****","M1U":"5375","M1F":"5375","M1N":"5375","M1H":"5375","M2":"5376","M2C":"FFFFFF"},{"ID":"E*F*LO----*****","M1U":"5378","M1F":"5378","M1N":"5378","M1H":"5378","M2":"5379","M2C":"FFFFFF"},{"ID":"E*F*LP----*****","M1U":"5380","M1F":"5380","M1N":"5380","M1H":"5380","M2":"5381","M2C":"FFFFFF"},{"ID":"E*F*MA----*****","M1U":"5383","M1F":"5383","M1N":"5383","M1H":"5383"},{"ID":"E*F*MB----*****","M1U":"5384","M1F":"5384","M1N":"5384","M1H":"5384"},{"ID":"E*F*MC----*****","M1U":"5385","M1F":"5385","M1N":"5385","M1H":"5385"},{"ID":"E*F*MD----*****","M1U":"5386","M1F":"5386","M1N":"5386","M1H":"5386"},{"ID":"E*F*ME----*****","M1U":"5387","M1F":"5387","M1N":"5387","M1H":"5387","M2":"5388","M2C":"FFFFFF"},{"ID":"E*F*MF----*****","M1U":"5389","M1F":"5389","M1N":"5389","M1H":"5389","M2":"5390","M2C":"FFFFFF"},{"ID":"E*F*MG----*****","M1U":"5391","M1F":"5391","M1N":"5391","M1H":"5391","M2":"5392","M2C":"FFFFFF"},{"ID":"E*F*MH----*****","M1U":"5393","M1F":"5393","M1N":"5393","M1H":"5393","M2":"5394","M2C":"FFFFFF"},{"ID":"E*F*MI----*****","M1U":"5395","M1F":"5395","M1N":"5395","M1H":"5395","M2":"5396","M2C":"FFFFFF"}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.xml=armyc2.c2sd.renderer.xml||{};armyc2.c2sd.renderer.xml.UnitConstantsC={"UNITCONSTANTS":{"SYMBOL":[{"ID":"S***------*****","D":"Warfighting Symbology","DC":"0","H":"1.X",},{"ID":"S*P*------*****","D":"Space Track","DC":"8","H":"1.X.1",},{"ID":"S*P*S-----*****","D":"Satellite","DC":"8","H":"1.X.1.1",},{"ID":"S*P*V-----*****","D":"Crewed Space Vehicle","DC":"8","H":"1.X.1.2",},{"ID":"S*P*T-----*****","D":"Space Station","DC":"8","H":"1.X.1.3",},{"ID":"S*P*L-----*****","D":"Space Launch Vehicle","DC":"8","H":"1.X.1.4",},{"ID":"S*A*------*****","D":"Air Track","DC":"8","H":"1.X.2",},{"ID":"S*A*M-----*****","D":"Military","DC":"8","H":"1.X.2.1",},{"ID":"S*A*MF----*****","D":"Fixed Wing","DC":"8","H":"1.X.2.1.1",},{"ID":"S*A*MFB---*****","D":"Fixed Wing Bomber","DC":"8","H":"1.X.2.1.1.1",},{"ID":"S*A*MFF---*****","D":"Fixed Wing Fighter","DC":"8","H":"1.X.2.1.1.2",},{"ID":"S*A*MFFI--*****","D":"Fixed Wing Interceptor","DC":"8","H":"1.X.2.1.1.2.1",},{"ID":"S*A*MFT---*****","D":"Fixed Wing Trainer","DC":"8","H":"1.X.2.1.1.3",},{"ID":"S*A*MFA---*****","D":"Attack/Strike","DC":"8","H":"1.X.2.1.1.4",},{"ID":"S*A*MFL---*****","D":"Fixed Wing V/STOL","DC":"8","H":"1.X.2.1.1.5",},{"ID":"S*A*MFK---*****","D":"Fixed Wing Tanker","DC":"8","H":"1.X.2.1.1.6",},{"ID":"S*A*MFKB--*****","D":"Fixed Wing Tanker Boom-Only","DC":"8","H":"1.X.2.1.1.6.1",},{"ID":"S*A*MFKD--*****","D":"Fixed Wing Tanker Drouge-Only","DC":"8","H":"1.X.2.1.1.6.2",},{"ID":"S*A*MFC---*****","D":"Fixed Wing Cargo Airlift (Transport)","DC":"8","H":"1.X.2.1.1.7",},{"ID":"S*A*MFCL--*****","D":"Fixed Wing Cargo Airlift (Light)","DC":"8","H":"1.X.2.1.1.7.1",},{"ID":"S*A*MFCM--*****","D":"Fixed Wing Cargo Airlift (Medium)","DC":"8","H":"1.X.2.1.1.7.2",},{"ID":"S*A*MFCH--*****","D":"Fixed Wing Cargo Airlift (Heavy)","DC":"8","H":"1.X.2.1.1.7.3",},{"ID":"S*A*MFJ---*****","D":"Fixed Wing ECM/Jammer","DC":"8","H":"1.X.2.1.1.8",},{"ID":"S*A*MFO---*****","D":"Fixed Wing Medical Evacuation MEDEVAC","DC":"8","H":"1.X.2.1.1.9",},{"ID":"S*A*MFR---*****","D":"Fixed Wing Reconnaissance","DC":"8","H":"1.X.2.1.1.10",},{"ID":"S*A*MFRW--*****","D":"Fixed Wing Airborne Early Warning (AEW)","DC":"8","H":"1.X.2.1.1.10.1",},{"ID":"S*A*MFRZ--*****","D":"Fixed Wing Electronic Surveillance Measures","DC":"8","H":"1.X.2.1.1.10.2",},{"ID":"S*A*MFRX--*****","D":"Fixed Wing Photographic","DC":"8","H":"1.X.2.1.1.10.3",},{"ID":"S*A*MFP---*****","D":"Fixed Wing Patrol","DC":"8","H":"1.X.2.1.1.11",},{"ID":"S*A*MFPN--*****","D":"Patrol Antisurface Warfare (ASUW)","DC":"8","H":"1.X.2.1.1.11.1",},{"ID":"S*A*MFPM--*****","D":"Fixed Wing Mine Countermeasures","DC":"8","H":"1.X.2.1.1.11.2",},{"ID":"S*A*MFU---*****","D":"Fixed Wing Utility","DC":"8","H":"1.X.2.1.1.12",},{"ID":"S*A*MFUL--*****","D":"Fixed Wing Utility (Light)","DC":"8","H":"1.X.2.1.1.12.1",},{"ID":"S*A*MFUM--*****","D":"Fixed Wing Utility (Medium)","DC":"8","H":"1.X.2.1.1.12.2",},{"ID":"S*A*MFUH--*****","D":"Fixed Wing Utility (Heavy)","DC":"8","H":"1.X.2.1.1.12.3",},{"ID":"S*A*MFY---*****","D":"Fixed Wing Communications","DC":"8","H":"1.X.2.1.1.13",},{"ID":"S*A*MFH---*****","D":"Fixed Wing Combat Search and Rescue (CSAR)","DC":"8","H":"1.X.2.1.1.14",},{"ID":"S*A*MFD---*****","D":"Fixed Wing Airborne Command Post (C2)","DC":"8","H":"1.X.2.1.1.15",},{"ID":"S*A*MFQ---*****","D":"Drone (RPV/UA) Fixed Wing","DC":"8","H":"1.X.2.1.1.16",},{"ID":"S*A*MFQA--*****","D":"Drone Attack","DC":"8","H":"1.X.2.1.1.16.1",},{"ID":"S*A*MFQB--*****","D":"Drone Bomber","DC":"8","H":"1.X.2.1.1.16.2",},{"ID":"S*A*MFQC--*****","D":"Drone Cargo","DC":"8","H":"1.X.2.1.1.16.3",},{"ID":"S*A*MFQD--*****","D":"Drone (RPV/UA) Airborne Command Post","DC":"8","H":"1.X.2.1.1.16.4",},{"ID":"S*A*MFQF--*****","D":"Drone Fighter","DC":"8","H":"1.X.2.1.1.16.5",},{"ID":"S*A*MFQH--*****","D":"Search & Rescue (CSAR)","DC":"8","H":"1.X.2.1.1.16.6",},{"ID":"S*A*MFQJ--*****","D":"Drone Electronic Countermeasures (Jammer)","DC":"8","H":"1.X.2.1.1.16.7",},{"ID":"S*A*MFQK--*****","D":"Drone Tanker","DC":"8","H":"1.X.2.1.1.16.8",},{"ID":"S*A*MFQL--*****","D":"Drone V/STOL","DC":"8","H":"1.X.2.1.1.16.9",},{"ID":"S*A*MFQM--*****","D":"Drone Special Operations Forces (SOF)","DC":"8","H":"1.X.2.1.1.16.10",},{"ID":"S*A*MFQI--*****","D":"Drone Mine Countermeasures","DC":"8","H":"1.X.2.1.1.16.11",},{"ID":"S*A*MFQN--*****","D":"Drone Antisurface Warfare (ASUW)","DC":"8","H":"1.X.2.1.1.16.12",},{"ID":"S*A*MFQP--*****","D":"Drone Patrol","DC":"8","H":"1.X.2.1.1.16.13",},{"ID":"S*A*MFQR--*****","D":"Drone Reconnaissance","DC":"8","H":"1.X.2.1.1.16.14",},{"ID":"S*A*MFQRW-*****","D":"Drone Airborne Early Warning (AEW)","DC":"8","H":"1.X.2.1.1.16.14.1",},{"ID":"S*A*MFQRZ-*****","D":"Drone Electronic Surveillance Measures","DC":"8","H":"1.X.2.1.1.16.14.2",},{"ID":"S*A*MFQRX-*****","D":"Drone Photographic","DC":"8","H":"1.X.2.1.1.16.14.3",},{"ID":"S*A*MFQS--*****","D":"Drone Antisubmarine Warfare (ASW)","DC":"8","H":"1.X.2.1.1.16.15",},{"ID":"S*A*MFQT--*****","D":"Drone Trainer","DC":"8","H":"1.X.2.1.1.16.16",},{"ID":"S*A*MFQU--*****","D":"Drone Utility Fixed Wing","DC":"8","H":"1.X.2.1.1.16.17",},{"ID":"S*A*MFQY--*****","D":"Drone Communications","DC":"8","H":"1.X.2.1.1.16.18",},{"ID":"S*A*MFQO--*****","D":"Drone Medevac","DC":"8","H":"1.X.2.1.1.16.19",},{"ID":"S*A*MFS---*****","D":"Antisubmarine Warfare (ASW) Carrier Based","DC":"8","H":"1.X.2.1.1.17",},{"ID":"S*A*MFM---*****","D":"Fixed Wing Special Operations Forces (SOF)","DC":"8","H":"1.X.2.1.1.18",},{"ID":"S*A*MH----*****","D":"Rotary Wing","DC":"8","H":"1.X.2.1.2",},{"ID":"S*A*MHA---*****","D":"Rotary Wing Attack","DC":"8","H":"1.X.2.1.2.1",},{"ID":"S*A*MHS---*****","D":"Antisubmarine Warfare/MPA ROTARY WING","DC":"8","H":"1.X.2.1.2.2",},{"ID":"S*A*MHU---*****","D":"Rotary Wing Utility","DC":"8","H":"1.X.2.1.2.3",},{"ID":"S*A*MHUL--*****","D":"Rotary Wing Utility (Light)","DC":"8","H":"1.X.2.1.2.3.1",},{"ID":"S*A*MHUM--*****","D":"Rotary Wing Utility (Medium)","DC":"8","H":"1.X.2.1.2.3.2",},{"ID":"S*A*MHUH--*****","D":"Rotary Wing Utility (Heavy)","DC":"8","H":"1.X.2.1.2.3.3",},{"ID":"S*A*MHI---*****","D":"Rotary Wing Mine Countermeasures","DC":"8","H":"1.X.2.1.2.4",},{"ID":"S*A*MHH---*****","D":"Rotary Wing Combat Search and Rescue(Military)","DC":"8","H":"1.X.2.1.2.5",},{"ID":"S*A*MHR---*****","D":"Rotary Wing Reconnaissance","DC":"8","H":"1.X.2.1.2.6",},{"ID":"S*A*MHQ---*****","D":"Drone (RPV/UAV) Rotary Wing","DC":"8","H":"1.X.2.1.2.7",},{"ID":"S*A*MHC---*****","D":"Rotary Wing Cargo AirLift (Transport)","DC":"8","H":"1.X.2.1.2.8",},{"ID":"S*A*MHCL--*****","D":"Rotary Wing Cargo Airlift (Light)","DC":"8","H":"1.X.2.1.2.8.1",},{"ID":"S*A*MHCM--*****","D":"Rotary Wing Cargo AirLift (Medium)","DC":"8","H":"1.X.2.1.2.8.2",},{"ID":"S*A*MHCH--*****","D":"Rotary Wing Cargo Airlift (Heavy)","DC":"8","H":"1.X.2.1.2.8.3",},{"ID":"S*A*MHT---*****","D":"Rotary Wing Trainer","DC":"8","H":"1.X.2.1.2.9",},{"ID":"S*A*MHO---*****","D":"Rotary Wing MEDEVAC","DC":"8","H":"1.X.2.1.2.10",},{"ID":"S*A*MHM---*****","D":"Rotary Wing Special Operations Forces","DC":"8","H":"1.X.2.1.2.11",},{"ID":"S*A*MHD---*****","D":"Rotary Wing Airborne Command Post","DC":"8","H":"1.X.2.1.2.12",},{"ID":"S*A*MHK---*****","D":"Rotary Wing Tanker","DC":"8","H":"1.X.2.1.2.13",},{"ID":"S*A*MHJ---*****","D":"Rotary Wing ECM/Jammer(TANKER)","DC":"8","H":"1.X.2.1.2.14",},{"ID":"S*A*ML----*****","D":"Military Aircraft Lighter Than Air","DC":"8","H":"1.X.2.1.3",},{"ID":"S*A*MV----*****","D":"VIP","DC":"8","H":"1.X.2.1.4",},{"ID":"S*A*ME----*****","D":"Escort","DC":"8","H":"1.X.2.1.5",},{"ID":"S*A*W-----*****","D":"Air Track Weapon","DC":"8","H":"1.X.2.2",},{"ID":"S*A*WM----*****","D":"Missile In Flight","DC":"8","H":"1.X.2.2.1",},{"ID":"S*A*WMS---*****","D":"Surface Launched Missile","DC":"8","H":"1.X.2.2.1.1",},{"ID":"S*A*WMSS--*****","D":"Surface-to-Surface Missile (SSM)","DC":"8","H":"1.X.2.2.1.1.1",},{"ID":"S*A*WMSA--*****","D":"Surface-to-Air Missile (SAM)","DC":"8","H":"1.X.2.2.1.1.2",},{"ID":"S*A*WMSU--*****","D":"Surface-to-Subsurface Missile","DC":"8","H":"1.X.2.2.1.1.3",},{"ID":"S*A*WMSB--*****","D":"Antiballistic Missile (ABM)","DC":"8","H":"1.X.2.2.1.1.4",},{"ID":"S*A*WMA---*****","D":"Air Launched Missile","DC":"8","H":"1.X.2.2.1.2",},{"ID":"S*A*WMAS--*****","D":"Air-to-Surface Missile (ASM)","DC":"8","H":"1.X.2.2.1.2.1",},{"ID":"S*A*WMAA--*****","D":"Air-to-Air Missile (AAM)","DC":"8","H":"1.X.2.2.1.2.2",},{"ID":"S*A*WMAP--*****","D":"Air-to-Space Missile","DC":"8","H":"1.X.2.2.1.2.3",},{"ID":"S*A*WMU---*****","D":"Subsurface-to-Surface Missile (S/SSM)","DC":"8","H":"1.X.2.2.1.3",},{"ID":"S*A*WMCM--*****","D":"Cruise Missile","DC":"8","H":"1.X.2.2.1.4",},{"ID":"S*A*WMB---*****","D":"Ballistic Missile","DC":"8","H":"1.X.2.2.1.5",},{"ID":"S*A*WD----*****","D":"Decoy","DC":"8","H":"1.X.2.2.2",},{"ID":"S*A*WB----*****","D":"Bomb","DC":"8","H":"1.X.2.2.3",},{"ID":"S*A*C-----*****","D":"Civil Aircraft","DC":"8","H":"1.X.2.3",},{"ID":"S*A*CF----*****","D":"Civil Fixed Wing","DC":"8","H":"1.X.2.3.1",},{"ID":"S*A*CH----*****","D":"Civil Rotary Wing","DC":"8","H":"1.X.2.3.2",},{"ID":"S*A*CL----*****","D":"Civil Aircraft Lighter Than Air","DC":"8","H":"1.X.2.3.3",},{"ID":"S*G*------*****","D":"Ground Track","DC":"8","H":"1.X.3",},{"ID":"S*G*U-----*****","D":"Unit","DC":"8","H":"1.X.3.1",},{"ID":"S*G*UC----*****","D":"Combat","DC":"8","H":"1.X.3.1.1",},{"ID":"S*G*UCD---*****","D":"Air Defense","DC":"8","H":"1.X.3.1.1.1",},{"ID":"S*G*UCDS--*****","D":"Short Range","DC":"8","H":"1.X.3.1.1.1.1",},{"ID":"S*G*UCDSC-*****","D":"Chaparral","DC":"8","H":"1.X.3.1.1.1.1.1",},{"ID":"S*G*UCDSS-*****","D":"Stinger","DC":"8","H":"1.X.3.1.1.1.1.2",},{"ID":"S*G*UCDSV-*****","D":"Vulcan","DC":"8","H":"1.X.3.1.1.1.1.3",},{"ID":"S*G*UCDM--*****","D":"Air Defense Missile","DC":"8","H":"1.X.3.1.1.1.2",},{"ID":"S*G*UCDML-*****","D":"Air Defense Missile Light","DC":"8","H":"1.X.3.1.1.1.2.1",},{"ID":"S*G*UCDMLA*****","D":"Air Defense Missile Motorized (Avenger)","DC":"8","H":"1.X.3.1.1.1.2.1.1",},{"ID":"S*G*UCDMM-*****","D":"Air Defense Missile Medium","DC":"8","H":"1.X.3.1.1.1.2.2",},{"ID":"S*G*UCDMH-*****","D":"Air Defense Missile Heavy","DC":"8","H":"1.X.3.1.1.1.2.3",},{"ID":"S*G*UCDH--*****","D":"H/MAD","DC":"8","H":"1.X.3.1.1.1.2.4",},{"ID":"S*G*UCDHH-*****","D":"Hawk","DC":"8","H":"1.X.3.1.1.1.2.4.1",},{"ID":"S*G*UCDHP-*****","D":"Patriot","DC":"8","H":"1.X.3.1.1.1.2.4.2",},{"ID":"S*G*UCDG--*****","D":"Gun Unit","DC":"8","H":"1.X.3.1.1.1.3",},{"ID":"S*G*UCDC--*****","D":"Air Defense Composite","DC":"8","H":"1.X.3.1.1.1.4",},{"ID":"S*G*UCDT--*****","D":"Targeting Unit","DC":"8","H":"1.X.3.1.1.1.5",},{"ID":"S*G*UCDO--*****","D":"Theater Missile Defense Unit","DC":"8","H":"1.X.3.1.1.1.6",},{"ID":"S*G*UCA---*****","D":"Armor","DC":"8","H":"1.X.3.1.1.2",},{"ID":"S*G*UCAT--*****","D":"Armor Track","DC":"8","H":"1.X.3.1.1.2.1",},{"ID":"S*G*UCATA-*****","D":"Armor Track Airborne","DC":"8","H":"1.X.3.1.1.2.1.1",},{"ID":"S*G*UCATW-*****","D":"Armor Track Amphibious","DC":"8","H":"1.X.3.1.1.2.1.2",},{"ID":"S*G*UCATWR*****","D":"Armor Track Amphibious Recovery","DC":"8","H":"1.X.3.1.1.2.1.2.1",},{"ID":"S*G*UCATL-*****","D":"Armor Track, Light","DC":"8","H":"1.X.3.1.1.2.1.3",},{"ID":"S*G*UCATM-*****","D":"Armor Track, Medium","DC":"8","H":"1.X.3.1.1.2.1.4",},{"ID":"S*G*UCATH-*****","D":"Armor Track, Heavy","DC":"8","H":"1.X.3.1.1.2.1.5",},{"ID":"S*G*UCATR-*****","D":"Armor Track, Recovery","DC":"8","H":"1.X.3.1.1.2.1.6",},{"ID":"S*G*UCAW--*****","D":"Armor, Wheeled","DC":"8","H":"1.X.3.1.1.2.2",},{"ID":"S*G*UCAWS-*****","D":"Armor, Wheeled Air Assault","DC":"8","H":"1.X.3.1.1.2.2.1",},{"ID":"S*G*UCAWA-*****","D":"Armor, Wheeled Airborne","DC":"8","H":"1.X.3.1.1.2.2.2",},{"ID":"S*G*UCAWW-*****","D":"Armor, Wheeled Amphibious","DC":"8","H":"1.X.3.1.1.2.2.3",},{"ID":"S*G*UCAWWR*****","D":"Armor, Wheeled Amphibious Recovery","DC":"8","H":"1.X.3.1.1.2.2.3.1",},{"ID":"S*G*UCAWL-*****","D":"Armor, Wheeled Light","DC":"8","H":"1.X.3.1.1.2.2.4",},{"ID":"S*G*UCAWM-*****","D":"Armor, Wheeled Medium","DC":"8","H":"1.X.3.1.1.2.2.5",},{"ID":"S*G*UCAWH-*****","D":"Armor, Wheeled Heavy","DC":"8","H":"1.X.3.1.1.2.2.6",},{"ID":"S*G*UCAWR-*****","D":"Armor, Wheeled Recovery","DC":"8","H":"1.X.3.1.1.2.2.7",},{"ID":"S*G*UCAA--*****","D":"Anti Armor","DC":"8","H":"1.X.3.1.1.3",},{"ID":"S*G*UCAAD-*****","D":"Anti Armor Dismounted","DC":"8","H":"1.X.3.1.1.3.1",},{"ID":"S*G*UCAAL-*****","D":"Anti Armor Light","DC":"8","H":"1.X.3.1.1.3.2",},{"ID":"S*G*UCAAM-*****","D":"Anti Armor Airborne","DC":"8","H":"1.X.3.1.1.3.3",},{"ID":"S*G*UCAAS-*****","D":"Anti Armor Air Assault","DC":"8","H":"1.X.3.1.1.3.4",},{"ID":"S*G*UCAAU-*****","D":"Anti Armor Mountain","DC":"8","H":"1.X.3.1.1.3.5",},{"ID":"S*G*UCAAC-*****","D":"Anti Armor Arctic","DC":"8","H":"1.X.3.1.1.3.6",},{"ID":"S*G*UCAAA-*****","D":"Anti Armor Armored","DC":"8","H":"1.X.3.1.1.3.7",},{"ID":"S*G*UCAAAT*****","D":"Anti Armor Armored Tracked","DC":"8","H":"1.X.3.1.1.3.7.1",},{"ID":"S*G*UCAAAW*****","D":"Anti Armor Armored Wheeled","DC":"8","H":"1.X.3.1.1.3.7.2",},{"ID":"S*G*UCAAAS*****","D":"Anti Armor Armored Air Assault","DC":"8","H":"1.X.3.1.1.3.7.3",},{"ID":"S*G*UCAAO-*****","D":"Anti Armor Motorized","DC":"8","H":"1.X.3.1.1.3.8",},{"ID":"S*G*UCAAOS*****","D":"Anti Armor Motorized Air Assault","DC":"8","H":"1.X.3.1.1.3.8.1",},{"ID":"S*G*UCV---*****","D":"Aviation","DC":"8","H":"1.X.3.1.1.4",},{"ID":"S*G*UCVF--*****","D":"Aviation Fixed Wing","DC":"8","H":"1.X.3.1.1.4.1",},{"ID":"S*G*UCVFU-*****","D":"Utility Fixed Wing","DC":"8","H":"1.X.3.1.1.4.1.1",},{"ID":"S*G*UCVFA-*****","D":"Fixed Wing Attack","DC":"8","H":"1.X.3.1.1.4.1.2",},{"ID":"S*G*UCVFR-*****","D":"Recon Fixed Wing","DC":"8","H":"1.X.3.1.1.4.1.3",},{"ID":"S*G*UCVR--*****","D":"Aviation Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2",},{"ID":"S*G*UCVRA-*****","D":"Attack Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.1",},{"ID":"S*G*UCVRS-*****","D":"Scout Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.2",},{"ID":"S*G*UCVRW-*****","D":"Antisubmarine Warfare Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.3",},{"ID":"S*G*UCVRU-*****","D":"Utility Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.4",},{"ID":"S*G*UCVRUL*****","D":"Light Utility Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.4.1",},{"ID":"S*G*UCVRUM*****","D":"Medium Utility Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.4.2",},{"ID":"S*G*UCVRUH*****","D":"Heavy Utility Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.4.3",},{"ID":"S*G*UCVRUC*****","D":"C2 Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.5",},{"ID":"S*G*UCVRUE*****","D":"Medevac Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.6",},{"ID":"S*G*UCVRM-*****","D":"Mine Countermeasure Rotary Wing","DC":"8","H":"1.X.3.1.1.4.2.7",},{"ID":"S*G*UCVS--*****","D":"Search and Rescue","DC":"8","H":"1.X.3.1.1.4.3",},{"ID":"S*G*UCVC--*****","D":"Aviation Composite","DC":"8","H":"1.X.3.1.1.4.4",},{"ID":"S*G*UCVV--*****","D":"Vertical and/or Short Takeoff and Landing Aircraft (V/STOL)","DC":"8","H":"1.X.3.1.1.4.5",},{"ID":"S*G*UCVU--*****","D":"Unmanned Aerial","DC":"8","H":"1.X.3.1.1.4.6",},{"ID":"S*G*UCVUF-*****","D":"Unmanned Aerial Fixed Wing","DC":"8","H":"1.X.3.1.1.4.6.1",},{"ID":"S*G*UCVUR-*****","D":"Unmanned Aerial Rotary Wing","DC":"8","H":"1.X.3.1.1.4.6.2",},{"ID":"S*G*UCI---*****","D":"Infantry","DC":"8","H":"1.X.3.1.1.5",},{"ID":"S*G*UCIL--*****","D":"Infantry Light","DC":"8","H":"1.X.3.1.1.5.1",},{"ID":"S*G*UCIM--*****","D":"Infantry Motorized","DC":"8","H":"1.X.3.1.1.5.2",},{"ID":"S*G*UCIO--*****","D":"Infantry Mountain","DC":"8","H":"1.X.3.1.1.5.3",},{"ID":"S*G*UCIA--*****","D":"Infantry Airborne","DC":"8","H":"1.X.3.1.1.5.4",},{"ID":"S*G*UCIS--*****","D":"Infantry Air Assault","DC":"8","H":"1.X.3.1.1.5.5",},{"ID":"S*G*UCIZ--*****","D":"Infantry Mechanized","DC":"8","H":"1.X.3.1.1.5.6",},{"ID":"S*G*UCIN--*****","D":"Infantry Naval","DC":"8","H":"1.X.3.1.1.5.7",},{"ID":"S*G*UCII--*****","D":"Infantry Fighting Vehicle","DC":"8","H":"1.X.3.1.1.5.8",},{"ID":"S*G*UCIC--*****","D":"Infantry Arctic","DC":"8","H":"1.X.3.1.1.5.9",},{"ID":"S*G*UCE---*****","D":"Engineer","DC":"8","H":"1.X.3.1.1.6",},{"ID":"S*G*UCEC--*****","D":"Engineer Combat","DC":"8","H":"1.X.3.1.1.6.1",},{"ID":"S*G*UCECS-*****","D":"Engineer Combat Air Assault","DC":"8","H":"1.X.3.1.1.6.1.1",},{"ID":"S*G*UCECA-*****","D":"Engineer Combat Airborne","DC":"8","H":"1.X.3.1.1.6.1.2",},{"ID":"S*G*UCECC-*****","D":"Engineer Combat Arctic","DC":"8","H":"1.X.3.1.1.6.1.3",},{"ID":"S*G*UCECL-*****","D":"Engineer Combat Light (Sapper)","DC":"8","H":"1.X.3.1.1.6.1.4",},{"ID":"S*G*UCECM-*****","D":"Engineer Combat Medium","DC":"8","H":"1.X.3.1.1.6.1.5",},{"ID":"S*G*UCECH-*****","D":"Engineer Combat Heavy","DC":"8","H":"1.X.3.1.1.6.1.6",},{"ID":"S*G*UCECT-*****","D":"Engineer Combat Mechanized (Track)","DC":"8","H":"1.X.3.1.1.6.1.7",},{"ID":"S*G*UCECW-*****","D":"Engineer Combat Motorized","DC":"8","H":"1.X.3.1.1.6.1.8",},{"ID":"S*G*UCECO-*****","D":"Engineer Combat Mountain","DC":"8","H":"1.X.3.1.1.6.1.9",},{"ID":"S*G*UCECR-*****","D":"Engineer Combat Recon","DC":"8","H":"1.X.3.1.1.6.1.10",},{"ID":"S*G*UCEN--*****","D":"Engineer Construction","DC":"8","H":"1.X.3.1.1.6.2",},{"ID":"S*G*UCENN-*****","D":"Engineer Naval Construction","DC":"8","H":"1.X.3.1.1.6.2.1",},{"ID":"S*G*UCF---*****","D":"Field Artillery","DC":"8","H":"1.X.3.1.1.7",},{"ID":"S*G*UCFH--*****","D":"Howitzer/Gun","DC":"8","H":"1.X.3.1.1.7.1",},{"ID":"S*G*UCFHE-*****","D":"Self-Propelled","DC":"8","H":"1.X.3.1.1.7.1.1",},{"ID":"S*G*UCFHS-*****","D":"Howitzer/Gun Air Assault","DC":"8","H":"1.X.3.1.1.7.1.2",},{"ID":"S*G*UCFHA-*****","D":"Howitzer/Gun Airborne","DC":"8","H":"1.X.3.1.1.7.1.3",},{"ID":"S*G*UCFHC-*****","D":"Arctic","DC":"8","H":"1.X.3.1.1.7.1.4",},{"ID":"S*G*UCFHO-*****","D":"Howitzer/Gun Mountain","DC":"8","H":"1.X.3.1.1.7.1.5",},{"ID":"S*G*UCFHL-*****","D":"Howitzer/Gun Light","DC":"8","H":"1.X.3.1.1.7.1.6",},{"ID":"S*G*UCFHM-*****","D":"Howitzer/Gun Medium","DC":"8","H":"1.X.3.1.1.7.1.7",},{"ID":"S*G*UCFHH-*****","D":"Heavy","DC":"8","H":"1.X.3.1.1.7.1.8",},{"ID":"S*G*UCFHX-*****","D":"Amphibious","DC":"8","H":"1.X.3.1.1.7.1.9",},{"ID":"S*G*UCFR--*****","D":"Rocket","DC":"8","H":"1.X.3.1.1.7.2",},{"ID":"S*G*UCFRS-*****","D":"Rocket Single Rocket Launcher","DC":"8","H":"1.X.3.1.1.7.2.1",},{"ID":"S*G*UCFRSS*****","D":"Single Rocket Self-Propelled","DC":"8","H":"1.X.3.1.1.7.2.1.1",},{"ID":"S*G*UCFRSR*****","D":"Single Rocket Truck","DC":"8","H":"1.X.3.1.1.7.2.1.2",},{"ID":"S*G*UCFRST*****","D":"Single Rocket Towed","DC":"8","H":"1.X.3.1.1.7.2.1.3",},{"ID":"S*G*UCFRM-*****","D":"Multiple Rocket Launcher (Field Artillary)","DC":"8","H":"1.X.3.1.1.7.2.2",},{"ID":"S*G*UCFRMS*****","D":"Multiple Rocket Self-Propelled","DC":"8","H":"1.X.3.1.1.7.2.2.1",},{"ID":"S*G*UCFRMR*****","D":"Multiple Rocket Truck","DC":"8","H":"1.X.3.1.1.7.2.2.2",},{"ID":"S*G*UCFRMT*****","D":"Multiple Rocket Towed","DC":"8","H":"1.X.3.1.1.7.2.2.3",},{"ID":"S*G*UCFT--*****","D":"Target Acquisition","DC":"8","H":"1.X.3.1.1.7.3",},{"ID":"S*G*UCFTR-*****","D":"Target Acquisition Radar","DC":"8","H":"1.X.3.1.1.7.3.1",},{"ID":"S*G*UCFTS-*****","D":"Sound","DC":"8","H":"1.X.3.1.1.7.3.2",},{"ID":"S*G*UCFTF-*****","D":"Flash (Optical)","DC":"8","H":"1.X.3.1.1.7.3.3",},{"ID":"S*G*UCFTC-*****","D":"Colt/Fist","DC":"8","H":"1.X.3.1.1.7.3.4",},{"ID":"S*G*UCFTCD*****","D":"Dismounted Colt/Fist","DC":"8","H":"1.X.3.1.1.7.3.4.1",},{"ID":"S*G*UCFTCM*****","D":"Tracked Colt/Fist","DC":"8","H":"1.X.3.1.1.7.3.4.2",},{"ID":"S*G*UCFTA-*****","D":"Anglico","DC":"8","H":"1.X.3.1.1.7.3.5",},{"ID":"S*G*UCFM--*****","D":"Field Artillery Mortar","DC":"8","H":"1.X.3.1.1.7.4",},{"ID":"S*G*UCFMS-*****","D":"Self-Propelled (SP) Tracked Mortar","DC":"8","H":"1.X.3.1.1.7.4.1",},{"ID":"S*G*UCFMW-*****","D":"SP Wheeled Mortar","DC":"8","H":"1.X.3.1.1.7.4.2",},{"ID":"S*G*UCFMT-*****","D":"Towed Mortar","DC":"8","H":"1.X.3.1.1.7.4.3",},{"ID":"S*G*UCFMTA*****","D":"Towed Airborne Mortar","DC":"8","H":"1.X.3.1.1.7.4.3.1",},{"ID":"S*G*UCFMTS*****","D":"Towed Air Assault Mortar","DC":"8","H":"1.X.3.1.1.7.4.3.2",},{"ID":"S*G*UCFMTC*****","D":"Towed Arctic Mortar","DC":"8","H":"1.X.3.1.1.7.4.3.3",},{"ID":"S*G*UCFMTO*****","D":"Towed Mountain Mortar","DC":"8","H":"1.X.3.1.1.7.4.3.4",},{"ID":"S*G*UCFML-*****","D":"Amphibious Mortar","DC":"8","H":"1.X.3.1.1.7.4.4",},{"ID":"S*G*UCFS--*****","D":"Artillery Survey","DC":"8","H":"1.X.3.1.1.7.5",},{"ID":"S*G*UCFSS-*****","D":"Artillery Survey Air Assault","DC":"8","H":"1.X.3.1.1.7.5.1",},{"ID":"S*G*UCFSA-*****","D":"Artillery Survey Airborne","DC":"8","H":"1.X.3.1.1.7.5.2",},{"ID":"S*G*UCFSL-*****","D":"Artillery Survey Light","DC":"8","H":"1.X.3.1.1.7.5.3",},{"ID":"S*G*UCFSO-*****","D":"Artillery Survey Mountain","DC":"8","H":"1.X.3.1.1.7.5.4",},{"ID":"S*G*UCFO--*****","D":"Field Artillery Meteorological","DC":"8","H":"1.X.3.1.1.7.6",},{"ID":"S*G*UCFOS-*****","D":"Air Assault Meteorological","DC":"8","H":"1.X.3.1.1.7.6.1",},{"ID":"S*G*UCFOA-*****","D":"Airborne Meteorological","DC":"8","H":"1.X.3.1.1.7.6.2",},{"ID":"S*G*UCFOL-*****","D":"Light Meteorological","DC":"8","H":"1.X.3.1.1.7.6.3",},{"ID":"S*G*UCFOO-*****","D":"Mountain Meteorological","DC":"8","H":"1.X.3.1.1.7.6.4",},{"ID":"S*G*UCR---*****","D":"Combat Reconnaissance","DC":"8","H":"1.X.3.1.1.8",},{"ID":"S*G*UCRH--*****","D":"Reconnaissance Horse","DC":"8","H":"1.X.3.1.1.8.1",},{"ID":"S*G*UCRV--*****","D":"Reconnaissance Cavalry","DC":"8","H":"1.X.3.1.1.8.2",},{"ID":"S*G*UCRVA-*****","D":"Reconnaissance Cavalry Armored","DC":"8","H":"1.X.3.1.1.8.2.1",},{"ID":"S*G*UCRVM-*****","D":"Reconnaissance Cavalry Motorized","DC":"8","H":"1.X.3.1.1.8.2.2",},{"ID":"S*G*UCRVG-*****","D":"Reconnaissance Cavalry Ground","DC":"8","H":"1.X.3.1.1.8.2.3",},{"ID":"S*G*UCRVO-*****","D":"Reconnaissance Cavalry Air","DC":"8","H":"1.X.3.1.1.8.2.4",},{"ID":"S*G*UCRC--*****","D":"Reconnaissance Arctic","DC":"8","H":"1.X.3.1.1.8.3",},{"ID":"S*G*UCRS--*****","D":"Reconnaissance Air Assault","DC":"8","H":"1.X.3.1.1.8.4",},{"ID":"S*G*UCRA--*****","D":"Reconnaissance Airborne","DC":"8","H":"1.X.3.1.1.8.5",},{"ID":"S*G*UCRO--*****","D":"Reconnaissance Mountain","DC":"8","H":"1.X.3.1.1.8.6",},{"ID":"S*G*UCRL--*****","D":"Reconnaissance Light","DC":"8","H":"1.X.3.1.1.8.7",},{"ID":"S*G*UCRR--*****","D":"Reconnaissance Marine","DC":"8","H":"1.X.3.1.1.8.8",},{"ID":"S*G*UCRRD-*****","D":"Reconnaissance Marine Division","DC":"8","H":"1.X.3.1.1.8.8.1",},{"ID":"S*G*UCRRF-*****","D":"Reconnaissance Marine Force","DC":"8","H":"1.X.3.1.1.8.8.2",},{"ID":"S*G*UCRRL-*****","D":"Reconnaissance Marine Light Armored (LAR)","DC":"8","H":"1.X.3.1.1.8.8.3",},{"ID":"S*G*UCRX--*****","D":"Reconnaissance Long Range Surveillance (LRS)","DC":"8","H":"1.X.3.1.1.8.9",},{"ID":"S*G*UCM---*****","D":"Missile (Surf-Surf)","DC":"8","H":"1.X.3.1.1.9",},{"ID":"S*G*UCMT--*****","D":"Missile (Surf-Surf) Tactical","DC":"8","H":"1.X.3.1.1.9.1",},{"ID":"S*G*UCMS--*****","D":"Missile (Surf-Surf) Strategic","DC":"8","H":"1.X.3.1.1.9.2",},{"ID":"S*G*UCS---*****","D":"Internal Security Forces","DC":"8","H":"1.X.3.1.1.10",},{"ID":"S*G*UCSW--*****","D":"Internal Security Forces Riverine","DC":"8","H":"1.X.3.1.1.10.1",},{"ID":"S*G*UCSG--*****","D":"Internal Security Forces Ground","DC":"8","H":"1.X.3.1.1.10.2",},{"ID":"S*G*UCSGD-*****","D":"Internal Security Forces Dismounted","DC":"8","H":"1.X.3.1.1.10.2.1",},{"ID":"S*G*UCSGM-*****","D":"Internal Security Forces Motorized","DC":"8","H":"1.X.3.1.1.10.2.2",},{"ID":"S*G*UCSGA-*****","D":"Internal Security Forces Mechanized","DC":"8","H":"1.X.3.1.1.10.2.3",},{"ID":"S*G*UCSM--*****","D":"Internal Security Forces Wheeled Mechanized","DC":"8","H":"1.X.3.1.1.10.3",},{"ID":"S*G*UCSR--*****","D":"Internal Security Forces Railroad","DC":"8","H":"1.X.3.1.1.10.4",},{"ID":"S*G*UCSA--*****","D":"Internal Security Forces Aviation","DC":"8","H":"1.X.3.1.1.10.5",},{"ID":"S*G*UCL---*****","D":"Surveillance Unit","DC":"8","H":"1.X.3.1.1.11",},{"ID":"S*G*UU----*****","D":"Combat Support","DC":"8","H":"1.X.3.1.2",},{"ID":"S*G*UUA---*****","D":"Combat Support CBRN","DC":"8","H":"1.X.3.1.2.1",},{"ID":"S*G*UUAC--*****","D":"Combat Support Chemical","DC":"8","H":"1.X.3.1.2.1.1",},{"ID":"S*G*UUACC-*****","D":"Smoke/Decon","DC":"8","H":"1.X.3.1.2.1.1.1",},{"ID":"S*G*UUACCK*****","D":"Mechanized Smoke/Decon","DC":"8","H":"1.X.3.1.2.1.1.1.1",},{"ID":"S*G*UUACCM*****","D":"Motorized Smoke/Decon","DC":"8","H":"1.X.3.1.2.1.1.1.2",},{"ID":"S*G*UUACS-*****","D":"Smoke","DC":"8","H":"1.X.3.1.2.1.1.2",},{"ID":"S*G*UUACSM*****","D":"Motorized Smoke","DC":"8","H":"1.X.3.1.2.1.1.2.1",},{"ID":"S*G*UUACSA*****","D":"Armor Smoke","DC":"8","H":"1.X.3.1.2.1.1.2.2",},{"ID":"S*G*UUACR-*****","D":"Chemical Recon","DC":"8","H":"1.X.3.1.2.1.1.3",},{"ID":"S*G*UUACRW*****","D":"Chemical Wheeled Armored Vehicle","DC":"8","H":"1.X.3.1.2.1.1.3.1",},{"ID":"S*G*UUACRS*****","D":"Chemical Wheeled Armored Vehicle Reconnaissance Surveillance","DC":"8","H":"1.X.3.1.2.1.1.3.2",},{"ID":"S*G*UUAN--*****","D":"Combat Support CBRN Nuclear","DC":"8","H":"1.X.3.1.2.1.2",},{"ID":"S*G*UUAB--*****","D":"Combat Support CBRN Biological","DC":"8","H":"1.X.3.1.2.1.3",},{"ID":"S*G*UUABR-*****","D":"Recon Equipped","DC":"8","H":"1.X.3.1.2.1.3.1",},{"ID":"S*G*UUAD--*****","D":"CBRN Decontamination","DC":"8","H":"1.X.3.1.2.1.4",},{"ID":"S*G*UUM---*****","D":"Military Intelligence","DC":"8","H":"1.X.3.1.2.2",},{"ID":"S*G*UUMA--*****","D":"Aerial Exploitation","DC":"8","H":"1.X.3.1.2.2.1",},{"ID":"S*G*UUMS--*****","D":"Signal Intelligence (SIGINT)","DC":"8","H":"1.X.3.1.2.2.2",},{"ID":"S*G*UUMSE-*****","D":"Electronic Warfare","DC":"8","H":"1.X.3.1.2.2.2.1",},{"ID":"S*G*UUMSEA*****","D":"Armored Wheeled Vehicle","DC":"8","H":"1.X.3.1.2.2.2.1.1",},{"ID":"S*G*UUMSED*****","D":"Direction Finding","DC":"8","H":"1.X.3.1.2.2.2.1.2",},{"ID":"S*G*UUMSEI*****","D":"Intercept","DC":"8","H":"1.X.3.1.2.2.2.1.3",},{"ID":"S*G*UUMSEJ*****","D":"Jamming","DC":"8","H":"1.X.3.1.2.2.2.1.4",},{"ID":"S*G*UUMSET*****","D":"Theater","DC":"8","H":"1.X.3.1.2.2.2.1.5",},{"ID":"S*G*UUMSEC*****","D":"Corps","DC":"8","H":"1.X.3.1.2.2.2.1.6",},{"ID":"S*G*UUMC--*****","D":"Counter Intelligence","DC":"8","H":"1.X.3.1.2.2.3",},{"ID":"S*G*UUMR--*****","D":"Counter Intelligence Surveillance","DC":"8","H":"1.X.3.1.2.2.4",},{"ID":"S*G*UUMRG-*****","D":"Ground Surveillance Radar","DC":"8","H":"1.X.3.1.2.2.4.1",},{"ID":"S*G*UUMRS-*****","D":"Surveillance Sensor","DC":"8","H":"1.X.3.1.2.2.4.2",},{"ID":"S*G*UUMRSS*****","D":"Sensor SCM","DC":"8","H":"1.X.3.1.2.2.4.2.1",},{"ID":"S*G*UUMRX-*****","D":"Ground Station Module","DC":"8","H":"1.X.3.1.2.2.4.3",},{"ID":"S*G*UUMMO-*****","D":"Surveillance Meteorological","DC":"8","H":"1.X.3.1.2.2.4.4",},{"ID":"S*G*UUMO--*****","D":"Military Intelligence Operations","DC":"8","H":"1.X.3.1.2.2.5",},{"ID":"S*G*UUMT--*****","D":"Tactical Exploit","DC":"8","H":"1.X.3.1.2.2.6",},{"ID":"S*G*UUMQ--*****","D":"Interrogation","DC":"8","H":"1.X.3.1.2.2.7",},{"ID":"S*G*UUMJ--*****","D":"Joint Intelligence Center","DC":"8","H":"1.X.3.1.2.2.8",},{"ID":"S*G*UUL---*****","D":"Law Enforcement Unit","DC":"8","H":"1.X.3.1.2.3",},{"ID":"S*G*UULS--*****","D":"Shore Patrol","DC":"8","H":"1.X.3.1.2.3.1",},{"ID":"S*G*UULM--*****","D":"Military Police","DC":"8","H":"1.X.3.1.2.3.2",},{"ID":"S*G*UULC--*****","D":"Civilian Law Enforcement","DC":"8","H":"1.X.3.1.2.3.3",},{"ID":"S*G*UULF--*****","D":"Security Police (Air)","DC":"8","H":"1.X.3.1.2.3.4",},{"ID":"S*G*UULD--*****","D":"Central Intelligence Division (CID)","DC":"8","H":"1.X.3.1.2.3.5",},{"ID":"S*G*UUS---*****","D":"Signal Unit","DC":"8","H":"1.X.3.1.2.4",},{"ID":"S*G*UUSA--*****","D":"Area","DC":"8","H":"1.X.3.1.2.4.1",},{"ID":"S*G*UUSC--*****","D":"Communication Configured Package","DC":"8","H":"1.X.3.1.2.4.2",},{"ID":"S*G*UUSCL-*****","D":"Large Communication Configured Package (LCCP)","DC":"8","H":"1.X.3.1.2.4.2.1",},{"ID":"S*G*UUSO--*****","D":"Command Operations","DC":"8","H":"1.X.3.1.2.4.3",},{"ID":"S*G*UUSF--*****","D":"Forward Communications","DC":"8","H":"1.X.3.1.2.4.4",},{"ID":"S*G*UUSM--*****","D":"Multiple Subscriber Element","DC":"8","H":"1.X.3.1.2.4.5",},{"ID":"S*G*UUSMS-*****","D":"Small Extension Node","DC":"8","H":"1.X.3.1.2.4.5.1",},{"ID":"S*G*UUSML-*****","D":"Large Extension Node","DC":"8","H":"1.X.3.1.2.4.5.2",},{"ID":"S*G*UUSMN-*****","D":"Node Center","DC":"8","H":"1.X.3.1.2.4.5.3",},{"ID":"S*G*UUSR--*****","D":"Radio Unit","DC":"8","H":"1.X.3.1.2.4.6",},{"ID":"S*G*UUSRS-*****","D":"Tactical Satellite","DC":"8","H":"1.X.3.1.2.4.6.1",},{"ID":"S*G*UUSRT-*****","D":"Teletype Center","DC":"8","H":"1.X.3.1.2.4.6.2",},{"ID":"S*G*UUSRW-*****","D":"Relay","DC":"8","H":"1.X.3.1.2.4.6.3",},{"ID":"S*G*UUSS--*****","D":"Signal Support","DC":"8","H":"1.X.3.1.2.4.7",},{"ID":"S*G*UUSW--*****","D":"Telephone Switch","DC":"8","H":"1.X.3.1.2.4.8",},{"ID":"S*G*UUSX--*****","D":"Electronic Ranging","DC":"8","H":"1.X.3.1.2.4.9",},{"ID":"S*G*UUI---*****","D":"Information Warfare Unit","DC":"8","H":"1.X.3.1.2.5",},{"ID":"S*G*UUP---*****","D":"Landing Support","DC":"8","H":"1.X.3.1.2.6",},{"ID":"S*G*UUE---*****","D":"Explosive Ordnance Disposal","DC":"8","H":"1.X.3.1.2.7",},{"ID":"S*G*US----*****","D":"Combat Service Support","DC":"8","H":"1.X.3.1.3",},{"ID":"S*G*USA---*****","D":"Administrative (ADMIN)","DC":"8","H":"1.X.3.1.3.1",},{"ID":"S*G*USAT--*****","D":"Admin Theater","DC":"8","H":"1.X.3.1.3.1.1",},{"ID":"S*G*USAC--*****","D":"Admin Corps","DC":"8","H":"1.X.3.1.3.1.2",},{"ID":"S*G*USAJ--*****","D":"Judge Advocate General (JAG)","DC":"8","H":"1.X.3.1.3.1.3",},{"ID":"S*G*USAJT-*****","D":"JAG Theater","DC":"8","H":"1.X.3.1.3.1.3.1",},{"ID":"S*G*USAJC-*****","D":"JAG Corps","DC":"8","H":"1.X.3.1.3.1.3.2",},{"ID":"S*G*USAO--*****","D":"Postal","DC":"8","H":"1.X.3.1.3.1.4",},{"ID":"S*G*USAOT-*****","D":"Postal Theater","DC":"8","H":"1.X.3.1.3.1.4.1",},{"ID":"S*G*USAOC-*****","D":"Postal Corps","DC":"8","H":"1.X.3.1.3.1.4.2",},{"ID":"S*G*USAF--*****","D":"Finance","DC":"8","H":"1.X.3.1.3.1.5",},{"ID":"S*G*USAFT-*****","D":"Finance Theater","DC":"8","H":"1.X.3.1.3.1.5.1",},{"ID":"S*G*USAFC-*****","D":"Finance Corps","DC":"8","H":"1.X.3.1.3.1.5.2",},{"ID":"S*G*USAS--*****","D":"Personnel Services","DC":"8","H":"1.X.3.1.3.1.6",},{"ID":"S*G*USAST-*****","D":"Personnel Theater","DC":"8","H":"1.X.3.1.3.1.6.1",},{"ID":"S*G*USASC-*****","D":"Personnel Corps","DC":"8","H":"1.X.3.1.3.1.6.2",},{"ID":"S*G*USAM--*****","D":"Mortuary/Graves Registry","DC":"8","H":"1.X.3.1.3.1.7",},{"ID":"S*G*USAMT-*****","D":"Mortuary/Graves Registry Theater","DC":"8","H":"1.X.3.1.3.1.7.1",},{"ID":"S*G*USAMC-*****","D":"Mortuary/Graves Registry Corps","DC":"8","H":"1.X.3.1.3.1.7.2",},{"ID":"S*G*USAR--*****","D":"Religious/Chaplain","DC":"8","H":"1.X.3.1.3.1.8",},{"ID":"S*G*USART-*****","D":"Religious/Chaplain Theater","DC":"8","H":"1.X.3.1.3.1.8.1",},{"ID":"S*G*USARC-*****","D":"Religious/Chaplain Corps","DC":"8","H":"1.X.3.1.3.1.8.2",},{"ID":"S*G*USAP--*****","D":"Public Affairs","DC":"8","H":"1.X.3.1.3.1.9",},{"ID":"S*G*USAPT-*****","D":"Public Affairs Theater","DC":"8","H":"1.X.3.1.3.1.9.1",},{"ID":"S*G*USAPC-*****","D":"Public Affairs Corps","DC":"8","H":"1.X.3.1.3.1.9.2",},{"ID":"S*G*USAPB-*****","D":"Public Affairs Broadcast","DC":"8","H":"1.X.3.1.3.1.9.3",},{"ID":"S*G*USAPBT*****","D":"Public Affairs Broadcast Theater","DC":"8","H":"1.X.3.1.3.1.9.3.1",},{"ID":"S*G*USAPBC*****","D":"Public Affairs Broadcast Corps","DC":"8","H":"1.X.3.1.3.1.9.3.2",},{"ID":"S*G*USAPM-*****","D":"Public Affairs Joint Information Bureau (JIB)","DC":"8","H":"1.X.3.1.3.1.9.4",},{"ID":"S*G*USAPMT*****","D":"Public Affairs JIB Theater","DC":"8","H":"1.X.3.1.3.1.9.4.1",},{"ID":"S*G*USAPMC*****","D":"Public Affairs JIB Corps","DC":"8","H":"1.X.3.1.3.1.9.4.2",},{"ID":"S*G*USAX--*****","D":"Replacement Holding Unit (RHU)","DC":"8","H":"1.X.3.1.3.1.10",},{"ID":"S*G*USAXT-*****","D":"RHU Theater","DC":"8","H":"1.X.3.1.3.1.10.1",},{"ID":"S*G*USAXC-*****","D":"RHU Corps","DC":"8","H":"1.X.3.1.3.1.10.2",},{"ID":"S*G*USAL--*****","D":"Labor","DC":"8","H":"1.X.3.1.3.1.11",},{"ID":"S*G*USALT-*****","D":"Labor Theater","DC":"8","H":"1.X.3.1.3.1.11.1",},{"ID":"S*G*USALC-*****","D":"Labor Corps","DC":"8","H":"1.X.3.1.3.1.11.2",},{"ID":"S*G*USAW--*****","D":"Morale, Welfare, Recreation (MWR)","DC":"8","H":"1.X.3.1.3.1.12",},{"ID":"S*G*USAWT-*****","D":"MWR Theater","DC":"8","H":"1.X.3.1.3.1.12.1",},{"ID":"S*G*USAWC-*****","D":"MWR Corps","DC":"8","H":"1.X.3.1.3.1.12.2",},{"ID":"S*G*USAQ--*****","D":"Quartermaster (Supply)","DC":"8","H":"1.X.3.1.3.1.13",},{"ID":"S*G*USAQT-*****","D":"Quartermaster (Supply) Theater","DC":"8","H":"1.X.3.1.3.1.13.1",},{"ID":"S*G*USAQC-*****","D":"Quartermaster (Supply) Corps","DC":"8","H":"1.X.3.1.3.1.13.2",},{"ID":"S*G*USM---*****","D":"Medical","DC":"8","H":"1.X.3.1.3.2",},{"ID":"S*G*USMT--*****","D":"Medical Theater","DC":"8","H":"1.X.3.1.3.2.1",},{"ID":"S*G*USMC--*****","D":"Medical Corps","DC":"8","H":"1.X.3.1.3.2.2",},{"ID":"S*G*USMM--*****","D":"Medical Treatment Facility","DC":"8","H":"1.X.3.1.3.2.3",},{"ID":"S*G*USMMT-*****","D":"Medical Treatment Facility Theater","DC":"8","H":"1.X.3.1.3.2.3.1",},{"ID":"S*G*USMMC-*****","D":"Medical Treatment Facility Corps","DC":"8","H":"1.X.3.1.3.2.3.2",},{"ID":"S*G*USMV--*****","D":"Medical Veterinary","DC":"8","H":"1.X.3.1.3.2.4",},{"ID":"S*G*USMVT-*****","D":"Medical Veterinary Theater","DC":"8","H":"1.X.3.1.3.2.4.1",},{"ID":"S*G*USMVC-*****","D":"Medical Veterinary Corps","DC":"8","H":"1.X.3.1.3.2.4.2",},{"ID":"S*G*USMD--*****","D":"Medical Dental","DC":"8","H":"1.X.3.1.3.2.5",},{"ID":"S*G*USMDT-*****","D":"Medical Dental Theater","DC":"8","H":"1.X.3.1.3.2.5.1",},{"ID":"S*G*USMDC-*****","D":"Medical Dental Corps","DC":"8","H":"1.X.3.1.3.2.5.2",},{"ID":"S*G*USMP--*****","D":"Medical Psychological","DC":"8","H":"1.X.3.1.3.2.6",},{"ID":"S*G*USMPT-*****","D":"Medical Psychological Theater","DC":"8","H":"1.X.3.1.3.2.6.1",},{"ID":"S*G*USMPC-*****","D":"Medical Psychological Corps","DC":"8","H":"1.X.3.1.3.2.6.2",},{"ID":"S*G*USS---*****","D":"Supply","DC":"8","H":"1.X.3.1.3.3",},{"ID":"S*G*USST--*****","D":"Supply Theater","DC":"8","H":"1.X.3.1.3.3.1",},{"ID":"S*G*USSC--*****","D":"Supply Corps","DC":"8","H":"1.X.3.1.3.3.2",},{"ID":"S*G*USS1--*****","D":"Supply Class I","DC":"8","H":"1.X.3.1.3.3.3",},{"ID":"S*G*USS1T-*****","D":"Supply Class I Theater","DC":"8","H":"1.X.3.1.3.3.3.1",},{"ID":"S*G*USS1C-*****","D":"Supply Class I Corps","DC":"8","H":"1.X.3.1.3.3.3.2",},{"ID":"S*G*USS2--*****","D":"Supply Class II","DC":"8","H":"1.X.3.1.3.3.4",},{"ID":"S*G*USS2T-*****","D":"Supply Class II Theater","DC":"8","H":"1.X.3.1.3.3.4.1",},{"ID":"S*G*USS2C-*****","D":"Supply Class II Corps","DC":"8","H":"1.X.3.1.3.3.4.2",},{"ID":"S*G*USS3--*****","D":"Supply Class III","DC":"8","H":"1.X.3.1.3.3.5",},{"ID":"S*G*USS3T-*****","D":"Supply Class III Theater","DC":"8","H":"1.X.3.1.3.3.5.1",},{"ID":"S*G*USS3C-*****","D":"Supply Class III Corps","DC":"8","H":"1.X.3.1.3.3.5.2",},{"ID":"S*G*USS3A-*****","D":"Supply Class III Aviation","DC":"8","H":"1.X.3.1.3.3.5.3",},{"ID":"S*G*USS3AT*****","D":"Supply Class III Aviation Theater","DC":"8","H":"1.X.3.1.3.3.5.3.1",},{"ID":"S*G*USS3AC*****","D":"Supply Class III Aviation Corps","DC":"8","H":"1.X.3.1.3.3.5.3.2",},{"ID":"S*G*USS4--*****","D":"Supply Class IV","DC":"8","H":"1.X.3.1.3.3.6",},{"ID":"S*G*USS4T-*****","D":"Supply Class IV Theater","DC":"8","H":"1.X.3.1.3.3.6.1",},{"ID":"S*G*USS4C-*****","D":"Supply Class IV Corps","DC":"8","H":"1.X.3.1.3.3.6.2",},{"ID":"S*G*USS5--*****","D":"Supply Class V","DC":"8","H":"1.X.3.1.3.3.7",},{"ID":"S*G*USS5T-*****","D":"Supply Class V Theater","DC":"8","H":"1.X.3.1.3.3.7.1",},{"ID":"S*G*USS5C-*****","D":"Supply Class V Corps","DC":"8","H":"1.X.3.1.3.3.7.2",},{"ID":"S*G*USS6--*****","D":"Supply Class VI","DC":"8","H":"1.X.3.1.3.3.8",},{"ID":"S*G*USS6T-*****","D":"Supply Class VI Theater","DC":"8","H":"1.X.3.1.3.3.8.1",},{"ID":"S*G*USS6C-*****","D":"Supply Class VI Corps","DC":"8","H":"1.X.3.1.3.3.8.2",},{"ID":"S*G*USS7--*****","D":"Supply Class VII","DC":"8","H":"1.X.3.1.3.3.9",},{"ID":"S*G*USS7T-*****","D":"Supply Class VII Theater","DC":"8","H":"1.X.3.1.3.3.9.1",},{"ID":"S*G*USS7C-*****","D":"Supply Class VII Corps","DC":"8","H":"1.X.3.1.3.3.9.2",},{"ID":"S*G*USS8--*****","D":"Supply Class VIII","DC":"8","H":"1.X.3.1.3.3.10",},{"ID":"S*G*USS8T-*****","D":"Supply Class VIII Theater","DC":"8","H":"1.X.3.1.3.3.10.1",},{"ID":"S*G*USS8C-*****","D":"Supply Class VIII Corps","DC":"8","H":"1.X.3.1.3.3.10.2",},{"ID":"S*G*USS9--*****","D":"Supply Class IX","DC":"8","H":"1.X.3.1.3.3.11",},{"ID":"S*G*USS9T-*****","D":"Supply Class IX Theater","DC":"8","H":"1.X.3.1.3.3.11.1",},{"ID":"S*G*USS9C-*****","D":"Supply Class IX Corps","DC":"8","H":"1.X.3.1.3.3.11.2",},{"ID":"S*G*USSX--*****","D":"Supply Class X","DC":"8","H":"1.X.3.1.3.3.12",},{"ID":"S*G*USSXT-*****","D":"Supply Class X Theater","DC":"8","H":"1.X.3.1.3.3.12.1",},{"ID":"S*G*USSXC-*****","D":"Supply Class X Corps","DC":"8","H":"1.X.3.1.3.3.12.2",},{"ID":"S*G*USSL--*****","D":"Supply Laundry/Bath","DC":"8","H":"1.X.3.1.3.3.13",},{"ID":"S*G*USSLT-*****","D":"Supply Laundry/Bath Theater","DC":"8","H":"1.X.3.1.3.3.13.1",},{"ID":"S*G*USSLC-*****","D":"Supply Laundry/Bath Corps","DC":"8","H":"1.X.3.1.3.3.13.2",},{"ID":"S*G*USSW--*****","D":"Supply Water","DC":"8","H":"1.X.3.1.3.3.14",},{"ID":"S*G*USSWT-*****","D":"Supply Water Theater","DC":"8","H":"1.X.3.1.3.3.14.1",},{"ID":"S*G*USSWC-*****","D":"Supply Water Corps","DC":"8","H":"1.X.3.1.3.3.14.2",},{"ID":"S*G*USSWP-*****","D":"Supply Water Purification","DC":"8","H":"1.X.3.1.3.3.14.3",},{"ID":"S*G*USSWPT*****","D":"Supply Water Purification Theater","DC":"8","H":"1.X.3.1.3.3.14.3.1",},{"ID":"S*G*USSWPC*****","D":"Supply Water Purification Corps","DC":"8","H":"1.X.3.1.3.3.14.3.2",},{"ID":"S*G*UST---*****","D":"Transportation","DC":"8","H":"1.X.3.1.3.4",},{"ID":"S*G*USTT--*****","D":"Transportation Theater","DC":"8","H":"1.X.3.1.3.4.1",},{"ID":"S*G*USTC--*****","D":"Transportation Corps","DC":"8","H":"1.X.3.1.3.4.2",},{"ID":"S*G*USTM--*****","D":"Movement Control Center (MCC)","DC":"8","H":"1.X.3.1.3.4.3",},{"ID":"S*G*USTMT-*****","D":"MCC Theater","DC":"8","H":"1.X.3.1.3.4.3.1",},{"ID":"S*G*USTMC-*****","D":"MCC Corps","DC":"8","H":"1.X.3.1.3.4.3.2",},{"ID":"S*G*USTR--*****","D":"Railhead","DC":"8","H":"1.X.3.1.3.4.4",},{"ID":"S*G*USTRT-*****","D":"Railhead Theater","DC":"8","H":"1.X.3.1.3.4.4.1",},{"ID":"S*G*USTRC-*****","D":"Railhead Corps","DC":"8","H":"1.X.3.1.3.4.4.2",},{"ID":"S*G*USTS--*****","D":"SPOD/SPOE","DC":"8","H":"1.X.3.1.3.4.5",},{"ID":"S*G*USTST-*****","D":"SPOD/SPOE Theater","DC":"8","H":"1.X.3.1.3.4.5.1",},{"ID":"S*G*USTSC-*****","D":"SPOD/SPOE Corps","DC":"8","H":"1.X.3.1.3.4.5.2",},{"ID":"S*G*USTA--*****","D":"APOD/APOE","DC":"8","H":"1.X.3.1.3.4.6",},{"ID":"S*G*USTAT-*****","D":"APOD/APOE Theater","DC":"8","H":"1.X.3.1.3.4.6.1",},{"ID":"S*G*USTAC-*****","D":"APOD/APOE Corps","DC":"8","H":"1.X.3.1.3.4.6.2",},{"ID":"S*G*USTI--*****","D":"Missile","DC":"8","H":"1.X.3.1.3.4.7",},{"ID":"S*G*USTIT-*****","D":"Missile Theater","DC":"8","H":"1.X.3.1.3.4.7.1",},{"ID":"S*G*USTIC-*****","D":"Missile Corps","DC":"8","H":"1.X.3.1.3.4.7.2",},{"ID":"S*G*USX---*****","D":"Maintenance","DC":"8","H":"1.X.3.1.3.5",},{"ID":"S*G*USXT--*****","D":"Maintenance Theater","DC":"8","H":"1.X.3.1.3.5.1",},{"ID":"S*G*USXC--*****","D":"Maintenance Corps","DC":"8","H":"1.X.3.1.3.5.2",},{"ID":"S*G*USXH--*****","D":"Maintenance Heavy","DC":"8","H":"1.X.3.1.3.5.3",},{"ID":"S*G*USXHT-*****","D":"Maintenance Heavy Theater","DC":"8","H":"1.X.3.1.3.5.3.1",},{"ID":"S*G*USXHC-*****","D":"Maintenance Heavy Corps","DC":"8","H":"1.X.3.1.3.5.3.2",},{"ID":"S*G*USXR--*****","D":"Maintenance Recovery","DC":"8","H":"1.X.3.1.3.5.4",},{"ID":"S*G*USXRT-*****","D":"Maintenance Recovery Theater","DC":"8","H":"1.X.3.1.3.5.4.1",},{"ID":"S*G*USXRC-*****","D":"Maintenance Recovery Corps","DC":"8","H":"1.X.3.1.3.5.4.2",},{"ID":"S*G*USXO--*****","D":"Ordnance","DC":"8","H":"1.X.3.1.3.5.5",},{"ID":"S*G*USXOT-*****","D":"Ordnance Theater","DC":"8","H":"1.X.3.1.3.5.5.1",},{"ID":"S*G*USXOC-*****","D":"Ordnance Corps","DC":"8","H":"1.X.3.1.3.5.5.2",},{"ID":"S*G*USXOM-*****","D":"Ordnance Missile","DC":"8","H":"1.X.3.1.3.5.5.3",},{"ID":"S*G*USXOMT*****","D":"Ordnance Missile Theater","DC":"8","H":"1.X.3.1.3.5.5.3.1",},{"ID":"S*G*USXOMC*****","D":"Ordnance Missile Corps","DC":"8","H":"1.X.3.1.3.5.5.3.2",},{"ID":"S*G*USXE--*****","D":"Electro-Optical","DC":"8","H":"1.X.3.1.3.5.6",},{"ID":"S*G*USXET-*****","D":"Electro-Optical Theater","DC":"8","H":"1.X.3.1.3.5.6.1",},{"ID":"S*G*USXEC-*****","D":"Electro-Optical Corps","DC":"8","H":"1.X.3.1.3.5.6.2",},{"ID":"S*G*UH----*****","D":"Special C2 Headquarters Component","DC":"8","H":"1.X.3.1.4",},{"ID":"S*G*E-----*****","D":"Ground Track Equipment","DC":"8","H":"1.X.3.2",},{"ID":"S*G*EW----*****","D":"Weapon","DC":"0","H":"1.X.3.2.1",},{"ID":"S*G*EWM---*****","D":"Missile Launcher","DC":"8","H":"1.X.3.2.1.1",},{"ID":"S*G*EWMA--*****","D":"Air Defense (AD) Missile Launcher","DC":"8","H":"1.X.3.2.1.1.1",},{"ID":"S*G*EWMAS-*****","D":"Short Range AD Missile Launcher","DC":"8","H":"1.X.3.2.1.1.1.1",},{"ID":"S*G*EWMASR*****","D":"Short Range Transporter Launcher and Radar (TLAR)","DC":"8","H":"1.X.3.2.1.1.1.1.1",},{"ID":"S*G*EWMASE*****","D":"Short Range Transporter Erector Launcher and Radar (TELAR)","DC":"8","H":"1.X.3.2.1.1.1.1.2",},{"ID":"S*G*EWMAI-*****","D":"Intermediate Range AD Missile Launcher","DC":"8","H":"1.X.3.2.1.1.1.2",},{"ID":"S*G*EWMAIR*****","D":"Intermediate Transporter Launcher and Radar (TLAR)","DC":"8","H":"1.X.3.2.1.1.1.2.1",},{"ID":"S*G*EWMAIE*****","D":"Intermediate Transporter Erector Launcher and Radar (TELAR)","DC":"8","H":"1.X.3.2.1.1.1.2.2",},{"ID":"S*G*EWMAL-*****","D":"Long Range AD Missile Launcher","DC":"8","H":"1.X.3.2.1.1.1.3",},{"ID":"S*G*EWMALR*****","D":"Long Range Transporter Launcher and Radar (TLAR)","DC":"8","H":"1.X.3.2.1.1.1.3.1",},{"ID":"S*G*EWMALE*****","D":"Long Range Transporter Erector Launcher and Radar (TELAR)","DC":"8","H":"1.X.3.2.1.1.1.3.2",},{"ID":"S*G*EWMAT-*****","D":"AD Missile Launcher Theater","DC":"8","H":"1.X.3.2.1.1.1.4",},{"ID":"S*G*EWMATR*****","D":"Theater Transporter Launcher and Radar (TLAR)","DC":"8","H":"1.X.3.2.1.1.1.4.1",},{"ID":"S*G*EWMATE*****","D":"Theater Transporter Erector Launcher and Radar (TELAR)","DC":"8","H":"1.X.3.2.1.1.1.4.2",},{"ID":"S*G*EWMS--*****","D":"Surf-Surf (SS) Missile Launcher","DC":"8","H":"1.X.3.2.1.1.2",},{"ID":"S*G*EWMSS-*****","D":"Short Range SS Missile Launcher","DC":"8","H":"1.X.3.2.1.1.2.1",},{"ID":"S*G*EWMSI-*****","D":"Intermediate Range SS Missile Launcher","DC":"8","H":"1.X.3.2.1.1.2.2",},{"ID":"S*G*EWMSL-*****","D":"Long Range SS Missile Launcher","DC":"8","H":"1.X.3.2.1.1.2.3",},{"ID":"S*G*EWMT--*****","D":"Missile Launcher Antitank (AT)","DC":"8","H":"1.X.3.2.1.1.3",},{"ID":"S*G*EWMTL-*****","D":"Missile Launcher AT Light","DC":"8","H":"1.X.3.2.1.1.3.1",},{"ID":"S*G*EWMTM-*****","D":"Missile Launcher AT Medium","DC":"8","H":"1.X.3.2.1.1.3.2",},{"ID":"S*G*EWMTH-*****","D":"Missile Launcher AT Heavy","DC":"8","H":"1.X.3.2.1.1.3.3",},{"ID":"S*G*EWS---*****","D":"Weapon Single Rocket Launcher","DC":"8","H":"1.X.3.2.1.2",},{"ID":"S*G*EWSL--*****","D":"Single Rocket Launcher Light","DC":"8","H":"1.X.3.2.1.2.1",},{"ID":"S*G*EWSM--*****","D":"Single Rocket Launcher Medium","DC":"8","H":"1.X.3.2.1.2.2",},{"ID":"S*G*EWSH--*****","D":"Single Rocket Launcher Heavy","DC":"8","H":"1.X.3.2.1.2.3",},{"ID":"S*G*EWX---*****","D":"Multiple Rocket Launcher","DC":"8","H":"1.X.3.2.1.3",},{"ID":"S*G*EWXL--*****","D":"Multiple Rocket Launcher Light","DC":"8","H":"1.X.3.2.1.3.1",},{"ID":"S*G*EWXM--*****","D":"Multiple Rocket Launcher Medium","DC":"8","H":"1.X.3.2.1.3.2",},{"ID":"S*G*EWXH--*****","D":"Multiple Rocket Launcher Heavy","DC":"8","H":"1.X.3.2.1.3.3",},{"ID":"S*G*EWT---*****","D":"Antitank Rocket Launcher","DC":"8","H":"1.X.3.2.1.4",},{"ID":"S*G*EWTL--*****","D":"Antitank Rocket Launcher Light","DC":"8","H":"1.X.3.2.1.4.1",},{"ID":"S*G*EWTM--*****","D":"Antitank Rocket Launcher Medium","DC":"8","H":"1.X.3.2.1.4.2",},{"ID":"S*G*EWTH--*****","D":"Antitank Rocket Launcher Heavy","DC":"8","H":"1.X.3.2.1.4.3",},{"ID":"S*G*EWR---*****","D":"Rifle/Automatic Weapon","DC":"8","H":"1.X.3.2.1.5",},{"ID":"S*G*EWRR--*****","D":"Rifle","DC":"8","H":"1.X.3.2.1.5.1",},{"ID":"S*G*EWRR--*****","D":"Weapons Cache","DC":"8","H":"1.X.3.2.1.5.1.1",},{"ID":"S*G*EWRR--*****","D":"Weapons Confiscated","DC":"8","H":"1.X.3.2.1.5.1.2",},{"ID":"S*G*EWRR--*****","D":"Weapons Found","DC":"8","H":"1.X.3.2.1.5.1.3",},{"ID":"S*G*EWRR--*****","D":"Weapons Market","DC":"8","H":"1.X.3.2.1.5.1.4",},{"ID":"S*G*EWRR--*****","D":"Weapons Sale","DC":"8","H":"1.X.3.2.1.5.1.5",},{"ID":"S*G*EWRL--*****","D":"Light Machine Gun","DC":"8","H":"1.X.3.2.1.5.2",},{"ID":"S*G*EWRH--*****","D":"Heavy Machine Gun","DC":"8","H":"1.X.3.2.1.5.3",},{"ID":"S*G*EWZ---*****","D":"Grenade Launcher","DC":"8","H":"1.X.3.2.1.6",},{"ID":"S*G*EWZL--*****","D":"Grenade Launcher Light","DC":"8","H":"1.X.3.2.1.6.1",},{"ID":"S*G*EWZM--*****","D":"Grenade Launcher Medium","DC":"8","H":"1.X.3.2.1.6.2",},{"ID":"S*G*EWZH--*****","D":"Grenade Launcher Heavy","DC":"8","H":"1.X.3.2.1.6.3",},{"ID":"S*G*EWO---*****","D":"Weapon Mortar","DC":"8","H":"1.X.3.2.1.7",},{"ID":"S*G*EWOL--*****","D":"Mortar Light","DC":"8","H":"1.X.3.2.1.7.1",},{"ID":"S*G*EWOM--*****","D":"Mortar Medium","DC":"8","H":"1.X.3.2.1.7.2",},{"ID":"S*G*EWOH--*****","D":"Mortar Heavy","DC":"8","H":"1.X.3.2.1.7.3",},{"ID":"S*G*EWH---*****","D":"Howitzer","DC":"8","H":"1.X.3.2.1.8",},{"ID":"S*G*EWHL--*****","D":"Howitzer Light","DC":"8","H":"1.X.3.2.1.8.1",},{"ID":"S*G*EWHLS-*****","D":"Howitzer Light Self-Propelled","DC":"8","H":"1.X.3.2.1.8.1.1",},{"ID":"S*G*EWHM--*****","D":"Howitzer Medium","DC":"8","H":"1.X.3.2.1.8.2",},{"ID":"S*G*EWHMS-*****","D":"Howitzer Medium Self-Propelled","DC":"8","H":"1.X.3.2.1.8.2.1",},{"ID":"S*G*EWHH--*****","D":"Howitzer Heavy","DC":"8","H":"1.X.3.2.1.8.3",},{"ID":"S*G*EWHHS-*****","D":"Howitzer Heavy Self-Propelled","DC":"8","H":"1.X.3.2.1.8.3.1",},{"ID":"S*G*EWG---*****","D":"Antitank Gun","DC":"8","H":"1.X.3.2.1.9",},{"ID":"S*G*EWGL--*****","D":"Antitank Gun Light","DC":"8","H":"1.X.3.2.1.9.1",},{"ID":"S*G*EWGM--*****","D":"Antitank Gun Medium","DC":"8","H":"1.X.3.2.1.9.2",},{"ID":"S*G*EWGH--*****","D":"Antitank Gun Heavy","DC":"8","H":"1.X.3.2.1.9.3",},{"ID":"S*G*EWGR--*****","D":"Antitank Gun Recoilless","DC":"8","H":"1.X.3.2.1.9.4",},{"ID":"S*G*EWD---*****","D":"Direct Fire Gun","DC":"8","H":"1.X.3.2.1.10",},{"ID":"S*G*EWDL--*****","D":"Direct Fire Gun Light","DC":"8","H":"1.X.3.2.1.10.1",},{"ID":"S*G*EWDLS-*****","D":"Direct Fire Gun Light Self-Propelled","DC":"8","H":"1.X.3.2.1.10.1.1",},{"ID":"S*G*EWDM--*****","D":"Direct Fire Gun Medium","DC":"8","H":"1.X.3.2.1.10.2",},{"ID":"S*G*EWDMS-*****","D":"Direct Fire Gun Medium Self-Propelled","DC":"8","H":"1.X.3.2.1.10.2.1",},{"ID":"S*G*EWDH--*****","D":"Direct Fire Gun Heavy","DC":"8","H":"1.X.3.2.1.10.3",},{"ID":"S*G*EWDHS-*****","D":"Direct Fire Gun Heavy Self-Propelled","DC":"8","H":"1.X.3.2.1.10.3.1",},{"ID":"S*G*EWA---*****","D":"Air Defense Gun","DC":"8","H":"1.X.3.2.1.11",},{"ID":"S*G*EWAL--*****","D":"Air Defense Gun Light","DC":"8","H":"1.X.3.2.1.11.1",},{"ID":"S*G*EWAM--*****","D":"Air Defense Gun Medium","DC":"8","H":"1.X.3.2.1.11.2",},{"ID":"S*G*EWAH--*****","D":"Air Defense Gun Heavy","DC":"8","H":"1.X.3.2.1.11.3",},{"ID":"S*G*EV----*****","D":"Ground Vehicle","DC":"8","H":"1.X.3.2.2",},{"ID":"S*G*EVA---*****","D":"Armored Vehicle","DC":"8","H":"1.X.3.2.2.1",},{"ID":"S*G*EVAT--*****","D":"Tank","DC":"8","H":"1.X.3.2.2.1.1",},{"ID":"S*G*EVATL-*****","D":"Tank Light","DC":"8","H":"1.X.3.2.2.1.1.1",},{"ID":"S*G*EVATLR*****","D":"Tank Light Recovery","DC":"8","H":"1.X.3.2.2.1.1.1.1",},{"ID":"S*G*EVATM-*****","D":"Tank Medium","DC":"8","H":"1.X.3.2.2.1.1.2",},{"ID":"S*G*EVATMR*****","D":"Tank Medium Recovery","DC":"8","H":"1.X.3.2.2.1.1.2.1",},{"ID":"S*G*EVATH-*****","D":"Tank Heavy","DC":"8","H":"1.X.3.2.2.1.1.3",},{"ID":"S*G*EVATHR*****","D":"Tank Heavy Recovery","DC":"8","H":"1.X.3.2.2.1.1.3.1",},{"ID":"S*G*EVAA--*****","D":"Armored Personnel Carrier","DC":"8","H":"1.X.3.2.2.1.2",},{"ID":"S*G*EVAAR-*****","D":"Armored Personnel Carrier Recovery","DC":"8","H":"1.X.3.2.2.1.2.1",},{"ID":"S*G*EVAI--*****","D":"Armored Infantry","DC":"8","H":"1.X.3.2.2.1.3",},{"ID":"S*G*EVAC--*****","D":"C2V/ACV","DC":"8","H":"1.X.3.2.2.1.4",},{"ID":"S*G*EVAS--*****","D":"Combat Service Support Vehicle","DC":"8","H":"1.X.3.2.2.1.5",},{"ID":"S*G*EVAL--*****","D":"Light Armored Vehicle","DC":"8","H":"1.X.3.2.2.1.6",},{"ID":"S*G*EVU---*****","D":"Utility Vehicle","DC":"8","H":"1.X.3.2.2.2",},{"ID":"S*G*EVUB--*****","D":"Bus","DC":"8","H":"1.X.3.2.2.2.1",},{"ID":"S*G*EVUS--*****","D":"Semi","DC":"8","H":"1.X.3.2.2.2.2",},{"ID":"S*G*EVUSL-*****","D":"Semi Light","DC":"8","H":"1.X.3.2.2.2.2.1",},{"ID":"S*G*EVUSM-*****","D":"Semi Medium","DC":"8","H":"1.X.3.2.2.2.2.2",},{"ID":"S*G*EVUSH-*****","D":"Semi Heavy","DC":"8","H":"1.X.3.2.2.2.2.3",},{"ID":"S*G*EVUL--*****","D":"Limited Cross-Country Truck","DC":"8","H":"1.X.3.2.2.2.3",},{"ID":"S*G*EVUX--*****","D":"Cross-Country Truck","DC":"8","H":"1.X.3.2.2.2.4",},{"ID":"S*G*EVUR--*****","D":"Water Craft","DC":"8","H":"1.X.3.2.2.2.5",},{"ID":"S*G*EVUT--*****","D":"Tow Truck","DC":"8","H":"1.X.3.2.2.2.6",},{"ID":"S*G*EVUTL-*****","D":"Tow Truck Light","DC":"8","H":"1.X.3.2.2.2.6.1",},{"ID":"S*G*EVUTH-*****","D":"Tow Truck Heavy","DC":"8","H":"1.X.3.2.2.2.6.2",},{"ID":"S*G*EVUA--*****","D":"Ambulance","DC":"8","H":"1.X.3.2.2.2.7",},{"ID":"S*G*EVUAA-*****","D":"Ambulance Armored","DC":"8","H":"1.X.3.2.2.2.7.1",},{"ID":"S*G*EVE---*****","D":"Engineer Vehicle","DC":"8","H":"1.X.3.2.2.3",},{"ID":"S*G*EVEB--*****","D":"Engineer Vehicle Bridge","DC":"8","H":"1.X.3.2.2.3.1",},{"ID":"S*G*EVEE--*****","D":"Earthmover","DC":"8","H":"1.X.3.2.2.3.2",},{"ID":"S*G*EVEC--*****","D":"Construction Vehicle","DC":"8","H":"1.X.3.2.2.3.3",},{"ID":"S*G*EVEM--*****","D":"Mine Laying Vehicle","DC":"8","H":"1.X.3.2.2.3.4",},{"ID":"S*G*EVEMV-*****","D":"Armored Carrier with Volcano","DC":"8","H":"1.X.3.2.2.3.4.1",},{"ID":"S*G*EVEML-*****","D":"Truck Mounted with Volcano","DC":"8","H":"1.X.3.2.2.3.4.2",},{"ID":"S*G*EVEA--*****","D":"Mine Clearing Vehicle","DC":"8","H":"1.X.3.2.2.3.5",},{"ID":"S*G*EVEAA-*****","D":"Armored Mounted Mine Clearing Vehicle","DC":"8","H":"1.X.3.2.2.3.5.1",},{"ID":"S*G*EVEAT-*****","D":"Trailer Mounted Mine Clearing Vehicle","DC":"8","H":"1.X.3.2.2.3.5.2",},{"ID":"S*G*EVED--*****","D":"Dozer","DC":"8","H":"1.X.3.2.2.3.6",},{"ID":"S*G*EVEDA-*****","D":"Armored Dozer","DC":"8","H":"1.X.3.2.2.3.6.1",},{"ID":"S*G*EVES--*****","D":"Armored Assault","DC":"8","H":"1.X.3.2.2.3.7",},{"ID":"S*G*EVER--*****","D":"Armored Engineer Recon Vehicle (AERV)","DC":"8","H":"1.X.3.2.2.3.8",},{"ID":"S*G*EVEH--*****","D":"Backhoe","DC":"8","H":"1.X.3.2.2.3.9",},{"ID":"S*G*EVEF--*****","D":"Ferry Transporter","DC":"8","H":"1.X.3.2.2.3.10",},{"ID":"S*G*EVT---*****","D":"Train Locomotive","DC":"8","H":"1.X.3.2.2.4",},{"ID":"S*G*EVC---*****","D":"Civilian Vehicle","DC":"8","H":"1.X.3.2.2.5",},{"ID":"S*G*EVCA--*****","D":"Civilian Automobile","DC":"8","H":"1.X.3.2.2.5.1",},{"ID":"S*G*EVCAL-*****","D":"Civilian Compact Automobile","DC":"8","H":"1.X.3.2.2.5.1.1",},{"ID":"S*G*EVCAM-*****","D":"Civilian Midsize Automobile","DC":"8","H":"1.X.3.2.2.5.1.2",},{"ID":"S*G*EVCAH-*****","D":"Civilian Automobile Sedan","DC":"8","H":"1.X.3.2.2.5.1.3",},{"ID":"S*G*EVCO--*****","D":"Civilian Open-Bed Truck","DC":"8","H":"1.X.3.2.2.5.2",},{"ID":"S*G*EVCOL-*****","D":"Civilian Pickup Truck","DC":"8","H":"1.X.3.2.2.5.2.1",},{"ID":"S*G*EVCOM-*****","D":"Civilian Small Open-Bed Truck","DC":"8","H":"1.X.3.2.2.5.2.2",},{"ID":"S*G*EVCOH-*****","D":"Civilian Large Open-Bed Truck","DC":"8","H":"1.X.3.2.2.5.2.3",},{"ID":"S*G*EVCM--*****","D":"Civilian Multiple Passenger Vehicle","DC":"8","H":"1.X.3.2.2.5.3",},{"ID":"S*G*EVCML-*****","D":"Civilian Multiple Passenger Van","DC":"8","H":"1.X.3.2.2.5.3.1",},{"ID":"S*G*EVCMM-*****","D":"Civilian Small Bus","DC":"8","H":"1.X.3.2.2.5.3.2",},{"ID":"S*G*EVCMH-*****","D":"Civilian Large Bus","DC":"8","H":"1.X.3.2.2.5.3.3",},{"ID":"S*G*EVCU--*****","D":"Civilian Utility Vehicle","DC":"8","H":"1.X.3.2.2.5.4",},{"ID":"S*G*EVCUL-*****","D":"Civilian Sport Utility Vehicle (SUV)","DC":"8","H":"1.X.3.2.2.5.4.1",},{"ID":"S*G*EVCUM-*****","D":"Civilian Utility Small Box Truck","DC":"8","H":"1.X.3.2.2.5.4.2",},{"ID":"S*G*EVCUH-*****","D":"Civilian Utility Large Box Truck","DC":"8","H":"1.X.3.2.2.5.4.3",},{"ID":"S*G*EVCJ--*****","D":"Civilian Jeep Type Vehicle","DC":"8","H":"1.X.3.2.2.5.5",},{"ID":"S*G*EVCJL-*****","D":"Civilian Small/Light Jeep Type Vehicle","DC":"8","H":"1.X.3.2.2.5.5.1",},{"ID":"S*G*EVCJM-*****","D":"Civilian Medium Jeep Type Vehicle","DC":"8","H":"1.X.3.2.2.5.5.2",},{"ID":"S*G*EVCJH-*****","D":"Civilian Large/Heavy Jeep Type Vehicle","DC":"8","H":"1.X.3.2.2.5.5.3",},{"ID":"S*G*EVCT--*****","D":"Civilian Tractor Trailer Truck With Box Trailer","DC":"8","H":"1.X.3.2.2.5.6",},{"ID":"S*G*EVCTL-*****","D":"Civilian Small/Light Box Trailer","DC":"8","H":"1.X.3.2.2.5.6.1",},{"ID":"S*G*EVCTM-*****","D":"Civilian Medium Box Trailer","DC":"8","H":"1.X.3.2.2.5.6.2",},{"ID":"S*G*EVCTH-*****","D":"Civilian Large/Heavy Box Trailer","DC":"8","H":"1.X.3.2.2.5.6.3",},{"ID":"S*G*EVCF--*****","D":"Civilian Tractor Trailer Truck With Flatbed Trailer","DC":"8","H":"1.X.3.2.2.5.7",},{"ID":"S*G*EVCFL-*****","D":"Civilian Small/Light Flatbed Trailer","DC":"8","H":"1.X.3.2.2.5.7.1",},{"ID":"S*G*EVCFM-*****","D":"Civilian Medium Flatbed Trailer","DC":"8","H":"1.X.3.2.2.5.7.2",},{"ID":"S*G*EVCFH-*****","D":"Civilian Large/Heavy Flatbed Trailer","DC":"8","H":"1.X.3.2.2.5.7.3",},{"ID":"S*G*EVS---*****","D":"Missile Support","DC":"8","H":"1.X.3.2.2.6",},{"ID":"S*G*EVST--*****","D":"Transloader","DC":"8","H":"1.X.3.2.2.6.1",},{"ID":"S*G*EVSR--*****","D":"Transporter","DC":"8","H":"1.X.3.2.2.6.2",},{"ID":"S*G*EVSC--*****","D":"Crane/Loading Device","DC":"8","H":"1.X.3.2.2.6.3",},{"ID":"S*G*EVSP--*****","D":"Propellant Transporter","DC":"8","H":"1.X.3.2.2.6.4",},{"ID":"S*G*EVSW--*****","D":"Warhead Transporter","DC":"8","H":"1.X.3.2.2.6.5",},{"ID":"S*G*EVM---*****","D":"Pack Animal(s)","DC":"8","H":"1.X.3.2.2.7",},{"ID":"S*G*ES----*****","D":"Equipment Sensor","DC":"8","H":"1.X.3.2.3",},{"ID":"S*G*ESR---*****","D":"Sensor Radar","DC":"8","H":"1.X.3.2.3.1",},{"ID":"S*G*ESE---*****","D":"Emplaced Sensor","DC":"8","H":"1.X.3.2.3.2",},{"ID":"S*G*EX----*****","D":"Special","DC":"0","H":"1.X.3.2.4",},{"ID":"S*G*EXL---*****","D":"Laser","DC":"8","H":"1.X.3.2.4.1",},{"ID":"S*G*EXN---*****","D":"CBRN Equipment","DC":"8","H":"1.X.3.2.4.2",},{"ID":"S*G*EXF---*****","D":"Flame Thrower","DC":"8","H":"1.X.3.2.4.3",},{"ID":"S*G*EXM---*****","D":"Land Mines","DC":"8","H":"1.X.3.2.4.4",},{"ID":"S*G*EXMC--*****","D":"Claymore","DC":"8","H":"1.X.3.2.4.4.1",},{"ID":"S*G*EXML--*****","D":"Less Than Lethal","DC":"8","H":"1.X.3.2.4.4.2",},{"ID":"S*G*EXI---*****","D":"IED","DC":"8","H":"1.X.3.2.4.5",},{"ID":"S*G*EXI---MO***","D":"VBIED","DC":"8","H":"1.X.3.2.4.5.1",},{"ID":"S*G*I-----H****","D":"Installation","DC":"8","H":"1.X.3.3",},{"ID":"S*G*IR----H****","D":"Raw Material Production/Storage","DC":"8","H":"1.X.3.3.1",},{"ID":"S*G*IRM---H****","D":"Raw Material Production/Storage Mine","DC":"8","H":"1.X.3.3.1.1",},{"ID":"S*G*IRP---H****","D":"Petroleum/Gas/Oil","DC":"8","H":"1.X.3.3.1.2",},{"ID":"S*G*IRN---H****","D":"Production/Storage CBRN","DC":"8","H":"1.X.3.3.1.3",},{"ID":"S*G*IRNB--H****","D":"Production/Storage CBRN Biological","DC":"8","H":"1.X.3.3.1.3.1",},{"ID":"S*G*IRNC--H****","D":"Production/Storage CBRN Chemical","DC":"8","H":"1.X.3.3.1.3.2",},{"ID":"S*G*IRNN--H****","D":"Production/Storage CBRN Nuclear","DC":"8","H":"1.X.3.3.1.3.3",},{"ID":"S*G*IP----H****","D":"Processing Facility","DC":"8","H":"1.X.3.3.2",},{"ID":"S*G*IPD---H****","D":"Processing Facility Decontamination","DC":"8","H":"1.X.3.3.2.1",},{"ID":"S*G*IE----H****","D":"Equipment Manufacture","DC":"8","H":"1.X.3.3.3",},{"ID":"S*G*IU----H****","D":"Service, Reasearch, Utility Facility","DC":"8","H":"1.X.3.3.4",},{"ID":"S*G*IUR---H****","D":"Technological Research Facility","DC":"8","H":"1.X.3.3.4.1",},{"ID":"S*G*IUT---H****","D":"Telecommunications Facility","DC":"8","H":"1.X.3.3.4.2",},{"ID":"S*G*IUE---H****","D":"Electric Power Facility","DC":"8","H":"1.X.3.3.4.3",},{"ID":"S*G*IUEN--H****","D":"Nuclear Plant","DC":"8","H":"1.X.3.3.4.3.1",},{"ID":"S*G*IUED--H****","D":"Dam","DC":"8","H":"1.X.3.3.4.3.2",},{"ID":"S*G*IUEF--H****","D":"Fossil Fuel","DC":"8","H":"1.X.3.3.4.3.3",},{"ID":"S*G*IUP---H****","D":"Public Water Services","DC":"8","H":"1.X.3.3.4.4",},{"ID":"S*G*IM----H****","D":"Military Materiel Facility","DC":"0","H":"1.X.3.3.5",},{"ID":"S*G*IMF---H****","D":"Nuclear Energy","DC":"8","H":"1.X.3.3.5.1",},{"ID":"S*G*IMFA--H****","D":"Atomic Energy Reactor","DC":"8","H":"1.X.3.3.5.1.1",},{"ID":"S*G*IMFP--H****","D":"Nuclear Material Production","DC":"8","H":"1.X.3.3.5.1.2",},{"ID":"S*G*IMFPW-H****","D":"Weapons Grade","DC":"8","H":"1.X.3.3.5.1.2.1",},{"ID":"S*G*IMFS--H****","D":"Nuclear Material Storage","DC":"8","H":"1.X.3.3.5.1.3",},{"ID":"S*G*IMA---H****","D":"Aircraft Production & Assembly","DC":"8","H":"1.X.3.3.5.2",},{"ID":"S*G*IME---H****","D":"Ammunition And Explosives Production","DC":"8","H":"1.X.3.3.5.3",},{"ID":"S*G*IMG---H****","D":"Armament Production","DC":"8","H":"1.X.3.3.5.4",},{"ID":"S*G*IMV---H****","D":"Military Vehicle Production","DC":"8","H":"1.X.3.3.5.5",},{"ID":"S*G*IMN---H****","D":"Engineering Equipment Production","DC":"8","H":"1.X.3.3.5.6",},{"ID":"S*G*IMNB--H****","D":"Engineering Equipment Production Bridge","DC":"8","H":"1.X.3.3.5.6.1",},{"ID":"S*G*IMC---H****","D":"Chemical & Biological Warfare Production","DC":"8","H":"1.X.3.3.5.7",},{"ID":"S*G*IMS---H****","D":"Ship Construction","DC":"8","H":"1.X.3.3.5.8",},{"ID":"S*G*IMM---H****","D":"Missile & Space System Production","DC":"8","H":"1.X.3.3.5.9",},{"ID":"S*G*IG----H****","D":"Government Leadership","DC":"8","H":"1.X.3.3.6",},{"ID":"S*G*IB----H****","D":"Military Base/Facility","DC":"8","H":"1.X.3.3.7",},{"ID":"S*G*IBA---H****","D":"Airport/Airbase","DC":"8","H":"1.X.3.3.7.1",},{"ID":"S*G*IBN---H****","D":"Seaport/Naval Base","DC":"8","H":"1.X.3.3.7.2",},{"ID":"S*G*IT----H****","D":"Transport Facility","DC":"8","H":"1.X.3.3.8",},{"ID":"S*G*IX----H****","D":"Medical Facility","DC":"8","H":"1.X.3.3.9",},{"ID":"S*G*IXH---H****","D":"Hospital","DC":"8","H":"1.X.3.3.9.1",},{"ID":"S*G*IC----H****","D":"Tented Camp","DC":"8","H":"1.X.3.3.10",},{"ID":"S*G*ICD---H****","D":"Tented Camp, Displaced Persons/Refugees","DC":"8","H":"1.X.3.3.10.1",},{"ID":"S*G*ICT---H****","D":"Tented Training Camp","DC":"8","H":"1.X.3.3.10.2",},{"ID":"S*G*IW----H****","D":"Warehouse/Storage Facility","DC":"8","H":"1.X.3.3.11",},{"ID":"S*S*------*****","D":"Sea Surface Track","DC":"8","H":"1.X.4",},{"ID":"S*S*C-----*****","D":"Sea Surface Track Combatant","DC":"8","H":"1.X.4.1",},{"ID":"S*S*CL----*****","D":"Line","DC":"8","H":"1.X.4.1.1",},{"ID":"S*S*CLCV--*****","D":"Carrier","DC":"8","H":"1.X.4.1.1.1",},{"ID":"S*S*CLBB--*****","D":"Battleship","DC":"8","H":"1.X.4.1.1.2",},{"ID":"S*S*CLCC--*****","D":"Cruiser","DC":"8","H":"1.X.4.1.1.3",},{"ID":"S*S*CLDD--*****","D":"Destroyer","DC":"8","H":"1.X.4.1.1.4",},{"ID":"S*S*CLFF--*****","D":"Frigate/Corvette","DC":"8","H":"1.X.4.1.1.5",},{"ID":"S*S*CLLL--*****","D":"Littoral Combatant","DC":"8","H":"1.X.4.1.1.6",},{"ID":"S*S*CLLLAS*****","D":"Antisubmarine Warfare Mission Package","DC":"8","H":"1.X.4.1.1.6.1",},{"ID":"S*S*CLLLMI*****","D":"Mine Warfare Mission Package","DC":"8","H":"1.X.4.1.1.6.2",},{"ID":"S*S*CLLLSU*****","D":"Surface Warfare (SUW) Mission Package","DC":"8","H":"1.X.4.1.1.6.3",},{"ID":"S*S*CA----*****","D":"Amphibious Warfare Ship","DC":"8","H":"1.X.4.1.2",},{"ID":"S*S*CALA--*****","D":"Assault Vessel","DC":"8","H":"1.X.4.1.2.1",},{"ID":"S*S*CALS--*****","D":"Landing Ship","DC":"8","H":"1.X.4.1.2.2",},{"ID":"S*S*CALSM-*****","D":"Landing Ship Medium","DC":"8","H":"1.X.4.1.2.2.1",},{"ID":"S*S*CALST-*****","D":"Landing Ship Tank","DC":"8","H":"1.X.4.1.2.2.2",},{"ID":"S*S*CALC--*****","D":"Landing Craft","DC":"8","H":"1.X.4.1.2.3",},{"ID":"S*S*CM----*****","D":"Mine Warfare Vessel","DC":"8","H":"1.X.4.1.3",},{"ID":"S*S*CMML--*****","D":"Minelayer","DC":"8","H":"1.X.4.1.3.1",},{"ID":"S*S*CMMS--*****","D":"Minesweeper","DC":"8","H":"1.X.4.1.3.2",},{"ID":"S*S*CMMH--*****","D":"Minehunter","DC":"8","H":"1.X.4.1.3.3",},{"ID":"S*S*CMMA--*****","D":"MCM Support","DC":"8","H":"1.X.4.1.3.4",},{"ID":"S*S*CP----*****","D":"Sea Surface Combatant Patrol","DC":"8","H":"1.X.4.1.4",},{"ID":"S*S*CPSB--*****","D":"Antisubmarine Warfare","DC":"8","H":"1.X.4.1.4.1",},{"ID":"S*S*CPSU--*****","D":"Antisurface Warfare","DC":"8","H":"1.X.4.1.4.2",},{"ID":"S*S*CPSUM-*****","D":"Antisurface Warfare Antiship Missile","DC":"8","H":"1.X.4.1.4.2.1",},{"ID":"S*S*CPSUT-*****","D":"Antisurface Warfare Torpedo","DC":"8","H":"1.X.4.1.4.2.2",},{"ID":"S*S*CPSUG-*****","D":"Antisurface Warfare Gun","DC":"8","H":"1.X.4.1.4.2.3",},{"ID":"S*S*CH----*****","D":"Combatant Hovercraft","DC":"8","H":"1.X.4.1.5",},{"ID":"S*S*S-----*****","D":"Sea Surface Station","DC":"8","H":"1.X.4.1.6",},{"ID":"S*S*SP----*****","D":"Picket","DC":"8","H":"1.X.4.1.6.1",},{"ID":"S*S*SA----*****","D":"ASW Ship","DC":"8","H":"1.X.4.1.6.2",},{"ID":"S*S*G-----*****","D":"Navy Group","DC":"8","H":"1.X.4.1.7",},{"ID":"S*S*GT----*****","D":"Navy Task Force","DC":"8","H":"1.X.4.1.7.1",},{"ID":"S*S*GG----*****","D":"Navy Task Group","DC":"8","H":"1.X.4.1.7.2",},{"ID":"S*S*GU----*****","D":"Navy Task Unit","DC":"8","H":"1.X.4.1.7.3",},{"ID":"S*S*GC----*****","D":"Convoy","DC":"8","H":"1.X.4.1.7.4",},{"ID":"S*S*CD----*****","D":"Surface Decoy","DC":"8","H":"1.X.4.1.8",},{"ID":"S*S*CU----*****","D":"Unmanned Surface Vehicle (USV)","DC":"8","H":"1.X.4.1.9",},{"ID":"S*S*CUM---*****","D":"USV Mine Countermeasures","DC":"8","H":"1.X.4.1.9.1",},{"ID":"S*S*CUS---*****","D":"USV Antisubmarine Warfare","DC":"8","H":"1.X.4.1.9.2",},{"ID":"S*S*CUN---*****","D":"USV Antisurface Warfare","DC":"8","H":"1.X.4.1.9.3",},{"ID":"S*S*CUR---*****","D":"USV Remote Multimission Vehicle","DC":"8","H":"1.X.4.1.9.4",},{"ID":"S*S*N-----*****","D":"Noncombatant","DC":"8","H":"1.X.4.2",},{"ID":"S*S*NR----*****","D":"Underway Replenishment","DC":"8","H":"1.X.4.2.1",},{"ID":"S*S*NF----*****","D":"Fleet Support","DC":"8","H":"1.X.4.2.2",},{"ID":"S*S*NI----*****","D":"Intelligence","DC":"8","H":"1.X.4.2.3",},{"ID":"S*S*NS----*****","D":"Service & Support Harbor","DC":"8","H":"1.X.4.2.4",},{"ID":"S*S*NM----*****","D":"Hospital Ship","DC":"8","H":"1.X.4.2.5",},{"ID":"S*S*NH----*****","D":"Noncombatant Hovercraft","DC":"8","H":"1.X.4.2.6",},{"ID":"S*S*NN----*****","D":"Noncombatant Station","DC":"8","H":"1.X.4.2.7",},{"ID":"S*S*NNR---*****","D":"Rescue","DC":"8","H":"1.X.4.2.7.1",},{"ID":"S*S*X-----*****","D":"Non-Military","DC":"0","H":"1.X.4.3",},{"ID":"S*S*XM----*****","D":"Merchant","DC":"8","H":"1.X.4.3.1",},{"ID":"S*S*XMC---*****","D":"Subsurface Non-military Cargo","DC":"8","H":"1.X.4.3.1.1",},{"ID":"S*S*XMR---*****","D":"Roll On/Roll Off","DC":"8","H":"1.X.4.3.1.2",},{"ID":"S*S*XMO---*****","D":"Oiler/Tanker","DC":"8","H":"1.X.4.3.1.3",},{"ID":"S*S*XMTU--*****","D":"Tug","DC":"8","H":"1.X.4.3.1.4",},{"ID":"S*S*XMF---*****","D":"Ferry","DC":"8","H":"1.X.4.3.1.5",},{"ID":"S*S*XMP---*****","D":"Passenger","DC":"8","H":"1.X.4.3.1.6",},{"ID":"S*S*XMH---*****","D":"Hazardous Materials (HAZMAT)","DC":"8","H":"1.X.4.3.1.7",},{"ID":"S*S*XMTO--*****","D":"Towing Vessel","DC":"8","H":"1.X.4.3.1.8",},{"ID":"S*S*XF----*****","D":"Fishing","DC":"8","H":"1.X.4.3.2",},{"ID":"S*S*XFDF--*****","D":"Drifter","DC":"8","H":"1.X.4.3.2.1",},{"ID":"S*S*XFDR--*****","D":"Dredge","DC":"8","H":"1.X.4.3.2.2",},{"ID":"S*S*XFTR--*****","D":"Trawler","DC":"8","H":"1.X.4.3.2.3",},{"ID":"S*S*XR----*****","D":"Leisure Craft","DC":"8","H":"1.X.4.3.3",},{"ID":"S*S*XL----*****","D":"Law Enforcement Vessel","DC":"8","H":"1.X.4.3.4",},{"ID":"S*S*XH----*****","D":"Non-military Hovercraft","DC":"8","H":"1.X.4.3.5",},{"ID":"S*S*XA----*****","D":"Fast Recreational Craft","DC":"8","H":"1.X.4.3.6",},{"ID":"S*S*XAR---*****","D":"Rigid-Hull Inflatable Boat","DC":"8","H":"1.X.4.3.6.1",},{"ID":"S*S*XAS---*****","D":"Speed Boat","DC":"8","H":"1.X.4.3.6.2",},{"ID":"S*S*XP----*****","D":"Personal Watercraft","DC":"8","H":"1.X.4.3.7",},{"ID":"S*S*O-----*****","D":"Own Track","DC":"8","H":"1.X.4.4",},{"ID":"S*U*------*****","D":"Subsurface Track","DC":"8","H":"1.X.5",},{"ID":"S*U*S-----*****","D":"Submarine","DC":"8","H":"1.X.5.1",},{"ID":"S*U*SN----*****","D":"Nuclear Propulsion","DC":"8","H":"1.X.5.1.1",},{"ID":"S*U*SNF---*****","D":"Submarine Nuclear Surfaced","DC":"8","H":"1.X.5.1.1.1",},{"ID":"S*U*SNA---*****","D":"Submarine Nuclear Attack (SSN)","DC":"8","H":"1.X.5.1.1.2",},{"ID":"S*U*SNM---*****","D":"Submarine Nuclear Missile Type Unknown","DC":"8","H":"1.X.5.1.1.3",},{"ID":"S*U*SNG---*****","D":"Submarine Nuclear Guided Missile (SSGN)","DC":"8","H":"1.X.5.1.1.4",},{"ID":"S*U*SNB---*****","D":"Ballistic Missile Submarine (SSB)","DC":"8","H":"1.X.5.1.1.5",},{"ID":"S*U*SC----*****","D":"Conventional Propulsion","DC":"8","H":"1.X.5.1.2",},{"ID":"S*U*SCF---*****","D":"Conventional Propulsion Surfaced","DC":"8","H":"1.X.5.1.2.1",},{"ID":"S*U*SCA---*****","D":"Attack Submarine (SS)","DC":"8","H":"1.X.5.1.2.2",},{"ID":"S*U*SCM---*****","D":"Conventional Propulsion Missile Submarine (TYPE UNKNOWN)","DC":"8","H":"1.X.5.1.2.3",},{"ID":"S*U*SCG---*****","D":"Guided Missile Submarine (SSG)","DC":"8","H":"1.X.5.1.2.4",},{"ID":"S*U*SCB---*****","D":"Conventional Propulsion Ballistic Missile (SSB)","DC":"8","H":"1.X.5.1.2.5",},{"ID":"S*U*SO----*****","D":"Other Submersible","DC":"8","H":"1.X.5.1.3",},{"ID":"S*U*SOF---*****","D":"Other Submersible Surfaced","DC":"8","H":"1.X.5.1.3.0",},{"ID":"S*U*SU----*****","D":"Unmanned Underwater Vehicle (UUV)","DC":"8","H":"1.X.5.1.3.1",},{"ID":"S*U*SUM---*****","D":"UUV Mine Warfare","DC":"8","H":"1.X.5.1.3.1.1",},{"ID":"S*U*SUS---*****","D":"UUV Antisubmarine Warfare","DC":"8","H":"1.X.5.1.3.1.2",},{"ID":"S*U*SUN---*****","D":"UUV Antisurface Warfare","DC":"8","H":"1.X.5.1.3.1.3",},{"ID":"S*U*SF----*****","D":"Submarine Surfaced","DC":"8","H":"1.X.5.1.5",},{"ID":"S*U*SB----*****","D":"Submarine Bottomed","DC":"8","H":"1.X.5.1.6",},{"ID":"S*U*SR----*****","D":"Submarine Certsub","DC":"8","H":"1.X.5.1.7",},{"ID":"S*U*SX----*****","D":"Non Submarine","DC":"8","H":"1.X.5.1.8",},{"ID":"S*U*S1----*****","D":"Possub-1","DC":"8","H":"1.X.5.1.9",},{"ID":"S*U*S2----*****","D":"Possub-2","DC":"8","H":"1.X.5.1.10",},{"ID":"S*U*S3----*****","D":"Possub-3","DC":"8","H":"1.X.5.1.11",},{"ID":"S*U*S4----*****","D":"Possub-4","DC":"8","H":"1.X.5.1.12",},{"ID":"S*U*SL----*****","D":"ProbSub","DC":"8","H":"1.X.5.1.13",},{"ID":"S*U*SK----*****","D":"Snorkeling","DC":"8","H":"1.X.5.1.14",},{"ID":"S*U*W-----*****","D":"Underwater Weapon","DC":"8","H":"1.X.5.2",},{"ID":"S*U*WT----*****","D":"Torpedo","DC":"8","H":"1.X.5.2.1",},{"ID":"S*U*WM----*****","D":"Sea Mine","DC":"8","H":"1.X.5.2.2",},{"ID":"S*U*WMD---*****","D":"Sea Mine Neutralized","DC":"8","H":"1.X.5.2.2.1",},{"ID":"S*U*WMG---*****","D":"Sea Mine (Ground)","DC":"8","H":"1.X.5.2.2.2",},{"ID":"S*U*WMGD--*****","D":"Sea Mine (Ground) Neutralized","DC":"8","H":"1.X.5.2.2.2.1",},{"ID":"S*U*WMGX--*****","D":"Ground (Bottom) Excercise Mine","DC":"8","H":"1.X.5.2.2.2.2",},{"ID":"S*U*WMGE--*****","D":"Ground (Bottom) MILEC","DC":"8","H":"1.X.5.2.2.2.3",},{"ID":"S*U*WMGC--*****","D":"Ground (Bottom) MILCO","DC":"8","H":"1.X.5.2.2.2.4",},{"ID":"S*U*WMGR--*****","D":"Ground (Bottom) Negative Reacquisition","DC":"8","H":"1.X.5.2.2.2.5",},{"ID":"S*U*WMGO--*****","D":"Ground (Bottom) Non-Mine Mike-Like Contact","DC":"8","H":"1.X.5.2.2.2.6",},{"ID":"S*U*WMM---*****","D":"Sea Mine (Moored)","DC":"8","H":"1.X.5.2.2.3",},{"ID":"S*U*WMMD--*****","D":"Sea Mine (Moored) Neutralized","DC":"8","H":"1.X.5.2.2.3.1",},{"ID":"S*U*WMMX--*****","D":"Moored Exercise Mine","DC":"8","H":"1.X.5.2.2.3.2",},{"ID":"S*U*WMME--*****","D":"Moored MILEC","DC":"8","H":"1.X.5.2.2.3.3",},{"ID":"S*U*WMMC--*****","D":"Moored MILCO","DC":"8","H":"1.X.5.2.2.3.4",},{"ID":"S*U*WMMR--*****","D":"Moored Negative Reacquisition","DC":"8","H":"1.X.5.2.2.3.5",},{"ID":"S*U*WMMO--*****","D":"Moored Non-Mine Mine-Like Object","DC":"8","H":"1.X.5.2.2.3.6",},{"ID":"S*U*WMF---*****","D":"Sea Mine (Floating)","DC":"8","H":"1.X.5.2.2.4",},{"ID":"S*U*WMFD--*****","D":"Sea Mine (Floating) Neutralized","DC":"8","H":"1.X.5.2.2.4.1",},{"ID":"S*U*WMFX--*****","D":"Floating Exercise Mine","DC":"8","H":"1.X.5.2.2.4.2",},{"ID":"S*U*WMFE--*****","D":"Floating MILEC","DC":"8","H":"1.X.5.2.2.4.3",},{"ID":"S*U*WMFC--*****","D":"Floating MILCO","DC":"8","H":"1.X.5.2.2.4.4",},{"ID":"S*U*WMFR--*****","D":"Floating Negative Reacquisition","DC":"8","H":"1.X.5.2.2.4.5",},{"ID":"S*U*WMFO--*****","D":"Floating Non-Mine Mine-Like Contact","DC":"8","H":"1.X.5.2.2.4.6",},{"ID":"S*U*WMO---*****","D":"Sea Mine (Other Position)","DC":"8","H":"1.X.5.2.2.5",},{"ID":"S*U*WMOD--*****","D":"Sea Mine (Other Position) Neutralized","DC":"8","H":"1.X.5.2.2.5.1",},{"ID":"S*U*WMX---*****","D":"General Exercise Mine","DC":"8","H":"1.X.5.2.2.6",},{"ID":"S*U*WME---*****","D":"General MILEC","DC":"8","H":"1.X.5.2.2.7",},{"ID":"S*U*WMA---*****","D":"General Mine Anchor","DC":"8","H":"1.X.5.2.2.8",},{"ID":"S*U*WMC---*****","D":"General MILCO","DC":"8","H":"1.X.5.2.2.9",},{"ID":"S*U*WMR---*****","D":"General Negative Reacquisition","DC":"8","H":"1.X.5.2.2.10",},{"ID":"S*U*WMB---*****","D":"General Obstructor","DC":"8","H":"1.X.5.2.2.11",},{"ID":"S*U*WMBD--*****","D":"General Obstructor Neutralized","DC":"8","H":"1.X.5.2.2.11.1",},{"ID":"S*U*WMN---*****","D":"General Non-Mine Mine-Like Object","DC":"8","H":"1.X.5.2.2.12",},{"ID":"S*U*WMS---*****","D":"Rising Mine","DC":"8","H":"1.X.5.2.2.13",},{"ID":"S*U*WMSX--*****","D":"Rising Exercise Mine","DC":"8","H":"1.X.5.2.2.13.1",},{"ID":"S*U*WMSD--*****","D":"Rising Mine Neutralized","DC":"8","H":"1.X.5.2.2.13.2",},{"ID":"S*U*WD----*****","D":"Underwater Decoy","DC":"8","H":"1.X.5.3",},{"ID":"S*U*WDM---*****","D":"Sea Mine Decoy","DC":"8","H":"1.X.5.3.1",},{"ID":"S*U*WDMG--*****","D":"Ground (Bottom) Decoy","DC":"8","H":"1.X.5.3.1.1",},{"ID":"S*U*WDMM--*****","D":"Moored Decoy","DC":"8","H":"1.X.5.3.1.2",},{"ID":"S*U*N-----*****","D":"Non-Submarine","DC":"0","H":"1.X.5.4",},{"ID":"S*U*ND----*****","D":"Diver","DC":"8","H":"1.X.5.4.1",},{"ID":"S*U*E-----*****","D":"Environmental Report Location","DC":"8","H":"1.X.5.5",},{"ID":"S*U*V-----*****","D":"Dive Report Location","DC":"8","H":"1.X.5.6",},{"ID":"S*U*X-----*****","D":"Unexploded Ordnance Area (Subsurface)","DC":"8","H":"1.X.5.7",},{"ID":"S*F*------*****","D":"Special Operations Forces (SOF) Unit","DC":"8","H":"1.X.6",},{"ID":"S*F*A-----*****","D":"SOF Unit Aviation","DC":"8","H":"1.X.6.1",},{"ID":"S*F*AF----*****","D":"SOF Unit Fixed Wing","DC":"8","H":"1.X.6.1.1",},{"ID":"S*F*AFA---*****","D":"SOF Unit Fixed Wing Attack","DC":"8","H":"1.X.6.1.1.1",},{"ID":"S*F*AFK---*****","D":"SOF Unit Refuel","DC":"8","H":"1.X.6.1.1.2",},{"ID":"S*F*AFU---*****","D":"SOF Unit Fixed Wing Utility","DC":"8","H":"1.X.6.1.1.3",},{"ID":"S*F*AFUL--*****","D":"SOF Unit Fixed Wing Utility (Light)","DC":"8","H":"1.X.6.1.1.3.1",},{"ID":"S*F*AFUM--*****","D":"SOF Unit Fixed Wing Utility (Medium)","DC":"8","H":"1.X.6.1.1.3.2",},{"ID":"S*F*AFUH--*****","D":"SOF Unit Fixed Wing Utility (Heavy)","DC":"8","H":"1.X.6.1.1.3.3",},{"ID":"S*F*AV----*****","D":"SOF Unit V/STOL","DC":"8","H":"1.X.6.1.2",},{"ID":"S*F*AH----*****","D":"SOF Unit Rotary Wing","DC":"8","H":"1.X.6.1.3",},{"ID":"S*F*AHH---*****","D":"SOF Unit Rotary Wing Combat Search & Rescue","DC":"8","H":"1.X.6.1.3.1",},{"ID":"S*F*AHA---*****","D":"SOF Unit Rotary Wing Attack","DC":"8","H":"1.X.6.1.3.2",},{"ID":"S*F*AHU---*****","D":"SOF Unit Rotary Wing Utility","DC":"8","H":"1.X.6.1.3.3",},{"ID":"S*F*AHUL--*****","D":"SOF Unit Rotary Wing Utility (Light)","DC":"8","H":"1.X.6.1.3.3.1",},{"ID":"S*F*AHUM--*****","D":"SOF Unit Rotary Wing Utility (Medium)","DC":"8","H":"1.X.6.1.3.3.2",},{"ID":"S*F*AHUH--*****","D":"SOF Unit Rotary Wing Utility (Heavy)","DC":"8","H":"1.X.6.1.3.3.3",},{"ID":"S*F*N-----*****","D":"SOF Unit SOF Unit Naval","DC":"8","H":"1.X.6.2",},{"ID":"S*F*NS----*****","D":"SOF Unit Seal","DC":"8","H":"1.X.6.2.1",},{"ID":"S*F*NU----*****","D":"SOF Unit Underwater Demolition Team","DC":"8","H":"1.X.6.2.2",},{"ID":"S*F*NB----*****","D":"SOF Unit Special Boat","DC":"8","H":"1.X.6.2.3",},{"ID":"S*F*NN----*****","D":"SOF Unit Special SSNR","DC":"8","H":"1.X.6.2.4",},{"ID":"S*F*G-----*****","D":"SOF Unit Ground","DC":"8","H":"1.X.6.3",},{"ID":"S*F*GS----*****","D":"SOF Unit Special Forces","DC":"8","H":"1.X.6.3.1",},{"ID":"S*F*GR----*****","D":"SOF Unit Ranger","DC":"8","H":"1.X.6.3.2",},{"ID":"S*F*GP----*****","D":"SOF Unit Psychological Operations (PSYOP)","DC":"8","H":"1.X.6.3.3",},{"ID":"S*F*GPA---*****","D":"SOF Unit Fixed Wing Aviation (PSYOP)","DC":"8","H":"1.X.6.3.3.1",},{"ID":"S*F*GC----*****","D":"SOF Unit Civil Affairs","DC":"8","H":"1.X.6.3.4",},{"ID":"S*F*B-----*****","D":"SOF Unit Support","DC":"8","H":"1.X.6.4",},{"ID":"S*Z*------*****","D":"Unknown Battle Dimension","DC":"8","H":"1.X.7",},{"ID":"I*-*--------***","D":"Signals Intelligence","DC":"0","H":"4.X",},{"ID":"I*P*--------***","D":"Space Track","DC":"0","H":"4.X.1",},{"ID":"I*P*S-------***","D":"Signal Intercept","DC":"0","H":"4.X.1.1",},{"ID":"I*P*SC------***","D":"Communications","DC":"0","H":"4.X.1.1.1",},{"ID":"I*P*SCD-----***","D":"Satellite Down-Link","DC":"8","H":"4.X.1.1.1.1",},{"ID":"I*P*SR------***","D":"Radar(Signal Intercept)","DC":"0","H":"4.X.1.1.2",},{"ID":"I*P*SRD-----***","D":"Data Transmission(SPACE TRACK)","DC":"8","H":"4.X.1.1.2.1",},{"ID":"I*P*SRE-----***","D":"Earth Surveillance","DC":"8","H":"4.X.1.1.2.2",},{"ID":"I*P*SRI-----***","D":"IFF (Transponder)(SPACE TRACK)","DC":"8","H":"4.X.1.1.2.3",},{"ID":"I*P*SRM-----***","D":"Multi-function(SPACE TRACK)","DC":"8","H":"4.X.1.1.2.4",},{"ID":"I*P*SRT-----***","D":"Target Acquisition(Space Track)","DC":"8","H":"4.X.1.1.2.5",},{"ID":"I*P*SRS-----***","D":"Space","DC":"8","H":"4.X.1.1.2.6",},{"ID":"I*P*SRU-----***","D":"Unknown(Space Track)","DC":"8","H":"4.X.1.1.2.7",},{"ID":"I*A*--------***","D":"Air Track","DC":"0","H":"4.X.2",},{"ID":"I*A*S-------***","D":"Signal Intercept","DC":"0","H":"4.X.2.1",},{"ID":"I*A*SC------***","D":"Communications","DC":"0","H":"4.X.2.1.1",},{"ID":"I*A*SCC-----***","D":"Cellular/Mobile(AIR TRACK)","DC":"8","H":"4.X.2.1.1.1",},{"ID":"I*A*SCO-----***","D":"Omni-Line-Of-Sight (LOS)(AIR TRACK)","DC":"8","H":"4.X.2.1.1.2",},{"ID":"I*A*SCP-----***","D":"Point-To-Point Line-Of-Sight (LOS)(Air Track)","DC":"8","H":"4.X.2.1.1.3",},{"ID":"I*A*SCS-----***","D":"Satellite Up-Link(Air Track)","DC":"8","H":"4.X.2.1.1.4",},{"ID":"I*A*SR------***","D":"Radar","DC":"0","H":"4.X.2.1.2",},{"ID":"I*A*SRAI----***","D":"Airborne Intercept","DC":"8","H":"4.X.2.1.2.1",},{"ID":"I*A*SRAS----***","D":"Airborne Search and Bombing","DC":"8","H":"4.X.2.1.2.2",},{"ID":"I*A*SRC-----***","D":"Controlled Intercept(AIR TRACK)","DC":"8","H":"4.X.2.1.2.3",},{"ID":"I*A*SRD-----***","D":"Data Transmission(AIR TRACK)","DC":"8","H":"4.X.2.1.2.4",},{"ID":"I*A*SRE-----***","D":"Early Warning(AIR TRACK)","DC":"8","H":"4.X.2.1.2.5",},{"ID":"I*A*SRF-----***","D":"Fire Control(AIR TRACK)","DC":"8","H":"4.X.2.1.2.6",},{"ID":"I*A*SRI-----***","D":"IFF (Transponder)(AIR TRACK)","DC":"8","H":"4.X.2.1.2.7",},{"ID":"I*A*SRMA----***","D":"Missile Acquisition(AIR TRACK)","DC":"8","H":"4.X.2.1.2.8",},{"ID":"I*A*SRMD----***","D":"Missile Downlink","DC":"8","H":"4.X.2.1.2.9",},{"ID":"I*A*SRMG----***","D":"Missile Guidance(AIR TRACK)","DC":"8","H":"4.X.2.1.2.10",},{"ID":"I*A*SRMT----***","D":"Missile Tracking(AIR TRACK)","DC":"8","H":"4.X.2.1.2.11",},{"ID":"I*A*SRMF----***","D":"Multi-Function(AIR TRACK)","DC":"8","H":"4.X.2.1.2.12",},{"ID":"I*A*SRTI----***","D":"Target Illuminator(Air Track)","DC":"8","H":"4.X.2.1.2.13",},{"ID":"I*A*SRTA----***","D":"Target Acquisition(Air Track)","DC":"8","H":"4.X.2.1.2.14",},{"ID":"I*A*SRTT----***","D":"Target Tracking(Air Track)","DC":"8","H":"4.X.2.1.2.15",},{"ID":"I*A*SRU-----***","D":"Unknown(Air Track)","DC":"8","H":"4.X.2.1.2.16",},{"ID":"I*G*--------***","D":"Ground Track","DC":"0","H":"4.X.3",},{"ID":"I*G*S-------***","D":"Signal Intercept","DC":"0","H":"4.X.3.1",},{"ID":"I*G*SC------***","D":"Communications","DC":"0","H":"4.X.3.1.1",},{"ID":"I*G*SCC-----***","D":"Cellular/Mobile(GROUND TRACK)","DC":"8","H":"4.X.3.1.1.1",},{"ID":"I*G*SCO-----***","D":"Omni-Line-Of-Sight (LOS)(GROUND TRACK)","DC":"8","H":"4.X.3.1.1.2",},{"ID":"I*G*SCP-----***","D":"Point-To-Point Line-Of-Sight (LOS)(Ground Track)","DC":"8","H":"4.X.3.1.1.3",},{"ID":"I*G*SCS-----***","D":"Satellite Up-Link(Ground Track)","DC":"8","H":"4.X.3.1.1.4",},{"ID":"I*G*SCT-----***","D":"Tropospheric Scatter","DC":"8","H":"4.X.3.1.1.5",},{"ID":"I*G*SR------***","D":"Radar(Signals Intelligence)","DC":"0","H":"4.X.3.1.2",},{"ID":"I*G*SRAT----***","D":"Air Traffic Control(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.1",},{"ID":"I*G*SRAA----***","D":"Anti-Aircraft(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.2",},{"ID":"I*G*SRB-----***","D":"Battlefield Surveillance","DC":"8","H":"4.X.3.1.2.3",},{"ID":"I*G*SRCS----***","D":"Coastal Surveillance","DC":"8","H":"4.X.3.1.2.4",},{"ID":"I*G*SRCA----***","D":"Controlled Approach(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.5",},{"ID":"I*G*SRD-----***","D":"Data Transmission(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.6",},{"ID":"I*G*SRE-----***","D":"Early Warning(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.7",},{"ID":"I*G*SRF-----***","D":"Fire Control(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.8",},{"ID":"I*G*SRH-----***","D":"Height Finding(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.9",},{"ID":"I*G*SRI-----***","D":"Indentification Friend/Foe (Interrogator)(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.10",},{"ID":"I*G*SRMM----***","D":"Meteorological (Military)(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.11",},{"ID":"I*G*SRMA----***","D":"Missile Acquisition(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.12",},{"ID":"I*G*SRMG----***","D":"Missile Guidance(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.13",},{"ID":"I*G*SRMT----***","D":"Missile Tracking(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.14",},{"ID":"I*G*SRMF----***","D":"Multi-Function(GROUND TRACK)","DC":"8","H":"4.X.3.1.2.15",},{"ID":"I*G*SRS-----***","D":"Shell Tracking","DC":"8","H":"4.X.3.1.2.16",},{"ID":"I*G*SRTA----***","D":"Target Acquisition(Radar)","DC":"8","H":"4.X.3.1.2.17",},{"ID":"I*G*SRTI----***","D":"Target Illuminator(Ground Track)","DC":"8","H":"4.X.3.1.2.18",},{"ID":"I*G*SRTT----***","D":"Target Tracking(Ground Track)","DC":"8","H":"4.X.3.1.2.19",},{"ID":"I*G*SRU-----***","D":"Unknown(Ground Track)","DC":"8","H":"4.X.3.1.2.20",},{"ID":"I*S*--------***","D":"Sea Surface Track","DC":"0","H":"4.X.4",},{"ID":"I*S*S-------***","D":"Signal Intercept","DC":"0","H":"4.X.4.1",},{"ID":"I*S*SC------***","D":"Communications","DC":"0","H":"4.X.4.1.1",},{"ID":"I*S*SCC-----***","D":"Cellular/Mobile(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.1.1",},{"ID":"I*S*SCO-----***","D":"Omni-Line-Of-Sight (LOS)(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.1.2",},{"ID":"I*S*SCP-----***","D":"Point-To-Point Line-Of-Sight (LOS)(Sea Surface Track)","DC":"8","H":"4.X.4.1.1.3",},{"ID":"I*S*SCS-----***","D":"Satellite Up-Link(Sea Surface Track)","DC":"8","H":"4.X.4.1.1.4",},{"ID":"I*S*SR------***","D":"Radar(Sea Surface Track)","DC":"0","H":"4.X.4.1.2",},{"ID":"I*S*SRAT----***","D":"Air Traffic Control(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.1",},{"ID":"I*S*SRAA----***","D":"Anti-Aircraft(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.2",},{"ID":"I*S*SRCA----***","D":"Controlled Approach(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.3",},{"ID":"I*S*SRCI----***","D":"Controlled Intercept(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.4",},{"ID":"I*S*SRD-----***","D":"Data Transmission(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.5",},{"ID":"I*S*SRE-----***","D":"Early Warning(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.6",},{"ID":"I*S*SRF-----***","D":"Fire Control(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.7",},{"ID":"I*S*SRH-----***","D":"Height Finding(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.8",},{"ID":"I*S*SRI-----***","D":"Indentification Friend/Foe (Interrogator)(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.9",},{"ID":"I*S*SRMM----***","D":"Meteorological (Military)(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.10",},{"ID":"I*S*SRMA----***","D":"Missile Acquisition(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.11",},{"ID":"I*S*SRMG----***","D":"Missile Guidance(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.12",},{"ID":"I*S*SRMT----***","D":"Missile Tracking(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.13",},{"ID":"I*S*SRMF----***","D":"Multi-Function(SEA SURFACE TRACK)","DC":"8","H":"4.X.4.1.2.14",},{"ID":"I*S*SRS-----***","D":"Surface Search(Sea Surface Track)","DC":"8","H":"4.X.4.1.2.15",},{"ID":"I*S*SRTA----***","D":"Target Acquisition(Sea Surface Track)","DC":"8","H":"4.X.4.1.2.16",},{"ID":"I*S*SRTI----***","D":"Target Illuminator(Sea Surface Track)","DC":"8","H":"4.X.4.1.2.17",},{"ID":"I*S*SRTT----***","D":"Target Tracking(Sea Surface Track)","DC":"8","H":"4.X.4.1.2.18",},{"ID":"I*S*SRU-----***","D":"Unknown(Sea Surface Track)","DC":"8","H":"4.X.4.1.2.19",},{"ID":"I*U*--------***","D":"Subsurface Track","DC":"0","H":"4.X.5",},{"ID":"I*U*S-------***","D":"Signal Intercept","DC":"0","H":"4.X.5.1",},{"ID":"I*U*SC------***","D":"Communications","DC":"0","H":"4.X.5.1.1",},{"ID":"I*U*SCO-----***","D":"Omni-Line-Of-Sight (LOS)(SUBSURFACE TRACK)","DC":"8","H":"4.X.5.1.1.1",},{"ID":"I*U*SCP-----***","D":"Point-To-Point Line-Of-Sight (LOS)(Subsurface Track)","DC":"8","H":"4.X.5.1.1.2",},{"ID":"I*U*SCS-----***","D":"Satellite Up-Link(Subsurface Track)","DC":"8","H":"4.X.5.1.1.3",},{"ID":"I*U*SR------***","D":"Radar(Subsurface Track)","DC":"0","H":"4.X.5.1.2",},{"ID":"I*U*SRD-----***","D":"Data Transmission(SUBSURFACE TRACK)","DC":"8","H":"4.X.5.1.2.1",},{"ID":"I*U*SRE-----***","D":"Early Warning(SUBSURFACE TRACK)","DC":"8","H":"4.X.5.1.2.2",},{"ID":"I*U*SRM-----***","D":"Multi-Function(Subsurface Track)","DC":"8","H":"4.X.5.1.2.3",},{"ID":"I*U*SRS-----***","D":"Surface Search(Subsurface Track)","DC":"8","H":"4.X.5.1.2.4",},{"ID":"I*U*SRT-----***","D":"Target Acquisition(Subsurface Track)","DC":"8","H":"4.X.5.1.2.5",},{"ID":"I*U*SRU-----***","D":"Unknown(Subsurface Track)","DC":"8","H":"4.X.5.1.2.6",},{"ID":"O*-*------*****","D":"Stability Operations","DC":"0","H":"5.X",},{"ID":"O*V*------*****","D":"Violent Activities","DC":"0","H":"5.X.1",},{"ID":"O*V*A-----*****","D":"Arson/Fire","DC":"8","H":"5.X.1.1",},{"ID":"O*V*M-----*****","D":"Killing (General)","DC":"8","H":"5.X.1.2",},{"ID":"O*V*MA----*****","D":"Murder","DC":"8","H":"5.X.1.2.1",},{"ID":"O*V*MB----*****","D":"Execution","DC":"8","H":"5.X.1.2.2",},{"ID":"O*V*MC----*****","D":"Assassination","DC":"8","H":"5.X.1.2.3",},{"ID":"O*V*B-----*****","D":"Bomb/Bombing","DC":"8","H":"5.X.1.3",},{"ID":"O*V*Y-----*****","D":"Booby Trap","DC":"8","H":"5.X.1.4",},{"ID":"O*V*D-----*****","D":"Drive-By Shooting","DC":"8","H":"5.X.1.5",},{"ID":"O*V*S-----*****","D":"Sniping","DC":"8","H":"5.X.1.6",},{"ID":"O*V*P-----*****","D":"Poisoning","DC":"8","H":"5.X.1.7",},{"ID":"O*V*E-----*****","D":"Explosion","DC":"8","H":"5.X.1.8",},{"ID":"O*V*EI----*****","D":"IED Explosion","DC":"8","H":"5.X.1.8.1",},{"ID":"O*V*EG----*****","D":"Explosion, Grenade","DC":"8","H":"5.X.1.8.2",},{"ID":"O*V*EN----*****","D":"Explosion, Incendiary","DC":"8","H":"5.X.1.8.3",},{"ID":"O*V*EM----*****","D":"Explosion, Mine","DC":"8","H":"5.X.1.8.4",},{"ID":"O*V*EO----*****","D":"Explosion, Mortar Fire","DC":"8","H":"5.X.1.8.5",},{"ID":"O*V*ER----*****","D":"Explosion, Rocket","DC":"8","H":"5.X.1.8.6",},{"ID":"O*V*EV----*****","D":"Explosion, Wheeled Vehicle","DC":"8","H":"5.X.1.8.7",},{"ID":"O*L*------*****","D":"Locations","DC":"0","H":"5.X.2",},{"ID":"O*L*B-----*****","D":"Black List Location","DC":"8","H":"5.X.2.1",},{"ID":"O*L*G-----*****","D":"Gray List Location","DC":"8","H":"5.X.2.2",},{"ID":"O*L*W-----*****","D":"White List Location","DC":"8","H":"5.X.2.3",},{"ID":"O*L*M-----*****","D":"Mass Grave Location","DC":"8","H":"5.X.2.4",},{"ID":"O*L*E-----H****","D":"Drug Lab","DC":"8","H":"5.X.2.6",},{"ID":"O*L*H-----H****","D":"House/Residence","DC":"8","H":"5.X.2.7",},{"ID":"O*L*N-----H****","D":"Cave Entrance","DC":"8","H":"5.X.2.8",},{"ID":"O*L*H-----H****","D":"Palace/Presidential Residence","DC":"8","H":"5.X.2.9",},{"ID":"O*L*F-----H****","D":"Polling Place","DC":"8","H":"5.X.2.10",},{"ID":"O*O*------*****","D":"Operations","DC":"0","H":"5.X.3",},{"ID":"O*O*P-----*****","D":"Patrolling","DC":"8","H":"5.X.3.1",},{"ID":"O*O*R-----*****","D":"Recruitment","DC":"0","H":"5.X.3.2",},{"ID":"O*O*RW----*****","D":"Recruitment (Willing)","DC":"8","H":"5.X.3.2.1",},{"ID":"O*O*RC----*****","D":"Recruitment (Coerced/Impressed)","DC":"8","H":"5.X.3.2.2",},{"ID":"O*O*D-----*****","D":"Demonstration","DC":"8","H":"5.X.3.3",},{"ID":"O*O*M-----*****","D":"Mine Laying","DC":"8","H":"5.X.3.4",},{"ID":"O*O*Y-----*****","D":"Psychological Operations (Psyop)","DC":"8","H":"5.X.3.5",},{"ID":"O*O*YT----*****","D":"Psyop (TV and Radio Propaganda)","DC":"8","H":"5.X.3.5.1",},{"ID":"O*O*YW----*****","D":"Psyop (Written Propaganda)","DC":"8","H":"5.X.3.5.2",},{"ID":"O*O*YH----*****","D":"House-to-House Propaganda","DC":"8","H":"5.X.3.5.3",},{"ID":"O*O*F-----*****","D":"Foraging/Searching","DC":"8","H":"5.X.3.6",},{"ID":"O*O*S-----*****","D":"Spy","DC":"8","H":"5.X.3.7",},{"ID":"O*O*O-----*****","D":"Food Distribution","DC":"8","H":"5.X.3.8",},{"ID":"O*O*E-----*****","D":"Extortion","DC":"8","H":"5.X.3.9",},{"ID":"O*O*H-----*****","D":"Hijacking","DC":"0","H":"5.X.3.10",},{"ID":"O*O*HT----*****","D":"Hijacking (Vehicle)","DC":"8","H":"5.X.3.10.1",},{"ID":"O*O*HA----*****","D":"Hijacking (Airplane)","DC":"8","H":"5.X.3.10.2",},{"ID":"O*O*HV----*****","D":"Hijacking (Boat)","DC":"8","H":"5.X.3.10.3",},{"ID":"O*O*K-----*****","D":"Kidnapping","DC":"8","H":"5.X.3.11",},{"ID":"O*O*KA----*****","D":"Attempted Kidnapping","DC":"8","H":"5.X.3.11.1",},{"ID":"O*O*A-----*****","D":"Arrest","DC":"8","H":"5.X.3.12",},{"ID":"O*O*U-----*****","D":"Drug Operation","DC":"8","H":"5.X.3.13",},{"ID":"O*O*UT----*****","D":"Drug Trafficking","DC":"8","H":"5.X.3.13.1",},{"ID":"O*O*C-----*****","D":"Composite Loss","DC":"8","H":"5.X.3.14",},{"ID":"O*O*CA----*****","D":"Composite Loss Combat","DC":"8","H":"5.X.3.14.1",},{"ID":"O*O*CB----*****","D":"Composite Loss Accident","DC":"8","H":"5.X.3.14.2",},{"ID":"O*O*CC----*****","D":"Composite Loss Other","DC":"8","H":"5.X.3.14.3",},{"ID":"O*O*N-----*****","D":"Raid on a House","DC":"8","H":"5.X.3.15",},{"ID":"O*O*2-----*****","D":"Burglary","DC":"8","H":"5.X.3.16",},{"ID":"O*O*V-----*****","D":"Home Eviction","DC":"8","H":"5.X.3.17",},{"ID":"O*O*I-----*****","D":"Black Marketing","DC":"8","H":"5.X.3.18",},{"ID":"O*O*J-----*****","D":"Jail Break","DC":"8","H":"5.X.3.19",},{"ID":"O*O*B-----*****","D":"Robbery","DC":"8","H":"5.X.3.20",},{"ID":"O*O*G-----*****","D":"Sabotage","DC":"8","H":"5.X.3.21",},{"ID":"O*O*X-----*****","D":"Smuggling","DC":"8","H":"5.X.3.22",},{"ID":"O*O*W-----*****","D":"Rock Throwing","DC":"8","H":"5.X.3.23",},{"ID":"O*O*Z-----*****","D":"Suspicious Activity","DC":"8","H":"5.X.3.24",},{"ID":"O*O*T-----*****","D":"Theft","DC":"8","H":"5.X.3.25",},{"ID":"O*O*TV----*****","D":"Wheeled Vehicle Theft","DC":"8","H":"5.X.3.25.1",},{"ID":"O*O*Q-----*****","D":"Warrant Served","DC":"8","H":"5.X.3.26",},{"ID":"O*I*------*****","D":"Items","DC":"0","H":"5.X.4",},{"ID":"O*I*R-----*****","D":"Refugees","DC":"8","H":"5.X.4.1",},{"ID":"O*I*S-----*****","D":"Safe House","DC":"8","H":"5.X.4.2",},{"ID":"O*I*G-----*****","D":"Graffiti","DC":"8","H":"5.X.4.3",},{"ID":"O*I*V-----*****","D":"Vandalism/Loot/Ransack/Plunder/Sack","DC":"8","H":"5.X.4.4",},{"ID":"O*I*I-----*****","D":"Known Insurgent Vehicle","DC":"8","H":"5.X.4.5",},{"ID":"O*I*D-----*****","D":"Drug Vehicle","DC":"8","H":"5.X.4.6",},{"ID":"O*I*F-----*****","D":"Internal Security Force","DC":"8","H":"5.X.4.7",},{"ID":"O*I*M-----*****","D":"Meeting","DC":"8","H":"5.X.4.8",},{"ID":"O*I*T-----*****","D":"Tent","DC":"8","H":"5.X.4.9",},{"ID":"O*P*------*****","D":"Individual","DC":"8","H":"5.X.5",},{"ID":"O*P*A-----*****","D":"Leader","DC":"8","H":"5.X.5.1",},{"ID":"O*P*AR----*****","D":"Religious Leader","DC":"8","H":"5.X.5.1.1",},{"ID":"O*P*B-----*****","D":"Targeted Individual","DC":"8","H":"5.X.5.2",},{"ID":"O*P*C-----*****","D":"Terrorist","DC":"8","H":"5.X.5.3",},{"ID":"O*P*D-----*****","D":"Dead Body","DC":"8","H":"5.X.5.4",},{"ID":"O*P*E-----*****","D":"Speaker","DC":"8","H":"5.X.5.5",},{"ID":"O*P*F-----*****","D":"IED Suicide Bomber","DC":"8","H":"5.X.5.6",},{"ID":"O*P*G-----*****","D":"Exfiltrating Individual","DC":"8","H":"5.X.5.7",},{"ID":"O*P*H-----*****","D":"Infiltrating Individual","DC":"8","H":"5.X.5.8",},{"ID":"O*G*------*****","D":"Non-Military Group or Organization","DC":"8","H":"5.X.6",},{"ID":"O*G*B-----*****","D":"Non-Governmental Organizations (NGO)","DC":"8","H":"5.X.6.2",},{"ID":"O*G*C-----*****","D":"Terrorist Organization","DC":"8","H":"5.X.6.3",},{"ID":"O*G*D-----*****","D":"Religious Organization","DC":"8","H":"5.X.6.4",},{"ID":"O*G*E-----*****","D":"Foreign Fighter","DC":"8","H":"5.X.6.5",},{"ID":"O*G*F-----*****","D":"Gang","DC":"8","H":"5.X.6.6",},{"ID":"O*R*------*****","D":"Rape","DC":"8","H":"5.X.7",},{"ID":"O*R*A-----*****","D":"Attempted Rape","DC":"8","H":"5.X.7.1",},{"ID":"O*E*------*****","D":"Events SASO","DC":"0","H":"5.X.10",},{"ID":"O*E*A-----*****","D":"Elections SASO","DC":"8","H":"5.X.10.1",},{"ID":"O*E*B-----*****","D":"Speech SASO","DC":"8","H":"5.X.10.2",},{"ID":"O*E*C-----*****","D":"Sermon SASO","DC":"8","H":"5.X.10.3",},{"ID":"O*E*D-----*****","D":"Meeting SASO","DC":"8","H":"5.X.10.4",},{"ID":"O*E*E-----*****","D":"Demonstration(Events) SASO","DC":"8","H":"5.X.10.5",},{"ID":"O*E*F-----*****","D":"Riot SASO","DC":"8","H":"5.X.10.6",},{"ID":"O*E*G-----*****","D":"Gang Activity SASO","DC":"8","H":"5.X.10.7",},{"ID":"O*E*H-----*****","D":"Jail Break/Escape Custody SASO","DC":"8","H":"5.X.10.8",},{"ID":"O*E*I-----*****","D":"Rock Throwing SASO","DC":"8","H":"5.X.10.9",},{"ID":"O*E*J-----*****","D":"Illegal Selling/Purchasing/Distributing/Black Market SASO","DC":"8","H":"5.X.10.10",},{"ID":"O*E*K-----*****","D":"Surveillance SASO","DC":"8","H":"5.X.10.11",},{"ID":"O*E*L-----*****","D":"Lights SASO","DC":"8","H":"5.X.10.12",},{"ID":"O*E*M-----*****","D":"Border Crossing SASO","DC":"8","H":"5.X.10.13",},{"ID":"O*E*N-----*****","D":"Border Activity SASO","DC":"8","H":"5.X.10.14",},{"ID":"O*E*O-----*****","D":"Smuggling SASO","DC":"8","H":"5.X.10.15",},{"ID":"O*E*P-----*****","D":"Exfiltration SASO","DC":"8","H":"5.X.10.16",},{"ID":"O*E*Q-----*****","D":"Infiltration SASO","DC":"8","H":"5.X.10.17",},{"ID":"O*E*R-----*****","D":"Auto Theft SASO","DC":"8","H":"5.X.10.18",},{"ID":"O*E*S-----*****","D":"Auto Accident SASO","DC":"8","H":"5.X.10.19",},{"ID":"O*E*T-----*****","D":"Looting SASO","DC":"8","H":"5.X.10.20",},{"ID":"O*E*U-----*****","D":"Theft SASO","DC":"8","H":"5.X.10.21",},{"ID":"O*E*V-----*****","D":"Robbery SASO","DC":"8","H":"5.X.10.22",},{"ID":"O*E*W-----*****","D":"Home Eviction SASO","DC":"8","H":"5.X.10.23",},{"ID":"O*E*X-----*****","D":"Shooting (Non Deadly) SASO","DC":"8","H":"5.X.10.24",},{"ID":"O*E*Y-----*****","D":"Raid SASO","DC":"8","H":"5.X.10.25",},{"ID":"O*E*Z-----*****","D":"Sabotage SASO","DC":"8","H":"5.X.10.26",},{"ID":"O*E*AA----*****","D":"Warrant Served SASO","DC":"8","H":"5.X.10.27",},{"ID":"O*E*AB----*****","D":"Rape SASO","DC":"8","H":"5.X.10.28",},{"ID":"O*E*AC----*****","D":"Attempted Rape SASO","DC":"8","H":"5.X.10.29",},{"ID":"O*E*AD----*****","D":"Attack(Events) SASO","DC":"0","H":"5.X.10.30",},{"ID":"O*E*ADA---*****","D":"Attack on NGO SASO","DC":"8","H":"5.X.10.30.1",},{"ID":"O*E*ADB---*****","D":"Terrorist Attack SASO","DC":"8","H":"5.X.10.30.2",},{"ID":"O*E*ADC---*****","D":"Grenade Attack SASO","DC":"8","H":"5.X.10.30.3",},{"ID":"O*E*ADD---*****","D":"Rocket Attack SASO","DC":"8","H":"5.X.10.30.4",},{"ID":"O*E*AE----*****","D":"Explosions SASO","DC":"0","H":"5.X.10.31",},{"ID":"O*E*AEA---*****","D":"Explosion (general) SASO","DC":"8","H":"5.X.10.31.1",},{"ID":"O*E*AEB---*****","D":"Explosion, Mine SASO","DC":"8","H":"5.X.10.31.2",},{"ID":"O*E*AEC---*****","D":"Explosion, Grenade SASO","DC":"8","H":"5.X.10.31.3",},{"ID":"O*E*AED---*****","D":"Explosion, Bomb SASO","DC":"8","H":"5.X.10.31.4",},{"ID":"O*E*AEE---*****","D":"Explosion, Mortar Fire SASO","DC":"8","H":"5.X.10.31.5",},{"ID":"O*E*AEF---*****","D":"Explosion, Incendiary SASO","DC":"8","H":"5.X.10.31.6",},{"ID":"O*E*AEG---*****","D":"Explosion, Rocket SASO","DC":"8","H":"5.X.10.31.7",},{"ID":"O*E*AEH---*****","D":"Explosion, Improvised Explosive Device (IED) SASO","DC":"8","H":"5.X.10.31.8",},{"ID":"O*E*AEI---*****","D":"Explosion, Car Bomb SASO","DC":"8","H":"5.X.10.31.9",},{"ID":"O*E*AEJ---*****","D":"Suicide Bombing SASO","DC":"8","H":"5.X.10.31.10",},{"ID":"O*E*AF----*****","D":"Fighting/Contact SASO","DC":"0","H":"5.X.10.32",},{"ID":"O*E*AFA---*****","D":"Fighting (General) SASO","DC":"8","H":"5.X.10.32.1",},{"ID":"O*E*AFB---*****","D":"Coalition vs. Enemy SASO","DC":"8","H":"5.X.10.32.2",},{"ID":"O*E*AFC---*****","D":"Coalition vs. Coalition SASO","DC":"8","H":"5.X.10.32.3",},{"ID":"O*E*AG----*****","D":"Drug Possession SASO","DC":"8","H":"5.X.10.33",},{"ID":"O*E*AH----*****","D":"Drug Trafficking SASO","DC":"8","H":"5.X.10.34",},{"ID":"O*E*AI----*****","D":"Suspicious Activity SASO","DC":"8","H":"5.X.10.35",},{"ID":"O*E*AJ----*****","D":"Activity SASO","DC":"8","H":"5.X.10.36",},{"ID":"O*E*AK----*****","D":"Threat SASO","DC":"8","H":"5.X.10.37",},{"ID":"O*E*AL----*****","D":"Crater SASO","DC":"8","H":"5.X.10.38",},{"ID":"O*E*AM----*****","D":"Pothole SASO","DC":"8","H":"5.X.10.39",},{"ID":"O*E*AN----*****","D":"Escalation of Force SASO","DC":"8","H":"5.X.10.40",},{"ID":"O*E*AO----*****","D":"Submunitions SASO","DC":"8","H":"5.X.10.41",},{"ID":"O*E*AP----*****","D":"Confiscation SASO","DC":"8","H":"5.X.10.42",},{"ID":"O*E*AQ----*****","D":"Counter Insurgency SASO","DC":"8","H":"5.X.10.43",},{"ID":"O*E*AR----*****","D":"Counter Terrorism SASO","DC":"8","H":"5.X.10.44",},{"ID":"O*E*AS----*****","D":"Humanitarian Assistance SASO","DC":"8","H":"5.X.10.45",},{"ID":"O*E*AT----*****","D":"Tests of Security SASO","DC":"8","H":"5.X.10.46",},{"ID":"O*E*AU----*****","D":"AWOL SASO","DC":"8","H":"5.X.10.47",},{"ID":"O*E*AV----*****","D":"Curfew SASO","DC":"8","H":"5.X.10.48",},{"ID":"O*E*AW----*****","D":"DUI SASO","DC":"8","H":"5.X.10.49",},{"ID":"O*E*AX----*****","D":"Prostitution SASO","DC":"8","H":"5.X.10.50",},{"ID":"O*Y*------*****","D":"Organization/Groups SASO","DC":"0","H":"5.X.11",},{"ID":"O*Y*A-----*****","D":"Organization (General) SASO","DC":"8","H":"5.X.11.1",},{"ID":"O*Y*B-----*****","D":"NGO Organization SASO","DC":"8","H":"5.X.11.2",},{"ID":"O*Y*C-----*****","D":"Displaced Persons, Refugees SASO","DC":"8","H":"5.X.11.3",},{"ID":"O*Y*D-----*****","D":"Terrorist Organization SASO","DC":"8","H":"5.X.11.4",},{"ID":"O*Y*E-----*****","D":"Religious Organization SASO","DC":"8","H":"5.X.11.5",},{"ID":"O*Y*F-----*****","D":"Group Tribe Cell SASO","DC":"8","H":"5.X.11.6",},{"ID":"O*Y*G-----*****","D":"Foreign Fighters SASO","DC":"8","H":"5.X.11.7",},{"ID":"O*Y*R-----*****","D":"Red Cross SASO","DC":"8","H":"5.X.11.8",},{"ID":"O*Y*SP----*****","D":"State Police SASO","DC":"8","H":"5.X.11.9",},{"ID":"O*Y*LP----*****","D":"Local Police SASO","DC":"8","H":"5.X.11.10",},{"ID":"O*Y*SH----*****","D":"Shelter SASO","DC":"8","H":"5.X.11.11",},{"ID":"O*Y*FM----*****","D":"FEMA SASO","DC":"8","H":"5.X.11.12",},{"ID":"O*Y*SA----*****","D":"Staging Area SASO","DC":"8","H":"5.X.11.13",},{"ID":"O*Y*EP----*****","D":"Evacuation Point SASO","DC":"8","H":"5.X.11.14",},{"ID":"O*Y*PD----*****","D":"Person in Distress SASO","DC":"8","H":"5.X.11.15",},{"ID":"O*S*------*****","D":"Structures SASO","DC":"0","H":"5.X.13",},{"ID":"O*S*A-----*****","D":"Compound/Post/Fort SASO","DC":"8","H":"5.X.13.1",},{"ID":"O*S*B-----*****","D":"House/Residence SASO","DC":"8","H":"5.X.13.2",},{"ID":"O*S*C-----*****","D":"Safe House(Structures) SASO","DC":"8","H":"5.X.13.3",},{"ID":"O*S*D-----*****","D":"Church SASO","DC":"8","H":"5.X.13.4",},{"ID":"O*S*E-----*****","D":"Mosque SASO","DC":"8","H":"5.X.13.5",},{"ID":"O*S*F-----*****","D":"Synagogue SASO","DC":"8","H":"5.X.13.6",},{"ID":"O*S*G-----*****","D":"Warehouse/Storage Facility SASO","DC":"8","H":"5.X.13.7",},{"ID":"O*S*H-----*****","D":"Bunker/Underground Facility SASO","DC":"8","H":"5.X.13.8",},{"ID":"O*S*I-----*****","D":"Tents SASO","DC":"8","H":"5.X.13.9",},{"ID":"O*S*J-----*****","D":"Cave SASO","DC":"8","H":"5.X.13.10",},{"ID":"O*S*K-----*****","D":"Camps SASO","DC":"0","H":"5.X.13.11",},{"ID":"O*S*KA----*****","D":"Camp (General) SASO","DC":"8","H":"5.X.13.11.1",},{"ID":"O*S*KB----*****","D":"Displaced Persons/Refugees Camp SASO","DC":"8","H":"5.X.13.11.2",},{"ID":"O*S*KC----*****","D":"Training Camp SASO","DC":"8","H":"5.X.13.11.3",},{"ID":"O*S*L-----*****","D":"Prison/Detention Facility SASO","DC":"8","H":"5.X.13.12",},{"ID":"O*S*M-----*****","D":"Police Station SASO","DC":"8","H":"5.X.13.13",},{"ID":"O*S*N-----*****","D":"Palace/Presidential Residence SASO","DC":"8","H":"5.X.13.14",},{"ID":"O*Q*------*****","D":"Equipment/Weapons SASO","DC":"0","H":"5.X.14",},{"ID":"O*Q*A-----*****","D":"Weapons Found SASO","DC":"8","H":"5.X.14.1",},{"ID":"O*Q*B-----*****","D":"Weapons Cache SASO","DC":"8","H":"5.X.14.2",},{"ID":"O*Q*C-----*****","D":"Weapons Confiscated SASO","DC":"8","H":"5.X.14.3",},{"ID":"O*Q*D-----*****","D":"Weapons Sale SASO","DC":"8","H":"5.X.14.4",},{"ID":"O*Q*E-----*****","D":"Weapons Market SASO","DC":"8","H":"5.X.14.5",},{"ID":"O*Q*F-----*****","D":"Chem/Bio Weapons Cache SASO","DC":"8","H":"5.X.14.6",},{"ID":"O*Q*G-----*****","D":"Improvised Explosive Device (IED) SASO","DC":"8","H":"5.X.14.7",},{"ID":"O*Q*H-----*****","D":"Unexploded Ordnance (UXO) SASO","DC":"8","H":"5.X.14.8",},{"ID":"O*Q*I-----*****","D":"Horses SASO","DC":"8","H":"5.X.14.9",},{"ID":"O*Q*J-----*****","D":"Camels SASO","DC":"8","H":"5.X.14.10",},{"ID":"O*Q*K-----*****","D":"Donkeys SASO","DC":"8","H":"5.X.14.11",},{"ID":"E*-*------*****","D":"Emergency Management Symbols","DC":"0","H":"6.X",},{"ID":"E*I*------*****","D":"Incident","DC":"0","H":"6.X.1",},{"ID":"E*I*A-----*****","D":"Civil Disturbance Incident","DC":"8","H":"6.X.1.1",},{"ID":"O*O*D-----*****","D":"Civil Demonstration","DC":"8","H":"6.X.1.1.1",},{"ID":"O*I*R-----*****","D":"Civil Displaced Population","DC":"0","H":"6.X.1.1.2",},{"ID":"E*I*AC----*****","D":"Civil Rioting","DC":"8","H":"6.X.1.1.3",},{"ID":"E*I*B-----*****","D":"Criminal Activity Incident","DC":"8","H":"6.X.1.2",},{"ID":"E*I*BA----*****","D":"Bomb Threat","DC":"8","H":"6.X.1.2.1",},{"ID":"O*V*B-----*****","D":"Bomb","DC":"8","H":"6.X.1.2.2",},{"ID":"E*I*BC----*****","D":"Explosion (Bomb)","DC":"8","H":"6.X.1.2.3",},{"ID":"E*I*BD----*****","D":"Looting","DC":"8","H":"6.X.1.2.4",},{"ID":"O*V*P-----*****","D":"Poisoning","DC":"8","H":"6.X.1.2.5",},{"ID":"E*I*BF----*****","D":"Shooting","DC":"8","H":"6.X.1.2.6",},{"ID":"E*I*C-----*****","D":"Fire Incident","DC":"8","H":"6.X.1.3",},{"ID":"E*I*CA----*****","D":"Hot Spot","DC":"8","H":"6.X.1.3.1",},{"ID":"E*I*CB----*****","D":"Non-Residential Fire","DC":"8","H":"6.X.1.3.2",},{"ID":"E*I*CC----*****","D":"Origin","DC":"8","H":"6.X.1.3.3",},{"ID":"E*I*CD----*****","D":"Residential Fire","DC":"8","H":"6.X.1.3.4",},{"ID":"E*I*CE----*****","D":"School Fire","DC":"8","H":"6.X.1.3.5",},{"ID":"E*I*CF----*****","D":"Smoke","DC":"8","H":"6.X.1.3.6",},{"ID":"E*I*CG----*****","D":"Special Needs Fire","DC":"8","H":"6.X.1.3.7",},{"ID":"E*I*CH----*****","D":"Wild Fire","DC":"8","H":"6.X.1.3.8",},{"ID":"E*I*D-----*****","D":"Hazardous Material Incident","DC":"8","H":"6.X.1.4",},{"ID":"E*I*DA----*****","D":"Chemical Agent","DC":"8","H":"6.X.1.4.1",},{"ID":"E*I*DB----*****","D":"Corrosive Material","DC":"8","H":"6.X.1.4.2",},{"ID":"E*I*DC----*****","D":"Hazardous When Wet","DC":"8","H":"6.X.1.4.3",},{"ID":"E*I*DD----*****","D":"Explosive","DC":"8","H":"6.X.1.4.4",},{"ID":"E*I*DE----*****","D":"Flammable Gas","DC":"8","H":"6.X.1.4.5",},{"ID":"E*I*DF----*****","D":"Flammable Liquid","DC":"8","H":"6.X.1.4.6",},{"ID":"E*I*DG----*****","D":"Flammable Solid","DC":"8","H":"6.X.1.4.7",},{"ID":"E*I*DH----*****","D":"Non-Flammable Gas","DC":"8","H":"6.X.1.4.8",},{"ID":"E*I*DI----*****","D":"Organic Peroxide","DC":"8","H":"6.X.1.4.9",},{"ID":"E*I*DJ----*****","D":"Oxidizer","DC":"8","H":"6.X.1.4.10",},{"ID":"E*I*DK----*****","D":"Radioactive Material","DC":"8","H":"6.X.1.4.11",},{"ID":"E*I*DL----*****","D":"Spontaneously Combustible","DC":"8","H":"6.X.1.4.12",},{"ID":"E*I*DM----*****","D":"Toxic Gas","DC":"8","H":"6.X.1.4.13",},{"ID":"E*I*DN----*****","D":"Toxic and Infectious","DC":"8","H":"6.X.1.4.14",},{"ID":"E*I*DO----*****","D":"Unexploded Ordinance","DC":"8","H":"6.X.1.4.15",},{"ID":"E*I*E-----*****","D":"Air Incident","DC":"8","H":"6.X.1.5",},{"ID":"E*I*EA----*****","D":"Air Accident","DC":"8","H":"6.X.1.5.1",},{"ID":"O*O*HA----*****","D":"Air Hijacking","DC":"8","H":"6.X.1.5.2",},{"ID":"E*I*F-----*****","D":"Marine Incident","DC":"8","H":"6.X.1.6",},{"ID":"E*I*FA----*****","D":"Marine Accident","DC":"8","H":"6.X.1.6.1",},{"ID":"O*O*HV----*****","D":"Marine Hijacking","DC":"8","H":"6.X.1.6.2",},{"ID":"E*I*G-----*****","D":"Rail Incident","DC":"8","H":"6.X.1.7",},{"ID":"E*I*GA----*****","D":"Rail Accident","DC":"8","H":"6.X.1.7.1",},{"ID":"E*I*GB----*****","D":"Rail Hijacking","DC":"8","H":"6.X.1.7.2",},{"ID":"E*I*H-----*****","D":"Vehicle Incident","DC":"8","H":"6.X.1.8",},{"ID":"E*I*HA----*****","D":"Vehicle Accident","DC":"8","H":"6.X.1.8.1",},{"ID":"O*O*HT----*****","D":"Vehicle Hijacking","DC":"8","H":"6.X.1.8.2",},{"ID":"E*N*------*****","D":"Natural Events","DC":"0","H":"6.X.2",},{"ID":"E*O*------*****","D":"Operations","DC":"0","H":"6.X.3",},{"ID":"E*O*A-----*****","D":"Emergency Medical Operation","DC":"8","H":"6.X.3.1",},{"ID":"E*O*AA----*****","D":"Emergency Medical Operation Unit","DC":"8","H":"6.X.3.1.1",},{"ID":"E*O*AB----*****","D":"Emergency Medical Operation Equipment","DC":"8","H":"6.X.3.1.2",},{"ID":"E*O*AC----H****","D":"Emergency Medical Operation Installation","DC":"8","H":"6.X.3.1.3",},{"ID":"E*O*AD----H****","D":"EMT Station Location","DC":"8","H":"6.X.3.1.4",},{"ID":"E*O*AE----*****","D":"Ambulance","DC":"8","H":"6.X.3.1.5",},{"ID":"E*O*AF----*****","D":"Medical Evacuation Helicopter","DC":"8","H":"6.X.3.1.6",},{"ID":"E*O*AG----H****","D":"Health Department Facility","DC":"8","H":"6.X.3.1.7",},{"ID":"S*G*IXH---H****","D":"Hospital","DC":"8","H":"6.X.3.1.8",},{"ID":"S*S*NM----*****","D":"Hospital Ship","DC":"8","H":"6.X.3.1.9",},{"ID":"E*O*AJ----H****","D":"Medical Facilities Out Patient","DC":"8","H":"6.X.3.1.10",},{"ID":"E*O*AK----H****","D":"Morgue","DC":"8","H":"6.X.3.1.11",},{"ID":"E*O*AL----H****","D":"Pharmacy","DC":"8","H":"6.X.3.1.12",},{"ID":"E*O*AM----H****","D":"Triage","DC":"8","H":"6.X.3.1.13",},{"ID":"E*O*B-----*****","D":"Emergency Operation","DC":"8","H":"6.X.3.2",},{"ID":"E*O*BA----*****","D":"Emergency Operation Unit","DC":"8","H":"6.X.3.2.1",},{"ID":"E*O*BB----*****","D":"Emergency Operation Equipment","DC":"8","H":"6.X.3.2.2",},{"ID":"E*O*BC----H****","D":"Emergency Operation Installation","DC":"8","H":"6.X.3.2.3",},{"ID":"E*O*BD----*****","D":"Emergency Collection Evacuation Point","DC":"8","H":"6.X.3.2.4",},{"ID":"E*O*BE----H****","D":"Emergency Incident Command Center","DC":"8","H":"6.X.3.2.5",},{"ID":"E*O*BF----H****","D":"Emergency Operations Center","DC":"8","H":"6.X.3.2.6",},{"ID":"E*O*BG----H****","D":"Emergency Public Information Center","DC":"8","H":"6.X.3.2.7",},{"ID":"E*O*BH----H****","D":"Emergency Shelter","DC":"8","H":"6.X.3.2.8",},{"ID":"E*O*BI----H****","D":"Emergency Staging Area","DC":"8","H":"6.X.3.2.9",},{"ID":"E*O*BJ----*****","D":"Emergency Team","DC":"8","H":"6.X.3.2.10",},{"ID":"E*O*BK----H****","D":"Emergency Water Distribution Center","DC":"8","H":"6.X.3.2.11",},{"ID":"E*O*BL----H****","D":"Emergency Food Distribution Center","DC":"8","H":"6.X.3.2.12",},{"ID":"E*O*C-----*****","D":"Fire Fighting Operation","DC":"8","H":"6.X.3.3",},{"ID":"E*O*CA----*****","D":"Fire Fighting Operation Unit","DC":"8","H":"6.X.3.3.1",},{"ID":"E*O*CB----*****","D":"Fire Fighting Operation Equipment","DC":"8","H":"6.X.3.3.2",},{"ID":"E*O*CC----*****","D":"Fire Hydrant","DC":"8","H":"6.X.3.3.3",},{"ID":"E*O*CD----H****","D":"Other Water Supply Location","DC":"8","H":"6.X.3.3.4",},{"ID":"E*O*CE----H****","D":"Fire Station","DC":"8","H":"6.X.3.3.5",},{"ID":"E*O*D-----*****","D":"Law Enforcement Operation","DC":"8","H":"6.X.3.4",},{"ID":"E*O*DA----*****","D":"Law Enforcement Operation Unit","DC":"8","H":"6.X.3.4.1",},{"ID":"E*O*DB----*****","D":"Law Enforcement Operation Equipment","DC":"8","H":"6.X.3.4.2",},{"ID":"E*O*DC----H****","D":"Law Enforcement Operation Installation","DC":"8","H":"6.X.3.4.3",},{"ID":"E*O*DD----*****","D":"ATF","DC":"8","H":"6.X.3.4.4",},{"ID":"E*O*DDA---*****","D":"ATF Unit","DC":"8","H":"6.X.3.4.4.1",},{"ID":"E*O*DDB---*****","D":"ATF Equipment","DC":"8","H":"6.X.3.4.4.2",},{"ID":"E*O*DDC---H****","D":"ATF Installation","DC":"8","H":"6.X.3.4.4.3",},{"ID":"E*O*DE----*****","D":"Border Patrol","DC":"8","H":"6.X.3.4.5",},{"ID":"E*O*DEA---*****","D":"Border Patrol Unit","DC":"8","H":"6.X.3.4.5.1",},{"ID":"E*O*DEB---*****","D":"Border Patrol Equipment","DC":"8","H":"6.X.3.4.5.2",},{"ID":"E*O*DEC---H****","D":"Border Patrol Installation","DC":"8","H":"6.X.3.4.5.3",},{"ID":"E*O*DF----*****","D":"Customs Service","DC":"8","H":"6.X.3.4.6",},{"ID":"E*O*DFA---*****","D":"Customs Service Unit","DC":"8","H":"6.X.3.4.6.1",},{"ID":"E*O*DFB---*****","D":"Customs Service Equipment","DC":"8","H":"6.X.3.4.6.2",},{"ID":"E*O*DFC---H****","D":"Customs Service Installation","DC":"8","H":"6.X.3.4.6.3",},{"ID":"E*O*DG----*****","D":"DEA","DC":"8","H":"6.X.3.4.7",},{"ID":"E*O*DGA---*****","D":"DEA Unit","DC":"8","H":"6.X.3.4.7.1",},{"ID":"E*O*DGB---*****","D":"DEA Equipment","DC":"8","H":"6.X.3.4.7.2",},{"ID":"E*O*DGC---H****","D":"DEA Installation","DC":"8","H":"6.X.3.4.7.3",},{"ID":"E*O*DH----*****","D":"DOJ","DC":"8","H":"6.X.3.4.8",},{"ID":"E*O*DHA---*****","D":"DOJ Unit","DC":"8","H":"6.X.3.4.8.1",},{"ID":"E*O*DHB---*****","D":"DOJ Equipment","DC":"8","H":"6.X.3.4.8.2",},{"ID":"E*O*DHC---H****","D":"DOJ Installation","DC":"8","H":"6.X.3.4.8.3",},{"ID":"E*O*DI----*****","D":"FBI","DC":"8","H":"6.X.3.4.9",},{"ID":"E*O*DIA---*****","D":"FBI Unit","DC":"8","H":"6.X.3.4.9.1",},{"ID":"E*O*DIB---*****","D":"FBI Equipment","DC":"8","H":"6.X.3.4.9.2",},{"ID":"E*O*DIC---H****","D":"FBI Installation","DC":"8","H":"6.X.3.4.9.3",},{"ID":"E*O*DJ----*****","D":"Police","DC":"8","H":"6.X.3.4.10",},{"ID":"S*G*UULC--*****","D":"Police Unit","DC":"8","H":"6.X.3.4.10.1",},{"ID":"E*O*DJB---*****","D":"Police Equipment","DC":"8","H":"6.X.3.4.10.2",},{"ID":"E*O*DJC---H****","D":"Police Installation","DC":"8","H":"6.X.3.4.10.3",},{"ID":"E*O*DK----H****","D":"Prison","DC":"8","H":"6.X.3.4.11",},{"ID":"E*O*DL----*****","D":"Secret Service","DC":"8","H":"6.X.3.4.12",},{"ID":"E*O*DLA---*****","D":"Secret Service Unit","DC":"8","H":"6.X.3.4.12.1",},{"ID":"E*O*DLB---*****","D":"Secret Service Equipment","DC":"8","H":"6.X.3.4.12.2",},{"ID":"E*O*DLC---H****","D":"Secret Service Installation","DC":"8","H":"6.X.3.4.12.3",},{"ID":"E*O*DM----*****","D":"TSA","DC":"8","H":"6.X.3.4.13",},{"ID":"E*O*DMA---*****","D":"TSA Unit","DC":"8","H":"6.X.3.4.13.1",},{"ID":"E*O*DMB---*****","D":"TSA Equipment","DC":"8","H":"6.X.3.4.13.2",},{"ID":"E*O*DMC---H****","D":"TSA Installation","DC":"8","H":"6.X.3.4.13.3",},{"ID":"E*O*DN----*****","D":"Coast Guard","DC":"8","H":"6.X.3.4.14",},{"ID":"E*O*DNA---*****","D":"Coast Guard Unit","DC":"8","H":"6.X.3.4.14.1",},{"ID":"S*S*XL----*****","D":"Coast Guard Equipment","DC":"8","H":"6.X.3.4.14.2",},{"ID":"E*O*DNC---H****","D":"Coast Guard Installation","DC":"8","H":"6.X.3.4.14.3",},{"ID":"E*O*DO----*****","D":"US Marshals Service","DC":"8","H":"6.X.3.4.15",},{"ID":"E*O*DOA---*****","D":"US Marshals Service Unit","DC":"8","H":"6.X.3.4.15.1",},{"ID":"E*O*DOB---*****","D":"US Marshals Service Equipment","DC":"8","H":"6.X.3.4.15.2",},{"ID":"E*O*DOC---H****","D":"US Marshals Service Installation","DC":"8","H":"6.X.3.4.15.3",},{"ID":"S*G*ES----*****","D":"Sensor","DC":"8","H":"6.X.3.5",},{"ID":"E*O*EA----*****","D":"Biological Sensor","DC":"8","H":"6.X.3.5.1",},{"ID":"E*O*EB----*****","D":"Chemical Sensor","DC":"8","H":"6.X.3.5.2",},{"ID":"E*O*EC----*****","D":"Intrusion Sensor","DC":"8","H":"6.X.3.5.3",},{"ID":"E*O*ED----*****","D":"Nuclear Sensor","DC":"8","H":"6.X.3.5.4",},{"ID":"E*O*EE----*****","D":"Radiological Sensor","DC":"8","H":"6.X.3.5.5",},{"ID":"E*F*------H****","D":"Infrastructure","DC":"0","H":"6.X.4",},{"ID":"E*F*A-----H****","D":"Agriculture and Food Infrastructure","DC":"8","H":"6.X.4.1",},{"ID":"E*F*AA----H****","D":"Agricultural Laboratory","DC":"8","H":"6.X.4.1.1",},{"ID":"E*F*AB----H****","D":"Animal Feedlot","DC":"8","H":"6.X.4.1.2",},{"ID":"E*F*AC----H****","D":"Commercial Food Distribution Center","DC":"8","H":"6.X.4.1.3",},{"ID":"E*F*AD----H****","D":"Farm/Ranch","DC":"8","H":"6.X.4.1.4",},{"ID":"E*F*AE----H****","D":"Food Production Center","DC":"8","H":"6.X.4.1.5",},{"ID":"E*F*AF----H****","D":"Food Retail","DC":"8","H":"6.X.4.1.6",},{"ID":"E*F*AG----H****","D":"Grain Storage","DC":"8","H":"6.X.4.1.7",},{"ID":"E*F*B-----H****","D":"Banking Finance and Insurance Infrastructure","DC":"8","H":"6.X.4.2",},{"ID":"E*F*BA----*****","D":"ATM","DC":"8","H":"6.X.4.2.1",},{"ID":"E*F*BB----H****","D":"Bank","DC":"8","H":"6.X.4.2.2",},{"ID":"E*F*BC----H****","D":"Bullion Storage","DC":"8","H":"6.X.4.2.3",},{"ID":"E*F*BD----H****","D":"Federal Reserve Bank","DC":"8","H":"6.X.4.2.4",},{"ID":"E*F*BE----H****","D":"Financial Exchange","DC":"8","H":"6.X.4.2.5",},{"ID":"E*F*BF----H****","D":"Financial Services Other","DC":"8","H":"6.X.4.2.6",},{"ID":"E*F*C-----H****","D":"Commercial Infrastructure","DC":"8","H":"6.X.4.3",},{"ID":"E*F*CA----H****","D":"Chemical Plant","DC":"8","H":"6.X.4.3.1",},{"ID":"E*F*CB----H****","D":"Firearms Manufacturer","DC":"8","H":"6.X.4.3.2",},{"ID":"E*F*CC----H****","D":"Firearms Retailer","DC":"8","H":"6.X.4.3.3",},{"ID":"E*F*CD----H****","D":"Hazardous Material Production","DC":"8","H":"6.X.4.3.4",},{"ID":"E*F*CE----H****","D":"Hazardous Material Storage","DC":"8","H":"6.X.4.3.5",},{"ID":"E*F*CF----H****","D":"Industrial Site","DC":"8","H":"6.X.4.3.6",},{"ID":"E*F*CG----*****","D":"Landfill","DC":"8","H":"6.X.4.3.7",},{"ID":"E*F*CH----H****","D":"Pharmaceutical Manufacturer","DC":"8","H":"6.X.4.3.8",},{"ID":"E*F*CI----H****","D":"Contaminated Hazardous Waste Site","DC":"8","H":"6.X.4.3.9",},{"ID":"E*F*CJ----H****","D":"Toxic Release Inventory","DC":"8","H":"6.X.4.3.10",},{"ID":"E*F*D-----H****","D":"Educational Facilties Infrastructure","DC":"8","H":"6.X.4.4",},{"ID":"E*F*DA----H****","D":"College University","DC":"8","H":"6.X.4.4.1",},{"ID":"E*F*DB----H****","D":"School","DC":"8","H":"6.X.4.4.2",},{"ID":"S*G*IUE---H****","D":"Energy Facilities Infrastructure","DC":"8","H":"6.X.4.5",},{"ID":"E*F*EA----H****","D":"Generation Station","DC":"8","H":"6.X.4.5.1",},{"ID":"E*F*EB----H****","D":"Natural Gas Facility","DC":"8","H":"6.X.4.5.2",},{"ID":"S*G*IUEN--H****","D":"Nuclear Facility","DC":"8","H":"6.X.4.5.3",},{"ID":"S*G*IRP---*****","D":"Petrolium Facility","DC":"8","H":"6.X.4.5.4",},{"ID":"E*F*EE----H****","D":"Propane Facility","DC":"8","H":"6.X.4.5.5",},{"ID":"E*F*F-----H****","D":"Government Site Infrastructure","DC":"8","H":"6.X.4.6",},{"ID":"E*F*G-----H****","D":"Military Infrastructure","DC":"8","H":"6.X.4.7",},{"ID":"E*F*GA----H****","D":"Military Armory","DC":"8","H":"6.X.4.7.1",},{"ID":"S*G*IB----H****","D":"Military Base","DC":"8","H":"6.X.4.7.2",},{"ID":"E*F*H-----H****","D":"Postal Service Infrastructure","DC":"8","H":"6.X.4.8",},{"ID":"E*F*HA----H****","D":"Postal Distribution Center","DC":"8","H":"6.X.4.8.1",},{"ID":"E*F*HB----H****","D":"Post Office","DC":"8","H":"6.X.4.8.2",},{"ID":"E*F*I-----H****","D":"Public Venues Infrastructure","DC":"8","H":"6.X.4.9",},{"ID":"E*F*IA----H****","D":"Enclosed Facility","DC":"8","H":"6.X.4.9.1",},{"ID":"E*F*IB----H****","D":"Open Facility","DC":"8","H":"6.X.4.9.2",},{"ID":"E*F*IC----H****","D":"Recreational Area","DC":"8","H":"6.X.4.9.3",},{"ID":"E*F*ID----H****","D":"Religious Institution","DC":"8","H":"6.X.4.9.4",},{"ID":"E*F*J-----H****","D":"Special Needs Infrastructure","DC":"8","H":"6.X.4.10",},{"ID":"E*F*JA----H****","D":"Adult Day Care","DC":"8","H":"6.X.4.10.1",},{"ID":"E*F*JB----H****","D":"Child Day Care","DC":"8","H":"6.X.4.10.2",},{"ID":"E*F*JC----H****","D":"Elder Care","DC":"8","H":"6.X.4.10.3",},{"ID":"E*F*K-----H****","D":"Telecommunications Infrastructure","DC":"8","H":"6.X.4.11",},{"ID":"S*G*IUT---H****","D":"Telecommunications Facility","DC":"8","H":"6.X.4.11.1",},{"ID":"E*F*KB----H****","D":"Telecommunications Tower","DC":"8","H":"6.X.4.11.2",},{"ID":"S*G*IT----H****","D":"Transportation Infrastructure","DC":"8","H":"6.X.4.12",},{"ID":"E*F*LA----H****","D":"Air Traffic Control Facility","DC":"8","H":"6.X.4.12.1",},{"ID":"S*G*IBA---H****","D":"Airport","DC":"8","H":"6.X.4.12.2",},{"ID":"G*M*BCB---****X","D":"Bridge","DC":"8","H":"6.X.4.12.3",},{"ID":"E*F*LD----H****","D":"Bus Station","DC":"8","H":"6.X.4.12.4",},{"ID":"E*F*LE----H****","D":"Ferry Terminal","DC":"8","H":"6.X.4.12.5",},{"ID":"E*F*LF----H****","D":"Helicopter Landing Site","DC":"8","H":"6.X.4.12.6",},{"ID":"WOS-ML----P----","D":"Lock","DC":"8","H":"6.X.4.12.7",},{"ID":"E*F*LH----H****","D":"Maintenance Facility","DC":"8","H":"6.X.4.12.8",},{"ID":"S*G*IBN---H****","D":"Port","DC":"8","H":"6.X.4.12.9",},{"ID":"E*F*LJ----H****","D":"Rail Station","DC":"8","H":"6.X.4.12.10",},{"ID":"E*F*LK----H****","D":"Rest Stop","DC":"8","H":"6.X.4.12.11",},{"ID":"WOS-HPBA--P----","D":"Ship Anchorage","DC":"8","H":"6.X.4.12.12",},{"ID":"E*F*LM----H****","D":"Toll Facility","DC":"8","H":"6.X.4.12.13",},{"ID":"G*S*PO----****X","D":"Traffic Control Point","DC":"8","H":"6.X.4.12.14",},{"ID":"E*F*LO----H****","D":"Traffic Inspection Facility","DC":"8","H":"6.X.4.12.15",},{"ID":"E*F*LP----H****","D":"Tunnel","DC":"8","H":"6.X.4.12.16",},{"ID":"S*G*IUP---H****","D":"Water Supply Infrastructure","DC":"8","H":"6.X.4.13",},{"ID":"E*F*MA----H****","D":"Control Valve","DC":"8","H":"6.X.4.13.1",},{"ID":"E*F*MB----H****","D":"Dam","DC":"8","H":"6.X.4.13.2",},{"ID":"E*F*MC----H****","D":"Discharge Outfall","DC":"8","H":"6.X.4.13.3",},{"ID":"E*F*MD----H****","D":"Ground Water Well","DC":"8","H":"6.X.4.13.4",},{"ID":"E*F*ME----H****","D":"Pumping Station","DC":"8","H":"6.X.4.13.5",},{"ID":"E*F*MF----H****","D":"Reservoir","DC":"8","H":"6.X.4.13.6",},{"ID":"E*F*MG----H****","D":"Storage Tower","DC":"8","H":"6.X.4.13.7",},{"ID":"E*F*MH----H****","D":"Surface Water Intake","DC":"8","H":"6.X.4.13.8",},{"ID":"E*F*MI----H****","D":"Wastewater Treatment Facility","DC":"8","H":"6.X.4.13.9",}]}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.ShapeTypes={};armyc2.c2sd.renderer.so.ShapeTypes.RECTANGLE="RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.POINT="POINT";armyc2.c2sd.renderer.so.ShapeTypes.ELLIPSE="ELLIPSE";armyc2.c2sd.renderer.so.ShapeTypes.ROUNDED_RECTANGLE="ROUNDED_RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.LINE="LINE";armyc2.c2sd.renderer.so.ShapeTypes.BCURVE="BCURVE";armyc2.c2sd.renderer.so.ShapeTypes.ARC="ARC";armyc2.c2sd.renderer.so.ShapeTypes.PATH="PATH";armyc2.c2sd.renderer.so.ActionTypes={};armyc2.c2sd.renderer.so.ActionTypes.ACTION_MOVE_TO=0;armyc2.c2sd.renderer.so.ActionTypes.ACTION_LINE_TO=1;armyc2.c2sd.renderer.so.ActionTypes.ACTION_CURVE_TO=2;armyc2.c2sd.renderer.so.ActionTypes.ACTION_QUAD_TO=3;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC_TO=4;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC=5;armyc2.c2sd.renderer.so.ActionTypes.ACTION_DASHED_LINE_TO=6;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.utilities=armyc2.c2sd.renderer.so.utilities||{};armyc2.c2sd.renderer.so.utilities.relativeCCW=function(x1,y1,x2,y2,px,py) +{x2-=x1;y2-=y1;px-=x1;py-=y1;var ccw=px*y2-py*x2;if(ccw===0.0){ccw=px*x2+py*y2;if(ccw>0.0){px-=x2;py-=y2;ccw=px*x2+py*y2;if(ccw<0.0){ccw=0.0;}}} +return(ccw<0.0)?-1:((ccw>0.0)?1:0);};armyc2.c2sd.renderer.so.utilities.linesIntersect=function(x1,y1,x2,y2,x3,y3,x4,y4) +{var rCCW1=this.relativeCCW(x1,y1,x2,y2,x3,y3),rCCW2=this.relativeCCW(x1,y1,x2,y2,x4,y4),rCCW3=this.relativeCCW(x3,y3,x4,y4,x1,y1),rCCW4=this.relativeCCW(x3,y3,x4,y4,x2,y2);return(((rCCW1*rCCW2)<=0)&&((rCCW3*rCCW4)<=0));};armyc2.c2sd.renderer.so.utilities.intersectRects=function(src1,src2) +{var x1=Math.max(src1.getMinX(),src2.getMinX()),y1=Math.max(src1.getMinY(),src2.getMinY()),x2=Math.min(src1.getMaxX(),src2.getMaxX()),y2=Math.min(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2-x1,y2-y1);};armyc2.c2sd.renderer.so.utilities.unionRects=function(src1,src2) +{var x1=Math.min(src1.getMinX(),src2.getMinX()),y1=Math.min(src1.getMinY(),src2.getMinY()),x2=Math.max(src1.getMaxX(),src2.getMaxX()),y2=Math.max(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2,y2);};if(typeof CanvasRenderingContext2D!=='undefined'&&CanvasRenderingContext2D.prototype.dashedLineTo!=='undefined') +{CanvasRenderingContext2D.prototype.dashedLineTo=function(fromX,fromY,toX,toY,pattern) +{var lt=function(a,b){return a<=b;};var gt=function(a,b){return a>=b;};var capmin=function(a,b){return Math.min(a,b);};var capmax=function(a,b){return Math.max(a,b);};var checkX={thereYet:gt,cap:capmin};var checkY={thereYet:gt,cap:capmin};if(fromY-toY>0){checkY.thereYet=lt;checkY.cap=capmax;} +if(fromX-toX>0) +{checkX.thereYet=lt;checkX.cap=capmax;} +this.moveTo(fromX,fromY);var offsetX=fromX;var offsetY=fromY;var idx=0,dash=true;while(!(checkX.thereYet(offsetX,toX)&&checkY.thereYet(offsetY,toY))) +{var ang=Math.atan2(toY-fromY,toX-fromX);var len=pattern[idx];offsetX=checkX.cap(toX,offsetX+(Math.cos(ang)*len));offsetY=checkY.cap(toY,offsetY+(Math.sin(ang)*len));if(dash)this.lineTo(offsetX,offsetY);else this.moveTo(offsetX,offsetY);idx=(idx+1)%pattern.length;dash=!dash;}};}var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Point=function(x,y){this.x=x,this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.getShapeType=function(){return"POINT";};armyc2.c2sd.renderer.so.Point.prototype.getX=function(){return this.x;};armyc2.c2sd.renderer.so.Point.prototype.getY=function(){return this.y;};armyc2.c2sd.renderer.so.Point.prototype.setLocation=function(x,y){this.x=x;this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.shift=function(x,y){this.x+=x;this.y+=y;};armyc2.c2sd.renderer.so.Point.prototype.toStringFormatted=function(){return"{x:"+this.x+", y:"+this.y+"}";};armyc2.c2sd.renderer.so.Point.prototype.clone=function(){return new armyc2.c2sd.renderer.so.Point(this.x,this.y);};armyc2.c2sd.renderer.so.Point.prototype.setPath=function(context){var x=this.x,y=this.y;context.moveTo(x,y);context.lineTo(x+1,y);context.lineTo(x+1,y+1);context.lineTo(x,y+1);context.closePath();};armyc2.c2sd.renderer.so.Point.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.Point.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Rectangle=function(x,y,width,height){this.x=x,this.y=y,this.width=width,this.height=height,this.bottom=y+height,this.right=x+width;};armyc2.c2sd.renderer.so.Rectangle.prototype.getShapeType=function(){return"RECTANGLE";};armyc2.c2sd.renderer.so.Rectangle.prototype.getBounds=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.x-1,this.y-1,this.width+2,this.height+2);};armyc2.c2sd.renderer.so.Rectangle.prototype.getX=function(){return this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.getY=function(){return this.y;};armyc2.c2sd.renderer.so.Rectangle.prototype.getWidth=function(){return this.width;};armyc2.c2sd.renderer.so.Rectangle.prototype.getHeight=function(){return this.height;};armyc2.c2sd.renderer.so.Rectangle.prototype.getBottom=function(){return this.bottom;};armyc2.c2sd.renderer.so.Rectangle.prototype.getRight=function(){return this.right;};armyc2.c2sd.renderer.so.Rectangle.prototype.getCenterX=function(){return this.x+(this.width/2);};armyc2.c2sd.renderer.so.Rectangle.prototype.getCenterY=function(){return this.y+(this.height/2);};armyc2.c2sd.renderer.so.Rectangle.prototype.setLocation=function(x,y){this.x=x;this.y=y;this.bottom=y+this.height;this.right=x+this.width;};armyc2.c2sd.renderer.so.Rectangle.prototype.isEmpty=function() +{return(this.width<=0.0)||(this.height<=0.0);};armyc2.c2sd.renderer.so.Rectangle.prototype.shift=function(x,y){this.x+=x;this.y+=y;this.right+=x;this.bottom+=y;};armyc2.c2sd.renderer.so.Rectangle.prototype.shiftTL=function(x,y){this.x+=x;this.y+=y;this.height=this.bottom-this.y;this.width=this.right-this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.shiftBR=function(x,y){this.right+=x;this.bottom+=y;this.height=this.bottom-this.y;this.width=this.right-this.x;};armyc2.c2sd.renderer.so.Rectangle.prototype.grow=function(pixel){this.shiftTL(-pixel,-pixel);this.shiftBR(pixel,pixel);};armyc2.c2sd.renderer.so.Rectangle.prototype.union=function(rect){if(rect) +{if(rect.ythis.bottom) +this.bottom=rect.bottom;if(rect.right>this.right) +this.right=rect.right;this.width=this.right-this.x;this.height=this.bottom-this.y;}};armyc2.c2sd.renderer.so.Rectangle.prototype.unionPoint=function(point){if(point) +{if(point.ythis.bottom) +this.bottom=point.y;if(point.x>this.right) +this.right=point.x;this.width=this.right-this.x;this.height=this.bottom-this.y;}};armyc2.c2sd.renderer.so.Rectangle.prototype.contains=function(x,y,w,h) +{if(x&&y&&w&&h) +{if(this.isEmpty()||w<=0||h<=0){return false;} +var x0=this.getX(),y0=this.getY();return(x>=x0&&y>=y0&&(x+w)<=x0+this.getWidth()&&(y+h)<=y0+this.getHeight());} +else if(x&&y) +{var x0=this.getX(),y0=this.getY();return(x>=x0&&y>=y0&&x=x0&&y>=y0&&x=x0&&y>=y0&&(x+w)<=x0+this.getWidth()&&(y+h)<=y0+this.getHeight());} +else +return false;};armyc2.c2sd.renderer.so.Rectangle.prototype.outcode=function(x,y) +{var out=0;if(this.width<=0){out|=this.OUT_LEFT|this.OUT_RIGHT;}else if(xthis.x+this.width){out|=this.OUT_RIGHT;} +if(this.height<=0){out|=this.OUT_TOP|this.OUT_BOTTOM;}else if(ythis.y+this.height){out|=this.OUT_BOTTOM;} +return out;};armyc2.c2sd.renderer.so.Rectangle.prototype.intersectsLine=function(x1,y1,x2,y2) +{var out1,out2;if((out2=outcode(x2,y2))===0){return true;} +while((out1=outcode(x1,y1))!==0){if((out1&out2)!==0){return false;} +if((out1&(this.OUT_LEFT|this.OUT_RIGHT))!==0){var x=this.getX();if((out1&this.OUT_RIGHT)!==0){x+=getWidth();} +y1=y1+(x-x1)*(y2-y1)/(x2-x1);x1=x;}else{var y=this.getY();if((out1&this.OUT_BOTTOM)!==0){y+=getHeight();} +x1=x1+(y-y1)*(x2-x1)/(y2-y1);y1=y;}} +return true;};armyc2.c2sd.renderer.so.Rectangle.prototype.setPath=function(context){var x=this.getX(),y=this.getY(),w=this.getWidth(),h=this.getHeight();context.moveTo(x,y);context.lineTo(x+w,y);context.lineTo(x+w,y+h);context.lineTo(x,y+h);context.closePath();};armyc2.c2sd.renderer.so.Rectangle.prototype.stroke=function(context){context.strokeRect(this.getX(),this.getY(),this.getWidth(),this.getHeight());};armyc2.c2sd.renderer.so.Rectangle.prototype.fill=function(context){context.fillRect(this.getX(),this.getY(),this.getWidth(),this.getHeight());};armyc2.c2sd.renderer.so.Rectangle.prototype.clone=function(){return new armyc2.c2sd.renderer.so.Rectangle(this.x,this.y,this.width,this.height);};armyc2.c2sd.renderer.so.Rectangle.prototype.intersects=function(r) +{if(r) +{var tw=this.width;var th=this.height;var rw=r.width;var rh=r.height;if(rw<=0||rh<=0||tw<=0||th<=0){return false;} +var tx=this.x;var ty=this.y;var rx=r.x;var ry=r.y;rw+=rx;rh+=ry;tw+=tx;th+=ty;return((rwtx)&&(rhty)&&(twrx)&&(thry));} +else +return false;};armyc2.c2sd.renderer.so.Rectangle.prototype.toSVGElement=function(stroke,strokeWidth,fill) +{var line='0) +return false;else +return true;};};'use strict';function defined(value){return value!==undefined&&value!==null;}'use strict';function DeveloperError(message){this.name='DeveloperError';this.message=message;var stack;try{throw new Error();}catch(e){stack=e.stack;} +this.stack=stack;} +if(defined(Object.create)){DeveloperError.prototype=Object.create(Error.prototype);DeveloperError.prototype.constructor=DeveloperError;} +DeveloperError.prototype.toString=function(){var str=this.name+': '+this.message;if(defined(this.stack)){str+='\n'+this.stack.toString();} +return str;};DeveloperError.throwInstantiationError=function(){throw new DeveloperError('This function defines an interface and should not be called directly.');};'use strict';var freezeObject=Object.freeze;if(!defined(freezeObject)){freezeObject=function(o){return o;};}'use strict';var definePropertyWorks=(function(){try{return'x'in Object.defineProperty({},'x',{});}catch(e){return false;}})();var defineProperties=Object.defineProperties;if(!definePropertyWorks||!defined(defineProperties)){defineProperties=function(o){return o;};}'use strict';function defaultValue(a,b){if(a!==undefined){return a;} +return b;} +defaultValue.EMPTY_OBJECT=freezeObject({});var CesiumMath={};CesiumMath.EPSILON1=0.1;CesiumMath.EPSILON2=0.01;CesiumMath.EPSILON3=0.001;CesiumMath.EPSILON4=0.0001;CesiumMath.EPSILON5=0.00001;CesiumMath.EPSILON6=0.000001;CesiumMath.EPSILON7=0.0000001;CesiumMath.EPSILON8=0.00000001;CesiumMath.EPSILON9=0.000000001;CesiumMath.EPSILON10=0.0000000001;CesiumMath.EPSILON11=0.00000000001;CesiumMath.EPSILON12=0.000000000001;CesiumMath.EPSILON13=0.0000000000001;CesiumMath.EPSILON14=0.00000000000001;CesiumMath.EPSILON15=0.000000000000001;CesiumMath.EPSILON16=0.0000000000000001;CesiumMath.EPSILON17=0.00000000000000001;CesiumMath.EPSILON18=0.000000000000000001;CesiumMath.EPSILON19=0.0000000000000000001;CesiumMath.EPSILON20=0.00000000000000000001;CesiumMath.GRAVITATIONALPARAMETER=3.986004418e14;CesiumMath.SOLAR_RADIUS=6.955e8;CesiumMath.LUNAR_RADIUS=1737400.0;CesiumMath.SIXTY_FOUR_KILOBYTES=64*1024;CesiumMath.sign=function(value){if(value>0){return 1;} +if(value<0){return-1;} +return 0;};CesiumMath.signNotZero=function(value){return value<0.0?-1.0:1.0;};CesiumMath.toSNorm=function(value){return Math.round((CesiumMath.clamp(value,-1.0,1.0)*0.5+0.5)*255.0);};CesiumMath.fromSNorm=function(value){return CesiumMath.clamp(value,0.0,255.0)/255.0*2.0-1.0;};CesiumMath.sinh=function(value){var part1=Math.pow(Math.E,value);var part2=Math.pow(Math.E,-1.0*value);return(part1-part2)*0.5;};CesiumMath.cosh=function(value){var part1=Math.pow(Math.E,value);var part2=Math.pow(Math.E,-1.0*value);return(part1+part2)*0.5;};CesiumMath.lerp=function(p,q,time){return((1.0-time)*p)+(time*q);};CesiumMath.PI=Math.PI;CesiumMath.ONE_OVER_PI=1.0/Math.PI;CesiumMath.PI_OVER_TWO=Math.PI*0.5;CesiumMath.PI_OVER_THREE=Math.PI/3.0;CesiumMath.PI_OVER_FOUR=Math.PI/4.0;CesiumMath.PI_OVER_SIX=Math.PI/6.0;CesiumMath.THREE_PI_OVER_TWO=(3.0*Math.PI)*0.5;CesiumMath.TWO_PI=2.0*Math.PI;CesiumMath.ONE_OVER_TWO_PI=1.0/(2.0*Math.PI);CesiumMath.RADIANS_PER_DEGREE=Math.PI/180.0;CesiumMath.DEGREES_PER_RADIAN=180.0/Math.PI;CesiumMath.RADIANS_PER_ARCSECOND=CesiumMath.RADIANS_PER_DEGREE/3600.0;CesiumMath.toRadians=function(degrees){if(!defined(degrees)){throw new DeveloperError('degrees is required.');} +return degrees*CesiumMath.RADIANS_PER_DEGREE;};CesiumMath.toDegrees=function(radians){if(!defined(radians)){throw new DeveloperError('radians is required.');} +return radians*CesiumMath.DEGREES_PER_RADIAN;};CesiumMath.convertLongitudeRange=function(angle){if(!defined(angle)){throw new DeveloperError('angle is required.');} +var twoPi=CesiumMath.TWO_PI;var simplified=angle-Math.floor(angle/twoPi)*twoPi;if(simplified<-Math.PI){return simplified+twoPi;} +if(simplified>=Math.PI){return simplified-twoPi;} +return simplified;};CesiumMath.negativePiToPi=function(x){if(!defined(x)){throw new DeveloperError('x is required.');} +return CesiumMath.zeroToTwoPi(x+CesiumMath.PI)-CesiumMath.PI;};CesiumMath.zeroToTwoPi=function(x){if(!defined(x)){throw new DeveloperError('x is required.');} +var mod=CesiumMath.mod(x,CesiumMath.TWO_PI);if(Math.abs(mod)CesiumMath.EPSILON14){return CesiumMath.TWO_PI;} +return mod;};CesiumMath.mod=function(m,n){if(!defined(m)){throw new DeveloperError('m is required.');} +if(!defined(n)){throw new DeveloperError('n is required.');} +return((m%n)+n)%n;};CesiumMath.equalsEpsilon=function(left,right,relativeEpsilon,absoluteEpsilon){if(!defined(left)){throw new DeveloperError('left is required.');} +if(!defined(right)){throw new DeveloperError('right is required.');} +if(!defined(relativeEpsilon)){throw new DeveloperError('relativeEpsilon is required.');} +absoluteEpsilon=defaultValue(absoluteEpsilon,relativeEpsilon);var absDiff=Math.abs(left-right);return absDiff<=absoluteEpsilon||absDiff<=relativeEpsilon*Math.max(Math.abs(left),Math.abs(right));};var factorials=[1];CesiumMath.factorial=function(n){if(typeof n!=='number'||n<0){throw new DeveloperError('A number greater than or equal to 0 is required.');} +var length=factorials.length;if(n>=length){var sum=factorials[length-1];for(var i=length;i<=n;i++){factorials.push(sum*i);}} +return factorials[n];};CesiumMath.incrementWrap=function(n,maximumValue,minimumValue){minimumValue=defaultValue(minimumValue,0.0);if(!defined(n)){throw new DeveloperError('n is required.');} +if(maximumValue<=minimumValue){throw new DeveloperError('maximumValue must be greater than minimumValue.');} +++n;if(n>maximumValue){n=minimumValue;} +return n;};CesiumMath.isPowerOfTwo=function(n){if(typeof n!=='number'||n<0){throw new DeveloperError('A number greater than or equal to 0 is required.');} +return(n!==0)&&((n&(n-1))===0);};CesiumMath.nextPowerOfTwo=function(n){if(typeof n!=='number'||n<0){throw new DeveloperError('A number greater than or equal to 0 is required.');} +--n;n|=n>>1;n|=n>>2;n|=n>>4;n|=n>>8;n|=n>>16;++n;return n;};CesiumMath.clamp=function(value,min,max){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(min)){throw new DeveloperError('min is required.');} +if(!defined(max)){throw new DeveloperError('max is required.');} +return valuemax?max:value;};CesiumMath.acosClamped=function(value){if(!defined(value)){throw new DeveloperError('value is required.');} +return Math.acos(CesiumMath.clamp(value,-1.0,1.0));};CesiumMath.asinClamped=function(value){if(!defined(value)){throw new DeveloperError('value is required.');} +return Math.asin(CesiumMath.clamp(value,-1.0,1.0));};CesiumMath.chordLength=function(angle,radius){if(!defined(angle)){throw new DeveloperError('angle is required.');} +if(!defined(radius)){throw new DeveloperError('radius is required.');} +return 2.0*radius*Math.sin(angle*0.5);};CesiumMath.logBase=function(number,base){if(!defined(number)){throw new DeveloperError('number is required.');} +if(!defined(base)){throw new DeveloperError('base is required.');} +return Math.log(number)/Math.log(base);};CesiumMath.fog=function(distanceToCamera,density){var scalar=distanceToCamera*density;return 1.0-Math.exp(-(scalar*scalar));};'use strict';var CesiumMath=CesiumMath||{};function Cartesian3(x,y,z){this.x=defaultValue(x,0.0);this.y=defaultValue(y,0.0);this.z=defaultValue(z,0.0);} +Cartesian3.fromSpherical=function(spherical,result){if(!defined(spherical)){throw new DeveloperError('spherical is required');} +if(!defined(result)){result=new Cartesian3();} +var clock=spherical.clock;var cone=spherical.cone;var magnitude=defaultValue(spherical.magnitude,1.0);var radial=magnitude*Math.sin(cone);result.x=radial*Math.cos(clock);result.y=radial*Math.sin(clock);result.z=magnitude*Math.cos(cone);return result;};Cartesian3.fromElements=function(x,y,z,result){if(!defined(result)){return new Cartesian3(x,y,z);} +result.x=x;result.y=y;result.z=z;return result;};Cartesian3.clone=function(cartesian,result){if(!defined(cartesian)){return undefined;} +if(!defined(result)){return new Cartesian3(cartesian.x,cartesian.y,cartesian.z);} +result.x=cartesian.x;result.y=cartesian.y;result.z=cartesian.z;return result;};Cartesian3.fromCartesian4=Cartesian3.clone;Cartesian3.packedLength=3;Cartesian3.pack=function(value,array,startingIndex){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);array[startingIndex++]=value.x;array[startingIndex++]=value.y;array[startingIndex]=value.z;};Cartesian3.unpack=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);if(!defined(result)){result=new Cartesian3();} +result.x=array[startingIndex++];result.y=array[startingIndex++];result.z=array[startingIndex];return result;};Cartesian3.fromArray=Cartesian3.unpack;Cartesian3.maximumComponent=function(cartesian){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +return Math.max(cartesian.x,cartesian.y,cartesian.z);};Cartesian3.minimumComponent=function(cartesian){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +return Math.min(cartesian.x,cartesian.y,cartesian.z);};Cartesian3.minimumByComponent=function(first,second,result){if(!defined(first)){throw new DeveloperError('first is required.');} +if(!defined(second)){throw new DeveloperError('second is required.');} +if(!defined(result)){throw new DeveloperError('result is required.');} +result.x=Math.min(first.x,second.x);result.y=Math.min(first.y,second.y);result.z=Math.min(first.z,second.z);return result;};Cartesian3.maximumByComponent=function(first,second,result){if(!defined(first)){throw new DeveloperError('first is required.');} +if(!defined(second)){throw new DeveloperError('second is required.');} +if(!defined(result)){throw new DeveloperError('result is required.');} +result.x=Math.max(first.x,second.x);result.y=Math.max(first.y,second.y);result.z=Math.max(first.z,second.z);return result;};Cartesian3.magnitudeSquared=function(cartesian){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +return cartesian.x*cartesian.x+cartesian.y*cartesian.y+cartesian.z*cartesian.z;};Cartesian3.magnitude=function(cartesian){return Math.sqrt(Cartesian3.magnitudeSquared(cartesian));};var distanceScratch=new Cartesian3();Cartesian3.distance=function(left,right){if(!defined(left)||!defined(right)){throw new DeveloperError('left and right are required.');} +Cartesian3.subtract(left,right,distanceScratch);return Cartesian3.magnitude(distanceScratch);};Cartesian3.distanceSquared=function(left,right){if(!defined(left)||!defined(right)){throw new DeveloperError('left and right are required.');} +Cartesian3.subtract(left,right,distanceScratch);return Cartesian3.magnitudeSquared(distanceScratch);};Cartesian3.normalize=function(cartesian,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var magnitude=Cartesian3.magnitude(cartesian);result.x=cartesian.x/magnitude;result.y=cartesian.y/magnitude;result.z=cartesian.z/magnitude;return result;};Cartesian3.dot=function(left,right){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +return left.x*right.x+left.y*right.y+left.z*right.z;};Cartesian3.multiplyComponents=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=left.x*right.x;result.y=left.y*right.y;result.z=left.z*right.z;return result;};Cartesian3.add=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=left.x+right.x;result.y=left.y+right.y;result.z=left.z+right.z;return result;};Cartesian3.subtract=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=left.x-right.x;result.y=left.y-right.y;result.z=left.z-right.z;return result;};Cartesian3.multiplyByScalar=function(cartesian,scalar,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(typeof scalar!=='number'){throw new DeveloperError('scalar is required and must be a number.');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=cartesian.x*scalar;result.y=cartesian.y*scalar;result.z=cartesian.z*scalar;return result;};Cartesian3.divideByScalar=function(cartesian,scalar,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(typeof scalar!=='number'){throw new DeveloperError('scalar is required and must be a number.');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=cartesian.x/scalar;result.y=cartesian.y/scalar;result.z=cartesian.z/scalar;return result;};Cartesian3.negate=function(cartesian,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=-cartesian.x;result.y=-cartesian.y;result.z=-cartesian.z;return result;};Cartesian3.abs=function(cartesian,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=Math.abs(cartesian.x);result.y=Math.abs(cartesian.y);result.z=Math.abs(cartesian.z);return result;};var lerpScratch=new Cartesian3();Cartesian3.lerp=function(start,end,t,result){if(!defined(start)){throw new DeveloperError('start is required.');} +if(!defined(end)){throw new DeveloperError('end is required.');} +if(typeof t!=='number'){throw new DeveloperError('t is required and must be a number.');} +if(!defined(result)){throw new DeveloperError('result is required.');} +Cartesian3.multiplyByScalar(end,t,lerpScratch);result=Cartesian3.multiplyByScalar(start,1.0-t,result);return Cartesian3.add(lerpScratch,result,result);};var angleBetweenScratch=new Cartesian3();var angleBetweenScratch2=new Cartesian3();Cartesian3.angleBetween=function(left,right){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +Cartesian3.normalize(left,angleBetweenScratch);Cartesian3.normalize(right,angleBetweenScratch2);var cosine=Cartesian3.dot(angleBetweenScratch,angleBetweenScratch2);var sine=Cartesian3.magnitude(Cartesian3.cross(angleBetweenScratch,angleBetweenScratch2,angleBetweenScratch));return Math.atan2(sine,cosine);};var mostOrthogonalAxisScratch=new Cartesian3();Cartesian3.mostOrthogonalAxis=function(cartesian,result){if(!defined(cartesian)){throw new DeveloperError('cartesian is required.');} +if(!defined(result)){throw new DeveloperError('result is required.');} +var f=Cartesian3.normalize(cartesian,mostOrthogonalAxisScratch);Cartesian3.abs(f,f);if(f.x<=f.y){if(f.x<=f.z){result=Cartesian3.clone(Cartesian3.UNIT_X,result);}else{result=Cartesian3.clone(Cartesian3.UNIT_Z,result);}}else{if(f.y<=f.z){result=Cartesian3.clone(Cartesian3.UNIT_Y,result);}else{result=Cartesian3.clone(Cartesian3.UNIT_Z,result);}} +return result;};Cartesian3.equals=function(left,right){return(left===right)||((defined(left))&&(defined(right))&&(left.x===right.x)&&(left.y===right.y)&&(left.z===right.z));};Cartesian3.equalsArray=function(cartesian,array,offset){return cartesian.x===array[offset]&&cartesian.y===array[offset+1]&&cartesian.z===array[offset+2];};Cartesian3.equalsEpsilon=function(left,right,relativeEpsilon,absoluteEpsilon){return(left===right)||(defined(left)&&defined(right)&&CesiumMath.equalsEpsilon(left.x,right.x,relativeEpsilon,absoluteEpsilon)&&CesiumMath.equalsEpsilon(left.y,right.y,relativeEpsilon,absoluteEpsilon)&&CesiumMath.equalsEpsilon(left.z,right.z,relativeEpsilon,absoluteEpsilon));};Cartesian3.cross=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var leftX=left.x;var leftY=left.y;var leftZ=left.z;var rightX=right.x;var rightY=right.y;var rightZ=right.z;var x=leftY*rightZ-leftZ*rightY;var y=leftZ*rightX-leftX*rightZ;var z=leftX*rightY-leftY*rightX;result.x=x;result.y=y;result.z=z;return result;};Cartesian3.fromDegrees=function(longitude,latitude,height,ellipsoid,result){if(!defined(longitude)){throw new DeveloperError('longitude is required');} +if(!defined(latitude)){throw new DeveloperError('latitude is required');} +var lon=CesiumMath.toRadians(longitude);var lat=CesiumMath.toRadians(latitude);return Cartesian3.fromRadians(lon,lat,height,ellipsoid,result);};var scratchN=new Cartesian3();var scratchK=new Cartesian3();var wgs84RadiiSquared=new Cartesian3(6378137.0*6378137.0,6378137.0*6378137.0,6356752.3142451793*6356752.3142451793);Cartesian3.fromRadians=function(longitude,latitude,height,ellipsoid,result){if(!defined(longitude)){throw new DeveloperError('longitude is required');} +if(!defined(latitude)){throw new DeveloperError('latitude is required');} +height=defaultValue(height,0.0);var radiiSquared=defined(ellipsoid)?ellipsoid.radiiSquared:wgs84RadiiSquared;var cosLatitude=Math.cos(latitude);scratchN.x=cosLatitude*Math.cos(longitude);scratchN.y=cosLatitude*Math.sin(longitude);scratchN.z=Math.sin(latitude);scratchN=Cartesian3.normalize(scratchN,scratchN);Cartesian3.multiplyComponents(radiiSquared,scratchN,scratchK);var gamma=Math.sqrt(Cartesian3.dot(scratchN,scratchK));scratchK=Cartesian3.divideByScalar(scratchK,gamma,scratchK);scratchN=Cartesian3.multiplyByScalar(scratchN,height,scratchN);if(!defined(result)){result=new Cartesian3();} +return Cartesian3.add(scratchK,scratchN,result);};Cartesian3.fromDegreesArray=function(coordinates,ellipsoid,result){if(!defined(coordinates)){throw new DeveloperError('positions is required.');} +var pos=new Array(coordinates.length);for(var i=0;iCesiumMath.EPSILON12);if(!defined(result)){return new Cartesian3(positionX*xMultiplier,positionY*yMultiplier,positionZ*zMultiplier);} +result.x=positionX*xMultiplier;result.y=positionY*yMultiplier;result.z=positionZ*zMultiplier;return result;}'use strict';var Cartesian3=Cartesian3||{};var CesiumMath=CesiumMath||{};function Cartographic(longitude,latitude,height){this.longitude=defaultValue(longitude,0.0);this.latitude=defaultValue(latitude,0.0);this.height=defaultValue(height,0.0);} +Cartographic.fromRadians=function(longitude,latitude,height,result){if(!defined(longitude)){throw new DeveloperError('longitude is required.');} +if(!defined(latitude)){throw new DeveloperError('latitude is required.');} +height=defaultValue(height,0.0);if(!defined(result)){return new Cartographic(longitude,latitude,height);} +result.longitude=longitude;result.latitude=latitude;result.height=height;return result;};Cartographic.fromDegrees=function(longitude,latitude,height,result){if(!defined(longitude)){throw new DeveloperError('longitude is required.');} +if(!defined(latitude)){throw new DeveloperError('latitude is required.');} +longitude=CesiumMath.toRadians(longitude);latitude=CesiumMath.toRadians(latitude);return Cartographic.fromRadians(longitude,latitude,height,result);};var cartesianToCartographicN=new Cartesian3();var cartesianToCartographicP=new Cartesian3();var cartesianToCartographicH=new Cartesian3();var wgs84OneOverRadii=new Cartesian3(1.0/6378137.0,1.0/6378137.0,1.0/6356752.3142451793);var wgs84OneOverRadiiSquared=new Cartesian3(1.0/(6378137.0*6378137.0),1.0/(6378137.0*6378137.0),1.0/(6356752.3142451793*6356752.3142451793));var wgs84CenterToleranceSquared=CesiumMath.EPSILON1;Cartographic.fromCartesian=function(cartesian,ellipsoid,result){var oneOverRadii=defined(ellipsoid)?ellipsoid.oneOverRadii:wgs84OneOverRadii;var oneOverRadiiSquared=defined(ellipsoid)?ellipsoid.oneOverRadiiSquared:wgs84OneOverRadiiSquared;var centerToleranceSquared=defined(ellipsoid)?ellipsoid._centerToleranceSquared:wgs84CenterToleranceSquared;var p=scaleToGeodeticSurface(cartesian,oneOverRadii,oneOverRadiiSquared,centerToleranceSquared,cartesianToCartographicP);if(!defined(p)){return undefined;} +var n=Cartesian3.multiplyComponents(cartesian,oneOverRadiiSquared,cartesianToCartographicN);n=Cartesian3.normalize(n,n);var h=Cartesian3.subtract(cartesian,p,cartesianToCartographicH);var longitude=Math.atan2(n.y,n.x);var latitude=Math.asin(n.z);var height=CesiumMath.sign(Cartesian3.dot(h,cartesian))*Cartesian3.magnitude(h);if(!defined(result)){return new Cartographic(longitude,latitude,height);} +result.longitude=longitude;result.latitude=latitude;result.height=height;return result;};Cartographic.clone=function(cartographic,result){if(!defined(cartographic)){return undefined;} +if(!defined(result)){return new Cartographic(cartographic.longitude,cartographic.latitude,cartographic.height);} +result.longitude=cartographic.longitude;result.latitude=cartographic.latitude;result.height=cartographic.height;return result;};Cartographic.equals=function(left,right){return(left===right)||((defined(left))&&(defined(right))&&(left.longitude===right.longitude)&&(left.latitude===right.latitude)&&(left.height===right.height));};Cartographic.equalsEpsilon=function(left,right,epsilon){if(typeof epsilon!=='number'){throw new DeveloperError('epsilon is required and must be a number.');} +return(left===right)||((defined(left))&&(defined(right))&&(Math.abs(left.longitude-right.longitude)<=epsilon)&&(Math.abs(left.latitude-right.latitude)<=epsilon)&&(Math.abs(left.height-right.height)<=epsilon));};Cartographic.ZERO=freezeObject(new Cartographic(0.0,0.0,0.0));Cartographic.prototype.clone=function(result){return Cartographic.clone(this,result);};Cartographic.prototype.equals=function(right){return Cartographic.equals(this,right);};Cartographic.prototype.equalsEpsilon=function(right,epsilon){return Cartographic.equalsEpsilon(this,right,epsilon);};Cartographic.prototype.toString=function(){return'('+this.longitude+', '+this.latitude+', '+this.height+')';};'use strict';var CesiumMath=CesiumMath||{};var Cartesian3=Cartesian3||{};var vincenty=vincenty||{};function initialize(ellipsoid,x,y,z){x=defaultValue(x,0.0);y=defaultValue(y,0.0);z=defaultValue(z,0.0);if(x<0.0||y<0.0||z<0.0){throw new DeveloperError('All radii components must be greater than or equal to zero.');} +ellipsoid._radii=new Cartesian3(x,y,z);ellipsoid._radiiSquared=new Cartesian3(x*x,y*y,z*z);ellipsoid._radiiToTheFourth=new Cartesian3(x*x*x*x,y*y*y*y,z*z*z*z);ellipsoid._oneOverRadii=new Cartesian3(x===0.0?0.0:1.0/x,y===0.0?0.0:1.0/y,z===0.0?0.0:1.0/z);ellipsoid._oneOverRadiiSquared=new Cartesian3(x===0.0?0.0:1.0/(x*x),y===0.0?0.0:1.0/(y*y),z===0.0?0.0:1.0/(z*z));ellipsoid._minimumRadius=Math.min(x,y,z);ellipsoid._maximumRadius=Math.max(x,y,z);ellipsoid._centerToleranceSquared=CesiumMath.EPSILON1;} +vincenty.Ellipsoid=function(x,y,z){this._radii=undefined;this._radiiSquared=undefined;this._radiiToTheFourth=undefined;this._oneOverRadii=undefined;this._oneOverRadiiSquared=undefined;this._minimumRadius=undefined;this._maximumRadius=undefined;this._centerToleranceSquared=undefined;initialize(this,x,y,z);} +defineProperties(vincenty.Ellipsoid.prototype,{radii:{get:function(){return this._radii;}},radiiSquared:{get:function(){return this._radiiSquared;}},radiiToTheFourth:{get:function(){return this._radiiToTheFourth;}},oneOverRadii:{get:function(){return this._oneOverRadii;}},oneOverRadiiSquared:{get:function(){return this._oneOverRadiiSquared;}},minimumRadius:{get:function(){return this._minimumRadius;}},maximumRadius:{get:function(){return this._maximumRadius;}}});vincenty.Ellipsoid.clone=function(ellipsoid,result){if(!defined(ellipsoid)){return undefined;} +var radii=ellipsoid._radii;if(!defined(result)){return new vincenty.Ellipsoid(radii.x,radii.y,radii.z);} +Cartesian3.clone(radii,result._radii);Cartesian3.clone(ellipsoid._radiiSquared,result._radiiSquared);Cartesian3.clone(ellipsoid._radiiToTheFourth,result._radiiToTheFourth);Cartesian3.clone(ellipsoid._oneOverRadii,result._oneOverRadii);Cartesian3.clone(ellipsoid._oneOverRadiiSquared,result._oneOverRadiiSquared);result._minimumRadius=ellipsoid._minimumRadius;result._maximumRadius=ellipsoid._maximumRadius;result._centerToleranceSquared=ellipsoid._centerToleranceSquared;return result;};vincenty.Ellipsoid.fromCartesian3=function(cartesian,result){if(!defined(result)){result=new Ellipsoid();} +if(!defined(cartesian)){return result;} +initialize(result,cartesian.x,cartesian.y,cartesian.z);return result;};vincenty.Ellipsoid.WGS84=freezeObject(new vincenty.Ellipsoid(6378137.0,6378137.0,6356752.3142451793));vincenty.Ellipsoid.UNIT_SPHERE=freezeObject(new vincenty.Ellipsoid(1.0,1.0,1.0));vincenty.Ellipsoid.MOON=freezeObject(new vincenty.Ellipsoid(CesiumMath.LUNAR_RADIUS,CesiumMath.LUNAR_RADIUS,CesiumMath.LUNAR_RADIUS));vincenty.Ellipsoid.prototype.clone=function(result){return vincenty.Ellipsoid.clone(this,result);};vincenty.Ellipsoid.packedLength=Cartesian3.packedLength;vincenty.Ellipsoid.pack=function(value,array,startingIndex){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);Cartesian3.pack(value._radii,array,startingIndex);};vincenty.Ellipsoid.unpack=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);var radii=Cartesian3.unpack(array,startingIndex);return Ellipsoid.fromCartesian3(radii,result);};vincenty.Ellipsoid.prototype.geocentricSurfaceNormal=Cartesian3.normalize;vincenty.Ellipsoid.prototype.geodeticSurfaceNormalCartographic=function(cartographic,result){if(!defined(cartographic)){throw new DeveloperError('cartographic is required.');} +var longitude=cartographic.longitude;var latitude=cartographic.latitude;var cosLatitude=Math.cos(latitude);var x=cosLatitude*Math.cos(longitude);var y=cosLatitude*Math.sin(longitude);var z=Math.sin(latitude);if(!defined(result)){result=new Cartesian3();} +result.x=x;result.y=y;result.z=z;return Cartesian3.normalize(result,result);};vincenty.Ellipsoid.prototype.geodeticSurfaceNormal=function(cartesian,result){if(!defined(result)){result=new Cartesian3();} +result=Cartesian3.multiplyComponents(cartesian,this._oneOverRadiiSquared,result);return Cartesian3.normalize(result,result);};var cartographicToCartesianNormal=new Cartesian3();var cartographicToCartesianK=new Cartesian3();vincenty.Ellipsoid.prototype.cartographicToCartesian=function(cartographic,result){var n=cartographicToCartesianNormal;var k=cartographicToCartesianK;this.geodeticSurfaceNormalCartographic(cartographic,n);Cartesian3.multiplyComponents(this._radiiSquared,n,k);var gamma=Math.sqrt(Cartesian3.dot(n,k));Cartesian3.divideByScalar(k,gamma,k);Cartesian3.multiplyByScalar(n,cartographic.height,n);if(!defined(result)){result=new Cartesian3();} +return Cartesian3.add(k,n,result);};vincenty.Ellipsoid.prototype.cartographicArrayToCartesianArray=function(cartographics,result){if(!defined(cartographics)){throw new DeveloperError('cartographics is required.');} +var length=cartographics.length;if(!defined(result)){result=new Array(length);}else{result.length=length;} +for(var i=0;iCesiumMath.EPSILON12);var uSquared=cosineSquaredAlpha*(major*major-minor*minor)/(minor*minor);var A=1.0+uSquared*(4096.0+uSquared*(uSquared*(320.0-175.0*uSquared)-768.0))/16384.0;var B=uSquared*(256.0+uSquared*(uSquared*(74.0-47.0*uSquared)-128.0))/1024.0;var cosineSquaredTwiceSigmaMidpoint=cosineTwiceSigmaMidpoint*cosineTwiceSigmaMidpoint;var deltaSigma=B*sineSigma*(cosineTwiceSigmaMidpoint+B*(cosineSigma*(2.0*cosineSquaredTwiceSigmaMidpoint-1.0)-B*cosineTwiceSigmaMidpoint*(4.0*sineSigma*sineSigma-3.0)*(4.0*cosineSquaredTwiceSigmaMidpoint-3.0)/6.0)/4.0);var distance=minor*A*(sigma-deltaSigma);var startHeading=Math.atan2(cosineU2*sineLambda,cs-sc*cosineLambda);var endHeading=Math.atan2(cosineU1*sineLambda,cs*cosineLambda-sc);ellipsoidGeodesic._distance=distance;ellipsoidGeodesic._startHeading=startHeading;ellipsoidGeodesic._endHeading=endHeading;ellipsoidGeodesic._uSquared=uSquared;},computeProperties:function(ellipsoidGeodesic,start,end,ellipsoid){var firstCartesian=Cartesian3.normalize(ellipsoid.cartographicToCartesian(start,this.scratchCart2),this.scratchCart1);var lastCartesian=Cartesian3.normalize(ellipsoid.cartographicToCartesian(end,this.scratchCart2),this.scratchCart2);if(Math.abs(Math.abs(Cartesian3.angleBetween(firstCartesian,lastCartesian))-Math.PI)<0.0125){throw new DeveloperError('geodesic position is not unique');} +this.vincentyInverseFormula(ellipsoidGeodesic,ellipsoid.maximumRadius,ellipsoid.minimumRadius,start.longitude,start.latitude,end.longitude,end.latitude);ellipsoidGeodesic._start=Cartographic.clone(start,ellipsoidGeodesic._start);ellipsoidGeodesic._end=Cartographic.clone(end,ellipsoidGeodesic._end);ellipsoidGeodesic._start.height=0;ellipsoidGeodesic._end.height=0;this.setConstants(ellipsoidGeodesic);},EllipsoidGeodesic:function(start,end,ellipsoid){var e=defaultValue(ellipsoid,vincenty.Ellipsoid.WGS84);this._ellipsoid=e;this._start=new Cartographic();this._end=new Cartographic();this._constants={};this._startHeading=undefined;this._endHeading=undefined;this._distance=undefined;this._uSquared=undefined;this.scratchCart1=new Cartesian3();this.scratchCart2=new Cartesian3();}};vincenty.EllipsoidGeodesic.setEndPoints=function(start,end){if(!defined(start)){throw new DeveloperError('start cartographic position is required');} +if(!defined(end)){throw new DeveloperError('end cartgraphic position is required');} +this.computeProperties(this,start,end,this._ellipsoid);};vincenty.EllipsoidGeodesic.interpolateUsingFraction=function(fraction,result){return this.interpolateUsingSurfaceDistance(this._distance*fraction,result);};vincenty.EllipsoidGeodesic.interpolateUsingSurfaceDistance=function(distance,result){if(!defined(this._distance)){throw new DeveloperError('start and end must be set before calling funciton interpolateUsingSurfaceDistance');} +var constants=this._constants;var s=constants.distanceRatio+distance/constants.b;var cosine2S=Math.cos(2.0*s);var cosine4S=Math.cos(4.0*s);var cosine6S=Math.cos(6.0*s);var sine2S=Math.sin(2.0*s);var sine4S=Math.sin(4.0*s);var sine6S=Math.sin(6.0*s);var sine8S=Math.sin(8.0*s);var s2=s*s;var s3=s*s2;var u8Over256=constants.u8Over256;var u2Over4=constants.u2Over4;var u6Over64=constants.u6Over64;var u4Over16=constants.u4Over16;var sigma=2.0*s3*u8Over256*cosine2S/3.0+ +s*(1.0-u2Over4+7.0*u4Over16/4.0-15.0*u6Over64/4.0+579.0*u8Over256/64.0- +(u4Over16-15.0*u6Over64/4.0+187.0*u8Over256/16.0)*cosine2S- +(5.0*u6Over64/4.0-115.0*u8Over256/16.0)*cosine4S- +29.0*u8Over256*cosine6S/16.0)+ +(u2Over4/2.0-u4Over16+71.0*u6Over64/32.0-85.0*u8Over256/16.0)*sine2S+ +(5.0*u4Over16/16.0-5.0*u6Over64/4.0+383.0*u8Over256/96.0)*sine4S- +s2*((u6Over64-11.0*u8Over256/2.0)*sine2S+5.0*u8Over256*sine4S/2.0)+ +(29.0*u6Over64/96.0-29.0*u8Over256/16.0)*sine6S+ +539.0*u8Over256*sine8S/1536.0;var theta=Math.asin(Math.sin(sigma)*constants.cosineAlpha);var latitude=Math.atan(constants.a/constants.b*Math.tan(theta));sigma=sigma-constants.sigma;var cosineTwiceSigmaMidpoint=Math.cos(2.0*constants.sigma+sigma);var sineSigma=Math.sin(sigma);var cosineSigma=Math.cos(sigma);var cc=constants.cosineU*cosineSigma;var ss=constants.sineU*sineSigma;var lambda=Math.atan2(sineSigma*constants.sineHeading,cc-ss*constants.cosineHeading);var l=lambda-this.computeDeltaLambda(constants.f,constants.sineAlpha,constants.cosineSquaredAlpha,sigma,sineSigma,cosineSigma,cosineTwiceSigmaMidpoint);if(defined(result)){result.longitude=this._start.longitude+l;result.latitude=latitude;result.height=0.0;return result;} +return new Cartographic(this._start.longitude+l,latitude,0.0);};var android=android||{};android.graphics=android.graphics||{};android.graphics.Bitmap=function() +{return;};var android=android||{};android.graphics=android.graphics||{};android.graphics.Paint=function() +{this.getTextBounds=function(str,x,length,rect){return null;};this.setTextSize=function(size){return;};this.setAntiAlias=function(b){return;};this.setColor=function(color){return;};this.setTypeface=function(tf){return;};};var android=android||{};android.graphics=android.graphics||{};android.graphics.Path=function(){this.pts=new java.util.ArrayList();};android.graphics.Path.prototype.lineTo=function(x,y){if(this.pts.size()>0) +{var lastPt=this.pts.get(this.pts.size()-1);if(lastPt.x===x&&lastPt.y===y) +return;} +this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};android.graphics.Path.prototype.moveTo=function(x,y){if(this.pts.size()>0) +{var lastPt=this.pts.get(this.pts.size()-1);if(lastPt.x===x&&lastPt.y===y) +return;} +this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};android.graphics.Path.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3));};android.graphics.Path.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3));};android.graphics.Path.prototype.quadTo=function(x1,y1,x2,y2){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1));this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2));};android.graphics.Path.prototype.addPath=function(path){this.pts.addAll(path.getPts());return;};android.graphics.Path.prototype.computeBounds=function(rect,exact){var j=0;var left=this.pts.get(0).x;var right=this.pts.get(0).x;var top=this.pts.get(0).y;var bottom=this.pts.get(0).y;var pt=null;for(j=1;jright) +right=pt.x;if(pt.ybottom) +bottom=pt.y;} +rect.left=left;rect.top=top;rect.right=right;rect.bottom=bottom;return;};android.graphics.Path.prototype.close=function(){};android.graphics.Path.prototype.getPts=function(){return this.pts;};var android=android||{};android.graphics=android.graphics||{};android.graphics.PointF=function() +{this.x=0;this.y=0;if(arguments.length===2) +{this.x=arguments[0];this.y=arguments[1];}};var android=android||{};android.graphics=android.graphics||{};android.graphics.Rect=function() +{this.left=0;this.top=0;this.width=function(){return 0;};this.height=function(){return 0;};};var android=android||{};android.graphics=android.graphics||{};android.graphics.RectF=function(){this.top=0;this.left=0;this.bottom=0;this.right=0;if(arguments.length===4) +{this.left=arguments[0];this.top=arguments[1];this.right=arguments[2];this.bottom=arguments[3];} +this.intersects=function(a,b){if(a.contains(b.left,b.top)) +return true;else if(a.contains(b.left,b.bottom)) +return true;else if(a.contains(b.right,b.top)) +return true;else if(a.contains(b.right,b.bottom)) +return true;return false;};this.width=function(){return this.right-this.left;};this.height=function(){return this.bottom-this.top;};this.contains=function(x,y){if(this.left0){for(j=0;jright)right=polygon.get(j).x;if(polygon.get(j).ybottom)bottom=polygon.get(j).y;} +return new armyc2.c2sd.graphics2d.Rectangle2D(left,top,right-left,bottom-top);};armyc2.c2sd.graphics2d.Area.isVertical=function(edge){if(edge.getX1()===edge.getX2())return true;else return false;};armyc2.c2sd.graphics2d.Area.adjustVerticalLine=function(line){var linePt0=line.getP1();var linePt1=line.getP2();if(armyc2.c2sd.graphics2d.Area.isVertical(line)) +{var x=line.getX2()+1;var y=line.getY2();linePt1.setLocation(x,y);line.setLine(linePt0,linePt1);}};armyc2.c2sd.graphics2d.Area.getLineIntersectPoints=function(polygon,hatchLine){var pts=null;try{var j=0;var k=0;var segment=null;var pt0=null;var pt1=null;pt0=polygon.get(0);pt1=polygon.get(polygon.size()-1);if(pt0.x!==pt1.x||pt0.y!==pt1.y) +polygon.add(pt0);var pt2=null;armyc2.c2sd.graphics2d.Area.adjustVerticalLine(hatchLine);var ptsPath=new java.util.ArrayList();var x=0;var y=0;var m1=0;var m2=0;var b1=0;var b2=0;for(j=0;j0) +poly=arguments[0];else +return null;var pts=poly.getPathIterator(null).getPoints();var j=0;var gp=new armyc2.c2sd.graphics2d.GeneralPath();var pt=null;var ptsx=new Array(pts.size());for(j=0;j0){_text=arguments[0];_type=arguments[1];_size=arguments[2];} +this.getSize=function() +{return _size;};};armyc2.c2sd.graphics2d.Font.PLAIN=0;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FontMetrics=function(font){var _fontRenderContext=null;var _font=null;_font=armyc2.c2sd.renderer.utilities.RendererSettings.getMPModifierFont();var textInfoBuffer=null;if(document.createElement) +{textInfoBuffer=document.createElement('canvas');} +else +{textInfoBuffer={};} +textInfoBuffer.width=1;textInfoBuffer.height=1;if(textInfoBuffer.getContext) +{this.textInfoContext=textInfoBuffer.getContext('2d');} +else +{this.textInfoContext={};} +this.textInfoContext.font=_font;this.stringWidth=function(str) +{var location=new armyc2.c2sd.renderer.so.Point(0,0);var bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.getTextBounds(this.textInfoContext,str,location,armyc2.c2sd.renderer.utilities.RendererSettings.getMPModifierFont());var stringWidth=bounds.width;return stringWidth;};this.stringHeight=function(str) +{var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;var fontName=RendererSettings.getMPModifierFontName();var fontStyle=RendererSettings.getMPModifierFontStyle();var fontSize=RendererSettings.getMPModifierFontSize();var height=armyc2.c2sd.renderer.utilities.RendererUtilities.measureTextHeight(fontName,fontSize,fontStyle).fullHeight;stringHeight=height;return stringHeight;};this.getTextBounds=function(str) +{var location=new armyc2.c2sd.renderer.so.Point(0,0);var bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.getTextBounds(this.textInfoContext,str,location,armyc2.c2sd.renderer.utilities.RendererSettings.getMPModifierFont());return bounds;};this.getFontRenderContext=function(){return _fontRenderContext;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FontRenderContext=function(){};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.GeneralPath=function(){this._path=new android.graphics.Path();this._pathIterator=new armyc2.c2sd.graphics2d.PathIterator(null);this.getBounds=function(){var rect=this._pathIterator.getBounds();return new armyc2.c2sd.graphics2d.Rectangle(Math.floor(rect.x),Math.floor(rect.y),Math.floor(rect.width),Math.floor(rect.height));};};armyc2.c2sd.graphics2d.GeneralPath.prototype.lineTo=function(x,y){this._path.lineTo(x,y);this._pathIterator.lineTo(x,y);};armyc2.c2sd.graphics2d.GeneralPath.prototype.moveTo=function(x,y){this._path.moveTo(x,y);this._pathIterator.moveTo(x,y);};armyc2.c2sd.graphics2d.GeneralPath.prototype.quadTo=function(x1,y1,x2,y2){this._path.quadTo(x1,y1,x2,y2);this._pathIterator.quadTo(x1,y1,x2,y2);};armyc2.c2sd.graphics2d.GeneralPath.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this._path.cubicTo(x1,y1,x2,y2,x3,y3);this._pathIterator.cubicTo(x1,y1,x2,y2,x3,y3);};armyc2.c2sd.graphics2d.GeneralPath.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this._path.cubicTo(x1,y1,x2,y2,x3,y3);this._pathIterator.cubicTo(x1,y1,x2,y2,x3,y3);};armyc2.c2sd.graphics2d.GeneralPath.prototype.computeBounds=function(rect){var rectf=new android.graphics.RectF();this._path.computeBounds(rectf,true);rect.x=rectf.left;rect.y=rectf.top;rect.width=rectf.bottom-rectf.top;rect.setRect(rectf.left,rectf.top,rectf.width(),rectf.height());};armyc2.c2sd.graphics2d.GeneralPath.prototype.closePath=function(){if(this._path!==null) +this._path.close();};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsPt2=function(x,y){return false;};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsPt=function(pt){return false;};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsRect2=function(x,y,width,height){var rect2=this.getBounds();return rect2.containsRect2(x,y,width,height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.containsRect=function(r){var rect=new armyc2.c2sd.graphics2d.Rectangle(Math.floor(r.x),Math.floor(r.y),Math.floor(r.width),Math.floor(r.height));var rect2=this.getBounds();return rect2.containsRect2(rect.x,rect.y,rect.width,rect.height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.getBounds2D=function(){return this._pathIterator.getBounds();};armyc2.c2sd.graphics2d.GeneralPath.prototype.intersectsRect2=function(x,y,w,h){return this.getBounds().intersectsRect2(x,y,w,h);};armyc2.c2sd.graphics2d.GeneralPath.prototype.intersectsRect=function(rect){return this.getBounds().intersectsRect2(rect.x,rect.y,rect.width,rect.height);};armyc2.c2sd.graphics2d.GeneralPath.prototype.append=function(shape,connect){var gp=shape;var pi=gp.getPathIterator(null);var pts=pi.getPoints();var j=0;var pt=null;var pt1=null;var pt2=null;for(j=0;jthis.x2&&edgex2>this.x2) +return false;} +else +{if(edgex1this.x1&&edgex2>this.x1) +return false;} +if(this.y1<=this.y2) +{if(edgey1this.y2&&edgey2>this.y2) +return false;} +else +{if(edgey1this.y1&&edgey2>this.y1) +return false;} +if(this.x1===this.x2) +{if(this.x1edgex1&&this.x1>edgex2) +return false;} +if(this.y1===this.y2) +{if(this.y1edgey1&&this.y1>edgey2) +return false;} +var slope=(this.y2-this.y1)/(this.x2-this.x1);var b1=this.y2-slope*this.x2;var edgeSlope=(edgey2-edgey1)/(edgex2-edgex1);var b2=edgey2-edgeSlope*edgex2;var rect=new armyc2.c2sd.graphics2d.Rectangle2D(this.x1,this.y1,this.x2,this.y2);var x0=edgex1;var width=Math.abs(edgex1-edgex2);var y0=edgey1;var height=Math.abs(edgey1-edgey2);var rect2=new armyc2.c2sd.graphics2d.Rectangle2D(x0,y0,width,height);if(slope===edgeSlope){if(b1===b2&&rect.intersectsRect(rect2)===true) +return true;else +return false;}else{var x=(b2-b1)/(slope-edgeSlope);var y=(slope*x+b1);if(this.x1this.x2) +return false;}else if(this.x2this.x1) +return false;} +if(this.y1this.y2) +return false;}else if(this.y2this.y1) +return false;} +if(edgex1edgex2) +return false;}else if(edgex2edgex1) +return false;} +if(edgey1edgey2) +return false;}else if(edgey2edgey1) +return false;}} +return true;};armyc2.c2sd.graphics2d.Line2D.prototype.setLine=function() +{if(arguments.length===1) +{var line1=arguments[0];this.x1=line1.x1;this.y1=line1.y1;this.x2=line1.x2;this.y2=line1.y2;} +else if(arguments.length===2) +{var pt1=arguments[0];var pt2=arguments[1];this.x1=pt1.x;this.y1=pt1.y;this.x2=pt2.x;this.y2=pt2.y;} +else if(arguments.length===4) +{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;}};armyc2.c2sd.graphics2d.Line2D.ptSegDistSq=function(x1,y1,x2,y2,px,py){x2-=x1;y2-=y1;px-=x1;py-=y1;var dotprod=px*x2+py*y2;var projlenSq;if(dotprod<=0.0){projlenSq=0.0;}else{px=x2-px;py=y2-py;dotprod=px*x2+py*y2;if(dotprod<=0.0){projlenSq=0.0;}else{projlenSq=dotprod*dotprod/(x2*x2+y2*y2);}} +var lenSq=px*px+py*py-projlenSq;if(lenSq<0){lenSq=0;} +return lenSq;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.PathIterator=function(){this._currentSeg=0;this._pts=new java.util.ArrayList();this.reset=function(){this._currentSeg=0;};this.setPathIterator=function(pts){this._currentSeg=0;this._pts=pts;};};armyc2.c2sd.graphics2d.PathIterator.prototype.getPoints=function(){return this._pts;};armyc2.c2sd.graphics2d.PathIterator.prototype.currentSegment=function(coords){coords[0]=this._pts.get(this._currentSeg).x;coords[1]=this._pts.get(this._currentSeg).y;return this._pts.get(this._currentSeg).style;};armyc2.c2sd.graphics2d.PathIterator.prototype.getWindingRule=function(){return 1;};armyc2.c2sd.graphics2d.PathIterator.prototype.isDone=function(){if(this._currentSeg===this._pts.size()) +return true;return false;};armyc2.c2sd.graphics2d.PathIterator.prototype.next=function(){this._currentSeg++;};armyc2.c2sd.graphics2d.PathIterator.prototype.moveTo=function(x,y){if(this._pts.size()>0) +{var lastPt=this._pts.get(this._pts.size()-1);if(lastPt.x===x&&lastPt.y===y) +return;} +this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y,0));};armyc2.c2sd.graphics2d.PathIterator.prototype.lineTo=function(x,y){if(this._pts.size()>0) +{var lastPt=this._pts.get(this._pts.size()-1);if(lastPt.x===x&&lastPt.y===y) +return;} +this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y,1));};armyc2.c2sd.graphics2d.PathIterator.prototype.cubicTo=function(x1,y1,x2,y2,x3,y3){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3,3));};armyc2.c2sd.graphics2d.PathIterator.prototype.curveTo=function(x1,y1,x2,y2,x3,y3){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,3));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x3,y3,3));};armyc2.c2sd.graphics2d.PathIterator.prototype.quadTo=function(x1,y1,x2,y2){this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x1,y1,2));this._pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x2,y2,2));};armyc2.c2sd.graphics2d.PathIterator.prototype.getBounds=function(){var j=0;var left=this._pts.get(0).x;var right=this._pts.get(0).x;var top=this._pts.get(0).y;var bottom=this._pts.get(0).y;for(j=1;jright) +right=this._pts.get(j).x;if(this._pts.get(j).ybottom) +bottom=this._pts.get(j).y;} +var rect=new armyc2.c2sd.graphics2d.Rectangle2D(left,top,right-left,bottom-top);return rect;};armyc2.c2sd.graphics2d.PathIterator.SEG_CLOSE=4;armyc2.c2sd.graphics2d.PathIterator.SEG_CUBICTO=3;armyc2.c2sd.graphics2d.PathIterator.SEG_LINETO=1;armyc2.c2sd.graphics2d.PathIterator.SEG_MOVETO=0;armyc2.c2sd.graphics2d.PathIterator.SEG_QUADTO=2;armyc2.c2sd.graphics2d.PathIterator.WIND_EVEN_ODD=0;armyc2.c2sd.graphics2d.PathIterator.WIND_NON_ZERO=1;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Point=function(x,y){this.x=0;this.y=0;if(x!==undefined&&y!==undefined) +{this.x=Number(x);this.y=Number(y);}};armyc2.c2sd.graphics2d.Point.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Point.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Point.prototype.setLocation=function(x1,y1){this.x=Number(x1);this.y=Number(y1);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Point2D=function(){this.x=0;this.y=0;if(arguments.length===2) +{this.x=Number(arguments[0]);this.y=Number(arguments[1]);} +if(arguments.length===1) +{this.x=Number(arguments[0].x);this.y=Number(arguments[0].y);}};armyc2.c2sd.graphics2d.Point2D.prototype.distance=function(x1,y1) +{var dist=Math.sqrt((this.x-x1)*(this.x-x1)+(this.y-y1)*(this.y-y1));return dist;};armyc2.c2sd.graphics2d.Point2D.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Point2D.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Point2D.prototype.setLocation=function(x1,y1){this.x=Number(x1);this.y=Number(y1);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Polygon=function(){this.bounds=null;this.pts=new java.util.ArrayList();this.contains=function(x,y){if(this.pts.size()<3) +return false;if((this.pts.get(0).x!==this.pts.get(this.pts.size()-1).x)||(this.pts.get(0).y!==this.pts.get(this.pts.size()-1).y)){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(this.pts.get(0)));} +var lowVal=-100;var pt0=new armyc2.c2sd.JavaLineArray.POINT2(lowVal,y);var pt1=new armyc2.c2sd.JavaLineArray.POINT2(x,y);var edge=null;var ray=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);var j=0;var intersectCounter=0;for(j=0;jright) +right=pt.x;if(pt.ybottom) +bottom=pt.y;} +rect.left=left;rect.top=top;rect.right=right;rect.bottom=bottom;return;};};armyc2.c2sd.graphics2d.Polygon.prototype.size=function() +{if(this.pts!==null) +return this.pts.size();else +return 0;};armyc2.c2sd.graphics2d.Polygon.prototype.addPoint=function(x,y) +{this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(x,y));};armyc2.c2sd.graphics2d.Polygon.prototype.containsPt2=function(x,y) +{if(this.pts.size()<3) +return false;if((this.pts.get(0).x!==this.pts.get(this.pts.size()-1).x)||(this.pts.get(0).y!==this.pts.get(this.pts.size()-1).y)){this.pts.add(new armyc2.c2sd.JavaLineArray.POINT2(this.pts.get(0)));} +var lowVal=-100;var pt0=new armyc2.c2sd.JavaLineArray.POINT2(lowVal,y);var pt1=new armyc2.c2sd.JavaLineArray.POINT2(x,y);var edge=null;var ray=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);var j=0;var intersectCounter=0;for(j=0;j0){pi.moveTo(this.pts.get(0).x,this.pts.get(0).y);for(j=1;jrect.x+rect.width) +return false;if(this.y+this.heightrect.y+rect.height) +return false;return true;};armyc2.c2sd.graphics2d.Rectangle.prototype.intersectsRect2=function(x1,y1,width1,height1){if(this.x+this.widthx1+width1) +return false;if(this.y+this.heighty1+height1) +return false;return true;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsRect=function(rect){var x1=Math.floor(rect.getX());var y1=Math.floor(rect.getY());if(this.containsPt2(x1,y1)){x1+=rect.getWidth();y1+=rect.getHeight();if(this.containsPt2(x1,y1)) +return true;} +return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsRect2=function(x1,y1,width1,height1){if(this.containsPt2(x1,y1)&&this.containsPt2(x1+width1,y1+height1)) +return true;else +return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.containsPt=function(pt){if(this.x<=pt.getX()&&pt.getX()<=this.x+this.width&&this.y<=pt.getY()&&pt.getY()<=this.y+this.height) +return true;else +return false;};armyc2.c2sd.graphics2d.Rectangle.prototype.getBounds2D=function(){return new armyc2.c2sd.graphics2d.Rectangle2D(this.x,this.y,this.width,this.height);};armyc2.c2sd.graphics2d.Rectangle.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Rectangle.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMinX=function(){return this.x;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMinY=function(){return this.y;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMaxX=function(){return this.x+this.width;};armyc2.c2sd.graphics2d.Rectangle.prototype.getMaxY=function(){return this.y+this.height;};armyc2.c2sd.graphics2d.Rectangle.prototype.getHeight=function(){return this.height;};armyc2.c2sd.graphics2d.Rectangle.prototype.getWidth=function(){return this.width;};armyc2.c2sd.graphics2d.Rectangle.prototype.grow=function(h,v){return;};armyc2.c2sd.graphics2d.Rectangle.prototype.setRect=function(rect){this.x=rect.x;this.y=rect.y;this.width=rect.width;this.height=rect.height;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Rectangle2D=function(){this.x=0;this.y=0;this.width=0;this.height=0;if(arguments.length===4) +{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];} +this.containsPt2=function(x1,y1){if(this.x<=x1&&x1<=this.x+this.width&&this.y<=y1&&y1<=this.y+this.width) +return true;else +return false;};this.add=function(x1,y1){if(x1this.x+this.width) +this.width+=(x1-this.x);if(y1>this.y+this.height) +this.height+=(y1-this.y);};};armyc2.c2sd.graphics2d.Rectangle2D.prototype.createIntersection=function(r){if(r.x>this.x+this.width) +return null;if(r.x+r.widththis.y+this.height) +return null;if(r.y+r.heightrect.x+rect.width) +return false;if(this.y+this.heightrect.y+rect.height) +return false;return true;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.intersectsRect2=function(x1,y1,width1,height1){if(this.x+this.widthx1+width1) +return false;if(this.y+this.heighty1+height1) +return false;return true;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsRect=function(rect){var x1=rect.getX();var y1=rect.getY();if(this.containsPt2(x1,y1)){x1+=rect.getWidth();y1+=rect.getHeight();if(this.containsPt2(x1,y1)) +return true;} +return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsPt=function(pt){if(this.x<=pt.getX()&&pt.getX()<=this.x+this.width) +if(this.y<=pt.getY()&&pt.getY()<=this.x+this.height) +return true;return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.intersectsLine=function(line){var pt0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x,this.y);var pt1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x+this.width,this.y);var edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0,pt1);if(line.intersectsLine(edge)) +return true;var pt2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x+this.width,this.y+this.height);edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt1,pt2);if(line.intersectsLine(edge)) +return true;var pt3=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(this.x,this.y+this.height);edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt2,pt3);if(line.intersectsLine(edge)) +return true;edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt3,pt0);if(line.intersectsLine(edge)) +return true;return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.containsRect2=function(x,y,width,height){var x1=x;var y1=y;if(this.containsPt2(x1,y1)){x1+=width;y1+=height;if(this.containsPt2(x1,y1)) +return true;} +return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.isEmpty=function(){if(this.width===0&&this.height===0) +return true;else +return false;};armyc2.c2sd.graphics2d.Rectangle2D.prototype.setRect=function() +{if(arguments.length===4) +{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];} +else if(arguments.length===1) +{this.x=arguments[0].getX();this.y=arguments[0].getY();this.width=arguments[0].getWidth();this.height=arguments[0].getHeight();}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Shape={};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Stroke={};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.TextLayout=function(){var _font=null;var _str="";if(arguments.length>1) +{_str=arguments[0];_font=arguments[1];} +this.getOutline=function(tx){return new armyc2.c2sd.graphics2d.GeneralPath();};this.getPixelBounds=function(frc,x,y){return null;};this.getBounds=function(){var width=Math.floor(_font.getSize()/2)*_str.length;var height=_font.getSize();var rect=new armyc2.c2sd.graphics2d.Rectangle(0,0,width,height);return rect;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.TexturePaint=function(){var _rect=null;var _g2d=null;var _bi=null;if(arguments.length===2) +{_bi=arguments[0];_rect=arguments[1];}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.Arc2D=function() +{this.x=0;this.y=0;this.width=0;this.height=0;this.start=0;this.extent=0;this.type=0;if(arguments.length===1) +{var t=arguments[0];this.setArcType(t);} +else if(arguments.length===7) +{this.x=arguments[0];this.y=arguments[1];this.width=arguments[2];this.height=arguments[3];this.start=arguments[4];this.extent=arguments[5];armyc2.c2sd.graphics2d.Arc2D.setArcType(this,arguments[6]);} +else if(arguments.length===4) +{var ellipseBounds=arguments[0];var start=arguments[1];var extent=arguments[2];var type=arguments[3];armyc2.c2sd.graphics2d.Arc2D.setArcType(this,type);this.x=ellipseBounds.getX();this.y=ellipseBounds.getY();this.width=ellipseBounds.getWidth();this.height=ellipseBounds.getHeight();this.start=start;this.extent=extent;}};armyc2.c2sd.graphics2d.Arc2D.prototype.getX=function(){return this.x;};armyc2.c2sd.graphics2d.Arc2D.prototype.getY=function(){return this.y;};armyc2.c2sd.graphics2d.Arc2D.prototype.getWidth=function(){return this.width;};armyc2.c2sd.graphics2d.Arc2D.prototype.getHeight=function(){return this.height;};armyc2.c2sd.graphics2d.Arc2D.prototype.getAngleStart=function(){return this.start;};armyc2.c2sd.graphics2d.Arc2D.prototype.getAngleExtent=function(){return this.extent;};armyc2.c2sd.graphics2d.Arc2D.prototype.isEmpty=function(){return(this.width<=0.0||this.height<=0.0);};armyc2.c2sd.graphics2d.Arc2D.prototype.setArc=function(x,y,w,h,angSt,angExt,closure){this.setArcType(closure);this.x=x;this.y=y;this.width=w;this.height=h;this.start=angSt;this.extent=angExt;};armyc2.c2sd.graphics2d.Arc2D.prototype.setAngleStart=function(angSt){this.start=angSt;};armyc2.c2sd.graphics2d.Arc2D.prototype.setAngleExtent=function(angExt){this.extent=angExt;};armyc2.c2sd.graphics2d.Arc2D.prototype.getArcType=function(){return this.type;};armyc2.c2sd.graphics2d.Arc2D.prototype.getStartPoint=function(){var angle=Math.toRadians(-this.getAngleStart());var x=this.getX()+(Math.cos(angle)*0.5+0.5)*this.getWidth();var y=this.getY()+(Math.sin(angle)*0.5+0.5)*this.getHeight();return new armyc2.c2sd.graphics2d.Point2D(x,y);};armyc2.c2sd.graphics2d.Arc2D.prototype.getEndPoint=function(){var angle=Math.toRadians(-this.getAngleStart()-this.getAngleExtent());var x=this.getX()+(Math.cos(angle)*0.5+0.5)*this.getWidth();var y=this.getY()+(Math.sin(angle)*0.5+0.5)*this.getHeight();return new armyc2.c2sd.graphics2d.Point2D(x,y);};armyc2.c2sd.graphics2d.Arc2D.prototype.setArc2=function(rect,angSt,angExt,closure){this.setArc(rect.getX(),rect.getY(),rect.getWidth(),rect.getHeight(),angSt,angExt,closure);};armyc2.c2sd.graphics2d.Arc2D.prototype.setArc3=function(a){this.setArc(a.getX(),a.getY(),a.getWidth(),a.getHeight(),a.getAngleStart(),a.getAngleExtent(),a.type);};armyc2.c2sd.graphics2d.Arc2D.prototype.setArcByCenter=function(x,y,radius,angSt,angExt,closure){this.setArc(x-radius,y-radius,radius*2.0,radius*2.0,angSt,angExt,closure);};armyc2.c2sd.graphics2d.Arc2D.prototype.setArcByTangent=function(p1,p2,p3,radius){var ang1=Math.atan2(p1.getY()-p2.getY(),p1.getX()-p2.getX());var ang2=Math.atan2(p3.getY()-p2.getY(),p3.getX()-p2.getX());var diff=ang2-ang1;if(diff>3.141592653589793){ang2-=6.283185307179586;}else if(diff<-3.141592653589793){ang2+=6.283185307179586;} +var bisect=(ang1+ang2)/2.0;var theta=Math.abs(ang2-bisect);var dist=radius/Math.sin(theta);var x=p2.getX()+dist*Math.cos(bisect);var y=p2.getY()+dist*Math.sin(bisect);if(ang12){throw new IllegalArgumentException("invalid type for Arc: "+type);} +this.type=type;};armyc2.c2sd.graphics2d.Arc2D.prototype.setFrame=function(x,y,w,h){this.setArc(x,y,w,h,this.getAngleStart(),this.getAngleExtent(),this.type);};armyc2.c2sd.graphics2d.Arc2D.prototype.getBounds2D=function(){if(this.isEmpty()){return this.makeBounds(this.getX(),this.getY(),this.getWidth(),this.getHeight());} +var x1;var y1;var x2;var y2;if(this.getArcType()===2){x1=y1=x2=y2=0.0;}else{x1=y1=1.0;x2=y2=-1.0;} +var angle=0.0;for(var i=0;i<6;i++){if(i<4){angle+=90.0;if(!this.containsAngle(angle)){continue;}}else if(i===4){angle=this.getAngleStart();}else{angle+=this.getAngleExtent();} +var rads=Math.toRadians(-angle);var xe=Math.cos(rads);var ye=Math.sin(rads);x1=Math.min(x1,xe);y1=Math.min(y1,ye);x2=Math.max(x2,xe);y2=Math.max(y2,ye);} +var w=this.getWidth();var h=this.getHeight();x2=(x2-x1)*0.5*w;y2=(y2-y1)*0.5*h;x1=this.getX()+(x1*0.5+0.5)*w;y1=this.getY()+(y1*0.5+0.5)*h;return this.makeBounds(x1,y1,x2,y2);};armyc2.c2sd.graphics2d.Arc2D.prototype.makeBounds=function(x,y,w,h){return null;};armyc2.c2sd.graphics2d.Arc2D.prototype.containsAngle=function(angle){var angExt=this.getAngleExtent();var backwards=(angExt<0.0);if(backwards){angExt=-angExt;} +if(angExt>=360.0){return true;} +angle=armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees(angle)-armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees(this.getAngleStart());if(backwards){angle=-angle;} +if(angle<0.0){angle+=360.0;} +return(angle>=0.0)&&(angle=0.25){return false;} +var angExt=Math.abs(this.getAngleExtent());if(angExt>=360.0){return true;} +var inarc=this.containsAngle(-Math.toDegrees(Math.atan2(normy,normx)));if(this.type===2){return inarc;} +if(inarc){if(angExt>=180.0){return true;}}else{if(angExt<=180.0){return false;}} +var angle=Math.toRadians(-this.getAngleStart());var x1=Math.cos(angle);var y1=Math.sin(angle);angle+=Math.toRadians(-this.getAngleExtent());var x2=Math.cos(angle);var y2=Math.sin(angle);var inside=(armyc2.c2sd.graphics2d.Line2D.relativeCCW(x1,y1,x2,y2,2*normx,2*normy)*armyc2.c2sd.graphics2d.Line2D.relativeCCW(x1,y1,x2,y2,0,0)>=0);return inarc?!inside:inside;};armyc2.c2sd.graphics2d.Arc2D.prototype.getPathIterator=function(at){return new armyc2.c2sd.graphics2d.ArcIterator(this,at);};armyc2.c2sd.graphics2d.Arc2D.prototype.hashCode=function(){var bits=java.lang.Double.doubleToLongBits(this.getX());bits+=java.lang.Double.doubleToLongBits(this.getY())*37;bits+=java.lang.Double.doubleToLongBits(this.getWidth())*43;bits+=java.lang.Double.doubleToLongBits(this.getHeight())*47;bits+=java.lang.Double.doubleToLongBits(this.getAngleStart())*53;bits+=java.lang.Double.doubleToLongBits(this.getAngleExtent())*59;bits+=this.getArcType()*61;return((bits)^((bits>>32)));};armyc2.c2sd.graphics2d.Arc2D.prototype.equals=function(obj){if(obj===this){return true;} +if(Clazz.instanceOf(obj,armyc2.c2sd.graphics2d.Arc2D)){var a2d=obj;return((this.getX()===a2d.getX())&&(this.getY()===a2d.getY())&&(this.getWidth()===a2d.getWidth())&&(this.getHeight()===a2d.getHeight())&&(this.getAngleStart()===a2d.getAngleStart())&&(this.getAngleExtent()===a2d.getAngleExtent())&&(this.getArcType()===a2d.getArcType()));} +return false;};armyc2.c2sd.graphics2d.Arc2D.setArcType=function(that,type) +{if(type<0||type>2){throw new IllegalArgumentException("invalid type for Arc: "+type);} +that.type=type;};armyc2.c2sd.graphics2d.Arc2D.normalizeDegrees=function(angle){if(angle>180.0){if(angle<=(540.0)){angle=angle-360.0;}else{angle=Math.IEEEremainder(angle,360.0);if(angle===-180.0){angle=180.0;}}}else if(angle<=-180.0){if(angle>(-540.0)){angle=angle+360.0;}else{angle=Math.IEEEremainder(angle,360.0);if(angle===-180.0){angle=180.0;}}} +return angle;};armyc2.c2sd.graphics2d.Arc2D.OPEN=0;armyc2.c2sd.graphics2d.Arc2D.CHORD=1;armyc2.c2sd.graphics2d.Arc2D.PIE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.ArcIterator=function() +{this.x=0;this.y=0;this.w=0;this.h=0;this.angStRad=0;this.increment=0;this.cv=0;this.affine=null;this.index=0;this.arcSegs=0;this.lineSegs=0;var a=arguments[0];var at=arguments[1];this.w=a.getWidth()/2;this.h=a.getHeight()/2;this.x=a.getX()+this.w;this.y=a.getY()+this.h;this.angStRad=-Math.toRadians(a.getAngleStart());this.affine=at;var ext=-a.getAngleExtent();if(ext>=360.0||ext<=-360){this.arcSegs=4;this.increment=1.5707963267948966;this.cv=0.5522847498307933;if(ext<0){this.increment=-this.increment;this.cv=-this.cv;}}else{this.arcSegs=Math.floor(Math.ceil(Math.abs(ext)/90.0));this.increment=Math.toRadians(ext/this.arcSegs);this.cv=armyc2.c2sd.graphics2d.ArcIterator.btan(this.increment);if(this.cv===0){this.arcSegs=0;}} +switch(a.getArcType()){case 0:this.lineSegs=0;break;case 1:this.lineSegs=1;break;case 2:this.lineSegs=2;break;} +if(this.w<0||this.h<0){this.arcSegs=this.lineSegs=-1;} +this.getWindingRule=function(){return 1;};this.isDone=function(){return this.index>this.arcSegs+this.lineSegs;};this.next=function(){this.index++;};this.currentSegmentFlt=function(coords){if(this.isDone()){System.out.println("arc iterator out of bounds");return-1;} +var angle=this.angStRad;if(this.index===0){coords[0]=(this.x+Math.cos(angle)*this.w);coords[1]=(this.y+Math.sin(angle)*this.h);if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} +return 0;} +if(this.index>this.arcSegs){if(this.index===this.arcSegs+this.lineSegs){return 4;} +coords[0]=this.x;coords[1]=this.y;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} +return 1;} +angle+=this.increment*(this.index-1);var relx=Math.cos(angle);var rely=Math.sin(angle);coords[0]=(this.x+(relx-this.cv*rely)*this.w);coords[1]=(this.y+(rely+this.cv*relx)*this.h);angle+=this.increment;relx=Math.cos(angle);rely=Math.sin(angle);coords[2]=(this.x+(relx+this.cv*rely)*this.w);coords[3]=(this.y+(rely-this.cv*relx)*this.h);coords[4]=(this.x+relx*this.w);coords[5]=(this.y+rely*this.h);if(this.affine!==null){this.affine.transform(coords,0,coords,0,3);} +return 3;};this.currentSegment=function(coords){if(this.isDone()){} +var angle=this.angStRad;if(this.index===0){coords[0]=this.x+Math.cos(angle)*this.w;coords[1]=this.y+Math.sin(angle)*this.h;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} +return 0;} +if(this.index>this.arcSegs){if(this.index===this.arcSegs+this.lineSegs){return 4;} +coords[0]=this.x;coords[1]=this.y;if(this.affine!==null){this.affine.transform(coords,0,coords,0,1);} +return 1;} +angle+=this.increment*(this.index-1);var relx=Math.cos(angle);var rely=Math.sin(angle);coords[0]=this.x+(relx-this.cv*rely)*this.w;coords[1]=this.y+(rely+this.cv*relx)*this.h;angle+=this.increment;relx=Math.cos(angle);rely=Math.sin(angle);coords[2]=this.x+(relx+this.cv*rely)*this.w;coords[3]=this.y+(rely-this.cv*relx)*this.h;coords[4]=this.x+relx*this.w;coords[5]=this.y+rely*this.h;if(this.affine!==null){this.affine.transform(coords,0,coords,0,3);} +return 3;};};armyc2.c2sd.graphics2d.ArcIterator.btan=function(increment){increment/=2.0;return 1.3333333333333333*Math.sin(increment)/(1.0+Math.cos(increment));};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.QuadCurve2D=function(){} +armyc2.c2sd.graphics2d.QuadCurve2D.getFlatnessSq2=function(x1,y1,ctrlx,ctrly,x2,y2){return armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx,ctrly);};armyc2.c2sd.graphics2d.QuadCurve2D.getFlatnessSq=function(coords,offset){return armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(coords[offset+0],coords[offset+1],coords[offset+4],coords[offset+5],coords[offset+2],coords[offset+3]);};armyc2.c2sd.graphics2d.QuadCurve2D.subdivide=function(src,srcoff,left,leftoff,right,rightoff){var x1=src[srcoff+0];var y1=src[srcoff+1];var ctrlx=src[srcoff+2];var ctrly=src[srcoff+3];var x2=src[srcoff+4];var y2=src[srcoff+5];if(left!==null){left[leftoff+0]=x1;left[leftoff+1]=y1;} +if(right!==null){right[rightoff+4]=x2;right[rightoff+5]=y2;} +x1=(x1+ctrlx)/2.0;y1=(y1+ctrly)/2.0;x2=(x2+ctrlx)/2.0;y2=(y2+ctrly)/2.0;ctrlx=(x1+x2)/2.0;ctrly=(y1+y2)/2.0;if(left!==null){left[leftoff+2]=x1;left[leftoff+3]=y1;left[leftoff+4]=ctrlx;left[leftoff+5]=ctrly;} +if(right!==null){right[rightoff+0]=ctrlx;right[rightoff+1]=ctrly;right[rightoff+2]=x2;right[rightoff+3]=y2;}};armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic=function(eqn){return armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2(eqn,eqn);};armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2=function(eqn,res){var a=eqn[2];var b=eqn[1];var c=eqn[0];var roots=0;if(a===0.0){if(b===0.0){return-1;} +res[roots++]=-c/b;}else{var d=b*b-4.0*a*c;if(d<0.0){return 0;} +d=Math.sqrt(d);if(b<0.0){d=-d;} +var q=(b+d)/-2.0;res[roots++]=q/a;if(q!==0.0){res[roots++]=c/q;}} +return roots;};armyc2.c2sd.graphics2d.QuadCurve2D.BELOW=-2;armyc2.c2sd.graphics2d.QuadCurve2D.LOWEDGE=-1;armyc2.c2sd.graphics2d.QuadCurve2D.INSIDE=0;armyc2.c2sd.graphics2d.QuadCurve2D.HIGHEDGE=1;armyc2.c2sd.graphics2d.QuadCurve2D.ABOVE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.CubicCurve2D=function() +{} +armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2=function(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2){return Math.max(armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx1,ctrly1),armyc2.c2sd.graphics2d.Line2D.ptSegDistSq(x1,y1,x2,y2,ctrlx2,ctrly2));};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness=function(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2){return Math.sqrt(armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2(x1,y1,ctrlx1,ctrly1,ctrlx2,ctrly2,x2,y2));};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq=function(coords,offset){return armyc2.c2sd.graphics2d.CubicCurve2D.getFlatnessSq2(coords[offset+0],coords[offset+1],coords[offset+2],coords[offset+3],coords[offset+4],coords[offset+5],coords[offset+6],coords[offset+7]);};armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness2=function(coords,offset){return armyc2.c2sd.graphics2d.CubicCurve2D.getFlatness(coords[offset+0],coords[offset+1],coords[offset+2],coords[offset+3],coords[offset+4],coords[offset+5],coords[offset+6],coords[offset+7]);};armyc2.c2sd.graphics2d.CubicCurve2D.subdivide=function(src,srcoff,left,leftoff,right,rightoff){var x1=src[srcoff+0];var y1=src[srcoff+1];var ctrlx1=src[srcoff+2];var ctrly1=src[srcoff+3];var ctrlx2=src[srcoff+4];var ctrly2=src[srcoff+5];var x2=src[srcoff+6];var y2=src[srcoff+7];if(left!==null){left[leftoff+0]=x1;left[leftoff+1]=y1;} +if(right!==null){right[rightoff+6]=x2;right[rightoff+7]=y2;} +x1=(x1+ctrlx1)/2.0;y1=(y1+ctrly1)/2.0;x2=(x2+ctrlx2)/2.0;y2=(y2+ctrly2)/2.0;var centerx=(ctrlx1+ctrlx2)/2.0;var centery=(ctrly1+ctrly2)/2.0;ctrlx1=(x1+centerx)/2.0;ctrly1=(y1+centery)/2.0;ctrlx2=(x2+centerx)/2.0;ctrly2=(y2+centery)/2.0;centerx=(ctrlx1+ctrlx2)/2.0;centery=(ctrly1+ctrly2)/2.0;if(left!==null){left[leftoff+2]=x1;left[leftoff+3]=y1;left[leftoff+4]=ctrlx1;left[leftoff+5]=ctrly1;left[leftoff+6]=centerx;left[leftoff+7]=centery;} +if(right!==null){right[rightoff+0]=centerx;right[rightoff+1]=centery;right[rightoff+2]=ctrlx2;right[rightoff+3]=ctrly2;right[rightoff+4]=x2;right[rightoff+5]=y2;}};armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic=function(eqn){return armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic2(eqn,eqn);};armyc2.c2sd.graphics2d.CubicCurve2D.solveCubic2=function(eqn,res){var d=eqn[3];if(d===0.0){return armyc2.c2sd.graphics2d.QuadCurve2D.solveQuadratic2(eqn,res);} +var a=eqn[2]/d;var b=eqn[1]/d;var c=eqn[0]/d;var roots=0;var Q=(a*a-3.0*b)/9.0;var R=(2.0*a*a*a-9.0*a*b+27.0*c)/54.0;var R2=R*R;var Q3=Q*Q*Q;a=a/3.0;if(R2=0){v=v*t+eqn[order];} +return v;};armyc2.c2sd.graphics2d.CubicCurve2D.findZero=function(t,target,eqn){var slopeqn=[eqn[1],2*eqn[2],3*eqn[3]];var slope;var origdelta=0;var origt=t;while(true){slope=armyc2.c2sd.graphics2d.CubicCurve2D.solveEqn(slopeqn,2,t);if(slope===0){return t;} +var y=armyc2.c2sd.graphics2d.CubicCurve2D.solveEqn(eqn,3,t);if(y===0){return t;} +var delta=-(y/slope);if(origdelta===0){origdelta=delta;} +if(ttarget){if(delta>0) +return t;}else{return(delta>0?(target+4.9E-324):(target-4.9E-324));} +var newt=t+delta;if(t===newt){return t;} +if(delta*origdelta<0){var tag=(origt=high){return(coord>high?2:1);} +return 0;};armyc2.c2sd.graphics2d.CubicCurve2D.BELOW=-2;armyc2.c2sd.graphics2d.CubicCurve2D.LOWEDGE=-1;armyc2.c2sd.graphics2d.CubicCurve2D.INSIDE=0;armyc2.c2sd.graphics2d.CubicCurve2D.HIGHEDGE=1;armyc2.c2sd.graphics2d.CubicCurve2D.ABOVE=2;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.graphics2d=armyc2.c2sd.graphics2d||{};armyc2.c2sd.graphics2d.FlatteningPathIterator=function(){this.src=null;this.squareflat=0;this.limit=0;this.hold=null;this.curx=0;this.cury=0;this.movx=0;this.movy=0;this.holdType=0;this.holdEnd=0;this.holdIndex=0;this.levels=null;this.levelIndex=0;this.done=false;var limit;var src=arguments[0];var flatness=arguments[1];if(arguments.length===2) +limit=10;if(arguments.length>2) +limit=arguments[2];if(flatness<0.0){throw new IllegalArgumentException("flatness must be >= 0");} +if(limit<0){throw new IllegalArgumentException("limit must be >= 0");} +this.src=src;this.squareflat=flatness*flatness;this.limit=limit;this.levels=Clazz.newArray(limit+1,0);this.hold=Clazz.newArray(14,0);armyc2.c2sd.graphics2d.FlatteningPathIterator.next2(this,false);this.getFlatness=function(){return Math.sqrt(this.squareflat);};this.getRecursionLimit=function(){return this.limit;};this.getWindingRule=function(){return this.src.getWindingRule();};this.isDone=function(){return this.done;};this.ensureHoldCapacity=function(want){if(this.holdIndex-want<0){var have=this.hold.length-this.holdIndex;var newsize=this.hold.length+24;var newhold=Clazz.newArray(newsize,0);System.arraycopy(this.hold,this.holdIndex,newhold,this.holdIndex+24,have);this.hold=newhold;this.holdIndex+=24;this.holdEnd+=24;}};this.next=function(){this.next2(true);};this.next2=function(doNext){var level;if(this.holdIndex>=this.holdEnd){if(doNext){this.src.next();} +if(this.src.isDone()){this.done=true;return;} +this.holdType=this.src.currentSegment(this.hold);this.levelIndex=0;this.levels[0]=0;} +switch(this.holdType){case 0:case 1:this.curx=this.hold[0];this.cury=this.hold[1];if(this.holdType===0){this.movx=this.curx;this.movy=this.cury;} +this.holdIndex=0;this.holdEnd=0;break;case 4:this.curx=this.movx;this.cury=this.movy;this.holdIndex=0;this.holdEnd=0;break;case 2:if(this.holdIndex>=this.holdEnd){this.holdIndex=this.hold.length-6;this.holdEnd=this.hold.length-2;this.hold[this.holdIndex+0]=this.curx;this.hold[this.holdIndex+1]=this.cury;this.hold[this.holdIndex+2]=this.hold[0];this.hold[this.holdIndex+3]=this.hold[1];this.hold[this.holdIndex+4]=this.curx=this.hold[2];this.hold[this.holdIndex+5]=this.cury=this.hold[3];} +level=this.levels[this.levelIndex];while(level=this.holdEnd){this.holdIndex=this.hold.length-8;this.holdEnd=this.hold.length-2;this.hold[this.holdIndex+0]=this.curx;this.hold[this.holdIndex+1]=this.cury;this.hold[this.holdIndex+2]=this.hold[0];this.hold[this.holdIndex+3]=this.hold[1];this.hold[this.holdIndex+4]=this.hold[2];this.hold[this.holdIndex+5]=this.hold[3];this.hold[this.holdIndex+6]=this.curx=this.hold[4];this.hold[this.holdIndex+7]=this.cury=this.hold[5];} +level=this.levels[this.levelIndex];while(level=that.holdEnd){if(doNext){that.src.next();} +if(that.src.isDone()){that.done=true;return;} +that.holdType=that.src.currentSegment(that.hold);that.levelIndex=0;that.levels[0]=0;} +switch(that.holdType){case 0:case 1:that.curx=that.hold[0];that.cury=that.hold[1];if(that.holdType===0){that.movx=that.curx;that.movy=that.cury;} +that.holdIndex=0;that.holdEnd=0;break;case 4:that.curx=that.movx;that.cury=that.movy;that.holdIndex=0;that.holdEnd=0;break;case 2:if(that.holdIndex>=that.holdEnd){that.holdIndex=that.hold.length-6;that.holdEnd=that.hold.length-2;that.hold[that.holdIndex+0]=that.curx;that.hold[that.holdIndex+1]=that.cury;that.hold[that.holdIndex+2]=that.hold[0];that.hold[that.holdIndex+3]=that.hold[1];that.hold[that.holdIndex+4]=that.curx=that.hold[2];that.hold[that.holdIndex+5]=that.cury=that.hold[3];} +level=that.levels[that.levelIndex];while(level=that.holdEnd){that.holdIndex=that.hold.length-8;that.holdEnd=that.hold.length-2;that.hold[that.holdIndex+0]=that.curx;that.hold[that.holdIndex+1]=that.cury;that.hold[that.holdIndex+2]=that.hold[0];that.hold[that.holdIndex+3]=that.hold[1];that.hold[that.holdIndex+4]=that.hold[2];that.hold[that.holdIndex+5]=that.hold[3];that.hold[that.holdIndex+6]=that.curx=that.hold[4];that.hold[that.holdIndex+7]=that.cury=that.hold[5];} +level=that.levels[that.levelIndex];while(level0) +nLast=6;if(nDiff1Y<0) +nLast=4;} +if(nDiff1Y===0){if(nDiff1X>0) +nLast=0;if(nDiff1X<0) +nLast=2;} +if(nDiff1X<0&&nDiff1Y>0) +nLast=3;if(nDiff1X>0&&nDiff1Y>0) +nLast=0;if(nDiff1X<0&&nDiff1Y<0) +nLast=3;if(nDiff1X>0&&nDiff1Y<0) +nLast=0;ResultChannelPoint=armyc2.c2sd.JavaLineArray.Channels.GetTrueEndPointDouble(nWidth,pLinePoints[0],pLinePoints[1],nLast);pResultChannelPoints[0]=new armyc2.c2sd.JavaLineArray.CChannelPoints2(ResultChannelPoint);for(nPointCounter=1;nPointCounter0&&nDiff2X>0){switch(nLast){case 0:case 3:case 4:case 7:lOrient=0;break;case 1:case 2:case 5:case 6:lOrient=3;break;default:break;}} +if(nDiff1X>0&&nDiff2X===0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff2Y>0) +lOrient=1;if(nDiff2Y<0) +lOrient=0;break;case 1:case 2:case 5:case 6:if(nDiff2Y>0) +lOrient=2;if(nDiff2Y<0) +lOrient=3;break;default:break;}} +if(nDiff1X<0&&nDiff2X===0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff2Y>0) +lOrient=3;if(nDiff2Y<0) +lOrient=2;break;case 1:case 2:case 5:case 6:if(nDiff2Y>0) +lOrient=0;if(nDiff2Y<0) +lOrient=1;break;default:break;}} +if(nDiff1X===0&&nDiff2X>0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff1Y>0) +lOrient=2;if(nDiff1Y<0) +lOrient=0;break;case 1:case 2:case 5:case 6:if(nDiff1Y>0) +lOrient=1;if(nDiff1Y<0) +lOrient=3;break;default:break;}} +if(nDiff1X===0&&nDiff2X<0){switch(nLast){case 0:case 3:case 4:case 7:if(nDiff1Y>0) +lOrient=3;if(nDiff1Y<0) +lOrient=1;break;case 1:case 2:case 5:case 6:if(nDiff1Y>0) +lOrient=0;if(nDiff1Y<0) +lOrient=2;break;default:break;}} +if(nDiff1X<0&&nDiff2X<0){switch(nLast){case 0:case 3:case 4:case 7:lOrient=3;break;case 1:case 2:case 5:case 6:lOrient=0;break;default:break;}} +if(new Boolean(nDiff1X>0&nDiff2X<0).valueOf()){switch(nLast){case 0:case 3:case 4:case 7:lOrient=1;break;case 1:case 2:case 5:case 6:lOrient=2;break;default:break;}} +if(new Boolean(nDiff1X<0&nDiff2X>0).valueOf()){switch(nLast){case 0:case 3:case 4:case 7:lOrient=2;break;case 1:case 2:case 5:case 6:lOrient=1;break;default:break;}} +if(nDiff1X===0&&nDiff2X===0){switch(nLast){case 4:if(nDiff2Y<0) +lOrient=0;break;case 6:if(nDiff2Y>0) +lOrient=0;break;case 5:if(nDiff2Y<0) +lOrient=3;break;case 7:if(nDiff2Y>0) +lOrient=3;break;default:break;}} +pResultChannelPoints[nPointCounter]=armyc2.c2sd.JavaLineArray.Channels.ConnectTrueDouble2(nWidth,LinePoint1,LinePoint2,LinePoint3,lOrient);if(nDiff2X===0){switch(lOrient){case 0:if(nDiff2Y>0){nLast=6;} +if(nDiff2Y<0){nLast=4;} +break;case 1:if(nDiff2Y>0){nLast=7;} +if(nDiff2Y<0){nLast=5;} +break;case 2:if(nDiff2Y>0){nLast=6;} +if(nDiff2Y<0){nLast=4;} +break;case 3:if(nDiff2Y>0){nLast=7;} +if(nDiff2Y<0){nLast=5;} +break;default:break;}} +if(nDiff2X>0){switch(lOrient){case 0:nLast=0;break;case 1:nLast=1;break;case 2:nLast=0;break;case 3:nLast=1;break;default:break;}} +if(nDiff2X<0){switch(lOrient){case 0:nLast=2;break;case 1:nLast=3;break;case 2:nLast=2;break;case 3:nLast=3;break;default:break;}}} +ResultChannelPoint=armyc2.c2sd.JavaLineArray.Channels.GetTrueEndPointDouble(nWidth,pLinePoints[nCounter],pLinePoints[nCounter-1],nLast);pResultChannelPoints[nCounter]=new armyc2.c2sd.JavaLineArray.CChannelPoints2(ResultChannelPoint);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"ConnectArrayTrueDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ConnectArrayTrueDouble",exc));}else{throw exc;}} +return pResultChannelPoints;},GetChannel2Double:function(nChannelWidth,vblCounter,pLinePoints,pResultChannelPoints){try{pResultChannelPoints=armyc2.c2sd.JavaLineArray.Channels.ConnectArrayTrueDouble(Math.floor(nChannelWidth/2),vblCounter-1,pLinePoints,pResultChannelPoints);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetChannel2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetChannel2Double",exc));}else{throw exc;}} +return pResultChannelPoints;},GetLowerChannelLineDouble:function(pChannelPoints,vblCounter,pResultLinePoints){try{var j=0;for(j=0;j45){var midPt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pLowerLinePoints[lLowerCounter-2],pUpperLinePoints[lUpperCounter-2],0);ArrowLinePoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(ArrowLinePoint,midPt,45);pLowerLinePoints[lLowerCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pLowerLinePoints[lLowerCounter-1],pLowerLinePoints[lLowerCounter-2],45);pUpperLinePoints[lUpperCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pUpperLinePoints[lUpperCounter-1],pUpperLinePoints[lUpperCounter-2],45);}} +for(j=0;j45){pUpperLinePoints[lUpperCounter-1].x=ptUpper0.x;pUpperLinePoints[lUpperCounter-1].y=ptUpper0.y;pLowerLinePoints[lLowerCounter-1].x=ptLower0.x;pLowerLinePoints[lLowerCounter-1].y=ptLower0.y;ArrowLinePoint.x=origArrowPt.x;ArrowLinePoint.y=origArrowPt.y;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetAXADDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetAXADDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} +return;},GetChannelArray2Double:function(nPrinter,pLinePoints,nUpperLower,vblCounter,vbiDrawThis,vblChannelWidth){try{switch(vbiDrawThis){case 231117301:case 231117201:case 231117101:case 22123001:case 22123000:case 22123002:case 22521200:case 22521300:case 22521100:case 21700000:case 21710000:case 22521410:case 22521411:case 22320000:case 22320001:case 22521420:case 22521421:case 23111000:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231114000:case 231111000:case 231112000:case 231113000:case 231113001:case 231113002:case 231113003:case 15000000:pLinePoints=armyc2.c2sd.JavaLineArray.Channels.CoordIL2Double(nPrinter,pLinePoints,nUpperLower,vblCounter,vbiDrawThis,vblChannelWidth);break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetChannelArray2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetChannelArray2Double "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} +return pLinePoints;},GetTrueEndPointDouble:function(nWidth,EndLinePoint,NextLinePoint,lLast){var cAnswers=new armyc2.c2sd.JavaLineArray.CChannelPoints2();try{var LinePoint1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var LinePoint2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var m=0;var b=0;var bPerpendicular=0;var Upperb=0;var Lowerb=0;var dWidth=nWidth;var bolVertical=0;var pdResult=new armyc2.c2sd.JavaLineArray.ref();bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,EndLinePoint,NextLinePoint,pdResult);m=pdResult.value[0];b=pdResult.value[1];Upperb=pdResult.value[3];Lowerb=pdResult.value[5];if(bolVertical===0){switch(lLast){case 4:case 6:cAnswers.m_Line1.x=EndLinePoint.x-dWidth;cAnswers.m_Line1.y=EndLinePoint.y;cAnswers.m_Line2.x=EndLinePoint.x+dWidth;cAnswers.m_Line2.y=EndLinePoint.y;break;case 5:case 7:cAnswers.m_Line1.x=EndLinePoint.x+dWidth;cAnswers.m_Line1.y=EndLinePoint.y;cAnswers.m_Line2.x=EndLinePoint.x-dWidth;cAnswers.m_Line2.y=EndLinePoint.y;break;default:break;}} +if(m===0){switch(lLast){case 0:case 2:cAnswers.m_Line1.x=EndLinePoint.x;cAnswers.m_Line1.y=EndLinePoint.y-dWidth;cAnswers.m_Line2.x=EndLinePoint.x;cAnswers.m_Line2.y=EndLinePoint.y+dWidth;break;case 1:case 3:cAnswers.m_Line1.x=EndLinePoint.x;cAnswers.m_Line1.y=EndLinePoint.y+dWidth;cAnswers.m_Line2.x=EndLinePoint.x;cAnswers.m_Line2.y=EndLinePoint.y-dWidth;break;default:break;}} +if(bolVertical!==0&&m!==0){bPerpendicular=EndLinePoint.y+EndLinePoint.x/m;LinePoint1=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m,Upperb,-1/m,bPerpendicular,1,1,0,0);LinePoint2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m,Lowerb,-1/m,bPerpendicular,1,1,0,0);switch(lLast){case 0:case 2:if(LinePoint1.yLinePoint2.y){cAnswers.m_Line1=LinePoint1;cAnswers.m_Line2=LinePoint2;}else{cAnswers.m_Line1=LinePoint2;cAnswers.m_Line2=LinePoint1;} +break;default:break;}} +pdResult=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"GetTrueEndPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetTrueEndPointDouble",exc));}else{throw exc;}} +return cAnswers;},ConnectTrueDouble2:function(nWidth,LinePoint1,LinePoint2,LinePoint3,lOrient){var pAnswerLinePoints=new armyc2.c2sd.JavaLineArray.CChannelPoints2();try{var m1=0;var b1=0;var m2=0;var b2=0;var Lowerb1=0;var Upperb1=0;var Lowerb2=0;var Upperb2=0;var dWidth=nWidth;var pdResult=new armyc2.c2sd.JavaLineArray.ref();var bolVerticalSlope1=0;var bolVerticalSlope2=0;var x=new armyc2.c2sd.JavaLineArray.ref();var y=new armyc2.c2sd.JavaLineArray.ref();bolVerticalSlope1=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,LinePoint1,LinePoint2,pdResult);if(bolVerticalSlope1!==0){m1=pdResult.value[0];b1=pdResult.value[1];Upperb1=pdResult.value[5];Lowerb1=pdResult.value[3];} +bolVerticalSlope2=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueLinesDouble(nWidth,LinePoint2,LinePoint3,pdResult);if(bolVerticalSlope2!==0){m2=pdResult.value[0];b2=pdResult.value[1];Upperb2=pdResult.value[5];Lowerb2=pdResult.value[3];} +switch(lOrient){case 0:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 1:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 2:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;case 3:armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);pAnswerLinePoints.m_Line1.x=x.value[0];pAnswerLinePoints.m_Line1.y=y.value[0];armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);pAnswerLinePoints.m_Line2.x=x.value[0];pAnswerLinePoints.m_Line2.y=y.value[0];break;default:break;} +pdResult=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"ConnectTrueDouble2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ConnectTrueDouble2",exc));}else{throw exc;}} +return pAnswerLinePoints;},shiftCATKBYFIREControlPoint:function(linetype,pLinePoints,shift){try{if(linetype!==21710000) +return;var controlPtIndex=pLinePoints.size()-1;var pt0=pLinePoints.get(0);var pt1=pLinePoints.get(1);var dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints.get(0),pLinePoints.get(1));if(dist<=45) +return;var controlPt=pLinePoints.get(controlPtIndex);var pt3=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(pt0,pt1,pt0,controlPt);var pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt3,controlPt,shift);pLinePoints.set(controlPtIndex,pt4);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.Channels._className,"shiftCATKBYFIREControlPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside shiftCATKBYFIREControlPoint",exc));}else{throw exc;}}},GetChannel1Double:function(lpsaUpperVBPoints,lpsaLowerVBPoints,resultVBPoints,vblUpperCounter,vblLowerCounter,vbiDrawThis,vblChannelWidth,useptr,shapes,rev){var lResult=-1;try{var k=0;var vblCounter=0;var nPrinter=1;var nArrowSize=40*nPrinter;var max=0;var dist=0;var remainder=0;var vblUpperCounter2=vblUpperCounter;var vblLowerCounter2=vblLowerCounter;var nReverseUpper=0;var lUpperFlotCount=0;var lLowerFlotCount=0;var nLowerCounter=0;var lUpperCounter=0;var lResultCounter=0;var XCounter=0;var j=0;var lHowManyThisSegment=0;var l=0;var t=0;var pi=3.141592653589793;var dAngle=0;var d=0;var a=13;var b=6;var dFactor=0;var lEllipseCounter=0;var arrowOffsetFactor=Math.floor(vblChannelWidth/4);var pLowerLinePoints=new Array(vblLowerCounter);var pUpperLinePoints=new Array(vblUpperCounter);var pArrowLinePoints=new Array(1);var pLinePoints=null;var pUpperFlotPoints=null;var pLowerFlotPoints=null;var pOriginalLinePoints=null;var pOriginalLinePoints2=null;armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLowerLinePoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pUpperLinePoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArrowLinePoints);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt4=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var arrowPts=new Array(3);var XPoints=new Array(4);var pEllipsePoints2=new Array(37);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(XPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pEllipsePoints2);var temp1LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLowerLinePoints[0]);var temp2LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var lastPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var nextToLastPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();if(vblChannelWidth<5&&vbiDrawThis!==15000000){vblChannelWidth=5;} +if(vblLowerCounter<2||vblUpperCounter<2){return-1;} +for(k=0;kpUpperLinePoints[1].x)&&(pUpperLinePoints[0].y!==pUpperLinePoints[1].y)){nReverseUpper=1;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLowerLinePoints,vblLowerCounter);}else if((pUpperLinePoints[0].x>pUpperLinePoints[1].x)&&(pUpperLinePoints[0].y===pUpperLinePoints[1].y)){nReverseUpper=0;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pUpperLinePoints,vblUpperCounter);}else if(pUpperLinePoints[0].xpUpperLinePoints[1].y)&&(pUpperLinePoints[0].x===pUpperLinePoints[1].x)){nReverseUpper=1;armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLowerLinePoints,vblLowerCounter);}else if((pUpperLinePoints[0].ypOriginalLinePoints[1].x){pLinePoints[k].style=26;} +if(pOriginalLinePoints[0].x>pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y===pOriginalLinePoints[1].y){pLinePoints[k].style=25;}} +if(pOriginalLinePoints[0].x===pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].ypOriginalLinePoints[1].x){pLinePoints[vblUpperCounter+k].style=25;} +if(pOriginalLinePoints[0].x>pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y===pOriginalLinePoints[1].y){pLinePoints[vblUpperCounter+k].style=26;}} +if(pOriginalLinePoints[0].x===pOriginalLinePoints[1].x){if(pOriginalLinePoints[0].y0){pLinePoints[lUpperFlotCount-1].style=5;} +for(k=0;k0){pLinePoints[lUpperFlotCount+lLowerFlotCount-1].style=5;}} +if(nReverseUpper===0){for(k=0;k0) +pLinePoints[lUpperFlotCount-1].style=5;for(k=0;k0) +pLinePoints[lUpperFlotCount+lLowerFlotCount-1].style=5;} +break;case 231117301:case 231117201:case 231117101:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231111000:case 231114000:case 231112000:case 231113000:case 231113001:case 231113002:case 231113003:pLinePoints=new Array(vblCounter);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);for(j=0;jlEllipseCounter){pLinePoints[lEllipseCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pOriginalLinePoints[j]);lEllipseCounter++;pLinePoints[lEllipseCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pOriginalLinePoints[j+1]);pLinePoints[lEllipseCounter].style=5;lEllipseCounter++;}}} +pLinePoints=armyc2.c2sd.JavaLineArray.lineutility.ResizeArray(pLinePoints,lEllipseCounter);vblCounter=pLinePoints.length;} +if(armyc2.c2sd.JavaLineArray.Channels.FenceType(vbiDrawThis)===1){if(lEllipseCounter<=vblLowerCounter+vblUpperCounter){for(k=0;karmyc2.c2sd.JavaLineArray.Channels.maxLength){d=armyc2.c2sd.JavaLineArray.Channels.maxLength;} +if(d45) +dist-=45;if(dist2>20){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],5+dist);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],5+dist);}else{pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],-50);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],-50);} +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt2,pt1,10+Math.abs(dist/2),18);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt2,10+Math.abs(dist/2),5);midPt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,pt2,17);pLinePoints[vblCounter-9]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[vblCounter-6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);if(dist2>20){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],15+dist);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],15+dist);}else{pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter-2],pUpperLinePoints[vblUpperCounter-1],-50);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter-2],pLowerLinePoints[vblLowerCounter-1],-50);} +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt2,pt1,Math.abs(dist/2),18);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt2,Math.abs(dist/2),18);midPt2=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,pt2,18);pLinePoints[vblCounter-8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[vblCounter-7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);pLinePoints[vblCounter-5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPt2);if(midPt1.x===midPt2.x&&midPt1.y===midPt2.y){if(armyc2.c2sd.JavaLineArray.Channels._client.substring(0,4).equals("cpof")) +dFeature=30;else +dFeature=15;midPt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],10,17);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt1,midPt1,dFeature,18);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt1,midPt1,-dFeature,5);pLinePoints[vblCounter-9]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[vblCounter-6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);if(armyc2.c2sd.JavaLineArray.Channels._client.substring(0,4).equals("cpof")) +midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],20,17);else{if(dist2>30) +midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],20,17);else +midPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(nextToLastPoint,pArrowLinePoints[0],dFeature,17);} +dFeature-=10;pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt2,midPt2,dFeature,18);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(lastPoint,midPt2,midPt2,-dFeature,18);pLinePoints[vblCounter-8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[vblCounter-7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[vblCounter-5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPt2);} +if(armyc2.c2sd.JavaLineArray.Channels._client.substring(0,4).equals("cpof")) +dFeature=30;else{if(dist2>30) +dFeature=30;else if(dist2>20) +dFeature=10;else +dFeature=10;} +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(midPt1,midPt2,dFeature,Math.floor(dFeature));pLinePoints[vblCounter-4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(midPt2,pt1,Math.floor(Math.floor(dFeature)/2),Math.floor(Math.floor(dFeature)/2),arrowPts,18);for(k=0;k<3;k++){pLinePoints[vblCounter-k-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arrowPts[k]);pLinePoints[vblCounter-k-1].style=18;}} +break;case 22320000:case 22320001:vblCounter=vblLowerCounter+vblUpperCounter+8;pLinePoints=new Array(vblCounter);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);for(j=0;j0) +if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5) +shape.lineTo(pLinePoints[k]);if(k===0) +shape.set_Style(pLinePoints[k].style);shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} +if(k===vblCounter-1){shapes.add(shape);}} +for(k=0;k0){if(pLinePoints[k].style===5){shape.lineTo(pLinePoints[k]);if(shape!==null&&shape.getShape()!==null){shapes.add(shape);} +beginPath=true;}else{shape.lineTo(pLinePoints[k]);}}else{shape.moveTo(pLinePoints[k]);}}else{shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pLinePoints[k]);shape.set_Style(pLinePoints[k].style);if(pLinePoints[k].style===25) +shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);beginPath=false;} +break;case 21700000:case 21710000:case 22521300:case 22521420:case 22521421:case 22521200:case 22521100:if(beginLine){if(k>0){if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5&&k!==vblCounter-1) +continue;} +shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} +if(k===vblCounter-1){if(shape!==null&&shape.getShape()!==null){shapes.add(shape);}} +break;case 231111000:case 231112000:case 231113000:case 231115000:case 231116000:if(k===0){shape.moveTo(pLinePoints[k]);if(pLinePoints[k].style===5){continue;}} +if(k>0&&k0) +shapes.addAll(0,fillShapes);if(vbiDrawThis===15000000) +{shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pOriginalLinePoints[0]);for(j=1;j=Math.floor(n/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-8)/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-19)/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j=Math.floor((n-17)/2);j--){newPts.add(pLinePoints[j]);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(newPts.get(0));for(j=1;j250) +result=3;else +result=2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetTGFontSize",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetTGFontSize",exc));}else{throw exc;}} +return result;},ArcApproximationDouble:function(left,top,right,bottom,startx,starty,endx,endy,lpoints){try{var dstartx=startx;var dstarty=starty;var dendx=endx;var dendy=endy;var a=0;var b=0;var ctrX=0;var ctrY=0;var x1;var y1;var x2;var y2;var startAngle;var endAngle;var angleIncrement=0;var t=0;var i=0;if(left>right){var temp=left;left=right;right=temp;} +if(top>bottom){temp=top;top=bottom;bottom=temp;} +a=(right-left)/2.0;b=(bottom-top)/2.0;ctrX=left+a;ctrY=top+b;x1=dstartx-ctrX;x2=dendx-ctrX;y1=ctrY-dstarty;y2=ctrY-dendy;if(y1===0){if(x1>0) +startAngle=0;else +startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;}else if(x1===0){if(y1>0) +startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*0.5;else +startAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*-0.5;}else +startAngle=Math.atan2(y1,x1);if(y2===0){if(x2>0) +endAngle=0;else +endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;}else if(x2===0){if(y2>0) +endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*0.5;else +endAngle=armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI*-0.5;}else +endAngle=Math.atan2(y2,x2);if(endAngle<=startAngle) +endAngle+=2*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI;angleIncrement=(endAngle-startAngle)/16.0;for(t=startAngle;i<17;t+=angleIncrement,i++){lpoints[i].x=ctrX+a*Math.cos(t);lpoints[i].y=ctrY-b*Math.sin(t);} +return;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"ArcApproximationDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ArcApproximationDouble",exc));}else{throw exc;}}},DrawOpenRectangleDouble:function(points,pointsCorner,resultpts){try{var point_mid=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;point_mid.x=(points[0].x+points[1].x)/2;point_mid.y=(points[0].y+points[1].y)/2;pointsCorner[0].x=points[0].x-point_mid.x+points[2].x;pointsCorner[0].y=points[0].y-point_mid.y+points[2].y;pointsCorner[1].x=points[1].x-point_mid.x+points[2].x;pointsCorner[1].y=points[1].y-point_mid.y+points[2].y;resultpts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[1]);resultpts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pointsCorner[1]);resultpts[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pointsCorner[0]);resultpts[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[0]);for(j=0;j<4;j++){resultpts[j].style=0;} +resultpts[3].style=5;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"DrawOpenRectangleDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DrawOpenRectangleDouble",exc));}else{throw exc;}} +return;},DetermineDirectionDouble:function(points){var result=0;try{var dP0P1M=0;var iP0P1B=0;if(points[0].x===points[1].x){if(points[2].xpoints[2].x){return 1;}else{return 0;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"DetermineDirectionDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DetermineDirectionDouble",exc));}else{throw exc;}} +return result;},CalcEndpieceDeltasDouble:function(points,piDeltaX,piDeltaY,dAngleDelta){try{var pntMid=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var iDiagEOL_length=0;var dAngle1=0;pntMid.x=(points[0].x+points[1].x)/2;pntMid.y=(points[0].y+points[1].y)/2;iDiagEOL_length=((Math.sqrt((points[1].x-points[0].x)*(points[1].x-points[0].x)+(points[1].y-points[0].y)*(points[1].y-points[0].y))+Math.sqrt((points[2].x-pntMid.x)*(points[2].x-pntMid.x)+(points[2].y-pntMid.y)*(points[2].y-pntMid.y)))/20);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengthpt2.x&&quadrant===2) +sign=-1;else if(pt1.x>pt2.x&&quadrant===3) +sign=-1;else if(pt1.xiLengthPt0Pt2){iLengthPt0Pt1=iLengthPt0Pt2;} +iFontSize=armyc2.c2sd.JavaLineArray.DISMSupport.GetTGFontSize(iLengthPt0Pt1);if(iFontSize>0){iDelta=iLengthPt0Pt1/15;if(iDelta>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDelta=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDeltapt2.x&&quadrant===2) +sign=-1;else if(pt1.x>pt2.x&&quadrant===3) +sign=-1;else if(pt1.xiLengthPt0Pt2){iLengthPt0Pt1=iLengthPt0Pt2;} +iFontSize=armyc2.c2sd.JavaLineArray.DISMSupport.GetTGFontSize(iLengthPt0Pt1);if(iFontSize>0){iDelta=iLengthPt0Pt1/15;if(iDelta>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDelta=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDeltaarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengthsavepoints[1].y){if(ptRelative.x>ptCenter.x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[0],savepoints[1]);}} +if(savepoints[0].yptCenter.y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[0],savepoints[1]);}} +if(savepoints[0].x>savepoints[1].x){if(ptRelative.yarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);pts[1].x=(pts[0].x+ptCenter.x)/2;pts[1].y=(pts[0].y+ptCenter.y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-(ptPerp.x-ptCenter.x)*iRadius/iPerpLength;pts[0].y=ptCenter.y-(ptPerp.y-ptCenter.y)*iRadius/iPerpLength;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dDeltaX1=Math.cos(dAngle2+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY1=Math.sin(dAngle2+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaX2=Math.cos(dAngle2-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY2=Math.sin(dAngle2-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dDeltaX1=Math.cos(dAngle2+3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY1=Math.sin(dAngle2+3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaX2=Math.cos(dAngle2-3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);dDeltaY2=Math.sin(dAngle2-3*armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/8);pts[0].x=ptCenter.x-dDeltaX1*iRadius;pts[0].y=ptCenter.y-dDeltaY1*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0].x=ptCenter.x-dDeltaX2*iRadius;pts[0].y=ptCenter.y-dDeltaY2*iRadius;pts[1].x=(ptCenter.x+pts[0].x)/2;pts[1].y=(ptCenter.y+pts[0].y)/2;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pts[0],pts[1]);if(d>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],pts[0],-armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts=null;savepoints=null;arcpoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMContainDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMContainDouble",exc));}else{throw exc;}} +return counter;},GetDISMFixDouble:function(points,linetype,clipBounds){var counter=0;try{var pts=new Array(3);var savepoints=new Array(2);var dAngle1=0;var dLength=0;var dJaggyHalfAmp=0;var dJaggyHalfPeriod=0;var dDeltaXOut=0;var dDeltaYOut=0;var dDeltaXAlong=0;var dDeltaYAlong=0;var iNumJaggies=0;var i=0;var j=0;for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +var drawJaggies=new Boolean(true);if(clipBounds!==null){var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMinX(),clipBounds.getMinY());var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMaxX(),clipBounds.getMaxY());savepoints=armyc2.c2sd.JavaLineArray.lineutility.BoundOneSegment(savepoints[0],savepoints[1],ul,lr);} +if(savepoints===null){savepoints=new Array(2);for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +drawJaggies=new Boolean(false);} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);dAngle1=Math.atan2(savepoints[0].y-savepoints[1].y,savepoints[0].x-savepoints[1].x);dLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dJaggyHalfAmp=dLength/15;if(dJaggyHalfAmp>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(dJaggyHalfAmpd){return true;}else{return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"IsSeizeArcReversed",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside IsSeizeArcReversed",exc));}else{throw exc;}} +return false;},GetDISMSeizeDouble:function(points,linetype,radius){var counter=0;try{var ptArcCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptArcStart=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var savepoints=new Array(3);var scale=0.9;var iCircleRadius=(25*scale);var arcpoints=new Array(17);var pts=new Array(3);var dAngle1=0;var dDeltaX1=0;var dDeltaY1=0;var dDeltaX2=0;var dDeltaY2=0;var dChordLength=0;var dArcRadius=0;var j=0;var dDeltaX3=0;var dDeltaY3=0;var iDiagEOL_length=0;var factor=1;if(radius>0) +iCircleRadius=radius;for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +var client=armyc2.c2sd.JavaLineArray.CELineArray.getClient();if(!client.substring(0,4).equals("cpof")&&radius===0) +{dArcRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],savepoints[1]);if(iCircleRadius>dArcRadius/2) +iCircleRadius=dArcRadius/2;} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(arcpoints);armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble(savepoints[0].x-iCircleRadius,savepoints[0].y-iCircleRadius,savepoints[0].x+iCircleRadius,savepoints[0].y+iCircleRadius,savepoints[0].x,savepoints[0].y,savepoints[0].x,savepoints[0].y,arcpoints);for(j=0;j<17;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);points[counter].style=0;counter++;} +points[counter-1].style=5;dAngle1=Math.atan2(savepoints[0].y-savepoints[1].y,savepoints[0].x-savepoints[1].x);dDeltaX1=Math.cos(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaY1=Math.sin(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaX2=Math.cos(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);dDeltaY2=Math.sin(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);var isArcReversed=armyc2.c2sd.JavaLineArray.DISMSupport.IsSeizeArcReversed(savepoints);if(isArcReversed===false){ptArcStart.x=savepoints[0].x-dDeltaX2*iCircleRadius;ptArcStart.y=savepoints[0].y-dDeltaY2*iCircleRadius;dChordLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dArcRadius=dChordLength/1.414213562373;ptArcCenter.x=savepoints[0].x-dDeltaX1*dArcRadius;ptArcCenter.y=savepoints[0].y-dDeltaY1*dArcRadius;armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptArcCenter.x-dArcRadius),(ptArcCenter.y-dArcRadius),(ptArcCenter.x+dArcRadius),(ptArcCenter.y+dArcRadius),savepoints[1].x,savepoints[1].y,ptArcStart.x,ptArcStart.y,arcpoints);}else{ptArcStart.x=savepoints[0].x-dDeltaX1*iCircleRadius;ptArcStart.y=savepoints[0].y-dDeltaY1*iCircleRadius;dChordLength=Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y));dArcRadius=dChordLength/1.414213562373;ptArcCenter.x=savepoints[0].x-dDeltaX2*dArcRadius;ptArcCenter.y=savepoints[0].y-dDeltaY2*dArcRadius;armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptArcCenter.x-dArcRadius),(ptArcCenter.y-dArcRadius),(ptArcCenter.x+dArcRadius),(ptArcCenter.y+dArcRadius),ptArcStart.x,ptArcStart.y,savepoints[1].x,savepoints[1].y,arcpoints);} +for(j=0;j<17;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);points[counter].style=0;counter++;} +points[counter-1].style=5;if(dChordLength/8>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){factor=dChordLength/(8*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);} +if(factor===0){factor=1;} +if(isArcReversed===false){pts[0].x=savepoints[1].x-(savepoints[1].x-savepoints[0].x)/(8*factor);pts[0].y=savepoints[1].y-(savepoints[1].y-savepoints[0].y)/(8*factor);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);dDeltaX3=Math.cos(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);dDeltaY3=Math.sin(dAngle1+armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);iDiagEOL_length=(dChordLength/8);pts[2].x=savepoints[1].x+dDeltaX3*iDiagEOL_length/factor;pts[2].y=savepoints[1].y+dDeltaY3*iDiagEOL_length/factor;}else{pts[0].x=savepoints[1].x-(savepoints[1].x-savepoints[0].x)/(8*factor);pts[0].y=savepoints[1].y-(savepoints[1].y-savepoints[0].y)/(8*factor);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);dDeltaX3=Math.cos(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);dDeltaY3=Math.sin(dAngle1-armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/2);iDiagEOL_length=(dChordLength/8);pts[2].x=savepoints[1].x+dDeltaX3*iDiagEOL_length/factor;pts[2].y=savepoints[1].y+dDeltaY3*iDiagEOL_length/factor;} +for(j=0;j<3;j++){points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[j]);points[counter].style=0;counter++;} +points[counter-1].style=5;savepoints=null;arcpoints=null;pts=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMSeizeDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMSeizeDouble",exc));}else{throw exc;}} +return counter;},side:function(x1,y1,x2,y2,px,py){var dx1;var dx2;var dy1;var dy2;try{var o;dx1=x2-x1;dy1=y2-y1;dx2=px-x1;dy2=py-y1;o=(dx1*dy2)-(dy1*dx2);if(o>0.0){return(armyc2.c2sd.JavaLineArray.DISMSupport.LEFT_SIDE);} +if(o<0.0){return(armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"side",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside side",exc));}else{throw exc;}} +return(armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR);},GetDISMRIPDouble:function(points,linetype){var counter=0;try{var pts=new Array(2);var savepoints=new Array(4);var j=0;var iLengthPt0Pt1=0;var iDiagEOL_length=0;var dAngle1=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;var iLengthPt2Pt3=0;var iRadius=0;var deltapoints=new Array(4);var arcpoints=new Array(17);var ptArcCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var clockwise=false;var side01=armyc2.c2sd.JavaLineArray.DISMSupport.side(points[0].x,points[0].y,points[1].x,points[1].y,points[2].x,points[2].y);var side12=armyc2.c2sd.JavaLineArray.DISMSupport.side(points[1].x,points[1].y,points[2].x,points[2].y,points[3].x,points[3].y);if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE) +clockwise=true;else if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR) +clockwise=true;else if(side01===armyc2.c2sd.JavaLineArray.DISMSupport.COLINEAR&&side12===armyc2.c2sd.JavaLineArray.DISMSupport.RIGHT_SIDE) +clockwise=true;for(j=0;j<4;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(arcpoints);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[3]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);iLengthPt0Pt1=Math.sqrt((pts[1].x-pts[0].x)*(pts[1].x-pts[0].x)+(pts[1].y-pts[0].y)*(pts[1].y-pts[0].y));iDiagEOL_length=iLengthPt0Pt1/8;if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(dJaggyHalfAmparmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(d/5600) +d=600;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(points[2],points[3],Math.floor(Math.floor(d)/20),Math.floor(Math.floor(d)/20),arrowpts,0);for(j=0;j<3;j++){points[4+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arrowpts[j]);} +arrowpts=null;savepoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMPenetrateDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMPenetrateDouble",exc));}else{throw exc;}} +return;},GetDISMByImpDouble:function(points,linetype){var counter=0;try{var j=0;var pointsCorner=new Array(2);var rectpts=new Array(4);var savepoints=new Array(3);var deltapoints1=new Array(4);var deltapoints2=new Array(4);var midpt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pts=new Array(6);var ptRelative=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var iDeltaX=new armyc2.c2sd.JavaLineArray.ref();var iDeltaY=new armyc2.c2sd.JavaLineArray.ref();var bPointsRight=0;var dMBR=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(points,3);if(dMBR>40*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=40*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(dMBR<5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength){dMBR=5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength;} +if(dMBR>250) +dMBR=250;for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(rectpts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints1);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints2);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pointsCorner);armyc2.c2sd.JavaLineArray.DISMSupport.DrawOpenRectangleDouble(savepoints,pointsCorner,rectpts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[1]);points[counter].style=0;counter++;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(rectpts[1],rectpts[2],0);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(rectpts[1],midpt,-5,5);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(rectpts[1],midpt,5,5);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=5;counter++;ptRelative=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(rectpts[0],rectpts[1],pts[0]);pts[2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[0],-dMBR/40);pts[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[0],dMBR/40);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[2]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[3]);points[counter].style=5;counter++;ptRelative=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(rectpts[2],rectpts[3],pts[1]);pts[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[1],-dMBR/40);pts[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptRelative,pts[1],dMBR/40);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[4]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[5]);points[counter].style=5;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[2]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(rectpts[3]);points[counter].style=5;counter++;bPointsRight=armyc2.c2sd.JavaLineArray.DISMSupport.DetermineDirectionDouble(savepoints);armyc2.c2sd.JavaLineArray.DISMSupport.CalcEndpieceDeltasDouble(savepoints,iDeltaX,iDeltaY,armyc2.c2sd.JavaLineArray.DISMSupport.CONST_PI/4);if((savepoints[0].y-savepoints[1].y)<0){if(bPointsRight!==0){armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints2);}else{armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints2);}}else{if(bPointsRight!==0){armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaY.value[0],-iDeltaX.value[0],iDeltaX.value[0],iDeltaY.value[0],deltapoints2);}else{armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[0],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints1);armyc2.c2sd.JavaLineArray.DISMSupport.DrawEndpieceDeltasDouble(savepoints[1],iDeltaX.value[0],iDeltaY.value[0],iDeltaY.value[0],-iDeltaX.value[0],deltapoints2);}} +points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[1]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[0]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[3]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints1[3]);points[counter].style=10;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[1]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[0]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[3]);points[counter].style=9;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(deltapoints2[3]);points[counter].style=10;counter++;pointsCorner=null;rectpts=null;savepoints=null;deltapoints1=null;deltapoints2=null;pts=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMByImpDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMByImpDouble",exc));}else{throw exc;}} +return counter;},GetDISMSupportByFireDouble:function(points,linetype){var counter=0;try{var pts=new Array(3);var savepoints=new Array(4);var j=0;var iDiagEOL_length=0;var dAngle1=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;for(j=0;j<4;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +armyc2.c2sd.JavaLineArray.DISMSupport.ReorderSptByFirePoints(savepoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;iDiagEOL_length=(Math.sqrt((savepoints[0].x-savepoints[1].x)*(savepoints[0].x-savepoints[1].x)+(savepoints[0].y-savepoints[1].y)*(savepoints[0].y-savepoints[1].y))/10);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_length2){distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(savepoints[1],savepoints[2],savepoints[0]);ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],2,distToLine);ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],3,distToLine);distanceToPointAboveLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptAboveLine);distanceToPointBelowLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptBelowLine);if(distanceToPointAboveLinesavepoints[1].x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[1],savepoints[2]);}}}else{distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(savepoints[1],savepoints[2],savepoints[0]);ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],0,distToLine);ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(savepoints[1],savepoints[2],savepoints[2],1,distToLine);distanceToPointLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptLeftOfLine);distanceToPointRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[0],ptRightOfLine);if(distanceToPointRightOfLinesavepoints[1].y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(savepoints[1],savepoints[2]);}}} +points[1].x=savepoints[1].x;points[1].y=savepoints[1].y;points[2].x=savepoints[2].x;points[2].y=savepoints[2].y;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"ReorderAtkByFirePoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMSupportByFireDouble",exc));}else{throw exc;}}},ReorderSptByFirePoints:function(points){try{var ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var distToLine=0;var distanceToPointAboveLine=0;var distanceToPointBelowLine=0;var distanceToPointLeftOfLine=0;var distanceToPointRightOfLine=0;var midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(points[0],points[1],0);if(Math.abs(points[2].x-points[3].x)>2){distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(points[1],points[2],midpt);ptAboveLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],2,distToLine);ptBelowLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],3,distToLine);distanceToPointAboveLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptAboveLine);distanceToPointBelowLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptBelowLine);if(distanceToPointAboveLinepoints[1].x){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[0],points[1]);armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[2],points[3]);}}}else{distToLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(points[1],points[2],midpt);ptLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],0,distToLine);ptRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(points[1],points[2],points[2],1,distToLine);distanceToPointLeftOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptLeftOfLine);distanceToPointRightOfLine=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(points[0],ptRightOfLine);if(distanceToPointLeftOfLinepoints[1].y){armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[0],points[1]);armyc2.c2sd.JavaLineArray.lineutility.Reverse2Points(points[2],points[3]);}}else{if(points[2].yarmyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength/5;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(dMBR/1020) +dist=20;var dist2=dist;switch(linetype){case 23222000:dist=1.5*dist;dist2=dist/2;break;default:dist2=dist;break;} +pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[1],savepoints[0],dist);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[2],savepoints[0],dist2);points[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[0]);points[4].style=0;points[5]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[0],savepoints[1],dist);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[3],savepoints[1],dist2);points[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[1]);points[6].style=0;points[7]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[0],savepoints[2],dist2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[3],savepoints[2],dist);points[8]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[2]);points[8].style=0;points[9]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[1],savepoints[3],dist2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(savepoints[2],savepoints[3],dist);points[10]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[3]);points[10].style=0;points[11]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],5);pts=null;savepoints=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.DISMSupport._className,"GetDISMGapDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDISMGapDouble",exc));}else{throw exc;}} +return 12;},GetDISMMinefieldDisruptDouble:function(points,linetype){var counter=0;try{var pts=new Array(2);var ptsArrow=new Array(3);var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;var savepoints=new Array(3);var dAngle1=0;var d=0;var dist=0;var deltapoints1=new Array(4);var deltapoints2=new Array(4);var deltapoints3=new Array(4);var iDiagEOL_length=0;var iDeltaX1=0;var iDeltaY1=0;var iDeltaX2=0;var iDeltaY2=0;var ptTail=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();for(j=0;j<3;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(points[j]);} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArrow);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints1);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints2);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(deltapoints3);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pts);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=5;counter++;ptCenter.x=(savepoints[0].x+savepoints[1].x)/2;ptCenter.y=(savepoints[0].y+savepoints[1].y)/2;ptsArrow[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);ptsArrow[1].x=ptCenter.x+(savepoints[2].x-savepoints[0].x)*4/5;ptsArrow[1].y=ptCenter.y+(savepoints[2].y-savepoints[0].y)*4/5;ptsArrow[2].x=savepoints[1].x+(savepoints[2].x-savepoints[0].x)*3/5;ptsArrow[2].y=savepoints[1].y+(savepoints[2].y-savepoints[0].y)*3/5;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[2]);points[counter].style=5;counter++;pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[1]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptCenter);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(savepoints[2],savepoints[0]);d=dist;if(d>5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(d<5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength){d=5*armyc2.c2sd.JavaLineArray.DISMSupport.minLength;} +ptTail.x=(savepoints[0].x+ptCenter.x)/2;ptTail.y=(savepoints[0].y+ptCenter.y)/2;pts[0].x=ptTail.x-(savepoints[2].x-savepoints[0].x)/5;pts[0].y=ptTail.y-(savepoints[2].y-savepoints[0].y)/5;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[0],ptTail,-d/5);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTail);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=5;counter++;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArrow[0]);points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);points[counter].style=0;counter++;points[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);points[counter].style=5;counter++;iDiagEOL_length=((Math.sqrt((savepoints[1].x-savepoints[0].x)*(savepoints[1].x-savepoints[0].x)+(savepoints[1].y-savepoints[0].y)*(savepoints[1].y-savepoints[0].y))+Math.sqrt((savepoints[2].x-savepoints[1].x)*(savepoints[2].x-savepoints[1].x)+(savepoints[2].y-savepoints[1].y)*(savepoints[2].y-savepoints[1].y)))/15);if(iDiagEOL_length>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength){iDiagEOL_length=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(iDiagEOL_lengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;} +if(dMBR/20250) +dMBR=250;for(j=0;jdist){var ptTemp=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[1]);savepoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[2]);savepoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptTemp);ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptCenter2);dAngle1=dAngle2;} +dRadius=Math.sqrt((savepoints[1].x-ptCenter.x)*(savepoints[1].x-ptCenter.x)+(savepoints[1].y-ptCenter.y)*(savepoints[1].y-ptCenter.y));armyc2.c2sd.JavaLineArray.DISMSupport.ArcApproximationDouble((ptCenter.x-dRadius),(ptCenter.y-dRadius),(ptCenter.x+dRadius),(ptCenter.y+dRadius),savepoints[2].x,savepoints[2].y,savepoints[1].x,savepoints[1].y,arcpoints);for(j=0;j<17;j++){pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcpoints[j]);pLinePoints[counter].style=0;counter++;} +pLinePoints[counter-1].style=5;pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(savepoints[0]);dAngle1c=Math.atan2(ptCenter.y-savepoints[1].y,ptCenter.x-savepoints[1].x);dAngle2c=Math.atan2(ptCenter.y-savepoints[2].y,ptCenter.x-savepoints[2].x);dAngle12c=(dAngle1c+dAngle2c)/2;if((dAngle1c>0)&&(dAngle2c<0)){pts[1].x=ptCenter.x+Math.cos(dAngle12c)*dRadius;pts[1].y=ptCenter.y+Math.sin(dAngle12c)*dRadius;}else{pts[1].x=ptCenter.x-Math.cos(dAngle12c)*dRadius;pts[1].y=ptCenter.y-Math.sin(dAngle12c)*dRadius;} +pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[0]);pLinePoints[counter].style=0;counter++;pLinePoints[counter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[1]);pLinePoints[counter].style=5;counter++;dAngle0=Math.atan2(pts[1].y-savepoints[0].y,pts[1].x-savepoints[0].x);iArrowLength=((Math.sqrt((savepoints[1].x-savepoints[2].x)*(savepoints[1].x-savepoints[2].x)+(savepoints[1].y-savepoints[2].y)*(savepoints[1].y-savepoints[2].y))+Math.sqrt((savepoints[0].x-ptMid.x)*(savepoints[0].x-ptMid.x)+(savepoints[0].y-ptMid.y)*(savepoints[0].y-ptMid.y)))/20);if(iArrowLength>armyc2.c2sd.JavaLineArray.DISMSupport.maxLength) +iArrowLength=Math.floor(armyc2.c2sd.JavaLineArray.DISMSupport.maxLength);if(iArrowLengtharmyc2.c2sd.JavaLineArray.DISMSupport.maxLength) +d=armyc2.c2sd.JavaLineArray.DISMSupport.maxLength;if(d0) +pLinePoints=new Array(vblCounter);else{shapes=null;return null;} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pLinePoints);if(vblSaveCounter>pts.size()) +vblSaveCounter=pts.size();if(vblSaveCounter>pLinePoints.length) +vblSaveCounter=pLinePoints.length;for(j=0;j25) +{dIncrement=25;numGlyphs=Math.floor(dLengthSegment/dIncrement);} +for(k=0;kpLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt0,3,dGlyphSize);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt1,3,dGlyphSize);nCounter++;} +if(pLinePoints[j].xpLinePoints[j+1].y){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt0,0,dGlyphSize);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pLinePoints[j+1],pt1,0,dGlyphSize);nCounter++;}} +pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-3],10,dIncrement/2);nCounter++;} +pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nCounter++;} +for(j=0;j25) +dIncrement=25;limit=numSpikes-1;for(k=-1;kpLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pSpikePoints[nCounter-1],pt0,2,dSpikeSize);} +if(pLinePoints[j].x=0&&oppSegment=1||bolVertical===0){nOrientation=0;for(j=0;jY0)||(pLinePoints[j].y>Y0&&pLinePoints[j+1].yX0)||(pLinePoints[j].x>X0&&pLinePoints[j+1].x0){pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-remainder/2,0);pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-10-remainder/2,0);}else{pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20,0);pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*20-10,0);} +switch(lineType){case 23115000:case 23114000:case 23113000:case 23111000:case 23111001:case 22624000:pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nCounter-1],5);break;case 23350000:case 22134000:pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-1]);break;default:break;} +pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt2,pt0,nDirection,10);switch(lineType){case 23115000:case 23114000:case 23113000:case 23111000:case 23111001:case 22624000:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-2],10,0);break;case 23350000:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-2]);break;case 22134000:pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nCounter-2],10,0);pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt2,pt3,nDirection,10);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);break;default:break;} +nCounter++;if(lineType===22624000) +pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nCounter-4]);} +pSpikePoints[nCounter++]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);} +for(j=0;j0) +pSpikePoints[nCounter-1].style=5;} +for(j=0;jd){return true;}else{return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.arraysupport._className,"IsTurnArcReversed",new armyc2.c2sd.renderer.utilities.RendererException("IsTurnArcReversed",exc));}else{throw exc;}} +return false;},GetIsolatePointsDouble:function(pLinePoints,lineType,converter){try{var reverseTurn=false;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[1]);var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);if(pt0.x===pt1.x&&pt0.y===pt1.y) +pt1.x+=1;var C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var E=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var j=0;var k=0;var l=0;var ptsArc=new Array(26);var midPts=new Array(7);var trianglePts=new Array(21);var pArrowPoints=new Array(3);var reversepArrowPoints=new Array(3);var dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);var dLength=Math.abs(dRadius-20);if(dRadius<40){dLength=dRadius/1.5;} +var d=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(pLinePoints,2);var ptsSeize=new Array(2);var savepoints=new Array(3);for(j=0;j<2;j++){savepoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);} +if(pLinePoints.length>=3){savepoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);} +armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArc);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(midPts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(trianglePts);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArrowPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(reversepArrowPoints);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsSeize);if(d/7>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){d=7*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(d/7140) +d=140;var ptsArc2=new Array(26);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(ptsArc2);E.x=2*pt1.x-pt0.x;E.y=2*pt1.y-pt0.y;ptsArc[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[1]);ptsArc[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(E);if(converter) +{ptsArc[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);ptsArc[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[1]);} +armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(ptsArc,0,dRadius,lineType,converter);for(j=0;j<26;j++){ptsArc[j].style=0;pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[j].style=0;} +if(lineType!==211600000) +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,0);else +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(1.75*d)/7),pArrowPoints,0);pLinePoints[25].style=5;switch(lineType){case 212600000:case 212500000:case 211400000:if(dRadius>100) +dLength=0.8*dRadius;for(j=1;j<=23;j++){if(j%3===0){midPts[k].x=pt0.x-Math.floor(((dLength/dRadius)*(pt0.x-ptsArc[j].x)));midPts[k].y=pt0.y-Math.floor(((dLength/dRadius)*(pt0.y-ptsArc[j].y)));midPts[k].style=0;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j-1]);l++;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midPts[k]);l++;trianglePts[l]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j+1]);trianglePts[l].style=5;l++;k++;}} +for(j=26;j<47;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(trianglePts[j-26]);} +pLinePoints[46].style=5;for(j=47;j<50;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-47]);pLinePoints[j].style=0;} +break;case 211600000:midPt.x=(pt1.x+ptsArc[25].x)/2;midPt.y=(pt1.y+ptsArc[25].y)/2;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(midPt,ptsArc[25],Math.floor(Math.floor(d)/7),Math.floor(Math.floor(1.75*d)/7),reversepArrowPoints,0);for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);} +for(j=29;j<32;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(reversepArrowPoints[j-29]);pLinePoints[j].style=0;} +break;case 212100000:for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=0;} +pLinePoints[28].style=5;break;case 23173000:var changeArc=armyc2.c2sd.JavaLineArray.arraysupport.IsTurnArcReversed(savepoints);if(reverseTurn===true||changeArc===true){pt0.x=pt1.x;pt0.y=pt1.y;pt1.x=pt2.x;pt1.y=pt2.y;} +ptsSeize[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);ptsSeize[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcClockwiseCenterDouble(ptsSeize);C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsSeize[0]);E=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsSeize[1]);ptsArc[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);ptsArc[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(E);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(ptsArc,0,dRadius,lineType);for(j=0;j<26;j++){ptsArc[j].style=0;pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[j].style=0;} +if(changeArc===true){armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[1],pt0,Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,5);}else{armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(ptsArc[24],pt1,Math.floor(Math.floor(d)/7),Math.floor(Math.floor(d)/7),pArrowPoints,5);} +pLinePoints[25].style=5;for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=9;} +pLinePoints[28].style=10;break;case 211900000:for(j=26;j<29;j++){pLinePoints[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j-26]);pLinePoints[j].style=0;} +pLinePoints[28].style=5;k=29;for(j=1;j<24;j++){pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptsArc[j]);pLinePoints[k].style=0;k++;pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,ptsArc[j],Math.floor(Math.floor(d)/7));pLinePoints[k].style=5;k++;} +break;default:break;} +savepoints=null;ptsArc=null;midPts=null;trianglePts=null;pArrowPoints=null;reversepArrowPoints=null;ptsSeize=null;ptsArc2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.arraysupport._className,"GetIsolatePointsDouble",new armyc2.c2sd.renderer.utilities.RendererException("GetIsolatePointsDouble "+Integer.toString(lineType),exc));}else{throw exc;}} +return;},AreaWithCenterFeatureDouble:function(pLinePoints,vblCounter,lineType){try{var k=0;var ptCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var fLength=4;if(lineType===221311000) +fLength=5;var d=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(pLinePoints,vblCounter-fLength);if(d>350) +d=350;for(k=0;k60) +d=60;var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();armyc2.c2sd.JavaLineArray.lineutility.CalcMBRPoints(pLinePoints,vblCounter-4,ul,lr);var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(lr);ur.y=ul.y;pLinePoints[vblCounter-3]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(ur,ul,0);pLinePoints[vblCounter-3].x-=d/2;pLinePoints[vblCounter-3].y-=d/5;pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(ur,ul,0);pLinePoints[vblCounter-2].y-=d*0.7;pLinePoints[vblCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(ur,ul,0);pLinePoints[vblCounter-1].x+=d/2;pLinePoints[vblCounter-1].y-=d/5;pLinePoints[vblCounter-4].style=5;break;case 221311000:if(d<100) +d=100;pLinePoints[vblCounter-5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);pLinePoints[vblCounter-5].style=5;pLinePoints[vblCounter-4]=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble(pLinePoints,vblCounter-6);pLinePoints[vblCounter-4].x-=d/10;pLinePoints[vblCounter-4].style=0;pLinePoints[vblCounter-3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-4]);pLinePoints[vblCounter-3].x=pLinePoints[vblCounter-4].x+d/5;pLinePoints[vblCounter-3].style=5;pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-4]);pLinePoints[vblCounter-2].y+=d/20;pLinePoints[vblCounter-2].style=0;pLinePoints[vblCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-3]);pLinePoints[vblCounter-1].y-=d/20;pLinePoints[vblCounter-1].style=0;break;case 22340000:if(d<50) +d=50;if(lineType===22340000){for(k=0;k0){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+45,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+4,5);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-1,20);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-7,0);}else{pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-45,0);} +break;case 31131300:if(k>0){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+45,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement+10,5);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter-1],pLinePoints[j+1],5,0);nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter-1],pLinePoints[j+1],10,5);nCounter++;crossPt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nCounter-2],pSpikePoints[nCounter-1],pSpikePoints[nCounter-1],2,5,0);crossPt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nCounter-1],pSpikePoints[nCounter-2],pSpikePoints[nCounter-2],3,5,5);pSpikePoints[nCounter]=crossPt1;nCounter++;pSpikePoints[nCounter]=crossPt2;nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-13,0);}else{pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-45,0);} +break;default:pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-30,0);break;} +if(lineType===31131000){pSpikePoints[nCounter].style=0;} +nCounter++;pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-k*dIncrement-dSpikeSize,0);if(lineType===31131000||lineType===31131200||lineType===31131300){pSpikePoints[nCounter].style=9;} +nCounter++;pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nCounter-1],dSpikeSize/2);if(pLinePoints[j].x>pLinePoints[j+1].x){pSpikePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[j],pSpikePoints[nCounter-1],pt0,2,dSpikeSize);} +if(pLinePoints[j].x0){pSquallSegPts=new Array(segQty);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSquallSegPts);} +else +{pSquallPts[counter].x=StartSegPt.x;pSquallPts[counter++].y=StartSegPt.y;pSquallPts[counter].x=EndSegPt.x;pSquallPts[counter++].y=EndSegPt.y;continue;} +sign.value[0]=-1;armyc2.c2sd.JavaLineArray.lineutility.GetSquallSegment(StartSegPt,EndSegPt,pSquallSegPts,sign,amplitude,quantity,length);for(k=0;k0){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt2,20);} +dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,pt2);lNumSegs=Math.floor((dDistance/20));if(lNumSegs>0){points2=Clazz.newArray(lNumSegs*32,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetAnchorageFlotSegment(vbPoints,Math.floor(pt1.x),Math.floor(pt1.y),Math.floor(pt2.x),Math.floor(pt2.y),l,points2,bFlip,lDirection,lLastDirection);points=Clazz.newArray(numSegPts,0);for(j=0;j2) +pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);pt0.style=0;pt1.style=0;pt2.style=0;var xPoints=null;pOriginalLinePoints=new Array(vblSaveCounter);for(j=0;j0) +pLinePoints[xCount-1].style=5;for(k=0;k=pLinePoints[2].y){pLinePoints[0].style=0;pLinePoints[2].style=1;}else{pLinePoints[0].style=1;pLinePoints[2].style=0;}} +break;default:break;} +acCounter=4;break;case 23224000:armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pLinePoints[2],pt0,pt1);pLinePoints[0].style=1;pLinePoints[1].style=5;pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2].style=1;pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[3].style=5;acCounter=4;break;case 23194000:pts=new Array(4);for(j=0;j<4;j++){pts[j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);} +dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(pLinePoints[0],pLinePoints[1],pLinePoints[2]);pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[1],d,0);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[0],d,5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[1],-d,0);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pts[0],pts[1],pts[0],-d,5);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],0);midpt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[0],midpt,d);pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,105,dRadius/2);pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,-75,dRadius/2);pLinePoints[5].style=5;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pts[0],pts[1],0);midpt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pts[1],midpt,d);pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,105,dRadius/2);pLinePoints[7]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAngledLine(pts[0],pts[1],midpt,-75,dRadius/2);pLinePoints[7].style=5;acCounter=8;break;case 221311000:case 22340000:case 2237000:armyc2.c2sd.JavaLineArray.arraysupport.AreaWithCenterFeatureDouble(pLinePoints,vblCounter,lineType);acCounter=vblCounter;break;case 22431100:for(j=0;jpt1.y){direction=0;}else{direction=1;}} +if(bolVertical!==0&&m.value[0]<=1){if(pt0.x1){if(pt0.xpt1.y){direction=1;} +if(pt0.xpt1.x&&pt0.y>pt1.y){direction=1;} +if(pt0.x>pt1.x&&pt0.yarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/20500) +dMBR=500;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,direction,dMBR/20);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,direction,dMBR/20);acCounter=4;break;case 211400000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType,converter);acCounter=50;break;case 212600000:case 212500000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType,converter);acCounter=50;break;case 211600000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType,converter);acCounter=32;break;case 211900000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType,converter);acCounter=75;break;case 212100000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType,converter);acCounter=29;break;case 23173000:armyc2.c2sd.JavaLineArray.arraysupport.GetIsolatePointsDouble(pLinePoints,lineType);acCounter=29;break;case 22624000:acCounter=armyc2.c2sd.JavaLineArray.arraysupport.GetZONEPointsDouble2(pLinePoints,lineType,vblSaveCounter);break;case 23111001:pUpperLinePoints=new Array(vblSaveCounter);pLowerLinePoints=new Array(vblSaveCounter);pUpperLowerLinePoints=new Array(2*vblCounter);for(j=0;j=1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,10);}} +if(pLinePoints[j].x>pLinePoints[j+1].x){if(m.value[0]<1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,3,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,3,10);} +if(m.value[0]>=1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,10);}} +if(bolVertical===0){if(pLinePoints[j].y>pLinePoints[j+1].y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,10);}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,10);}} +pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);nCounter++;pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);nCounter++;d=10;if(dMBR/20=1) +{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,15);}} +if(pLinePoints[j].x>pLinePoints[j+1].x){if(m.value[0]<1) +{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,3,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,3,15);} +if(m.value[0]>=1) +{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,15);}} +if(bolVertical===0){if(pLinePoints[j].y>pLinePoints[j+1].y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,0,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,0,15);}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt2,1,15);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt3,1,15);}} +pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);nCounter++;pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);nCounter++;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt3,pt2,Math.floor(d),Math.floor(d),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[nCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);nCounter++;}}} +acCounter=nCounter;break;case 24222000:for(j=0;jarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){d=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(d/10500) +d=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt2,Math.floor(Math.floor(d)/10),Math.floor(Math.floor(d)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=pArrowPoints[k];} +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(d)/10),Math.floor(Math.floor(d)/10),pArrowPoints,18);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=pArrowPoints[k];} +acCounter=vblCounter;break;case 23225000:armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pLinePoints[2],pt4,pt5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);for(j=0;j1){pt0=savepoints[0];pt1=savepoints[1];} +else +{savepoints=new Array(2);savepoints[0]=new armyc2.c2sd.JavaLineArray.POINT2(pt0);savepoints[1]=new armyc2.c2sd.JavaLineArray.POINT2(pt1);drawJaggies=false;} +midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);var dist0=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt0);var dist1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt1);if(dist0>dist1){armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt0,pt4,pt5);}else{armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt1,pt4,pt5);} +pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);}else{midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pLinePoints[0],pLinePoints[1],0);dist0=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt0);dist1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(midpt,pt1);if(dist0>dist1) +armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt0,pt4,pt5);else +armyc2.c2sd.JavaLineArray.lineutility.LineRelativeToLine(pLinePoints[0],pLinePoints[1],pt1,pt4,pt5);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);} +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pt0,-10,0);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[3],pt1,-10,0);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pt0,10,0);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[3],pt1,10,0);dWidth=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);pointCounter=4;n=1;pLinePoints[pointCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[pointCounter].style=0;pointCounter++;if((drawJaggies).valueOf()) +while(dExtendLength=pLinePoints.length-1) +break;n++;} +pLinePoints[pointCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[pointCounter].style=5;pointCounter++;acCounter=pointCounter;break;case 23131100:acCounter=armyc2.c2sd.JavaLineArray.lineutility.GetDitchSpikeDouble(pLinePoints,vblSaveCounter,0,lineType);break;case 23131200:pLinePoints[0].style=9;acCounter=armyc2.c2sd.JavaLineArray.lineutility.GetDitchSpikeDouble(pLinePoints,vblSaveCounter,0,lineType);break;case 23132000:armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLinePoints,vblSaveCounter);pLinePoints[0].style=9;acCounter=armyc2.c2sd.JavaLineArray.lineutility.GetDitchSpikeDouble(pLinePoints,vblSaveCounter,0,lineType);break;case 22522210:if(dMBR/30>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=30*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/30500) +dMBR=250;d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);if(darmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/10250) +dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt3,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} +pLinePoints[vblSaveCounter-1].style=5;acCounter=vblCounter;break;case 23227000:pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[vblCounter-8],pLinePoints[vblCounter-7],dMBR/2);pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-7]);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],dMBR/2);if(dMBR/10>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/10200) +dMBR=200;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt3,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/5),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt1,pt0,Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/5),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} +pLinePoints[vblSaveCounter-1].style=5;acCounter=vblCounter;break;case 22522100:armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLinePoints,vblSaveCounter);for(k=vblSaveCounter-1;k>0;k--){d+=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[k],pLinePoints[k-1]);if(d>60) +break;} +if(d>60){middleSegment=k;pt2=pLinePoints[middleSegment];if(middleSegment>=1) +pt3=pLinePoints[middleSegment-1];}else{if(vblSaveCounter<=3) +middleSegment=1;else +middleSegment=2;pt2=pLinePoints[middleSegment];if(middleSegment>=1) +pt3=pLinePoints[middleSegment-1];} +pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);if(dMBR/20>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/20250) +dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-11],pLinePoints[vblCounter-10],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[vblCounter-9+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} +pLinePoints[vblCounter-6].x=(pLinePoints[vblCounter-11].x+pLinePoints[vblCounter-10].x)/2;pLinePoints[vblCounter-6].y=(pLinePoints[vblCounter-11].y+pLinePoints[vblCounter-10].y)/2;pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[vblCounter-6]);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-11],pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);if(middleSegment>=1){pt0=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt2,pt3,0);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt3,pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);} +for(j=0;j<3;j++){pLinePoints[vblCounter-6+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-10],pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);if(middleSegment>=1){pt0=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt2,pt3,0);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pt2,pt0,Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,9);} +for(j=0;j<3;j++){pLinePoints[vblCounter-3+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} +var airPts=new java.util.ArrayList();pLinePoints[middleSegment-1].style=5;if(vblSaveCounter===2) +pLinePoints[1].style=5;for(j=0;jarmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR250) +dMBR=250;pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,-dMBR/10);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=pt2.y+(1/m.value[0])*pt2.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,-2);pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,2);pLinePoints[4].style=0;} +if(bolVertical!==0&&m.value[0]===0){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3].y=pt2.y-2;pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[4].y=pt2.y+2;pLinePoints[4].style=0;} +if(bolVertical===0){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3].x=pt2.x-2;pLinePoints[3].style=0;pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[4].x=pt2.x+2;pLinePoints[4].style=0;} +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt1,pt0,-dMBR/10);if(bolVertical!==0&&m.value[0]!==0){b=pt2.y+(1/m.value[0])*pt2.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,2);pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,pt2,-2);} +if(bolVertical!==0&&m.value[0]===0){pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[5].y=pt2.y+2;pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[6].y=pt2.y-2;} +if(bolVertical===0){pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[5].x=pt2.x+2;pLinePoints[5].style=0;pLinePoints[6]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[6].x=pt2.x-2;} +pLinePoints[6].style=0;pLinePoints[7]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[3]);pLinePoints[7].style=5;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[0],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[8+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);} +armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[2],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(j=0;j<3;j++){pLinePoints[11+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[j]);pLinePoints[11+j].style=0;} +acCounter=14;break;case 22522220:armyc2.c2sd.JavaLineArray.lineutility.ReversePointsDouble2(pLinePoints,vblSaveCounter);if(dMBR/20>armyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=20*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/20500) +dMBR=500;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-5],pLinePoints[vblCounter-4],Math.floor(Math.floor(dMBR)/20),Math.floor(Math.floor(dMBR)/20),pArrowPoints,0);for(k=0;k<3;k++){pLinePoints[vblCounter-k-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);} +acCounter=vblCounter;break;case 23120000:pts2=new Array(2);pts2[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts2[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.GetPixelsMin(pts2,2,offsetX,offsetY);if(offsetX.value[0]<=0){offsetX.value[0]=offsetX.value[0]-100;}else{offsetX.value[0]=0;} +if(dMBR>300) +dMBR=300;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],-dMBR/10);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);midpt.x=(pt0.x+pLinePoints[0].x)/2;midpt.y=(pt0.y+pLinePoints[0].y)/2;pLinePoints[vblCounter-3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[vblCounter-4].style=5;pLinePoints[vblCounter-3].style=0;if(bolVertical!==0&&m.value[0]!==0){b=midpt.y+(1/m.value[0])*midpt.x;b1=(-1/m.value[0])*offsetX.value[0]+b;ptYIntercept.x=offsetX.value[0];ptYIntercept.y=b1;pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,dMBR/20);if(pLinePoints[vblCounter-2].y>=midpt.y){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dMBR/20);}} +if(bolVertical!==0&&m.value[0]===0){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midpt);pLinePoints[vblCounter-2].y=midpt.y-dMBR/20;} +if(bolVertical===0){pLinePoints[vblCounter-2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(midpt);pLinePoints[vblCounter-2].x=midpt.x-dMBR/20;} +pLinePoints[vblCounter-2].style=0;pLinePoints[vblCounter-1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);acCounter=vblCounter;break;case 23157000:pts2=new Array(2);if(Math.abs(pt0.y-pt1.y)<1){pt1.y=pt0.y+1;} +pts2[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts2[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pts=new Array(26);dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1)/2;midpt.x=(pt1.x+pt0.x)/2;midpt.y=(pt1.y+pt0.y)/2;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=midpt.y+(1/m.value[0])*midpt.x;ptYIntercept.x=0;ptYIntercept.y=b;pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,dRadius);if(pLinePoints[0].x<=pLinePoints[1].x){if(pt2.y>=midpt.y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dRadius);}}else{if(pt2.y<=midpt.y){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(ptYIntercept,midpt,-dRadius);}}} +if(bolVertical!==0&&m.value[0]===0){pt2=midpt;if(pLinePoints[0].x<=pLinePoints[1].x){pt2.y=midpt.y-dRadius;}else{pt2.y=midpt.y+dRadius;}} +if(bolVertical===0){pt2=midpt;if(pLinePoints[0].y<=pLinePoints[1].y){pt2.x=midpt.x+dRadius;}else{pt2.x=midpt.x-dRadius;}} +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(midpt,pt2,100);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(pts,0,dRadius,lineType);pLinePoints[0].style=1;pLinePoints[1].style=5;for(j=0;j<26;j++){pLinePoints[2+j]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pts[j]);pLinePoints[2+j].style=1;} +acCounter=28;break;case 231100000:dRadius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceToLineDouble(pt0,pt1,pt2);bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical!==0&&m.value[0]!==0){b=pt1.y+1/m.value[0]*pt1.x;b1=pt2.y-m.value[0]*pt2.x;calcPoint0=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);b=calcPoint1.y+1/m.value[0]*calcPoint1.x;calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);b=calcPoint2.y+1/m.value[0]*calcPoint2.x;calcPoint4=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);b=pt1.y+1/m.value[0]*pt1.x;calcPoint0=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b,m.value[0],b1,1,1,pt0.x,pt0.y);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} +if(bolVertical!==0&&m.value[0]===0){calcPoint0.x=pt1.x;calcPoint0.y=pt2.y;calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=pt2;calcPoint3.x=calcPoint0.x+dRadius/2;calcPoint3.y=calcPoint0.y;calcPoint4.x=pt1.x+dRadius;calcPoint4.y=pt2.y;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} +if(bolVertical===0){calcPoint0.x=pt2.x;calcPoint0.y=pt1.y;calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius/2);calcPoint2=pt2;calcPoint3.y=calcPoint0.y+dRadius/2;calcPoint3.x=calcPoint0.x;calcPoint4.y=pt1.y+dRadius;calcPoint4.x=pt2.x;midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint1,calcPoint3,0);midpt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(calcPoint2,calcPoint4,0);calcPoint3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,dRadius);d=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(calcPoint0,calcPoint3);calcPoint1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(calcPoint0,calcPoint3,-(d-dRadius));} +arcPts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(calcPoint1);arcPts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(calcPoint3);armyc2.c2sd.JavaLineArray.lineutility.ArcArrayDouble(arcPts,0,dRadius,lineType);pLinePoints[0].style=5;pLinePoints[1].style=5;for(k=0;k<26;k++){pLinePoints[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(arcPts[k]);} +for(k=25;karmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/10150) +dMBR=150;pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[1],pLinePoints[0],-2*dMBR/10);for(k=0;karmyc2.c2sd.JavaLineArray.arraysupport.maxLength){dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;} +if(dMBR/100;k--){pLinePoints[vblCounter-k].style=5;} +acCounter=12;break;case 23223000:lLinestyle=9;if(dMBR/10>armyc2.c2sd.JavaLineArray.arraysupport.maxLength) +dMBR=10*armyc2.c2sd.JavaLineArray.arraysupport.maxLength;if(dMBR/10250) +dMBR=250;armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[vblCounter-8],pLinePoints[vblCounter-7],Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,lLinestyle);for(k=0;k<3;k++) +pLinePoints[vblCounter-6+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);armyc2.c2sd.JavaLineArray.lineutility.GetArrowHead4Double(pLinePoints[1],pLinePoints[0],Math.floor(Math.floor(dMBR)/10),Math.floor(Math.floor(dMBR)/10),pArrowPoints,lLinestyle);for(k=0;k<3;k++) +pLinePoints[vblCounter-3+k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pArrowPoints[k]);acCounter=8;break;case 26220000:pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt1,pt0,-10,0);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pt0,pt1,-10,0);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt3,10,0);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt3,-10,0);pt7=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt4,10,0);pt8=armyc2.c2sd.JavaLineArray.lineutility.ExtendTrueLinePerpDouble(pt0,pt1,pt4,-10,0);if(pt5.ypt8.y){pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt7);}else{pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt8);} +pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);acCounter=4;break;case 23330000:acCounter=armyc2.c2sd.JavaLineArray.arraysupport.GetFORTLPointsDouble(pLinePoints,lineType,vblSaveCounter);break;case 21400000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCanalizeDouble(pLinePoints,lineType);break;case 21200000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBreachDouble(pLinePoints,lineType);break;case 212210000:case 212220000:case 212230000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDouble(pLinePoints,lineType);break;case 212210001:case 212220001:case 212230001:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDoubleRevC(pLinePoints,lineType,vblSaveCounter);break;case 22139000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMCoverDouble(pLinePoints,lineType);var saraPts=new Array(acCounter);for(j=0;j<4;j++) +saraPts[j]=pLinePoints[j];for(j=4;j<8;j++) +saraPts[j]=pLinePoints[j+4];for(j=8;j<12;j++) +saraPts[j]=pLinePoints[j-4];for(j=12;j<16;j++) +saraPts[j]=pLinePoints[j];pLinePoints=saraPts;break;case 211000000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMDisruptDouble(pLinePoints,lineType);break;case 21600000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMContainDouble(pLinePoints,lineType);break;case 211700000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMPenetrateDouble(pLinePoints,lineType);acCounter=7;break;case 23171000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBlockDouble2(pLinePoints,lineType);acCounter=4;break;case 21100000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBlockDouble2(pLinePoints,lineType);acCounter=4;break;case 24250000:case 24211000:case 24260000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMLinearTargetDouble(pLinePoints,lineType,vblCounter);break;case 23163000:case 23221000:case 23222000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMGapDouble(pLinePoints,lineType);acCounter=12;break;case 23174000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMMinefieldDisruptDouble(pLinePoints,lineType);break;case 22534000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSupportByFireDouble(pLinePoints,lineType);break;case 22533000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMATKBYFIREDouble(pLinePoints,lineType);break;case 23213000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMByImpDouble(pLinePoints,lineType);break;case 21500000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMClearDouble(pLinePoints,lineType);break;case 23212000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMByDifDouble(pLinePoints,lineType,clipBounds);break;case 212300000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSeizeDouble(pLinePoints,lineType,0);break;case 212300001:var radius=0;if(rev===1){radius=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[0],pLinePoints[1]);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[3]);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[2]);} +acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMSeizeDouble(pLinePoints,lineType,radius);break;case 211100000:case 23172000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMFixDouble(pLinePoints,lineType,clipBounds);break;case 211800000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMRIPDouble(pLinePoints,lineType);break;case 21800000:case 212400000:case 212410000:case 212000000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDelayGraphicEtcDouble(pLinePoints);break;case 23211000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMEasyDouble(pLinePoints,lineType);break;case 22310000:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMDeceiveDouble(pLinePoints);acCounter=4;break;case 21300000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMBypassDouble(pLinePoints,lineType);break;case 24326100:armyc2.c2sd.JavaLineArray.DISMSupport.GetDISMPAADouble(pLinePoints,lineType);acCounter=5;break;case 22611000:acCounter=armyc2.c2sd.JavaLineArray.DISMSupport.AmbushPointsDouble(pLinePoints);break;case 22122000:acCounter=armyc2.c2sd.JavaLineArray.flot.GetFlotDouble(pLinePoints,vblSaveCounter);break;default:acCounter=vblSaveCounter;break;} +switch(lineType){case 22121000:armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);return points;case 21600000:case 21100000:case 212230000:case 212210000:case 212220000:case 212230001:case 212210001:case 212220001:case 24326100:case 211210000:case 211200000:case 21200000:case 21300000:case 21400000:case 21500000:case 211000000:case 211100000:case 211400000:case 211600000:case 211700000:case 211900000:case 212100000:case 212300000:case 212300001:case 14000000:case 15000003:case 221311000:case 22340000:case 2237000:case 212500000:case 212600000:case 23410000:case 25211000:case 25212000:case 23226000:case 22522100:case 23120000:armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);break;default:if(shapes===null){armyc2.c2sd.JavaLineArray.arraysupport.FillPoints(pLinePoints,acCounter,points);return points;} +break;} +if(shapes===null) +return points;var shape=null;var gp=null;var redShape=null;var blueShape=null;var paleBlueShape=null;var whiteShape=null;var redFillShape=null;var blueFillShape=null;var blackShape=null;var blueStroke;var paleBlueStroke;var blueArea=null;var paleBlueArea=null;var whiteArea=null;var beginLine=true;var poly=null;switch(lineType){case 15000001:case 15000003:case 13000001:case 13000002:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.moveTo(pLinePoints[0]);for(j=0;j0;j--){if(pLinePoints[acCounter-j-1].style===5){shape.moveTo(pLinePoints[acCounter-j]);}else{shape.lineTo(pLinePoints[acCounter-j]);}} +shapes.add(shape);break;case 32214000:var wideStroke=20,thinStroke=10;dMBR=armyc2.c2sd.JavaLineArray.lineutility.MBRDistance(pLinePoints,pLinePoints.length);wideStroke=dMBR/8;if(wideStroke>20) +wideStroke=20;thinStroke=wideStroke/2;var minBeta=this.getMinBeta(pLinePoints);if(minBeta<0.1) +{wideStroke=6;thinStroke=3;} +whiteShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);whiteShape.setFillColor(armyc2.c2sd.renderer.utilities.Color.WHITE);var whiteStroke=new armyc2.c2sd.graphics2d.BasicStroke(wideStroke);blueShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);blueShape.setFillColor(new armyc2.c2sd.renderer.utilities.Color(30,144,255));paleBlueStroke=new armyc2.c2sd.graphics2d.BasicStroke(thinStroke);paleBlueShape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);paleBlueShape.setFillColor(new armyc2.c2sd.renderer.utilities.Color(153,204,255));poly=new armyc2.c2sd.graphics2d.Polygon();for(k=0;k0&&k0&&k0) +if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5) +continue;if(k===0) +shape.set_Style(pLinePoints[k].style);shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5){beginLine=true;}} +if(k===vblCounter-1){if(shape!==null&&shape.getShape()!==null) +shapes.add(shape);}} +for(k=0;k0) +if(points.get(k).style===5&&points.get(k-1).style===5) +shape.lineTo(points.get(k));shape.moveTo(points.get(k));beginLine=false;}else{shape.lineTo(points.get(k));if(points.get(k).style===5||points.get(k).style===10){beginLine=true;}} +if(k===points.size()-1){if(shape!==null&&shape.getShape()!==null) +shapes.add(shape);}} +break;case 221311000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.moveTo(pLinePoints[0]);for(k=1;k0){if(pLinePoints[k].style===5&&pLinePoints[k-1].style===5&&k1) +if(pLinePoints[k].style===5&&pLinePoints[k+1].style===5) +continue;shape.moveTo(pLinePoints[k]);beginLine=false;}else{shape.lineTo(pLinePoints[k]);if(pLinePoints[k].style===5||pLinePoints[k].style===10){beginLine=true;}} +if(k===acCounter-1){if(shape!==null&&shape.getShape()!==null) +shapes.add(shape);}} +break;} +switch(lineType){case 22221000:case 22223000:case 22222000:case 22222001:case 22224000:case 22224001:case 22225000:for(j=0;j=0;j--){shape.lineTo(pLowerLinePoints[j]);} +shape.lineTo(pUpperLinePoints[0]);shapes.add(0,shape);break;case 22522100:var outLineCounter=0;var ptOutline=new Array(4);for(k=0;k1) +count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(pLinePoints[0],pLinePoints[1],clipBounds);else +count=0;break;case 23212000:if(clipBounds!==null){armyc2.c2sd.JavaLineArray.countsupport.GetByDifSegment(pLinePoints,pointsCorner);var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMinX(),clipBounds.getMinY());var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(clipBounds.getMaxX(),clipBounds.getMaxY());var ptsCorner=armyc2.c2sd.JavaLineArray.lineutility.BoundOneSegment(pointsCorner[0],pointsCorner[1],ul,lr);if(ptsCorner!==null) +count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(ptsCorner[0],ptsCorner[1],clipBounds);else +count=20;}else +count=armyc2.c2sd.JavaLineArray.countsupport.GetDISMFixCountDouble(pLinePoints[0],pLinePoints[1],clipBounds);break;default:count=vblCounter;break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.countsupport._className,"GetCountersDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCountersDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} +return Math.floor(count);},GetReefCount:function(pLinePoints,vblCounter){var count=0;try{var d=0;for(var j=0;j24){switch(vbiDrawThis){case 23132000:vblXCounter+=5*nHowManyThisSegment+1;break;default:vblXCounter+=4*nHowManyThisSegment;break;}}else{vblXCounter+=2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.countsupport._className,"GetDitchcountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDitchCountDouble "+Integer.toString(vbiDrawThis),exc));}else{throw exc;}} +return vblXCounter;},GetSquallQty:function(pLinePoints,quantity,length,numPoints){var counter=0;try{var j=0;var dist=0;var numCurves=0;for(j=0;jarmyc2.c2sd.JavaLineArray.countsupport.maxLength){dJaggyHalfAmp=armyc2.c2sd.JavaLineArray.countsupport.maxLength;} +if(dJaggyHalfAmp=vbPoints[2]){bFlip.value[0]=1;}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(x1,y1,x2,y2);nNumSegs=Math.floor((dDistance/20));if(nNumSegs%2===0){nNumSegs-=1;}dRemainder=nNumSegs*20-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){lTotalpts+=lNumSegs*12;}else{lTotalpts+=1;}} +lTotalpts+=1;vbPoints2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.flot._className,"GetAnchorageCountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetAnchorageCountDouble",exc));}else{throw exc;}} +return(lTotalpts);},GetFlotCount2Double:function(vbPoints,numPts,lineType){var lTotalpts=0;try{var j=0;var lNumSegs=0;var dDistance=0;var dIncrement=0;var nFactor=10;switch(lineType){case 31132000:case 31132100:dIncrement=40;break;case 31132200:dIncrement=60;nFactor=17;break;case 31132300:dIncrement=60;nFactor=20;break;default:dIncrement=20;break;} +for(j=0;j0){points=Clazz.newArray(lNumSegs*30,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,l,points,lineType,bFlip,lDirection,lLastDirection);for(j=0;j=vbPoints[2]){if(lineType!==31134000&&lineType!==31134100&&lineType!==31134200&&lineType!==31134300){bFlip.value[0]=1;}else{bFlip.value[0]=0;}}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(vbPoints[2*segment],vbPoints[2*segment+1],vbPoints[2*segment+2],vbPoints[2*segment+3]);nNumSegs=Math.floor((dDistance/dIncrement));dRemainder=nNumSegs*dIncrement-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){points=Clazz.newArray(lNumFlots*30,0);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}pFlotPoints[nFlotCounter].style=9;if(lineType===31133100){pFlotPoints[nFlotCounter].style=0;}}if((nFlotCounter+1)%10===0){if(lineType===31133000||lineType===31133100){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pFlotPoints[nFlotCounter-9]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pFlotPoints[nFlotCounter-9]);if(d2>d1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1-20);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2+20);}if(lineType===31133000){pFlotPoints[nFlotCounter].style=10;}if(lineType===31133100){pFlotPoints[nFlotCounter].style=5;}}if(lineType===31134000){pFlotPoints[nFlotCounter].style=23;}}k+=3;nFlotCounter++;} +points=null;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);for(k=0;kd1){tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-d1-dIncrement/2,0);}else{tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pLinePoints[j+1],-d2+dIncrement/2,0);}break;case 31134000:if(d2>d1){tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pLinePoints[j],-d1-dIncrement/8,0);}else{tempPoint=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pLinePoints[j+1],-d2+dIncrement/8,0);}break;default:break;} +spikeLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],tempPoint);if(spikeLength+dSpikeSized2){pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-1],dSpikeSize/2);}else{pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-1],-dSpikeSize/2);}if(bolTooLong===0){if(bolVertical!==0){if(pLinePoints[j].xpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}pSpikePoints[nSpikeCounter-1].style=9;if(bolTooLong===0){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-2]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2]);if(d1>d2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nSpikeCounter-2],dSpikeSize,0);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2],-dSpikeSize,0);}if(lineType===31133000){pSpikePoints[nSpikeCounter].style=10;}if(lineType===31133100){pSpikePoints[nSpikeCounter].style=5;}if(lineType===31134000){pSpikePoints[nSpikeCounter].style=24;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;} +if(nSpikeCounter===0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter].style=5;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+2].style=5;nSpikeCounter+=3;}} +for(j=0;j360){angle=angle-360;}if(0<=angle&&angle<=90){nQuadrant=0;angle=90-angle;angle=Math.abs(angle)*(0.017453292519943295);}if(90=vbPoints[2]){bFlip.value[0]=1;}if(segment===0&&vbPoints[0]=vbPoints[2*segment+3]){dAngle=90-dAngle;}else if(vbPoints[2*segment+0]<=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=dAngle+90;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]<=vbPoints[2*segment+3]){dAngle=270-dAngle;}else if(vbPoints[2*segment+0]>=vbPoints[2*segment+2]&&vbPoints[2*segment+1]>=vbPoints[2*segment+3]){dAngle=270+dAngle;}dDistance=armyc2.c2sd.JavaLineArray.lineutility.CalcDistance2(vbPoints[2*segment],vbPoints[2*segment+1],vbPoints[2*segment+2],vbPoints[2*segment+3]);nNumSegs=Math.floor((dDistance/20));dRemainder=nNumSegs*20-dDistance;dDistance=dDistance+dRemainder;if(vbPoints[2*segment]>=vbPoints[2*segment+2]){dAngle=dAngle+90;lDirection.value[0]=1;}else{dAngle=dAngle-90;lDirection.value[0]=0;}if(segment>0&&lDirection.value[0]!==lLastDirection.value[0]){if(bFlip.value[0]===1){bFlip.value[0]=0;}else{bFlip.value[0]=1;}}if(bFlip.value[0]===1){dAngle=dAngle+180;}for(m=0;m0){points=Clazz.newArray(lNumSegs*30,0);numSegPts=armyc2.c2sd.JavaLineArray.flot.GetFlotSegment(vbPoints,l,points,bFlip,lDirection,lLastDirection);for(j=0;j0){lTotalpts+=lNumSegs*10;}else{lTotalpts+=1;}} +lTotalpts+=1;vbPoints2=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.flot._className,"GetFlotCountDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetFlotCountDouble",exc));}else{throw exc;}} +return(lTotalpts);},GetOFYPointsDouble:function(pLinePoints,numPts,lineType){var nTotalCounter=0;try{var j=0;var k=0;var lNumSegs=0;var l=0;var lNumFlots=0;var lNumSpikes=0;var dDistance=0;var m=new armyc2.c2sd.JavaLineArray.ref();var lTotalPoints=0;var points=null;var pSpikePoints=null;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var tempPoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pFlotPoints=null;var pSegmentPoints=null;var dSpikeSize=20;var dIncrement=80;var vbPoints=null;var nFlotCounter=0;var nSpikeCounter=0;var nSegmentCounter=0;var flots=null;var segmentLength=0;var spikeLength=0;var bolTooLong=0;var d1=0;var d2=0;var bolVertical=0;var pFlotStart=null;var pFlotEnd=null;var pSpikeStart=null;var pSpikeEnd=null;var nSpikeEndCounter=0;var nFlotEndCounter=0;var bFlip=new armyc2.c2sd.JavaLineArray.ref();var lDirection=new armyc2.c2sd.JavaLineArray.ref();var lLastDirection=new armyc2.c2sd.JavaLineArray.ref();m.value=Clazz.newArray(1,0);bFlip.value=Clazz.newArray(1,0);lDirection.value=Clazz.newArray(1,0);lLastDirection.value=Clazz.newArray(1,0);lTotalPoints=armyc2.c2sd.JavaLineArray.flot.GetOFYCountDouble(pLinePoints,numPts,lineType);vbPoints=Clazz.newArray(numPts*2,0);pSpikePoints=new Array(lTotalPoints);pFlotPoints=new Array(lTotalPoints);pSegmentPoints=new Array(lTotalPoints);for(j=0;j0){points=Clazz.newArray(lNumFlots*30,0);pFlotStart=new Array(lNumFlots);pFlotEnd=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}pFlotPoints[nFlotCounter].style=9;}if((nFlotCounter+1)%10===0){if(lineType===31133200){pFlotEnd[Math.floor(l/10)]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotPoints[nFlotCounter]);nFlotEndCounter++;d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pFlotPoints[nFlotCounter-9]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pFlotPoints[nFlotCounter-9]);if(d2>d1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1-20);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2+20);}pFlotPoints[nFlotCounter].style=10;}}k+=3;nFlotCounter++;} +points=null;}else{pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegmentPoints[nSegmentCounter++].style=5;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);pSpikeStart=new Array(lNumSpikes);pSpikeEnd=new Array(lNumSpikes);for(k=0;kpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}pSpikePoints[nSpikeCounter-1].style=9;if(bolTooLong===0){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pSpikePoints[nSpikeCounter-2]);d2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2]);if(d1>d2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j],pSpikePoints[nSpikeCounter-2],dSpikeSize,0);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[j+1],pSpikePoints[nSpikeCounter-2],-dSpikeSize,0);}pSpikeEnd[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter]);nSpikeEndCounter++;if(lineType===31133200){pSpikePoints[nSpikeCounter].style=10;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;} +if(nSpikeEndCounter===0&&nFlotEndCounter===1){pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[0]);pSegmentPoints[nSegmentCounter++].style=5;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegmentPoints[nSegmentCounter++].style=0;pSegmentPoints[nSegmentCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[0]);pSegmentPoints[nSegmentCounter++].style=5;}for(l=0;l0){points=Clazz.newArray(lNumFlots*30,0);pFlotStart=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pFlotStart);pFlotEnd=new Array(lNumFlots);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pFlotEnd);armyc2.c2sd.JavaLineArray.flot.GetFlotSegment2(vbPoints,j,points,lineType,bFlip,lDirection,lLastDirection);for(l=0;ld1){pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j+1],pLinePoints[j],-d1);}else{pFlotPoints[nFlotCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pLinePoints[j],pLinePoints[j+1],-d2);}if(lineType===31134100){pFlotPoints[nFlotCounter].style=19;}else{pFlotPoints[nFlotCounter].style=9;}}if((nFlotCounter+1)%10===0){if(lineType===31134100){pFlotPoints[nFlotCounter].style=5;}else{pFlotPoints[nFlotCounter].style=23;}pFlotEnd[Math.floor(l/10)]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotPoints[nFlotCounter]);}if(l===0){pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegPoints[nSegCounter++].style=19;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[l]);pSegPoints[nSegCounter++].style=5;}if(l===lNumFlots*10-1){pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegPoints[nSegCounter++].style=19;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[Math.floor(l/10)]);pSegPoints[nSegCounter++].style=5;}k+=3;nFlotCounter++;} +points=null;}else{pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSegPoints[nSegCounter++].style=0;pSegPoints[nSegCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSegPoints[nSegCounter++].style=5;}segmentLength=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pLinePoints[j+1]);pSpikeStart=new Array(lNumSpikes);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSpikeStart);pSpikeEnd=new Array(lNumSpikes);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pSpikeEnd);for(k=0;kpLinePoints[j+1].y){pSpikePoints[nSpikeCounter].x=pt0.x-dSpikeSize;}else{pSpikePoints[nSpikeCounter].x=pt0.x+dSpikeSize;}pSpikePoints[nSpikeCounter].y=pt0.y;nSpikeCounter++;}}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);nSpikeCounter++;}if(lineType==31134100){pSpikePoints[nSpikeCounter-1].style=25;}else{pSpikePoints[nSpikeCounter-1].style=9;}if(bolTooLong==0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikePoints[nSpikeCounter-2],pLinePoints[j+1],dSpikeSize);if(lineType==31134100){pSpikePoints[nSpikeCounter].style=5;}else{pSpikePoints[nSpikeCounter].style=24;}pSpikeEnd[k]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter]);}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;}nSpikeCounter++;if(lineType==31134000||lineType==31134100){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotStart[k],pSpikeStart[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotStart[k],pLinePoints[j+1],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotEnd[k],pLinePoints[j],d1/2,5);if(k==lNumSpikes-2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotStart[k+1],pLinePoints[j+1],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pFlotEnd[k+1],pLinePoints[j],d1/2,5);}pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeStart[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2,5);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeEnd[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2,5);if(lineType==31134100){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k]);pSpikePoints[nSpikeCounter++].style=5;if(k==lNumSpikes-2){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotEnd[k+1]);pSpikePoints[nSpikeCounter++].style=19;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pFlotStart[k+1]);pSpikePoints[nSpikeCounter++].style=5;}pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeEnd[k]);pSpikePoints[nSpikeCounter++].style=25;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikeStart[k]);pSpikePoints[nSpikeCounter++].style=5;}}if(lineType==31134200){pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],dSpikeSize/2,22);pSpikePoints[nSpikeCounter++]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],dSpikeSize/2,20);}if(lineType==31134300){d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotStart[k],pSpikeStart[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/4);pSpikePoints[nSpikeCounter].style=25;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],d1/2);pSpikePoints[nSpikeCounter+2].style=19;pSpikePoints[nSpikeCounter+3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeStart[k],pLinePoints[j],3*d1/4);pSpikePoints[nSpikeCounter+3].style=5;pSpikePoints[nSpikeCounter+4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter],pLinePoints[j],pSpikePoints[nSpikeCounter],2,5,25);pSpikePoints[nSpikeCounter+5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter+3],pLinePoints[j],pSpikePoints[nSpikeCounter+3],3,5,5);nSpikeCounter+=6;d1=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pFlotEnd[k+1],pSpikeEnd[k]);pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/4);pSpikePoints[nSpikeCounter].style=25;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],d1/2);pSpikePoints[nSpikeCounter+2].style=19;pSpikePoints[nSpikeCounter+3]=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pSpikeEnd[k],pLinePoints[j+1],3*d1/4);pSpikePoints[nSpikeCounter+3].style=5;pSpikePoints[nSpikeCounter+4]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter],pLinePoints[j+1],pSpikePoints[nSpikeCounter],3,5,19);pSpikePoints[nSpikeCounter+5]=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pSpikePoints[nSpikeCounter+3],pLinePoints[j+1],pSpikePoints[nSpikeCounter+3],2,5,5);nSpikeCounter+=6;}} +if(nSpikeCounter==0){pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[j+1]);pSpikePoints[nSpikeCounter].style=5;nSpikeCounter++;}else{pSpikePoints[nSpikeCounter]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter].style=5;pSpikePoints[nSpikeCounter+1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+1].style=5;pSpikePoints[nSpikeCounter+2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pSpikePoints[nSpikeCounter-1]);pSpikePoints[nSpikeCounter+2].style=5;nSpikeCounter+=3;}} +for(j=0;j0;k--){d+=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[k],pLinePoints[k-1]);if(d>60){break;}} +if(d>60){middleSegment=k;}else{if(vblSaveCounter<=3){middleSegment=1;}else{middleSegment=2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetDirAtkAirMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetDirAtkAirMiddleSegment",exc));}else{throw exc;}} +return middleSegment;},CalcSegmentAngleDouble:function(pt0,pt1){var dAngle=0;try{var nTemp=0;var m=new armyc2.c2sd.JavaLineArray.ref();nTemp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(nTemp===0) +dAngle=1.5707963267948966;else{dAngle=Math.atan(m.value[0]);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcSegmentAngleDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcSegmentAngleDouble",exc));}else{throw exc;}} +return dAngle;},InitializePOINT2Array:function(pts){if(pts===null||pts.length===0) +return;for(var j=0;jdMaxX) +dMaxX=pLinePoints[j].x;if(pLinePoints[j].y>dMaxY) +dMaxY=pLinePoints[j].y;} +CenterLinePoint.x=(dMinX+dMaxX)/2;CenterLinePoint.y=(dMinY+dMaxY)/2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcCenterPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcCenterPointDouble",exc));}else{throw exc;}} +return CenterLinePoint;},CalcCenterPointDouble2:function(pLinePoints,vblCounter){var pt0=pLinePoints[0];var CenterLinePoint=new armyc2.c2sd.JavaLineArray.POINT2();try{var j=0;var dMinX=pt0.x;var dMinY=pt0.y;var dMaxX=pt0.x;var dMaxY=pt0.y;dMinX=pt0.x;dMinY=pt0.y;dMaxX=pt0.x;dMaxY=pt0.y;var pt;for(j=0;jdMaxX) +dMaxX=pt.x;if(pt.y>dMaxY) +dMaxY=pt.y;} +CenterLinePoint.x=(dMinX+dMaxX)/2;CenterLinePoint.y=(dMinY+dMaxY)/2;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcCenterPointDouble2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcCenterPointDouble2",exc));}else{throw exc;}} +return CenterLinePoint;},CalcDistanceDouble:function(p1,p2){var returnValue=0;try{returnValue=Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));var xdist=Math.abs(p1.x-p2.x);var ydist=Math.abs(p1.y-p2.y);var max=xdist;if(ydist>xdist) +max=ydist;if(returnValue===0||Double.isInfinite(returnValue)){if(max>0) +returnValue=max;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcDistanceDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcDistanceDouble",exc));}else{throw exc;}} +return returnValue;},CalcTrueSlopeDouble:function(firstLinePoint,lastLinePoint,slope){var result=1;try{if(slope.value===null) +slope.value=Clazz.newArray(1,0);var deltaX=0;var deltaY=0;deltaX=firstLinePoint.x-lastLinePoint.x;if(deltaX===0) +{deltaX=1;result=1;} +deltaY=firstLinePoint.y-lastLinePoint.y;slope.value[0]=deltaY/deltaX;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcTrueSlopeDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcTrueSlopeDouble",exc));}else{throw exc;}} +return result;},WriteFile:function(str){try{}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"WriteFile",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside WriteFile",exc));}else{throw exc;}}},ReversePointsDouble2:function(pLowerLinePoints,vblCounter){try{var pResultPoints=new Array(vblCounter);var k=0;for(k=0;k0){tempLinePoint.x=endLinePoint.x;tempLinePoint.y=endLinePoint.y+dOffset;}else{tempLinePoint.x=endLinePoint.x;tempLinePoint.y=endLinePoint.y-dOffset;} +return tempLinePoint;} +if(dy===0){if(dx>0){tempLinePoint.x=endLinePoint.x+dOffset;tempLinePoint.y=endLinePoint.y;}else{tempLinePoint.x=endLinePoint.x-dOffset;tempLinePoint.y=endLinePoint.y;} +return tempLinePoint;} +if(dy===0) +dAngle=0;else +dAngle=Math.atan(dx/dy)+1.5707963267948966;dHypotenuse=nOffset;if(endLinePoint.x>startLinePoint.x) +tempLinePoint.x=endLinePoint.x+dHypotenuse*Math.abs(Math.cos(dAngle));else +tempLinePoint.x=endLinePoint.x-dHypotenuse*Math.abs(Math.cos(dAngle));if(endLinePoint.y>startLinePoint.y) +tempLinePoint.y=endLinePoint.y+dHypotenuse*Math.abs(Math.sin(dAngle));else +tempLinePoint.y=endLinePoint.y-dHypotenuse*Math.abs(Math.sin(dAngle));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetOffsetPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetOffsetPointDouble",exc));}else{throw exc;}} +return(tempLinePoint);},GetArcFEBADouble:function(dRadius,pLinePoints,vblCounter,pResultLinePoints){try{var dStartAngle=0;var dEndAngle=6.283185307179586;var dIncrement=(dEndAngle-dStartAngle)/25.0;var i=0;var j=0;var nArcCounter=0;var x=0;var y=0;var CenterLinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pArcLinePoints=new Array(26);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(pArcLinePoints);for(i=0;i10) +iterations+=1;for(k=0;k1){if(pt2.x0) +{pt3.x=(dOriginalDistance+dist)/dOriginalDistance*(pt2.x-pt1.x)+pt1.x;pt3.y=(dOriginalDistance+dist)/dOriginalDistance*(pt2.y-pt1.y)+pt1.y;pt3.style=styl;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"ExtendLine2Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendLine2Double",exc));}else{throw exc;}} +return pt3;},ExtendAngledLine:function(pt0,pt1,pt2,alpha,d){var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var psi=Math.atan((pt1.y-pt0.y)/(pt1.x-pt0.x));var alpha1=3.141592653589793*alpha/180;var theta=psi+alpha1;var dx=d*Math.cos(theta);var dy=d*Math.sin(theta);pt.x=pt2.x+dx;pt.y=pt2.y+dy;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"ExtendAngledLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendAngledLine",exc));}else{throw exc;}} +return pt;},GetQuadrantDouble:function(){var nQuadrant=-1;try{if(arguments.length===2) +{var pt1=arguments[0];var pt2=arguments[1];if(pt2.x>=pt1.x&&pt2.y<=pt1.y) +nQuadrant=1;if(pt2.x>=pt1.x&&pt2.y>=pt1.y) +nQuadrant=2;if(pt2.x<=pt1.x&&pt2.y>=pt1.y) +nQuadrant=3;if(pt2.x<=pt1.x&&pt2.y<=pt1.y) +nQuadrant=4;} +else if(arguments.length===4) +{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];if(x2>=x1&&y2<=y1) +nQuadrant=1;if(x2>=x1&&y2>=y1) +nQuadrant=2;if(x2<=x1&&y2>=y1) +nQuadrant=3;if(x2<=x1&&y2<=y1) +nQuadrant=4;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetQuadrantDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetQuadrantDouble",exc));}else{throw exc;}} +return nQuadrant;},GetPixelsMin:function(ptsSeize,vblCounter,x,y){try{var xmin=Infinity;var ymin=Infinity;var j=0;for(j=0;j0) +dAngle=3.141592653589793;else +dAngle=0;}else +dAngle=Math.atan(dx/dy)+1.5707963267948966;tempLinePoint.style=0;if(dx<=0.0&&dy<=0.0) +dSign=-1.0;if(dx>=0.0&&dy<=0.0) +dSign=-1.0;if(dx<=0.0&&dy>=0.0) +dSign=1.0;if(dx>=0.0&&dy>=0.0) +dSign=1.0;dHypotenuse=dSign*nBiSector;AHBX=endLinePoint.x+dHypotenuse*Math.cos(dAngle);AHBY=endLinePoint.y-dHypotenuse*Math.sin(dAngle);dHypotenuse=dSign*(nBase/2.0);AHBLX=AHBX-dHypotenuse*Math.sin(dAngle);AHBLY=AHBY-dHypotenuse*Math.cos(dAngle);AHBRX=AHBX+dHypotenuse*Math.sin(dAngle);AHBRY=AHBY+dHypotenuse*Math.cos(dAngle);tempLinePoint.x=Math.floor(AHBLX);tempLinePoint.y=Math.floor(AHBLY);pResultLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tempLinePoint);pResultLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(endLinePoint);tempLinePoint.x=Math.floor(AHBRX);tempLinePoint.y=Math.floor(AHBRY);pResultLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tempLinePoint);switch(styl){case 0:for(j=0;j<2;j++) +pResultLinePoints[j].style=0;pResultLinePoints[2].style=5;break;case 9:for(j=0;j<2;j++) +pResultLinePoints[j].style=9;pResultLinePoints[2].style=10;break;case 18:for(j=0;j<2;j++) +pResultLinePoints[j].style=18;pResultLinePoints[2].style=5;break;default:for(j=0;j<2;j++) +pResultLinePoints[j].style=styl;pResultLinePoints[2].style=5;break;} +return;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetArrowhead4Double",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetArrowhead4Double",exc));}else{throw exc;}}},MidPointDouble:function(pt0,pt1,styl){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);try{ptResult.x=(pt0.x+pt1.x)/2;ptResult.y=(pt0.y+pt1.y)/2;ptResult.style=styl;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MidPointDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MidPointDouble",exc));}else{throw exc;}} +return ptResult;},RotateGeometryDoubleOrigin:function(pLinePoints,vblCounter,lAngle){try{var j=0;var dRotate=0;var dTheta=0;var dGamma=0;var x=0;var y=0;if(lAngle!==0){var pdCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();dRotate=lAngle*3.141592653589793/180;pdCenter=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);for(j=0;j=pdCenter.x){dGamma=dGamma+3.141592653589793;} +dTheta=dRotate+dGamma;y=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.sin(dTheta);x=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.cos(dTheta);pLinePoints[j].y=pdCenter.y+y;pLinePoints[j].x=pdCenter.x+x;} +return pLinePoints;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"RotateGeometryDoubleOrigin",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RotateGeometryDoubleOrigin",exc));}else{throw exc;}} +return pLinePoints;},ExtendTrueLinePerpDouble:function(pt0,pt1,pt2,d,styl){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);try{var ptYIntercept=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);var m=new armyc2.c2sd.JavaLineArray.ref();var b=0;var b1=0;var nTemp=0;var offsetX=new armyc2.c2sd.JavaLineArray.ref();var offsetY=new armyc2.c2sd.JavaLineArray.ref();var pts=new Array(3);pts[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pts[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pts[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);armyc2.c2sd.JavaLineArray.lineutility.GetPixelsMin(pts,3,offsetX,offsetY);if(offsetX.value[0]<=0) +offsetX.value[0]=offsetX.value[0]-100;else +offsetX.value[0]=0;nTemp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);switch(nTemp){case 0:if(pt0.y0){dy=-m1*dWidth/Math.sqrt(1+m1*m1);dx=-dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;} +break;case 3:if(m1<=0){dy=-m1*dWidth/Math.sqrt(1+m1*m1);dx=dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;}else{dy=m1*dWidth/Math.sqrt(1+m1*m1);dx=-dy/m1;X.value[0]=p2.x+dx;Y.value[0]=p2.y+dy;} +break;default:X.value[0]=p2.x;Y.value[0]=p2.y;break;} +return 1;} +X.value[0]=(b2-b1)/(m1-m2);Y.value[0]=(m1*(X.value[0])+b1);return 1;}catch(exc){if(Clazz.instanceOf(exc)){X.value[0]=p2.x;Y.value[0]=p2.y;armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcTrueIntersectDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtendTrueIntersectDouble",exc));}else{throw exc;}} +return 1;},CalcDistance2:function(x1,y1,x2,y2){var dResult=0;try{dResult=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));var xdist=Math.abs(x1-x2);var ydist=Math.abs(y1-y2);var max=xdist;if(ydist>xdist) +max=ydist;if(dResult===0||Double.isInfinite(dResult)){if(max>0) +dResult=max;}} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"CalcDistance2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside CalcDistance2",exc));}else{throw exc;}} +return dResult;},GetSAAFRMiddleLine:function(pLinePoints) +{var pts=null;try +{var j=0,count=0;for(j=0;j0){count++;}} +pts=[];count=0;var dMRR=0;var firstSegPt=null,lastSegPt=null,pt0=null,pt1=null;for(j=0;j=0||j===pLinePoints.length-1) +{if(lastSegPt!==null) +{firstSegPt=new armyc2.c2sd.JavaLineArray.POINT2(lastSegPt);lastSegPt=new armyc2.c2sd.JavaLineArray.POINT2(pLinePoints[j]);dMRR=firstSegPt.style;pt0=this.ExtendLine2Double(lastSegPt,firstSegPt,-dMRR,0);pt1=this.ExtendLine2Double(firstSegPt,lastSegPt,-dMRR,5);pts.push(pt0);pts.push(pt1);} +else +{lastSegPt=new armyc2.c2sd.JavaLineArray.POINT2(pLinePoints[j]);}}}} +catch(exc) +{if(Clazz.instanceOf(exc)) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetSAAFRMiddleLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSAAFRMiddleLine",exc));}else{throw exc;}} +return pts;},GetSAAFRSegment:function(pLinePoints,lineType,dMRR,rev){try{var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt4=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt5=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var m=new armyc2.c2sd.JavaLineArray.ref();var bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pLinePoints[0],pLinePoints[1],m);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[0],pLinePoints[1],-dMRR,5);pt0=armyc2.c2sd.JavaLineArray.lineutility.ExtendLine2Double(pLinePoints[1],pLinePoints[0],-dMRR,0);if(bolVertical!==0&&m.value[0]<1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],2,dMRR);pt2.style=0;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],2,dMRR);pt3.style=5;pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],3,dMRR);pt4.style=0;pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],3,dMRR);pt5.style=5;}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],0,dMRR);pt2.style=0;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],0,dMRR);pt3.style=5;pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],1,dMRR);pt4.style=0;pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],1,dMRR);pt5.style=5;} +pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[4]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);pLinePoints[5]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[5].style=5;pLinePoints[0].style=5;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetSAAFRSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSAAFRSegment",exc));}else{throw exc;}} +return;},GetSAAFRFillSegment:function(pLinePoints,dMRR){try{var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt3=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt4=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt5=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var m=new armyc2.c2sd.JavaLineArray.ref();var bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pLinePoints[0],pLinePoints[1],m);if(bolVertical!==0&&m.value[0]<1){pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],2,dMRR);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],2,dMRR);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],3,dMRR);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],3,dMRR);}else{pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],0,dMRR);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],0,dMRR);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[0],1,dMRR);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pLinePoints[0],pLinePoints[1],pLinePoints[1],1,dMRR);} +pLinePoints[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2);pLinePoints[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt3);pLinePoints[2]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt5);pLinePoints[3]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt4);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"GetSAAFRFillSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSAAFRFillSegment",exc));}else{throw exc;}} +return;},ArcArrayDouble:function(pResultLinePoints,vblCounter,dRadius,linetype,converter){try{var startangle=0;var endangle=0;var increment=0;var length=0;var M=0;var j;var numarcpts=0;var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var C=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[0]);var a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[1]);var e=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pResultLinePoints[0]);var pArcLinePoints=null;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(a,e,m);if(bolVertical!==0) +M=Math.atan(m.value[0]);else{if(a.y=minX&&pt.y<=maxY&&pt.y>=minY) +return 1;else +return 0;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"PointInBounds2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointInBounds2",exc));}else{throw exc;}} +return 1;},intersectSegment:function(pt0,pt1,sidePt0,sidePt1){var pt=null;try{if(pt0.x===pt1.x){return null;} +var m=(pt1.y-pt0.y)/(pt1.x-pt0.x);var dx=0;var dy=0;var x=0;var y=0;var upper=null;var lower=null;var left=null;var right=null;var bolVertical=new Boolean(false);if(sidePt0.x===sidePt1.x){bolVertical=new Boolean(true);if(sidePt0.y=pt.x&&pt.x>=pt1.x){if(upper.y<=pt.y&&pt.y<=lower.y){return pt;}}}else{dy=left.y-pt0.y;dx=dy/m;x=pt0.x+dx;y=left.y;pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);if(pt0.y<=pt.y&&pt.y<=pt1.y){if(left.x<=pt.x&&pt.x<=right.x){return pt;}}else if(pt0.y>=pt.y&&pt.y>=pt1.y){if(left.x<=pt.x&&pt.x<=right.x){return pt;}}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"intersectSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside intersectSegment",exc));}else{throw exc;}} +return null;},BoundOneSegment:function(pt0,pt1,ul,lr){var line=new Array(2);try{if(pt0.ylr.y&&pt1.y>lr.y){return null;} +if(pt0.xlr.x&&pt1.x>lr.x){return null;} +var bolVertical=new Boolean(false);armyc2.c2sd.JavaLineArray.lineutility.InitializePOINT2Array(line);if(pt0.x===pt1.x){bolVertical=new Boolean(true);} +if(bolVertical.valueOf()){line[0]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);if(line[0].ylr.y){line[0].y=lr.y;} +line[1]=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);if(line[1].ylr.y){line[1].y=lr.y;} +return line;} +var dx=0;var dy=0;var x=0;var y=0;var m=(pt1.y-pt0.y)/(pt1.x-pt0.x);var side0Intersect=new Boolean(false);var side1Intersect=new Boolean(false);var side2Intersect=new Boolean(false);var side3Intersect=new Boolean(false);var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(lr.x,ul.y);var ll=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ul.x,lr.y);var pt0Intersect=null;if(armyc2.c2sd.JavaLineArray.lineutility.PointInBounds2(pt0,ul,lr)===1){pt0Intersect=pt0;} +if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ll,ul);side0Intersect=new Boolean(true);} +if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ul,ur);side1Intersect=new Boolean(true);} +if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ur,lr);side2Intersect=new Boolean(true);} +if(pt0Intersect===null){pt0Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt0,pt1,ll,lr);side3Intersect=new Boolean(true);} +var pt1Intersect=null;if(armyc2.c2sd.JavaLineArray.lineutility.PointInBounds2(pt1,ul,lr)===1){pt1Intersect=pt1;} +if(pt1Intersect===null&&side0Intersect.valueOf()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ll,ul);} +if(pt1Intersect===null&&side1Intersect.valueOf()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ul,ur);} +if(pt1Intersect===null&&side2Intersect.valueOf()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ur,lr);} +if(pt1Intersect===null&&side3Intersect.valueOf()===false){pt1Intersect=armyc2.c2sd.JavaLineArray.lineutility.intersectSegment(pt1,pt0,ll,lr);} +if(pt0Intersect!==null&&pt1Intersect!==null){line[0]=pt0Intersect;line[1]=pt1Intersect;}else{line=null;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"BoundOneSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BoundOneSegment",exc));}else{throw exc;}} +return line;},GetDitchSpikeDouble:function(pLinePoints,nOldCounter,bWayIs,linetype){var nSpikeCounter=0;try{var nNumberOfSegments=0;var lCircleCounter=0;var bolVertical=0;var nTemp=0;var i;var j;var dPrinter=1.0;var dIntLocation1x=0;var dIntLocation2x=0;var dIntLocation1y=0;var dIntLocation2y=0;var r=0;var s=0;var use=0;var length=0;var k=0;var bint=0;var pdAnswer=new armyc2.c2sd.JavaLineArray.ref();var m=new armyc2.c2sd.JavaLineArray.ref();var UpperLinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var Lower1LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var Lower2LinePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var b=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[0]);var pCirclePoints=new Array(pLinePoints.length);var averagePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var lastAveragePoint=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pTempLinePoints=null;var minLength=24;pTempLinePoints=new Array(nOldCounter);for(j=0;jminLength*dPrinter){if(bWayIs!==0){if(pLinePoints[i].x<=pLinePoints[i+1].x){use=r;} +if(pLinePoints[i].x>=pLinePoints[i+1].x){use=s;}}else{if(pLinePoints[i].x<=pLinePoints[i+1].x){use=s;} +if(pLinePoints[i].x>=pLinePoints[i+1].x){use=r;}} +for(j=1;j<=nNumberOfSegments;j++){k=j;a=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[i]);b=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints[i+1]);if(j>1){dIntLocation1x=dIntLocation2x;}else{dIntLocation1x=pLinePoints[i].x+((k*12.0-12)*dPrinter/length)*(pLinePoints[i+1].x-pLinePoints[i].x);} +if(j>1){dIntLocation1y=dIntLocation2y;}else{dIntLocation1y=pLinePoints[i].y+((k*12.0-6.0)*dPrinter/length)*(pLinePoints[i+1].y-pLinePoints[i].y);} +dIntLocation2x=pLinePoints[i].x+((k*12.0+6.0)*dPrinter/length)*(pLinePoints[i+1].x-pLinePoints[i].x);dIntLocation2y=pLinePoints[i].y+((k*12.0+6.0)*dPrinter/length)*(pLinePoints[i+1].y-pLinePoints[i].y);if(m.value[0]!==0&&bolVertical!==0){bint=(dIntLocation1y+dIntLocation2y)/2.0+(1/m.value[0])*(dIntLocation1x+dIntLocation2x)/2.0;UpperLinePoint=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(m.value[0],use,-1/m.value[0],bint,1,1,pLinePoints[0].x,pLinePoints[0].y);} +if(bolVertical===0){if(dIntLocation1y1&&j1){if(j%2===0){pCirclePoints[lCircleCounter]=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(averagePoint,lastAveragePoint,20);lCircleCounter++;}} +if(j1){if(pLinePoints[1].y===pLinePoints[0].y) +pLinePoints[1].y++;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MoveSingleCPixels",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MoveSingleCPixels",exc));}else{throw exc;}}},RotateGeometryDouble:function(pLinePoints,vblCounter,lAngle,converter,ptCenter){try{var j=0;var dRotate=0;var dTheta=0;var dGamma=0;var x=0;var y=0;var temp2d=null,d=0,theta=0;var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();if(lAngle!==0){var pdCenter;dRotate=lAngle*3.141592653589793/180;pdCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble(pLinePoints,vblCounter);if(converter) +{pdCenter=new armyc2.c2sd.graphics2d.Point2D(pdCenter.x,pdCenter.y);pdCenter=converter.PixelsToGeo(pdCenter);if(ptCenter) +pdCenter=ptCenter;} +for(j=0;jpdCenter.y)) +dGamma=4.71238898038469;else +dGamma=1.5707963267948966;}else +dGamma=3.141592653589793+Math.atan((pLinePoints[j].y-pdCenter.y)/(pLinePoints[j].x-pdCenter.x));if(pLinePoints[j].x>=pdCenter.x) +dGamma=dGamma+3.141592653589793;dTheta=dRotate+dGamma;y=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.sin(dTheta);x=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints[j],pdCenter)*Math.cos(dTheta);pLinePoints[j].y=pdCenter.y+y;pLinePoints[j].x=pdCenter.x+x;}} +return;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"RotateGeometryDouble",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RotateGeometryDouble",exc));}else{throw exc;}} +return;},adjustCATKBYFIREControlPoint:function(linetype,pLinePoints,dist){try{if(linetype!==21710000) +return;var dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pLinePoints.get(0),pLinePoints.get(1));if(dist2<=dist) +return;var pt=null;var count=pLinePoints.size();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(0));var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(1));var controlPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pLinePoints.get(count-1));var pt4=armyc2.c2sd.JavaLineArray.lineutility.PointRelativeToLine(pt0,pt1,pt1,controlPt);pt=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt4,controlPt,dist);pLinePoints.set(count-1,pt);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"adjustCATKBYFIREControlPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside adjustCATKBYFIREControlPoint",exc));}else{throw exc;}} +return;},PointRelativeToLine:function(){var ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var pt0=arguments[0];var pt1=arguments[1];var atPoint=null;var ptRelative=null;if(arguments.length===3) +{ptRelative=arguments[2];var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var midPt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);var b1=0;var b2=0;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){ptResult.x=ptRelative.x;ptResult.y=midPt.y;} +if(bolVertical!==0&&m.value[0]===0){ptResult.x=midPt.x;ptResult.y=ptRelative.y;} +if(bolVertical!==0&&m.value[0]!==0){b1=midPt.y+(1/m.value[0])*midPt.x;b2=ptRelative.y-m.value[0]*ptRelative.x;ptResult=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);}} +else if(arguments.length===4) +{atPoint=arguments[2];ptRelative=arguments[3];bolVertical=0;m=new armyc2.c2sd.JavaLineArray.ref();b1=0;b2=0;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){ptResult.x=ptRelative.x;ptResult.y=atPoint.y;} +if(bolVertical!==0&&m.value[0]===0){ptResult.x=atPoint.x;ptResult.y=ptRelative.y;} +if(bolVertical!==0&&m.value[0]!==0){b1=atPoint.y+(1/m.value[0])*atPoint.x;b2=ptRelative.y-m.value[0]*ptRelative.x;ptResult=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);}}} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"PointRelativeToLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointRelativeToLine",exc));}else{throw exc;}} +return ptResult;},LineRelativeToLine:function(pt0,pt1,ptRelative,pt2,pt3){try{var bolVertical=0;var m=new armyc2.c2sd.JavaLineArray.ref();var b1=0;var b2=0;var pt2Temp=null;var pt3Temp=null;bolVertical=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueSlopeDouble(pt0,pt1,m);if(bolVertical===0){pt2.x=ptRelative.x;pt2.y=pt0.y;pt3.x=ptRelative.x;pt3.y=pt1.y;} +if(bolVertical!==0&&m.value[0]===0){pt2.x=pt0.x;pt2.y=ptRelative.y;pt3.x=pt1.x;pt3.y=ptRelative.y;} +if(bolVertical!==0&&m.value[0]!==0){b1=pt0.y+(1/m.value[0])*pt0.x;b2=ptRelative.y-m.value[0]*ptRelative.x;pt2Temp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);b1=pt1.y+(1/m.value[0])*pt1.x;pt3Temp=armyc2.c2sd.JavaLineArray.lineutility.CalcTrueIntersectDouble2(-1/m.value[0],b1,m.value[0],b2,1,1,0,0);pt2.x=pt2Temp.x;pt2.y=pt2Temp.y;pt3.x=pt3Temp.x;pt3.y=pt3Temp.y;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"LineRelativeToLine",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LineRelativeToLine",exc));}else{throw exc;}} +return;},CalcMBR:function(pLinePoints,numpts,ulx,uly,lrx,lry){try{var j=0;ulx.value=Clazz.newArray(1,0);uly.value=Clazz.newArray(1,0);lrx.value=Clazz.newArray(1,0);lry.value=Clazz.newArray(1,0);ulx.value[0]=1.7976931348623157E308;uly.value[0]=1.7976931348623157E308;lrx.value[0]=-1.7976931348623157E308;lry.value[0]=-1.7976931348623157E308;for(j=0;jlrx.value[0]) +lrx.value[0]=pLinePoints[j].x;if(pLinePoints[j].y>lry.value[0]) +lry.value[0]=pLinePoints[j].y;if(pLinePoints[j].xlr.x) +lr.x=pLinePoints[j].x;if(pLinePoints[j].y>lr.y) +lr.y=pLinePoints[j].y;if(pLinePoints[j].xxdist) +max=ydist;if(result===0||Double.isInfinite(result)){if(max>0) +result=max;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"MBRDistance",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside MBRDistance",exc));}else{throw exc;}} +return result;},Reverse2Points:function(pt1,pt2){try{var tempPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();tempPt.x=pt1.x;tempPt.y=pt1.y;pt1.x=pt2.x;pt1.y=pt2.y;pt2.x=tempPt.x;pt2.y=tempPt.y;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"Reverse2Points",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside Reverse2Points",exc));}else{throw exc;}} +return;},createStrokedShape:function(shape){var newshape=new armyc2.c2sd.graphics2d.GeneralPath();try{var coords=Clazz.newArray(6,0);for(var i=shape.getPathIterator(null);!i.isDone();i.next()){var type=i.currentSegment(coords);switch(type){case 0:newshape.moveTo(coords[0],coords[1]);break;case 1:newshape.lineTo(coords[0],coords[1]);break;case 2:newshape.quadTo(coords[0],coords[1],coords[2],coords[3]);break;case 3:newshape.curveTo(coords[0],coords[1],coords[2],coords[3],coords[4],coords[5]);break;case 4:newshape.closePath();break;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaLineArray.lineutility._className,"createStrokedShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createStrokedShape",exc));}else{throw exc;}} +return newshape;},setPOINT2:function(x,y,param1,param2){return new armyc2.c2sd.JavaLineArray.POINT2(x,y,param1,param2);},getExteriorPoints:function(pLinePoints,vblCounter,lineType,interior){var j;var index;var pt0;var pt1;var pt2;var m01=new armyc2.c2sd.JavaLineArray.ref();var m12=new armyc2.c2sd.JavaLineArray.ref();var direction;var intersectPt;var intersectPoints=new java.util.ArrayList();var b01;var b12;var dist=pLinePoints[0].style;for(j=0;j0){dist=pt1.style;} +var pt00;var pt01;var pt10;var pt11;index=j-1;if(index<0){index=vblCounter-1;} +var pts=new Array(pLinePoints.length);for(var k=0;k0.1) +result=false;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"DoublesBack",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCenterLabel",exc));}else{throw exc;}} +return result;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetCenterLabel=function(tg){var label="";try{switch(tg.get_LineType()){case 22223000:label="SAAFR";break;case 22221000:label="AC";break;case 212100000:case 212300000:case 212300001:label="S";break;case 211900000:label="R";break;case 211700000:label="P";break;case 211600000:label="O";break;case 211400000:label="I";break;case 211100000:label="F";break;case 211000000:label="D";break;case 21400000:case 21500000:label="C";break;case 21200000:case 21300000:label="B";break;case 212600000:label="C/K";break;case 212500000:label="C/S";break;case 23180000:label="UXO";break;case 212000000:label="R";break;case 22623000:case 22623001:label="BL ";break;case 22612000:case 22612001:label="HL ";break;case 22124000:label="PL ";break;case 22125000:label="LL";break;case 212210000:case 212210001:label="S";break;case 212230000:case 212230001:label="C";break;case 212220000:case 212220001:label="G";break;case 211800000:label="RIP";break;case 212400000:label="W";break;case 212410000:label="WP";break;case 21700000:case 21710000:label="CATK";break;case 22122000:label="FLOT";break;case 22132000:label="AA";break;case 22133000:label="EA";break;case 22135000:label="DZ";break;case 22136000:label="EZ";break;case 22137000:label="LZ";break;case 22138000:label="PZ";break;case 22222000:case 22222001:label="MRR";break;case 22224000:if(tg.getSymbologyStandard()===1) +label="UA";else +label="UAV";break;case 22224001:label="UAV";break;case 22225000:label="LLTR";break;case 22231000:label="ROZ";break;case 22232000:if(tg.getSymbologyStandard()===1) +label="SHORADEZ";else +label="FAADEZ";break;case 22233000:label="HIDACZ";break;case 22234000:label="MEZ";break;case 22234100:label="LOMEZ";break;case 22234200:label="HIMEZ";break;case 22235000:label="WFZ";break;case 22340000:label="M";break;case 23164000:case 22350000:label="M";break;case 22421000:label="FEBA";break;case 22422000:label="(PDF)";break;case 22431100:label="(P)";break;case 22432000:label="EA ";break;case 22535000:label="OBJ ";if(tg.get_Client().equalsIgnoreCase("ge")) +label="OBJ ";break;case 22625000:label="NAI";break;case 22626000:label="TAI";break;case 24211000:label="SMOKE";break;case 24260000:label="FPF";break;case 22532000:label="ATK";break;case 22523000:label="FINAL CL";break;case 22525000:label="LOA";break;case 22526000:label="LD";break;case 22528000:label="PLD";break;case 21800000:label="D";break;case 22613000:label="RL";break;case 24314000:label="SMOKE";break;case 24223000:label="NFL";break;case 24225000:label="MFP";break;case 24221000:label=" FSCL";break;case 24222000:label="CFL ";break;case 24224000:label="RFL ";break;case 22621000:label="AO ";break;case 24315000:label="BOMB";break;case 24226000:label="TGMF";break;case 24321100:label="FSA ";break;case 24321300:case 24321200:label="FSA";break;case 24322100:case 24322300:case 24322200:label="ACA";break;case 24323100:case 24323300:case 24323200:label="FFA";break;case 24324100:case 24324300:case 24324200:label="NFA";break;case 24325100:case 24325300:case 24325200:label="RFA";break;case 24331100:case 24331300:case 24331200:label="ATI ZONE";break;case 243100000:case 24326200:case 24326100:case 24326101:label="PAA";break;case 24332100:case 24332300:case 24332200:label="CFF ZONE";break;case 24336100:case 24336300:case 24336200:label="CF ZONE";break;case 24333100:case 24333300:case 24333200:label="SENSOR ZONE";break;case 24334100:case 24334300:case 24334200:label="CENSOR ZONE";break;case 24335100:case 24335300:case 24335200:label="DA";break;case 24337100:case 24337300:case 24337200:label="ZOR";break;case 24338100:case 24338300:case 24338200:label="TBA";break;case 24339100:case 24339300:case 24339200:label="TVAR";break;case 24351000:case 24353000:case 24352000:label="BKB";break;case 24361000:case 24363000:case 24362000:label="PKB";break;case 25221000:label="MSR ";break;case 25222000:label="ASR ";break;case 25224000:case 25223000:case 25225000:label="MSR ";break;case 22527000:label="LD/LC";break;case 22622000:label="AIRHEAD LINE";break;case 21100000:case 26400000:label="B";break;case 26410000:label="E";break;case 26420000:label="A";break;case 26430000:label="T";break;case 26440000:label="O";break;case 25330000:label="FARP";break;case 25351000:label="BSA";break;case 25352000:label="DSA";break;case 25353000:label="RSA";break;case 21600000:label="ENY";break;case 23114000:label="FREE";break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"GetCenterLabel",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCenterLabel",exc));}else{throw exc;}} +return label;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddOffsetModifier=function(tg,text,type,lineFactor,startIndex,endIndex,spaces,rightOrLeft){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(text===null||text.equals("")){return;} +if(tg.Pixels===null||tg.Pixels.size()<2){return;} +modifier.text=text;modifier.set_IsIntegral(false);modifier.type=type;modifier.lineFactor=lineFactor;if(tg.Pixels.size()>endIndex){modifier.textPath[0]=tg.Pixels.get(startIndex);modifier.textPath[1]=tg.Pixels.get(endIndex);if(rightOrLeft!==null){if(rightOrLeft.equals("left")){modifier.textPath[0].x-=spaces;modifier.textPath[1].x-=spaces;}else{modifier.textPath[0].x+=spaces;modifier.textPath[1].x+=spaces;}} +tg.modifiers.add(modifier);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddOffsetModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddOffsetModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier=function(tg,text,type,lineFactor,ptStart,ptEnd){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(text===null||text.equals("")){return;} +if(tg.Pixels===null||tg.Pixels.size()<2){return;} +modifier.text=text;modifier.set_IsIntegral(false);modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=ptStart;modifier.textPath[1]=ptEnd;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2=function(tg,text,type,lineFactor,pt0,pt1,isIntegral,modifierType){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(text===null||text.equals("")){return;} +modifier.text=text;if(isIntegral!==undefined) +modifier.set_IsIntegral(isIntegral);modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;modifier.isIntegral=isIntegral;modifier.textID=modifierType;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier=function(tg,text,type,lineFactor,startIndex,endIndex,isIntegral){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(isIntegral!==undefined) +modifier.set_IsIntegral((isIntegral).valueOf());if(text===null||text.equals("")){return;} +if(tg.Pixels===null||tg.Pixels.isEmpty()){return;} +modifier.text=text;modifier.type=type;modifier.lineFactor=lineFactor;if(tg.Pixels.size()>endIndex){modifier.textPath[0]=tg.Pixels.get(startIndex);modifier.textPath[1]=tg.Pixels.get(endIndex);tg.modifiers.add(modifier);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddIntegralModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier=function(tg,text,type,lineFactor,pt0,pt1,modifierType){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();modifier.text=text;modifier.set_IsIntegral(true);if(pt0===null||pt1===null){return;} +modifier.type=type;if(arguments.length>6) +modifier.textID=modifierType;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddAreaModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddAreaModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier=function(tg,text,type,lineFactor,pt0,pt1,isIntegral,modifierType){try{if(text===null||text.equals("")){return;} +var modifier=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();modifier.set_IsIntegral((isIntegral).valueOf());modifier.text=text;if(text===null||text.equals("")){return;} +if(pt0===null||pt1===null){return;} +modifier.type=type;modifier.lineFactor=lineFactor;modifier.textPath[0]=pt0;modifier.textPath[1]=pt1;modifier.textID=modifierType;tg.modifiers.add(modifier);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddAreaModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddAreaModifier",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR=function(tg,ptUl,ptUr,ptLr,ptLl){try{var j=0;var x=0;var y=0;ptUl.x=tg.Pixels.get(0).x;ptUl.y=tg.Pixels.get(0).y;ptUr.x=tg.Pixels.get(0).x;ptUr.y=tg.Pixels.get(0).y;ptLl.x=tg.Pixels.get(0).x;ptLl.y=tg.Pixels.get(0).y;ptLr.x=tg.Pixels.get(0).x;ptLr.y=tg.Pixels.get(0).y;for(j=1;jptLr.x){ptLr.x=x;ptUr.x=x;} +if(y>ptLl.y){ptLl.y=y;ptLr.y=y;} +if(y1.5*labelLength&&last.equalsIgnoreCase(eny)){last=label;sumLabel++;}else if(dist>1.5*enyLength&&last.equalsIgnoreCase(label)){sumENY++;last=eny;}} +if(eny.isEmpty()){if(sumENY<2){sumENY=2;}} +if(sumLabel+sumENY<4){return false;} +var aboveMiddle=2;for(j=0;j1.5*labelLength&&last.equalsIgnoreCase(eny)){if(!label.isEmpty()) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,0,pt0,pt1,new Boolean(true));last=label;}else if(dist>1.5*enyLength&&last.equalsIgnoreCase(label)){if(!eny.isEmpty()) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,eny,aboveMiddle,0,pt0,pt1,new Boolean(true));last=eny;}} +return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"areasWithTwoLabels",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside areasWithTwoLabels",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY=function(tg,g2d){try{var metrics=g2d.getFontMetrics();var label=null;var middleSegment=Math.floor(tg.Pixels.size()/2)-1;var middleSegment2=tg.Pixels.size()-2;var startIndex=0;var j=0;var linetype=tg.get_LineType();var affiliation=tg.get_Affiliation();var echelonSymbol=tg.get_EchelonSymbol();if(affiliation!==null&&affiliation.equals("H")) +label=tg.get_N();if(tg.Pixels.size()>3) +middleSegment=Math.floor(tg.Pixels.size()/4);if(tg.Pixels.size()>3) +middleSegment2=Math.floor(3*tg.Pixels.size()/4);switch(linetype){case 22340000:case 22350000:case 23164000:label="M";break;case 23180000:label="UXO";break;case 22431000:case 22431100:if(echelonSymbol!==null&&!echelonSymbol.isEmpty()) +startIndex=1;break;default:break;} +if(label===null||label.isEmpty()) +return;var stringWidth=metrics.stringWidth(label);var foundLongSegment=false;var dist=0;var pt0=null;var pt1=null;var northestPtIndex=null;var southestPtIndex=null;var northestPt=null;var southestPt=null;if(armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTwoLabelOnly()===false){for(j=startIndex;j1.5*stringWidth){foundLongSegment=true;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,0,pt0,pt1,new Boolean(true));}} +if(foundLongSegment===false){if(middleSegment!==startIndex) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment,middleSegment+1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment2,middleSegment2+1,new Boolean(true));}}else{for(j=startIndex;j=northestPt.y){northestPt=pt0;northestPtIndex=j;} +if(pt0.y<=southestPt.y){southestPt=pt0;southestPtIndex=j;}} +middleSegment=northestPtIndex;middleSegment2=southestPtIndex;if(middleSegment!==startIndex) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment,middleSegment+1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0,middleSegment2,middleSegment2+1,new Boolean(true));}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"areasWithENY",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside areasWithENY",exc));}else{throw exc;}} +return;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment=function(tg,clipBounds){var middleSegment=-1;try{var pt0=null;var pt1=null;var j=0;var dist=0;var lastPt=null;var doublesBack=false;var lineType=tg.get_LineType();middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;var foundVisibleSegment=new Boolean(false);if(clipBounds===null) +return middleSegment;for(j=middleSegment;j0&&lineType===22121000) +{if(lastPt===null) +lastPt=tg.Pixels.get(j-1);doublesBack=armyc2.c2sd.JavaTacticalRenderer.Modifier2.DoublesBack(lastPt,pt0,pt1);if(doublesBack===true) +continue;lastPt=null;} +if(clipBounds.containsPt2(pt0.x,pt0.y)||clipBounds.containsPt2(pt1.x,pt1.y)){middleSegment=j;foundVisibleSegment=new Boolean(true);break;}} +if(foundVisibleSegment.valueOf()===false){for(j=middleSegment;j>0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);if(dist<5) +continue;if(j>0&&lineType===22121000) +{if(lastPt===null) +lastPt=tg.Pixels.get(j-1);doublesBack=armyc2.c2sd.JavaTacticalRenderer.Modifier2.DoublesBack(lastPt,pt0,pt1);if(doublesBack===true) +continue;lastPt=null;} +if(clipBounds.containsPt2(pt0.x,pt0.y)||clipBounds.containsPt2(pt1.x,pt1.y)){middleSegment=j-1;foundVisibleSegment=new Boolean(true);break;}}} +if(foundVisibleSegment.valueOf()===false){middleSegment=Math.floor(tg.Pixels.size()/2)-1;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMiddleSegment",exc));}else{throw exc;}} +return middleSegment;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getvisibleMiddleSegment2=function(tg,clipBounds){var middleSegment=-1;try{var clipBoundsPoly=new armyc2.c2sd.graphics2d.Polygon();var pt0=null;var pt1=null;var j=0;var x=0;var y=0;var dist=0;var lastPt=null;var doublesBack=false;middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;var foundVisibleSegment=new Boolean(false);if(clipBounds===null) +return middleSegment;for(j=0;j0&&lineType===22121000) +{if(lastPt===null);lastPt=tg.Pixels.get(j-1);doublesBack=armyc2.c2sd.JavaTacticalRenderer.Modifier2.DoublesBack(lastPt,pt0,pt1);if(doublesBack===true) +continue;lastPt=null;} +if(clipBoundsPoly.contains(pt0.x,pt0.y)||clipBoundsPoly.contains(pt1.x,pt1.y)){middleSegment=j;foundVisibleSegment=new Boolean(true);break;}} +lastPt=null;if(foundVisibleSegment.valueOf()===false){for(j=middleSegment;j>0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);if(dist<5) +continue;if(j>0&&lineType===22121000) +{if(lastPt===null) +lastPt=tg.Pixels.get(j-1);doublesBack=armyc2.c2sd.JavaTacticalRenderer.Modifier2.DoublesBack(lastPt,pt0,pt1);if(doublesBack===true) +continue;lastPt=null;} +if(clipBoundsPoly.contains(pt0.x,pt0.y)||clipBoundsPoly.contains(pt1.x,pt1.y)){middleSegment=j-1;foundVisibleSegment=new Boolean(true);break;}}} +if(foundVisibleSegment.valueOf()===false){middleSegment=Math.floor(tg.Pixels.size()/2)-1;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getMiddleSegment",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMiddleSegment",exc));}else{throw exc;}} +return middleSegment;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.removeModifier=function(tg,modifierType){try{var j=0;var modifier=null;for(j=0;j=0) +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt0,pt0,3,Math.abs((lineFactor)*stringHeight));else +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt0,pt0,2,Math.abs((lineFactor)*stringHeight));if(lineFactor>=0) +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt1,pt1,3,Math.abs((lineFactor)*stringHeight));else +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptCenter,pt1,pt1,2,Math.abs((lineFactor)*stringHeight));x1=pt2.x;y1=pt2.y;x2=pt3.x;y2=pt3.y;if(mbrPoly.contains(x1,y1)&&mbrPoly.contains(x2,y2)) +modifier.fitsMBR=true;else +modifier.fitsMBR=false;}else +modifier.fitsMBR=true;} +for(j=0;jheightMBR) +shrinkModifiers=true;else if(heightModifiers<0.5*heightMBR) +expandModifiers=true;var addEllipsis=false;var modifierE=new armyc2.c2sd.JavaTacticalRenderer.Modifier2();if(expandModifiers){var factor=heightMBR/heightModifiers;factor=1+(factor-1)/4;if(factor>1) +factor=1;for(j=0;j=heightMBR){if(modifier.lineFactor>minLF){modifierE.type=modifier.type;modifier.type=7;if(!modifier.text.isEmpty()) +addEllipsis=true;} +modifier.lineFactor=newLF;modifierE.textPath=modifier.textPath;continue;} +modifier.lineFactor=newLF;} +var modifiers2=new java.util.ArrayList();for(j=0;jmaxLF) +maxLF=modifier.lineFactor;modifiers2.add(modifier);}} +if(addEllipsis){var s=String.fromCharCode(9679);var echelonSymbol=s+s+s;modifierE.text=echelonSymbol;modifierE.lineFactor=maxLF+1;modifiers2.add(modifierE);} +tg.modifiers=modifiers2;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"scaleModifiers",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside scaleModifiers",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo=function(tg,g2d,clipBounds,converter){try{if(tg.Pixels===null||tg.Pixels.isEmpty()) +return;var origPoints=null;var font=tg.get_Font();var stringHeight=font.getSize();var shiftLines=armyc2.c2sd.JavaLineArray.Channels.getShiftLines();var usas=false;var foundSegment=false;var csFactor=1;var dist=0;var dist2=0;var midPt=null;var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null);if(isChange1Area) +return;var clipRect=null;var clipArray=null;if(clipBounds!==null&&clipBounds instanceof java.util.ArrayList){clipArray=clipBounds;} +if(clipBounds!==null&&clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle2D){clipRect=clipBounds;} +if(clipBounds!==null&&clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle){clipRect=clipBounds;} +var metrics=g2d.getFontMetrics();var stringWidth=0;var stringWidth2=0;var dash="";if(tg.get_DTG()!==null&&tg.get_DTG1()!==null&&tg.get_DTG().isEmpty()===false&&tg.get_DTG1().isEmpty()===false) +dash=" - ";if(tg.get_Client().equals("cpof3d")) +csFactor=0.9;switch(tg.get_LineType()){case 2237000:case 24313000:case 25224000:case 25223000:case 25225000:case 25310000:case 25320000:case 23180000:case 25330000:case 25351000:case 25352000:case 25353000:case 31770000:case 31740000:case 317100000:case 25340000:case 25221000:case 25222000:case 24250000:case 24211000:case 24260000:case 23163000:case 23162000:case 22622000:case 25211000:case 25212000:case 24321100:case 22522100:case 22535000:case 22432000:case 22621000:case 24322100:case 24323100:case 24324100:case 24325100:case 24331100:case 24332100:case 24336100:case 24338100:case 24339100:case 24351000:case 24361000:case 24337100:case 24335100:case 24333100:case 24334100:case 24314000:case 22431000:case 22431100:case 22422000:case 22421000:case 22625000:case 22626000:case 22532000:case 22531000:case 22235000:case 23114000:case 23115000:case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:case 22223000:case 22221000:case 22222000:case 22224000:case 22222001:case 22224001:case 22225000:case 221311000:case 22131000:case 22134000:case 22624000:case 22132000:case 22133000:case 22135000:case 22136000:case 22137000:case 22138000:case 22121000:case 22340000:case 22350000:case 23164000:case 22124000:case 22523000:case 22525000:case 22526000:case 22125000:case 22613000:case 22527000:case 22528000:case 24223000:case 24225000:case 24221000:case 24222000:case 24224000:case 22122000:case 22123000:case 21700000:case 21710000:case 22320000:case 22330000:case 22524000:case 23490000:case 212000000:case 212400000:case 212410000:case 26400000:case 26410000:case 26420000:case 26430000:case 26440000:case 211800000:case 24315000:case 23111000:case 23111001:case 23113000:case 24330000:case 23350000:case 23410000:case 212210000:case 212230000:case 212220000:case 212210001:case 212230001:case 212220001:case 21800000:case 24226000:case 22131001:case 15000000:case 15000001:case 10000000:case 11000000:origPoints=armyc2.c2sd.JavaLineArray.lineutility.getDeepCopy(tg.Pixels);break;default:return;} +var factor=1;var linetype=tg.get_LineType();var j=0;var k=0;var x=0;var y=0;if(tg.get_Font()!==null&&tg.get_Font().getSize()>0){factor=10/tg.get_Font().getSize();}else +return;var lastIndex=tg.Pixels.size()-1;var nextToLastIndex=tg.Pixels.size()-2;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var pt1=null;var pt2=null;var pt3=null;var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex));var ptNextToLast=null;if(lastIndex>0) +ptNextToLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex-1));if(tg.Pixels.size()>1) +pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(1));armyc2.c2sd.JavaTacticalRenderer.Modifier2.shiftModifierPath(tg,pt0,pt1,ptLast,ptNextToLast);var label=armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetCenterLabel(tg);var pts=tg.Pixels.toArray();var ptCenter=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_center(tg.LatLongs);if(ptCenter===null) +ptCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble2(pts,pts.length);else{var pt=converter.GeoToPixels(new armyc2.c2sd.graphics2d.Point2D(ptCenter.x,ptCenter.y));ptCenter.x=pt.x;ptCenter.y=pt.y;} +var middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;if(clipRect!==null) +middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment(tg,clipRect);else if(clipArray!==null) +middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment2(tg,clipArray);var affiliation=tg.get_Affiliation();if(tg.Pixels.size()>2){pt2=tg.Pixels.get(2);} +if(tg.Pixels.size()>3){pt3=tg.Pixels.get(3);} +var TLineFactor=0;var T1LineFactor=0;var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ll=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var index=0;var nextIndex=0;var size=tg.Pixels.size();switch(linetype){case 10000000:case 15000000:if(tg.get_T1()===null||tg.get_T1().isEmpty()){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),1,T1LineFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),1,T1LineFactor,ptLast,ptNextToLast,false);}else{if(tg.get_T1().equalsIgnoreCase("1")){for(j=0;j3) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,Math.floor(lastIndex/2)-1,Math.floor(lastIndex/2),new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H(),2,0,Math.floor(lastIndex/2)+1,Math.floor(lastIndex/2)+2,new Boolean(true));} +break;case 24313000:y=pt0.y;index=0;for(j=1;j0){if(tg.Pixels.get(index-1).ystringWidth) +stringWidth=stringWidth2;foundSegment=false;if(armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTwoLabelOnly()===false){for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,j,j+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,j,j+1,new Boolean(true));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,0.7*csFactor,j,j+1,new Boolean(true));} +foundSegment=true;}} +if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(true));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,0.7*csFactor,middleSegment,middleSegment+1,new Boolean(true));}}}else{var southestPtIndex=0,northestPt=null,southestPt=null,middleSegment2=0;for(j=0;j=northestPt.y){northestPt=pt0 +northestPtIndex=j;} +if(pt0.y<=southestPt.y){southestPt=pt0;southestPtIndex=j;}} +middleSegment=northestPtIndex;middleSegment2=southestPtIndex;if(middleSegment==tg.Pixels.size()-1){middleSegment-=1;} +if(middleSegment2==tg.Pixels.size()-1){middleSegment2-=1;} +if(middleSegment==middleSegment2){middleSegment2-=1;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(true));if(middleSegment!==middleSegment2) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3.5*factor*csFactor,middleSegment2,middleSegment2+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"ALT",2,-1.5*factor*csFactor,middleSegment2,middleSegment2+1,new Boolean(true));} +break;case 25223000:stringWidth=Math.floor((1.5*metrics.stringWidth(label+tg.get_Name())));foundSegment=false;if(armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTwoLabelOnly()===false){for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3*factor*csFactor,j,j+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));} +foundSegment=true;}} +if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-3*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}}}else{var southestPtIndex=0,northestPt=null,southestPt=null,middleSegment2=0;for(j=0;j=northestPt.y){northestPt=pt0 +northestPtIndex=j;} +if(pt0.y<=southestPt.y){southestPt=pt0;southestPtIndex=j;}} +middleSegment=northestPtIndex;middleSegment2=southestPtIndex;if(middleSegment==tg.Pixels.size()-1){middleSegment-=1;} +if(middleSegment2==tg.Pixels.size()-1){middleSegment2-=1;} +if(middleSegment==middleSegment2){middleSegment2-=1;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment,middleSegment+1,new Boolean(false));if(middleSegment!==middleSegment2) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment2,middleSegment2+1,new Boolean(false));} +break;case 25225000:stringWidth=Math.floor((1.5*metrics.stringWidth(label+tg.get_Name())));foundSegment=false;if(armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTwoLabelOnly()===false){for(j=0;jpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-4.5*factor*csFactor,j,j+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,j,j+1,new Boolean(false));} +foundSegment=true;}} +if(foundSegment===false){pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);if(pt0.xpt1.y)){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-4.5*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-2*factor*csFactor,middleSegment,middleSegment+1,new Boolean(false));}}}else{var southestPtIndex=0,northestPt=null,southestPt=null,middleSegment2=0;for(j=0;j=northestPt.y){northestPt=pt0 +northestPtIndex=j;} +if(pt0.y<=southestPt.y){southestPt=pt0;southestPtIndex=j;}} +middleSegment=northestPtIndex;middleSegment2=southestPtIndex;if(middleSegment==tg.Pixels.size()-1){middleSegment-=1;} +if(middleSegment2==tg.Pixels.size()-1){middleSegment2-=1;} +if(middleSegment==middleSegment2){middleSegment2-=1;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment,middleSegment+1,new Boolean(false));if(middleSegment!==middleSegment2) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment2,middleSegment2+1,new Boolean(false));} +break;case 25310000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"DETAINEE",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 25320000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"EPW",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 23180000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 25330000:case 25351000:case 25352000:case 25353000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 31770000:case 31740000:case 317100000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,tg.get_H(),3,-0.5,ptCenter,ptCenter,"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,tg.get_H1(),3,0.5,ptCenter,ptCenter,"H1");break;case 25340000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"REFUGEE",3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"HOLDING",3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"AREA",3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 25221000:case 25222000:foundSegment=false;if(armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTwoLabelOnly()===false){for(j=0;j=northestPt.y){northestPt=pt0 +northestPtIndex=j;} +if(pt0.y<=southestPt.y){southestPt=pt0;southestPtIndex=j;}} +middleSegment=northestPtIndex;middleSegment2=southestPtIndex;if(middleSegment==tg.Pixels.size()-1){middleSegment-=1;} +if(middleSegment2==tg.Pixels.size()-1){middleSegment2-=1;} +if(middleSegment==middleSegment2){middleSegment2-=1;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment,middleSegment+1,new Boolean(false));if(middleSegment!==middleSegment2) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1*csFactor,middleSegment2,middleSegment2+1,new Boolean(false));} +break;case 24250000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,-0.8*csFactor,middleSegment,middleSegment+1,new Boolean(false));break;case 24211000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,-0.8*csFactor,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,0.8*csFactor,middleSegment,middleSegment+1,new Boolean(false));break;case 24260000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,-1*csFactor,0,1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label,2,1*csFactor,0,1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_T1(),2,2*csFactor,0,1,new Boolean(false));break;case 23163000:if(tg.Pixels.get(1).y>tg.Pixels.get(0).y){pt0=tg.Pixels.get(1);pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(0);pt3=tg.Pixels.get(2);}else{pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(2);pt2=tg.Pixels.get(1);pt3=tg.Pixels.get(3);} +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt0,pt2,-20);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt1,pt3,-20);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,0,pt2,pt3,new Boolean(false));break;case 23162000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_H(),2,-1.5*factor*csFactor,ul,ur,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),2,1.5*factor*csFactor,ll,lr,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22622000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,0,ll,lr,new Boolean(false));break;case 25211000:case 25212000:var convoyBlankString=armyc2.c2sd.JavaTacticalRenderer.Modifier2.blankString(metrics,35);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_H()+convoyBlankString+tg.get_H1(),2,0,0,1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,1.2*csFactor,0,1,new Boolean(false));break;case 22522100:if(affiliation!==null&&affiliation.equals("H")){k=tg.Pixels.size();j=armyc2.c2sd.JavaLineArray.lineutility.GetDirAtkAirMiddleSegment(tg.Pixels.toArray(new Array(tg.Pixels.size())),tg.Pixels.size());pt1=tg.Pixels.get(k-j-1);pt0=tg.Pixels.get(k-j);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,2*dist/3);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_N(),2,0,pt0,pt1,true);} +break;case 22535000:case 22432000:case 22621000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));break;case 24322100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-3*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-2*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),3,-1*csFactor,ptCenter,ptCenter,new Boolean(false),"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),3,0,ptCenter,ptCenter,new Boolean(false),"H1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"Grids: "+tg.get_H2(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"H2");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"EFF: "+tg.get_DTG(),3,2*csFactor,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,3*csFactor,ptCenter,ptCenter,new Boolean(false),"W1");break;case 24323100:case 24325100:case 24351000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");break;case 24361000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_H1(),3,2*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 24324100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(true),"W+W1");break;case 24321100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+" "+tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);var ptLeftFSA=ul;var ptRightFSA=ur;if(tg.get_Client().equalsIgnoreCase("ge")){ptLeftFSA.x-=Math.floor(font.getSize()/2);ptRightFSA.x-=Math.floor(font.getSize()/2);} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),1,0.5*csFactor,ptLeftFSA,ptRightFSA,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),1,1.5*csFactor,ptLeftFSA,ptRightFSA,new Boolean(false),"W1");break;case 24331100:case 24332100:case 24336100:case 24338100:case 24339100:case 24337100:case 24335100:case 24333100:case 24334100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetMBR(tg,ul,ur,lr,ll);var ptLeft=ul;var ptRight=ur;if(tg.get_Client().equalsIgnoreCase("ge")){ptLeft.x-=Math.floor(font.getSize()/2);ptRight.x-=Math.floor(font.getSize()/2);} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),1,0.5*csFactor,ptLeft,ptRight,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),1,1.5*csFactor,ptLeft,ptRight,new Boolean(false),"W1");break;case 24314000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false),"W+W1");break;case 22431000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_EchelonSymbol(),2,-0.2*csFactor,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22431100:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label+tg.get_Name(),3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_EchelonSymbol(),2,-0.2*csFactor,0,1,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.areasWithENY(tg,g2d);break;case 22422000:pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,-22,0);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));break;case 22421000:stringWidth=metrics.stringWidth(label);pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);if(pt0.x>ptLast.x) +pt1.x+=32;else{pt1.x-=stringWidth-8;pt1.y-=1.1*stringHeight;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptLast);if(pt0.x>ptLast.x){pt1.x-=stringWidth-8;pt1.y-=1.1*stringHeight;}else +pt1.x+=32;armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,0,pt1,pt1,new Boolean(false));break;case 22625000:case 22626000:case 22532000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 22531000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"ASLT",3,-1*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"PSN",3,0,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,1*csFactor,ptCenter,ptCenter,new Boolean(false));break;case 22235000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME FROM: "+tg.get_DTG(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(true),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME TO: "+tg.get_DTG1(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(true),"W1");break;case 23114000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-1.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.5*csFactor,ptCenter,ptCenter,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),3,0.5*csFactor,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,1.5*csFactor,ptCenter,ptCenter,new Boolean(false),"W1");break;case 23115000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-1*csFactor,ptCenter,ptCenter,new Boolean(true));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),3,0,ptCenter,ptCenter,new Boolean(true),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),3,1*csFactor,ptCenter,ptCenter,new Boolean(true),"W1");break;case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,3,-2.5,ptCenter,ptCenter,new Boolean(false),"");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-1.5,ptCenter,ptCenter,new Boolean(false),"T");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),3,-0.5,ptCenter,ptCenter,new Boolean(false),"H");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),3,0.5,ptCenter,ptCenter,new Boolean(false),"H1");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME FROM: "+tg.get_DTG(),3,1.5,ptCenter,ptCenter,new Boolean(false),"W");armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"TIME TO: "+tg.get_DTG1(),3,2.5,ptCenter,ptCenter,new Boolean(false),"W1");break;case 22223000:pt0=new armyc2.c2sd.JavaLineArray.POINT2(tg.Pixels.get(middleSegment));dist=pt0.style/tg.get_Font().getSize();dist/=2;if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"SAAFR "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-4*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-5*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-6*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-7*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),2,-3*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),2,-2*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-2*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-3*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-4*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-5*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));} +break;case 22221000:pt0=new armyc2.c2sd.JavaLineArray.POINT2(tg.Pixels.get(middleSegment));dist=pt0.style/tg.get_Font().getSize();dist/=2;if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),2,-4*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),2,-5*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),2,-6*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),2,-7*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),2,-3*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),2,-2*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));}else{armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_Name(),2,-1.0*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_T1(),2,1.0*csFactor-dist,middleSegment,middleSegment+1,new Boolean(false));} +break;case 22222001:case 22224001:case 22222000:case 22224000:case 22225000:if(tg.getSymbologyStandard()===1){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),2,0,middleSegment,middleSegment+1,new Boolean(false));pt0=new armyc2.c2sd.JavaLineArray.POINT2(tg.Pixels.get(middleSegment));pt1=new armyc2.c2sd.JavaLineArray.POINT2(tg.Pixels.get(middleSegment+1));if(pt0.ystringWidth) +stringWidth=stringWidth2;if(tg.Pixels.size()===2){if(pt0.x2*stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);if(pt0.x>pt1.x) +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth/2);else +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}}else{var dist3=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);} +if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_Name()+" "+label,2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}} +break;case 24222000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,label+tg.get_Name(),2,-1,middleSegment,middleSegment+1,new Boolean(false));armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),2,1,middleSegment,middleSegment+1,new Boolean(false));break;case 24224000:pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);pt2=tg.Pixels.get(tg.Pixels.size()-1);pt3=tg.Pixels.get(tg.Pixels.size()-2);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt2,pt3);stringWidth=Math.floor((metrics.stringWidth(label+" "+tg.get_Name())));stringWidth2=Math.floor((metrics.stringWidth(tg.get_DTG())));if(stringWidth2>stringWidth) +stringWidth=stringWidth2;if(tg.Pixels.size()===2){if(pt0.x2*stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);if(pt0.x>pt1.x) +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth/2);else +pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}}else{dist3=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);} +if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),2,-0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG(),2,0.7*csFactor,pt0,pt1,false);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifier2(tg,tg.get_DTG1(),2,1.7*csFactor,pt0,pt1,false);}} +break;case 22122000:armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,pt0,pt1,new Boolean(false));if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),1,-1*csFactor,pt0,pt1,new Boolean(false));} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,1,0,ptLast,ptNextToLast,new Boolean(false));if(affiliation!==null&&affiliation.equals("H")){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),1,-1*csFactor,ptLast,ptNextToLast,new Boolean(false));} +break;case 22123000:var shiftFactor=1;if(affiliation!==null&&affiliation.equals("H")){if(pt0.x=locModifier.size()){break;} +pt0=locModifier.get(k);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"ALT "+altitudes[k],3,0,pt0,pt0);}} +if(tg.get_HideOptionalLabels()) +return true;for(var k=0;k1) +nextToLastIndex=tg.Pixels.size()-2;var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex));var ptNextToLast=null;if(tg.Pixels.size()>1) +ptNextToLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(nextToLastIndex));var dash="";if(tg.get_DTG()!==null&&tg.get_DTG1()!==null&&tg.get_DTG().isEmpty()===false&&tg.get_DTG1().isEmpty()===false) +dash=" - ";var ptLeft=null;var ptRight=null;var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();var metrics=g2d.getFontMetrics();var stringWidth=0;var rfaLines=0;var pts=null;pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));if(tg.Pixels.size()>1) +pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(1));if(tg.get_Client().equals("cpof3d")) +csFactor=0.9;armyc2.c2sd.JavaTacticalRenderer.Modifier2.shiftModifierPath(tg,pt0,pt1,ptLast,ptNextToLast);if(tg.getSymbologyStandard()===1){switch(linetype){case 14000000:case 15000003:pts=new Array(4);for(j=0;j<4;j++) +pts[j]=tg.Pixels.get(j);ptCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble2(pts,4);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),3,-0.125*csFactor,ptCenter,ptCenter,false);break;case 21200000:case 21300000:case 21400000:pt0=tg.Pixels.get(1);pt1=tg.Pixels.get(2);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211700000:case 21500000:pt0=tg.Pixels.get(2);pt1=tg.Pixels.get(3);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211000000:pt0=tg.Pixels.get(4);pt1=tg.Pixels.get(5);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211100000:pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 211400000:case 211600000:case 211900000:case 212100000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(14);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 21600000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(14);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,"C",2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;case 212300000:case 212300001:pt0=tg.Pixels.get(26);pt1=tg.Pixels.get(27);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,-0.125*csFactor,pt0,pt1,new Boolean(true));break;default:break;}} +switch(linetype){case 212600000:case 212500000:pt0=tg.Pixels.get(13);pt1=tg.Pixels.get(0);stringWidth=metrics.stringWidth(label);if(pt0.xj*102+25){pt0=tg.Pixels.get(j*102+25);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"ALT "+H1[j],3,0,pt0,pt0);}}} +if(!tg.get_HideOptionalLabels()){var H2=tg.get_H2();var am=H2.split(",");for(j=0;jj*102+25){pt0=tg.Pixels.get(j*102+25);if(j===0) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"MIN RG "+am[j],3,-1,pt0,pt0);else +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddAreaModifier(tg,"MAX RG "+"("+j.toString()+") "+am[j],3,-1,pt0,pt0);}}} +break;case 243112000:break;default:return;} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.scaleModifiers(tg);tg.Pixels=origPoints;g2d.dispose();g2d=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifiers2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifiers2",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers=function(tg,g2d){try{var id=new armyc2.c2sd.graphics2d.AffineTransform();id.setToIdentity();g2d.setTransform(id);var font=g2d.getFont();var j=0;var modifier=null;g2d.setBackground(armyc2.c2sd.renderer.utilities.Color.white);var pt=null;var theta=0;var stringWidth=0;var stringHeight=0;var metrics=g2d.getFontMetrics();var s="";var x=0;var y=0;var pt1=null;var pt2=null;var quadrant=-1;for(j=0;jx2){theta-=3.141592653589793;} +switch(modifier.type){case 1:g2d.rotate(theta,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();if(x1y2)){x=Math.floor(x1)-stringWidth;y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);}else{x=Math.floor(x1);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);} +break;case 2:midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2((x1+x2)/2,(y1+y2)/2);g2d.rotate(theta,midPt.x,midPt.y);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(midPt.x)-Math.floor(stringWidth/2);y=Math.floor(midPt.y)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(midPt.y)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);break;case 3:g2d.rotate(0,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(x1)-Math.floor(stringWidth/2);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);break;case 4:if(tg.Pixels.size()>=14){pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(10);quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(pt1,pt2);theta=Math.atan2(pt2.y-pt1.y,pt2.x-pt1.x);switch(quadrant){case 1:theta+=1.5707963267948966;break;case 2:theta-=1.5707963267948966;break;case 3:theta-=1.5707963267948966;break;case 4:theta+=1.5707963267948966;break;default:break;} +g2d.rotate(theta,x1,y1);stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(x1)-Math.floor(stringWidth/2);y=Math.floor(y1)-Math.floor(stringHeight/2)+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=Math.floor(y1)+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);}else{stringWidth=metrics.stringWidth(s);stringHeight=font.getSize();x=Math.floor(tg.Pixels.get(0).x);y=Math.floor(tg.Pixels.get(0).y);g2d.setColor(tg.get_FontBackColor());g2d.clearRect(x,y,stringWidth,stringHeight);y=y+(Math.floor(stringHeight/2))+Math.floor((lineFactor*stringHeight));g2d.setColor(tg.get_TextColor());g2d.drawString(s,x,y);} +break;default:break;} +g2d.setTransform(id);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"DisplayModifiers",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DisplayModifiers",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.BuildModifierShape=function(tg,pt0,pt1,stringWidth,stringHeight,lineFactor,isTextFlipped){var modifierFill=null;try{var ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt0);var ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);if(isTextFlipped===true) +lineFactor+=1;if(lineFactor<0){ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,2,-lineFactor*stringHeight);ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,2,-lineFactor*stringHeight);} +if(lineFactor>0){ptTemp0=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,3,lineFactor*stringHeight);ptTemp1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,3,lineFactor*stringHeight);} +if(ptTemp0.y===ptTemp1.y){ptTemp0.y+=1;} +var pt3=null;var pt4=null;var pt5=null;var pt6=null;var pt7=null;pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(ptTemp0,ptTemp1,-stringWidth);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,pt3,0,Math.floor(stringHeight/2));pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,pt3,1,Math.floor(stringHeight/2));pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,ptTemp0,1,Math.floor(stringHeight/2));pt7=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(ptTemp1,ptTemp0,ptTemp0,0,Math.floor(stringHeight/2));modifierFill=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);modifierFill.moveTo(pt4);modifierFill.lineTo(pt5);modifierFill.lineTo(pt6);modifierFill.lineTo(pt7);modifierFill.lineTo(pt4);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"BuildModifierShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BuildModifierShape",exc));}else{throw exc;}} +return modifierFill;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetIntegralTextShapes=function(tg,g2d,shapes){try{if(tg.Pixels===null||shapes===null) +return;var hmap=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getMSRSegmentColors(tg);var color=null;var shape=null;var segShape=null;g2d.setFont(tg.get_Font());var j=0;var affiliation=null;var metrics=g2d.getFontMetrics();var echelonSymbol=null;var stringWidthEchelonSymbol=0;var stringWidthENY=0;var ptEchelonStart=null;var ptEchelonEnd=null;var midpt;var ptENY0Start=null;var ptENY0End=null;var ptENY1Start;var ptENY1End;var pt0=null;var pt1=null;var dist=0;var stroke=null;switch(tg.get_LineType()){case 22121000:echelonSymbol=tg.get_EchelonSymbol();shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setLineColor(tg.get_LineColor());shape.set_Style(tg.get_LineStyle());affiliation=tg.get_Affiliation();stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke(tg.get_LineThickness(),shape.get_Style(),1,1);shape.setStroke(stroke);if(tg.get_Affiliation()!==null&&tg.get_Affiliation().equals("H")){stringWidthENY=metrics.stringWidth(tg.get_N());} +if(echelonSymbol!==null&&!echelonSymbol.isEmpty()) +stringWidthEchelonSymbol=metrics.stringWidth(echelonSymbol);if(hmap===null||hmap.isEmpty()){shape.moveTo(tg.Pixels.get(0));for(j=1;j0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,midpt,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,midpt,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)-stringWidthENY/1.5;ptENY0Start=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)+stringWidthENY/1.5;ptENY0End=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);if(segShape!==null){segShape.moveTo(pt0);segShape.lineTo(ptENY0Start);segShape.moveTo(ptENY0End);}else{shape.moveTo(pt0);shape.lineTo(ptENY0Start);shape.moveTo(ptENY0End);}}else{if(segShape!==null) +segShape.moveTo(pt0);else +shape.moveTo(pt0);} +if(stringWidthEchelonSymbol>0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)-stringWidthEchelonSymbol/1.5;ptEchelonStart=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,midpt)+stringWidthEchelonSymbol/1.5;ptEchelonEnd=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,dist);if(segShape!==null){segShape.lineTo(ptEchelonStart);segShape.moveTo(ptEchelonEnd);}else{shape.lineTo(ptEchelonStart);shape.moveTo(ptEchelonEnd);}} +if(stringWidthENY>0){midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,midpt,0);midpt=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt1,midpt,0);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,midpt)-stringWidthENY/1.5;ptENY1Start=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,dist);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt1,midpt)+stringWidthENY/1.5;ptENY1End=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt1,pt0,dist);if(segShape!==null){segShape.lineTo(ptENY1End);segShape.moveTo(ptENY1Start);segShape.lineTo(pt1);}else{shape.lineTo(ptENY1End);shape.moveTo(ptENY1Start);shape.lineTo(pt1);}}else{if(segShape!==null) +segShape.lineTo(pt1);else +shape.lineTo(pt1);} +if(segShape!==null) +shapes.add(segShape);} +if(!shape.getShape().getPathIterator().getPoints().isEmpty()) +shapes.add(shape);break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"GetIntegralTextShapes",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetIntegralTextShapes",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.switchDirection=function(direction){var result=-1;switch(direction){case 0:return 1;case 1:return 0;case 2:return 3;case 3:return 2;} +return result;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2=function(tg,g2d,shapes,isTextFlipped,converter){try{if(shapes===null) +return;if(tg.modifiers===null||tg.modifiers.isEmpty()) +return;var font=null;var j=0;var modifier=null;var fontBackColor=tg.get_FontBackColor();var textColor=tg.get_TextColor();var theta=0;var stringWidth=0;var stringHeight=0;var s="";var x=0;var y=0;var pt0=null;var pt1=null;var pt2=null;var pt3=null;var quadrant=-1;var shape2=null;var lineType=tg.get_LineType();var sz=armyc2.c2sd.renderer.utilities.RendererSettings.getMPModifierFontSize();if(sz===0) +return;font=tg.get_Font();if(font===null){font=g2d.getFont();} +if(font.getSize()===0) +return;g2d.setFont(font);var metrics=g2d.getFontMetrics();if(fontBackColor!==null){g2d.setBackground(fontBackColor);}else{g2d.setBackground(armyc2.c2sd.renderer.utilities.Color.white);} +if(textColor===null) +textColor=tg.get_LineColor();var direction=-1;var glyphPosition=null;var modifierPosition=null;for(j=0;jx2){theta-=3.141592653589793;} +pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x1,y1);pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x2,y2);midPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2((x1+x2)/2,(y1+y2)/2);var justify=armyc2.c2sd.renderer.utilities.ShapeInfo.justify_left;switch(modifier.type){case 5:if(x1===x2){x2+=1;} +if(x1=0){direction=2;}else{direction=3;} +if(lineType===22123000||tg.get_Client().equalsIgnoreCase("ge")){direction=armyc2.c2sd.JavaTacticalRenderer.Modifier2.switchDirection(direction);} +if(x1=0) +direction=2;else +direction=3;if(lineType===22123000||tg.get_Client().equalsIgnoreCase("ge")){direction=armyc2.c2sd.JavaTacticalRenderer.Modifier2.switchDirection(direction);} +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt0,pt1,direction,lineFactor*stringHeight);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt1,pt0,pt0,direction,lineFactor*stringHeight);if(x1pt1.x) +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt3,pt2,-stringWidth/2);else +pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt3,pt2,-stringWidth);glyphPosition=new armyc2.c2sd.graphics2d.Point(pt3.x,pt3.y);pt3.x-=stringWidth/2;pt3.y-=stringHeight/2;glyphPosition=new armyc2.c2sd.graphics2d.Point(pt3.x,pt3.y);break;case 2:dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);if(converter!==null&&dist>100&&lineType!==22121000){var pt1Geo=converter.PixelsToGeo(new armyc2.c2sd.graphics2d.Point(Math.floor(pt0.x),Math.floor(pt0.y)));var pt2Geo=converter.PixelsToGeo(new armyc2.c2sd.graphics2d.Point(Math.floor(pt1.x),Math.floor(pt1.y)));var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();a12.value=Clazz.newArray(1,0);a21.value=Clazz.newArray(1,0);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo.x,pt1Geo.y),armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2Geo.x,pt2Geo.y),a12,a21);var midPtGeo=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo.x,pt1Geo.y),dist/2,a12.value[0]);var pt2d=new armyc2.c2sd.graphics2d.Point2D(midPtGeo.x,midPtGeo.y);var midPt2D=converter.GeoToPixels(pt2d);midPt.x=midPt2D.getX();midPt.y=midPt2D.getY();} +x=Math.floor(midPt.x)-Math.floor(Math.floor(stringWidth)/2);y=Math.floor(midPt.y)+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));if(pt0.x<=pt1.x) +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(midPt,pt0,0.5*stringWidth);else +pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(midPt,pt1,0.5*stringWidth);if(tg.get_Client().equals("2D")) +lineFactor+=0.5;if(lineFactor>=0){pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,3,Math.abs((lineFactor)*stringHeight));midPt=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,midPt,midPt,3,Math.abs((lineFactor)*stringHeight));}else{pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,2,Math.abs((lineFactor)*stringHeight));midPt=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,midPt,midPt,2,Math.abs((lineFactor)*stringHeight));} +if(x1===x2&&y1>y2){pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt2,pt2,1,Math.abs((lineFactor)*stringHeight));midPt=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,midPt,midPt,1,Math.abs((lineFactor)*stringHeight));} +if(x1===x2&&y1=14){pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(10);quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(pt1,pt2);theta=Math.atan2(pt2.y-pt1.y,pt2.x-pt1.x);if(Math.abs(theta)<0.39269908169872414){if(theta<0){theta-=1.5707963267948966;}else{theta+=1.5707963267948966;}} +switch(quadrant){case 1:theta+=1.5707963267948966;break;case 2:theta-=1.5707963267948966;break;case 3:theta-=1.5707963267948966;break;case 4:theta+=1.5707963267948966;break;default:break;} +x=Math.floor(x1)-Math.floor(Math.floor(stringWidth)/2);y=Math.floor(y1)-Math.floor(Math.floor(stringHeight)/2)+Math.floor((lineFactor*stringHeight));y=Math.floor(y1)+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));}else{theta=0;x=Math.floor(tg.Pixels.get(0).x);y=Math.floor(tg.Pixels.get(0).y);x=x-Math.floor(Math.floor(stringWidth)/2);y=y-Math.floor(Math.floor(stringHeight)/2)+Math.floor((lineFactor*stringHeight));y=y+Math.floor((stringHeight/2))+Math.floor((lineFactor*stringHeight));} +glyphPosition=new armyc2.c2sd.graphics2d.Point(x,y);break;default:break;} +shape2=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);shape2.setStroke(new armyc2.c2sd.graphics2d.BasicStroke(0,1,1,3));if(tg.get_TextColor()!==null){shape2.setFillColor(tg.get_TextColor());}else if(tg.get_LineColor()!==null){shape2.setFillColor(tg.get_LineColor());} +if(tg.get_LineColor()!==null){shape2.setLineColor(tg.get_LineColor());} +var tl=new armyc2.c2sd.graphics2d.TextLayout(s,font,g2d.getFontMetrics().getFontRenderContext());shape2.setTextLayout(tl);if(converter!==null) +shape2.setGlyphPosition(glyphPosition);else +shape2.setGlyphPosition(new armyc2.c2sd.graphics2d.Point2D(0,0));shape2.setModifierString(s);shape2.setModifierStringAngle(theta*180/3.141592653589793);shape2.setModifierStringPosition(modifierPosition);shape2.setTextJustify(justify);if(shape2!==null){shapes.add(shape2);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"DisplayModifiers2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DisplayModifiers2",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getTextShape=function(g2d,str,font,tx){var tl=null;var frc=null;try{frc=g2d.getFontRenderContext();tl=new armyc2.c2sd.graphics2d.TextLayout(str,font,frc);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"getTextShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getTextShape",exc));}else{throw exc;}} +return tl.getOutline(tx);};armyc2.c2sd.JavaTacticalRenderer.Modifier2.createTextOutline=function(originalText){var siOutline=null;try{var outline=originalText.getShape();siOutline=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_MODIFIER_FILL);siOutline.setShape(outline);if(originalText.getFillColor().getRed()===255&&originalText.getFillColor().getGreen()===255&&originalText.getFillColor().getBlue()===255) +siOutline.setLineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);else +siOutline.setLineColor(armyc2.c2sd.renderer.utilities.Color.WHITE);var width=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getTextOutlineWidth();siOutline.setStroke(new armyc2.c2sd.graphics2d.BasicStroke(width,1,1,3));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"createTextOutline",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createTextOutline",exc));}else{throw exc;}} +return siOutline;};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getShapePoints=function(shape){try{var ptsPoly=new java.util.ArrayList();var ptPoly=null;var coords=new Array(6);var zeros=0;for(var i=shape.getPathIterator(null);!i.isDone();i.next()){var type=i.currentSegment(coords);if(type===0&&zeros===2) +break;switch(type){case armyc2.c2sd.graphics2d.PathIterator.SEG_MOVETO:ptPoly=new armyc2.c2sd.graphics2d.Point2D(coords[0],coords[1]);ptsPoly.add(ptPoly);zeros++;break;case armyc2.c2sd.graphics2d.PathIterator.SEG_LINETO:ptPoly=new armyc2.c2sd.graphics2d.Point2D(coords[0],coords[1]);ptsPoly.add(ptPoly);break;case armyc2.c2sd.graphics2d.PathIterator.SEG_QUADTO:break;case armyc2.c2sd.graphics2d.PathIterator.SEG_CUBICTO:break;case armyc2.c2sd.graphics2d.PathIterator.SEG_CLOSE:break;}} +if(ptsPoly.size()>0){var pts=null;pts=new java.util.ArrayList();for(var j=0;jtg.Pixels.get(3).x) +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,csFactor,tg.Pixels.get(0),tg.Pixels.get(3),false);else +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,label,2,csFactor,tg.Pixels.get(1),tg.Pixels.get(2),false);break;case 141500:case 141400:case 200300:case 240804:break;case 151407:case 151408:var shape=shapes.get(shapes.size()-1);var pts=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getShapePoints(shape.getShape());n=pts.size();if(n===4) +{pt0=pts.get(0);pt1=pts.get(1);pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);}else if(n===6){pt0=pts.get(3);pt1=pts.get(4);}else{pt0=pts.get(1);pt1=pts.get(2);} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,false);if(n===4){pt0=pts.get(2);pt1=pts.get(3);pt1=armyc2.c2sd.JavaLineArray.lineutility.MidPointDouble(pt0,pt1,0);}else if(n===6){pt0=pts.get(0);pt1=pts.get(1);}else{pt0=pts.get(n/2+1);pt1=pts.get(n/2+2);} +armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),2,0,pt0,pt1,false);break;default:var saveStd=tg.getSymbologyStandard();tg.setSymbologyStandard(armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525C);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiers2(tg);tg.setSymbologyStandard(saveStd);break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifiers2RevD",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside addModifiers2RevD",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.getRevDLabel=function(code){switch(code){case 200401:case 200402:return"AOI";case 200300:return"N";case 200101:return"LA";case 200201:case 200202:return"DA";case 170800:return"BDZ";case 150501:return"JTAA";case 150502:return"SAA";case 150503:return"SGSA";case 140700:return"FCL";case 151500:return"ASLT";case 170400:return"SL";case 170600:return"TC";case 171100:return"AARROZ";case 171200:return"UAROZ";case 171300:return"WEZ";case 171400:return"FEZ";case 171500:return"JEZ";case 171900:return"SHORADEZ";case 190100:return"IFF OFF";case 190200:return"IFF ON";case 220102:return"EW";case 220107:return"J";case 220108:return"RDF";case 260300:return"NFL";case 260400:return"BCL";case 300100:return"ICL";case 140400:case 140401:return"FEBA";case 140900:return"LOA";default:return"";}};armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo2=function(tg,g2d,clipBounds,converter){if(tg.get_SymbolId().length<20){armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);return;} +try{var country="US";var v="MORTAR";var ap="QC 1968";var symbolId=tg.get_SymbolId();var setA=symbolId.substring(0,10);var setB=symbolId.substring(10);var code=setB.substring(0,6);var code2=Integer.parseInt(code);var nCode=code2.valueOf();var t=tg.get_Name();switch(nCode){case 110101:case 110102:case 110103:t+=" "+"("+country+")";tg.set_Name(t);tg.set_T1(t);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);return;default:break;} +var symbolSet=setA.substring(4,6);var nSymbol=Integer.parseInt(symbolSet);var lineutility=armyc2.c2sd.JavaLineArray.lineutility;var Modifier2=armyc2.c2sd.JavaTacticalRenderer.Modifier2;var mdlGeodesic=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic;var graphics2d=armyc2.c2sd.graphics2d;var label=Modifier2.GetCenterLabel(tg);if(nSymbol.valueOf()!==25){Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);return;} +var ptUl=null,ptUr=null,ptLl=null,ptLr=null;var toEnd=1,aboveMiddle=2,area=3,screen=4,aboveEnd=5;if(tg.Pixels===null||tg.Pixels.isEmpty()) +return;var font=tg.get_Font();var stringHeight=font.getSize();var shiftLines=armyc2.c2sd.JavaLineArray.Channels.getShiftLines();var usas=false;var foundSegment=false;var csFactor=1;var dist=0;var dist2=0;var midPt=null;var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null);if(isChange1Area){switch(nCode){case 200101:case 200201:case 240804:break;default:return;}} +var clipRect=null;var clipArray=null;if(clipBounds!==null&&clipBounds instanceof java.util.ArrayList){clipArray=clipBounds;} +if(clipBounds!==null&&clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle2D){clipRect=clipBounds;} +if(clipBounds!==null&&clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle){clipRect=clipBounds;} +var metrics=g2d.getFontMetrics();var stringWidth=0;var stringWidth2=0;var dash="";if(tg.get_DTG()!==null&&tg.get_DTG1()!==null&&tg.get_DTG().isEmpty()===false&&tg.get_DTG1().isEmpty()===false) +dash=" - ";if(tg.get_Client().equals("cpof3d")) +csFactor=0.9;var factor=1;var linetype=tg.get_LineType();var j=0;var k=0;var x=0;var y=0;if(nCode===110101){var s=tg.get_Name()+" "+"("+country+")";tg.set_Name(s);tg.set_T1(s);armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);return;} +if(tg.get_Font()!==null&&tg.get_Font().getSize()>0){factor=10/tg.get_Font().getSize();}else +return;var lastIndex=tg.Pixels.size()-1;var nextToLastIndex=tg.Pixels.size()-2;var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var pt1=null;var pt2=null;var pt3=null;var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex));var ptNextToLast=null;if(lastIndex>0) +ptNextToLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(lastIndex-1));if(tg.Pixels.size()>1) +pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(1));armyc2.c2sd.JavaTacticalRenderer.Modifier2.shiftModifierPath(tg,pt0,pt1,ptLast,ptNextToLast);var pts=tg.Pixels.toArray();var ptCenter=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_center(tg.LatLongs);if(ptCenter===null) +ptCenter=armyc2.c2sd.JavaLineArray.lineutility.CalcCenterPointDouble2(pts,pts.length);else{var pt=converter.GeoToPixels(new armyc2.c2sd.graphics2d.Point2D(ptCenter.x,ptCenter.y));ptCenter.x=pt.x;ptCenter.y=pt.y;} +var middleSegment=Math.floor((tg.Pixels.size()+1)/2)-1;if(clipRect!==null) +middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment(tg,clipRect);else if(clipArray!==null) +middleSegment=armyc2.c2sd.JavaTacticalRenderer.Modifier2.getVisibleMiddleSegment2(tg,clipArray);var affiliation=tg.get_Affiliation();if(tg.Pixels.size()>2){pt2=tg.Pixels.get(2);} +if(tg.Pixels.size()>3){pt3=tg.Pixels.get(3);} +var TLineFactor=0;var T1LineFactor=0;var lr=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ll=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ul=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var ur=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(0));var index=0;var nextIndex=0;var size=tg.Pixels.size();switch(nCode){case 200401:ptUr=new armyc2.c2sd.JavaLineArray.POINT2();ptUl=new armyc2.c2sd.JavaLineArray.POINT2();ptLl=new armyc2.c2sd.JavaLineArray.POINT2();ptLr=new armyc2.c2sd.JavaLineArray.POINT2();Modifier2.GetMBR(tg,ptUl,ptUr,ptLr,ptLl);label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,csFactor,ptLl,ptLr,false);break;case 110200:case 141000:case 141100:case 141200:case 141400:case 141500:case 141600:Modifier2.AddIntegralAreaModifier(tg,label,aboveEnd,-csFactor,pt0,pt1,false);Modifier2.AddIntegralAreaModifier(tg,label,aboveEnd,-csFactor,ptLast,ptNextToLast,false);break;case 120400:ptUr=new armyc2.c2sd.JavaLineArray.POINT2();ptUl=new armyc2.c2sd.JavaLineArray.POINT2();ptLl=new armyc2.c2sd.JavaLineArray.POINT2();ptLr=new armyc2.c2sd.JavaLineArray.POINT2();Modifier2.GetMBR(tg,ptUl,ptUr,ptLr,ptLl);stringWidth=metrics.stringWidth(tg.get_H());pt0.x=ptUr.x+stringWidth/2+1;pt0.y=(ptUr.y+ptLr.y)/2-stringHeight;Modifier2.AddIntegralAreaModifier(tg,tg.get_H(),area,csFactor,pt0,pt0,false);break;case 200101:case 200201:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label+" - "+tg.get_Name(),area,0,ptCenter,ptCenter,false);break;case 140700:case 140900:case 190100:case 190200:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,aboveEnd,-csFactor,pt0,pt1,false);Modifier2.AddIntegralAreaModifier(tg,label,aboveEnd,-csFactor,ptLast,ptNextToLast,false);break;case 140103:case 140104:Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),toEnd,-1*csFactor,pt0,pt1,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),toEnd,-1*csFactor,ptLast,ptNextToLast,false);break;case 200402:case 140101:case 140102:case 150101:case 150102:case 151900:case 152000:case 152100:case 152200:case 141700:break;case 140400:case 140401:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,toEnd,0,pt0,pt1,false);Modifier2.AddIntegralAreaModifier(tg,label,toEnd,0,ptLast,ptNextToLast,false);break;case 150103:case 150104:Modifier2.areasWithENY(tg,g2d);break;case 150501:case 150502:case 150503:Modifier2.areasWithENY(tg,g2d);label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label+" "+tg.get_Name(),area,0,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),aboveMiddle,csFactor,ptCenter,ptCenter,false);break;case 151000:Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),area,0,ptCenter,ptCenter,false);break;case 151401:case 151402:if(tg.Pixels.size()===3) +{midPt=lineutility.MidPointDouble(pt0,pt1,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,0,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),aboveMiddle,csFactor,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,2*csFactor,midPt,midPt,false);}else if(tg.Pixels.size()===4) +{midPt=lineutility.MidPointDouble(pt1,pt2,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,0,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),aboveMiddle,csFactor,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,2*csFactor,midPt,midPt,false);}else +{midPt=lineutility.MidPointDouble(pt1,pt2,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,-csFactor/2,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),aboveMiddle,csFactor/2,midPt,midPt,false);midPt=lineutility.MidPointDouble(pt2,pt3,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,-csFactor/2,midPt,midPt,false);} +break;case 151403:case 151404:case 151405:case 151406:case 151407:case 151408:if(tg.Pixels.size()===3) +{midPt=lineutility.MidPointDouble(pt0,pt1,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,0,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),aboveMiddle,csFactor,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,2*csFactor,midPt,midPt,false);}else +{midPt=lineutility.MidPointDouble(pt0,pt1,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,-csFactor/2,midPt,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),aboveMiddle,csFactor/2,midPt,midPt,false);midPt=lineutility.MidPointDouble(pt1,pt2,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,-csFactor/2,midPt,midPt,false);} +break;case 140601:case 140602:case 140603:case 140604:case 140605:midPt=lineutility.MidPointDouble(pt0,pt1,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),aboveMiddle,-csFactor/2,pt0,midPt,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),aboveMiddle,csFactor/2,pt0,pt1,false);break;case 140606:case 140607:midPt=lineutility.MidPointDouble(pt0,pt1,0);Modifier2.AddIntegralAreaModifier(tg,tg.get_N(),aboveMiddle,-csFactor/2,pt1,midPt,false);break;case 170800:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,-csFactor/2,ptCenter,ptCenter,false);break;case 151500:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label+" "+tg.get_Name(),aboveMiddle,0,ptCenter,ptCenter,false);break;case 151600:case 151700:Modifier2.AddIntegralAreaModifier(tg,label+" "+tg.get_Name(),aboveMiddle,0,ptCenter,ptCenter,false);break;case 141300:Modifier2.GetMBR(tg,ul,ur,lr,ll);Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,1.35*factor*csFactor,ll,lr,false);break;case 170100:case 170101:case 170200:case 170300:case 170500:case 170700:Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),aboveMiddle,0,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),aboveMiddle,-4*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),aboveMiddle,-5*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),aboveMiddle,-6*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),aboveMiddle,-7*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),aboveMiddle,-3*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),aboveMiddle,-2*csFactor,middleSegment,middleSegment+1,false);break;case 170400:case 170600:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralModifier(tg,label+" "+tg.get_Name(),aboveMiddle,0,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Max Alt: "+tg.get_H1(),aboveMiddle,-4*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Min Alt: "+tg.get_H(),aboveMiddle,-5*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Width: "+tg.get_H2(),aboveMiddle,-6*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"Name: "+tg.get_Name(),aboveMiddle,-7*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"DTG Start: "+tg.get_DTG(),aboveMiddle,-3*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,"DTG End: "+tg.get_DTG1(),aboveMiddle,-2*csFactor,middleSegment,middleSegment+1,false);break;case 171100:case 171200:case 171300:case 171400:case 171500:case 171900:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,area,-2.5,ptCenter,ptCenter,false,"");Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),area,-1.5,ptCenter,ptCenter,false,"T");Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),area,-0.5,ptCenter,ptCenter,false,"H");Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),area,0.5,ptCenter,ptCenter,false,"H1");Modifier2.AddIntegralAreaModifier(tg,"TIME FROM: "+tg.get_DTG(),area,1.5,ptCenter,ptCenter,false,"W");Modifier2.AddIntegralAreaModifier(tg,"TIME TO: "+tg.get_DTG1(),area,2.5,ptCenter,ptCenter,false,"W1");break;case 200300:label=getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,-1,pt0,pt0,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),aboveMiddle,csFactor,pt0,pt0,false);break;case 220107:case 220108:label=Modifier2.getRevDLabel(nCode);Modifier2.AddIntegralAreaModifier(tg,label,aboveMiddle,0,pt0,pt1,false);break;case 240101:Modifier2.AddIntegralAreaModifier(tg,label,area,-3*csFactor,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),area,-2*csFactor,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,"MIN ALT: "+tg.get_H(),area,-1*csFactor,ptCenter,ptCenter,false,"H");Modifier2.AddIntegralAreaModifier(tg,"MAX ALT: "+tg.get_H1(),area,0,ptCenter,ptCenter,false,"H1");Modifier2.AddIntegralAreaModifier(tg,tg.get_Location(),area,1*csFactor,ptCenter,ptCenter,false,"H2");Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),area,2*csFactor,ptCenter,ptCenter,false,"W");Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),area,3*csFactor,ptCenter,ptCenter,false,"W1");break;case 300100:label=Modifier2.getRevDLabel(nCode);pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);pt2=tg.Pixels.get(tg.Pixels.size()-1);pt3=tg.Pixels.get(tg.Pixels.size()-2);dist=lineutility.CalcDistanceDouble(pt0,pt1);dist2=lineutility.CalcDistanceDouble(pt2,pt3);stringWidth=(metrics.stringWidth(tg.get_Name()+" "+label));stringWidth2=(metrics.stringWidth(tg.get_DTG()));if(stringWidth2>stringWidth){stringWidth=stringWidth2;} +if(tg.Pixels.size()===2) +{pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);if(dist>3.5*stringWidth) +{pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);}}else +{var dist3=lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);} +if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);}} +break;case 260300:case 260400:label=Modifier2.getRevDLabel(nCode);pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(1);pt2=tg.Pixels.get(tg.Pixels.size()-1);pt3=tg.Pixels.get(tg.Pixels.size()-2);dist=lineutility.CalcDistanceDouble(pt0,pt1);dist2=lineutility.CalcDistanceDouble(pt2,pt3);stringWidth=(metrics.stringWidth(tg.get_Name()+" "+label));stringWidth2=(metrics.stringWidth(tg.get_DTG()));if(stringWidth2>stringWidth){stringWidth=stringWidth2;} +if(tg.Pixels.size()==2) +{pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);if(dist>3.5*stringWidth) +{pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);}}else +{var dist3=lineutility.CalcDistanceDouble(pt0,pt2);if(dist>stringWidth+5||dist>=dist2||dist3>stringWidth+5){pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);} +if(dist2>stringWidth+5||dist2>dist||dist3>stringWidth+5){pt0=tg.Pixels.get(tg.Pixels.size()-1);pt1=tg.Pixels.get(tg.Pixels.size()-2);pt1=lineutility.ExtendAlongLineDouble(pt0,pt1,stringWidth);Modifier2.AddModifier2(tg,label+" "+tg.get_Name(),aboveMiddle,-0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG(),aboveMiddle,0.7*csFactor,pt0,pt1,false);Modifier2.AddModifier2(tg,tg.get_DTG1(),aboveMiddle,1.7*csFactor,pt0,pt1,false);}} +break;case 260600:pt0=tg.Pixels.get(middleSegment);pt1=tg.Pixels.get(middleSegment+1);Modifier2.AddIntegralModifier(tg,label,aboveMiddle,0,middleSegment,middleSegment+1,true);Modifier2.AddIntegralModifier(tg,tg.get_DTG(),aboveEnd,1*csFactor,0,1,false);Modifier2.AddIntegralModifier(tg,tg.get_DTG1(),aboveEnd,2*csFactor,0,1,false);break;case 240701:Modifier2.AddIntegralModifier(tg,ap,aboveMiddle,-0.8*csFactor,middleSegment,middleSegment+1,false);break;case 240702:Modifier2.AddIntegralModifier(tg,ap,aboveMiddle,-0.8*csFactor,middleSegment,middleSegment+1,false);Modifier2.AddIntegralModifier(tg,label,aboveMiddle,0.8*csFactor,middleSegment,middleSegment+1,false);break;case 240703:Modifier2.AddIntegralModifier(tg,ap,aboveMiddle,-1*csFactor,0,1,false);Modifier2.AddIntegralModifier(tg,label,aboveMiddle,1*csFactor,0,1,false);Modifier2.AddIntegralModifier(tg,tg.get_T1(),aboveMiddle,2*csFactor,0,1,false);Modifier2.AddIntegralModifier(tg,v,aboveMiddle,3*csFactor,0,1,false);break;case 240801:Modifier2.AddIntegralAreaModifier(tg,ap,area,0,ptCenter,ptCenter,false);break;case 240802:case 240803:Modifier2.AddIntegralAreaModifier(tg,ap,area,0,pt0,pt0,false);break;case 240804:Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),area,0,ptCenter,ptCenter,false);break;case 240806:case 240807:Modifier2.AddIntegralAreaModifier(tg,ap,area,-csFactor,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,label,area,0,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),area,1*csFactor,ptCenter,ptCenter,false,"W+W1");break;case 242301:case 242304:Modifier2.AddIntegralAreaModifier(tg,label,area,0,ptCenter,ptCenter,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_Name(),area,1*csFactor,ptCenter,ptCenter,false);Modifier2.GetMBR(tg,ul,ur,lr,ll);var ptLeft=ul;var ptRight=ur;if(tg.get_Client().equalsIgnoreCase("ge")){ptLeft.x-=font.getSize()/2;ptRight.x-=font.getSize()/2;} +Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),toEnd,0.5*csFactor,ptLeft,ptRight,false,"W");Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG1(),toEnd,1.5*csFactor,ptLeft,ptRight,false,"W1");break;case 242302:case 242303:case 242305:case 242306:case 140500:break;case 290100:Modifier2.AddIntegralModifier(tg,tg.get_Name(),aboveMiddle,csFactor,middleSegment,middleSegment+1,false);break;case 290600:break;case 270800:Modifier2.GetMBR(tg,ul,ur,lr,ll);Modifier2.AddIntegralAreaModifier(tg,tg.get_H(),aboveMiddle,-1.5*factor*csFactor,ul,ur,false);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG(),aboveMiddle,1.5*factor*csFactor,ll,lr,false);Modifier2.areasWithENY(tg,g2d);break;case 271300:if(tg.Pixels.get(1).y>tg.Pixels.get(0).y){pt0=tg.Pixels.get(1);pt1=tg.Pixels.get(3);pt2=tg.Pixels.get(0);pt3=tg.Pixels.get(2);}else{pt0=tg.Pixels.get(0);pt1=tg.Pixels.get(2);pt2=tg.Pixels.get(1);pt3=tg.Pixels.get(3);} +pt2=lineutility.ExtendAlongLineDouble2(pt0,pt2,-20);pt3=lineutility.ExtendAlongLineDouble2(pt1,pt3,-20);Modifier2.AddIntegralAreaModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),aboveMiddle,0,pt2,pt3,false);break;case 330100:case 330200:var convoyBlankString=Modifier2.blankString(metrics,35);Modifier2.AddIntegralModifier(tg,v+convoyBlankString+tg.get_H(),aboveMiddle,0,0,1,false);Modifier2.AddIntegralModifier(tg,tg.get_DTG()+dash+tg.get_DTG1(),aboveMiddle,1.2*csFactor,0,1,false);break;default:Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.Modifier2._className,"AddModifier",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddModifiersGeo2",exc));}else{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.Modifier2._className="Modifier2";armyc2.c2sd.JavaTacticalRenderer.Modifier2.toEnd=1;armyc2.c2sd.JavaTacticalRenderer.Modifier2.aboveMiddle=2;armyc2.c2sd.JavaTacticalRenderer.Modifier2.area=3;armyc2.c2sd.JavaTacticalRenderer.Modifier2.screen=4;armyc2.c2sd.JavaTacticalRenderer.Modifier2.aboveEnd=5;armyc2.c2sd.JavaTacticalRenderer.Modifier2.fillAlphaCanObscureText=50;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.P1=function(){this.start=0;this.end_Renamed=0;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.TGLight=function(){this.LatLongs=null;this.Pixels=null;this.modifiers=null;this.tp=null;this.maskOff=false;this.font=null;this.lineType=0;this.lineStyle=0;this.lineColor=null;this.fillStyle=0;this.fillColor=null;this.fontBackColor=null;this.textColor=null;this.lineThickness=0;this.t="";this.client="";this.t1="";this.h="";this.h1="";this.y="";this.n="ENY";this.h2="";this.w="";this.w1="";this.affiliation=null;this.echelon=null;this.echelonSymbol="";this.symbolId=null;this.status=null;this.visibleModifiers=false;this.visibleLabels=false;this._SymbologyStandard=0;this._useLineInterpolation=false;this.fontBackColor=armyc2.c2sd.renderer.utilities.Color.WHITE;this._useDashArray=false;this._useHatchFill=false;this._wasClipped=false;this._HideOptionalLabels=false;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_WasClipped=function(){return this._wasClipped;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_WasClipped=function(value){this._wasClipped=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LatLongs=function(){return this.LatLongs;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LatLongs=function(value){this.LatLongs=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Pixels=function(){return this.Pixels;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Pixels=function(value){this.Pixels=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Modifiers=function(){return this.modifiers;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Modifiers=function(value){this.modifiers=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_TexturePaint=function(value){this.tp=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_TexturePaint=function(){return this.tp;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Font=function(value){this.font=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Font=function(){return this.font;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineType=function(value){this.lineType=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineType=function(){return this.lineType;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineStyle=function(value){this.lineStyle=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineStyle=function(){return this.lineStyle;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineColor=function(){return this.lineColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineColor=function(value){this.lineColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FillStyle=function(){return this.fillStyle;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Fillstyle=function(value){this.fillStyle=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FillColor=function(){return this.fillColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_FillColor=function(value){this.fillColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_FontBackColor=function(){return this.fontBackColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_FontBackColor=function(value){this.fontBackColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_TextColor=function(){return this.textColor;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_TextColor=function(value){this.textColor=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_LineThickness=function(){return this.lineThickness;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_LineThickness=function(value){this.lineThickness=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Name=function(){if(this.visibleModifiers) +return this.t;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Client=function(){return this.client;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_client=function(value){this.client=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Name=function(value){this.t=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_T1=function(){if(this.visibleModifiers) +return this.t1;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_T1=function(value){this.t1=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H=function(){if(this.visibleModifiers||this.lineType===24311000) +return this.h;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H=function(value){this.h=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Location=function(){if(this.visibleModifiers) +return this.y;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Location=function(value){this.y=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H1=function(){if(this.visibleModifiers) +return this.h1;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H1=function(value){this.h1=value.toString();};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_N=function(){return this.n;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_N=function(value){this.n=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_H2=function(){if(this.visibleModifiers||this.lineType===24311000) +return this.h2;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_H2=function(value){this.h2=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_DTG=function(){if(this.visibleModifiers) +return this.w;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_DTG=function(value){this.w=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_DTG1=function(){if(this.visibleModifiers) +return this.w1;else +return"";};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_DTG1=function(value){this.w1=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Affiliation=function(){return this.affiliation;};this.set_Affiliation=function(value){this.affiliation=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Echelon=function(){return this.echelon;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Echelon=function(value){this.echelon=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_EchelonSymbol=function(){return this.echelonSymbol;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_EcheclonSymbol=function(value){this.echelonSymbol=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_SymbolId=function(){return this.symbolId;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_Status=function(){return this.status;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_Status=function(value){this.status=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_SymbolId=function(value){try{this.symbolId=value;var letter;if(this.symbolId.length===15) +{this.status=this.symbolId.substring(3,4);if(this.status.equals("A")&&!value.equalsIgnoreCase("BS_AREA--------")){this.lineStyle=1;} +this.affiliation=this.symbolId.substring(1,2);this.echelon=this.symbolId.substring(11,12);} +else if(this.symbolId.length>=20) +{var setA=this.symbolId.substring(0,10);var symbolSet=setA.substring(4,6);var setB=this.symbolId.substring(10);var entityCode=setB.substring(0,6);var code=Integer.parseInt(entityCode);var nCode=code.valueOf();if(symbolSet.equalsIgnoreCase("25")) +{this.affiliation=setA.substring(2,4);if(this.affiliation.equalsIgnoreCase("03")){this.affiliation="F";}else if(this.affiliation.equalsIgnoreCase("06")){this.affiliation="H";} +switch(nCode) +{case 140103:case 140104:case 150103:case 150104:case 150501:case 150502:case 150503:case 140606:case 140607:case 151802:case 200300:this.affiliation="H";break;default:break;} +this.status=setA.substring(6,7);if(this.status.equalsIgnoreCase("0")){this.status="P";}else if(this.status.equalsIgnoreCase("1")){this.status="A";} +if(this.status.equalsIgnoreCase("A")){this.lineStyle=1;} +this.echelon=setA.substring(8);if(this.echelon.equalsIgnoreCase("11")){this.echelon="A";}else if(this.echelon.equalsIgnoreCase("12")){this.echelon="B";}else if(this.echelon.equalsIgnoreCase("13")){this.echelon="C";}else if(this.echelon.equalsIgnoreCase("14")){this.echelon="D";}else if(this.echelon.equalsIgnoreCase("15")){this.echelon="E";}else if(this.echelon.equalsIgnoreCase("16")){this.echelon="F";}else if(this.echelon.equalsIgnoreCase("17")){this.echelon="G";}else if(this.echelon.equalsIgnoreCase("18")){this.echelon="H";}else if(this.echelon.equalsIgnoreCase("21")){this.echelon="I";}else if(this.echelon.equalsIgnoreCase("22")){this.echelon="J";}else if(this.echelon.equalsIgnoreCase("23")){this.echelon="K";}else if(this.echelon.equalsIgnoreCase("24")){this.echelon="L";}else if(this.echelon.equalsIgnoreCase("M")){this.echelon="M";}} +else return;} +if(this.echelon.equals("M")) +this.echelonSymbol="XXXXXX";else if(this.echelon.equals("L")) +this.echelonSymbol="XXXXX";else if(this.echelon.equals("K")) +this.echelonSymbol="XXXX";else if(this.echelon.equals("J")) +this.echelonSymbol="XXX";else if(this.echelon.equals("I")) +this.echelonSymbol="XX";else if(this.echelon.equals("H")) +this.echelonSymbol="X";else if(this.echelon.equals("G")) +this.echelonSymbol="III";else if(this.echelon.equals("F")) +this.echelonSymbol="II";else if(this.echelon.equals("E")) +this.echelonSymbol="I";else if(this.echelon.equals("D")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter)+(letter)+(letter);}else if(this.echelon.equals("C")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter)+(letter);}else if(this.echelon.equals("B")){letter=String.fromCharCode(9679);this.echelonSymbol=(letter);}else if(this.echelon.equals("A")){letter=String.fromCharCode(216);this.echelonSymbol=(letter);}} +catch(exc) +{if(Clazz.instanceOf(exc)) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.TGLight._className,"set_SymbolId",exc);} +else +{throw exc;}}};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_VisibleModifiers=function(value){this.visibleModifiers=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_VisibleModifiers=function(){return this.visibleModifiers;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_VisibleLabels=function(value){this.visibleLabels=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_VisibleLabels=function(){return this.visibleLabels;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.setSymbologyStandard=function(standard){this._SymbologyStandard=standard;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.getSymbologyStandard=function(){return this._SymbologyStandard;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_UseLineInterpolation=function(){return this._useLineInterpolation;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_UseLineInterpolation=function(value){this._useLineInterpolation=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_UseDashArray=function(){return this._useDashArray;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_UseDashArray=function(value){this._useDashArray=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_UseHatchFill=function(){return this._useHatchFill;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_UseHatchFill=function(value){this._useHatchFill=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.get_HideOptionalLabels=function(){return this._HideOptionalLabels;};armyc2.c2sd.JavaTacticalRenderer.TGLight.prototype.set_HideOptionalLabels=function(value){this._HideOptionalLabels=value;};armyc2.c2sd.JavaTacticalRenderer.TGLight._className="TGLight";var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaTacticalRenderer=armyc2.c2sd.JavaTacticalRenderer||{};armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility={GetPartitions:function(segments,partitions){try{var j=0;var nextSegment=false;var p1=new armyc2.c2sd.JavaTacticalRenderer.P1();if(segments[0]===false){return 0;} +if(partitions!==null){partitions.clear();}else{return 0;} +p1.start=0;for(j=0;j0){returnValue=channelPixels.length;}else{returnValue=0;} +if(lineCount>0){channelPixels[lineCount-1]=5;} +goodUpperPixels=null;goodLowerPixels=null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility._className,"DrawGoodChannel2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside DrawGoodChannel2",exc));}else{throw exc;}} +return returnValue;},DrawSegments:function(pixels,partitions,linetype,channelWidth,shapes,channelPoints,distanceToChannelPoint,rev){try{var j=0;var n=0;for(j=0;j=21) +return pixels;else if(lr.y-ul.y>=21) +return pixels;var x0=pts[0].x,y0=pts[0].y,x1=pts[1].x,y1=pts[1].y;if(x0<=x1) +x1=x0+21;else +x1=x0-21;y1=y0;var pt0=new armyc2.c2sd.JavaLineArray.POINT2(x0,y0),pt1=new armyc2.c2sd.JavaLineArray.POINT2(x1,y1);pixels2=new java.util.ArrayList();pixels2.add(pt0);pixels2.add(pt1);} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility._className,"DrawSegments",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getLCPixels",exc));}else{throw exc;}} +return pixels2;},DrawChannel:function(pixels,linetype,tg,shapes,channelPoints,rev){try{pixels=this.getLCPixels(tg,pixels);armyc2.c2sd.JavaLineArray.lineutility.adjustCATKBYFIREControlPoint(linetype,pixels,45);if(tg.get_LineType()===22123000&&tg.get_Affiliation().equalsIgnoreCase("H")) +linetype=22123002;var j=0;var pixels2=Clazz.newArray(pixels.size()*2,0);for(j=0;j15) +{var TacticalLines=new armyc2.c2sd.JavaLineArray.TacticalLines();var setA=symbolID.substring(0,10);var setB=symbolID.substring(10);var entityCode=setB.substring(0,6);var entityCode2=Integer.parseInt(entityCode);var nEntityCode=entityCode2.valueOf();var symbolSet=setA.substring(4,6);var symbolSet2=Integer.parseInt(symbolSet);var nSymbolSet=symbolSet2.valueOf();switch(nSymbolSet) +{case 25:if(nEntityCode===141400) +return TacticalLines.BRDGHD;else if(nEntityCode===141500) +return TacticalLines.HOLD;break;case 45:case 46:return armyc2.c2sd.JavaTacticalRenderer.clsMETOC.getWeatherLinetype(symbolSet,entityCode);}} +if(symbolID===null) +return-1;if(symbolID.length!==15) +return-1;var strLine=symbolID;var str1;var str2;var str3;var str4;var str5;var str6;var str7;var str10;var c0=strLine.substring(0,1);var c1=strLine.substring(1,2);var c2=strLine.substring(2,3);str1=strLine.substring(4,5);str2=strLine.substring(4,6);str3=strLine.substring(4,7);str4=strLine.substring(4,8);str5=strLine.substring(4,9);str6=strLine.substring(3,9);str7=strLine.substring(3,10);str10=strLine.substring(3,13);if(str3.equals("SLH")&&c0.equals("G")&&c2.equals("G")) +return 22612000;if(str3.equals("SLB")&&c0.equals("G")&&c2.equals("G")) +return 22623000;if(c0.equalsIgnoreCase("W")===false) +return-1;if(c0.equals("W")&&c1.equals("A")){if(str7.equals("DPXSQ--")){return 31143000;} +if(str7.equals("DPFC---")){return 31131000;} +if(str7.equals("DPFC-FG")){return 31131200;} +if(str7.equals("DPFC-FY")){return 31131300;} +if(str7.equals("DPFW-FG")){return 31132200;} +if(str7.equals("DPFW-FY")){return 31132300;} +if(str7.equals("DPFOU--")){return 31133100;} +if(str7.equals("DPFO-FY")){return 31133200;} +if(str7.equals("DPFSU--")){return 31134100;} +if(str7.equals("DPFS-FG")){return 31134200;} +if(str7.equals("DPFS-FY")){return 31134300;} +if(str7.equals("DPXIL--")){return 31144000;} +if(str7.equals("DPXSH--")){return 31145000;} +if(str7.equals("DPXITCZ")){return 31146000;} +if(str7.equals("DPXCV--")){return 31147000;} +if(str7.equals("DPXITD-")){return 31148000;} +if(str7.equals("DWJ----")){return 31430000;} +if(str7.equals("DWS----")){return 31440000;} +if(str7.equals("DBAIF--")){return 31710000;} +if(str7.equals("DBAMV--")){return 31720000;} +if(str7.equals("DBATB--")){return 31730000;} +if(str7.equals("DBAI---")){return 31740000;} +if(str7.equals("DBALPNC")){return 31750000;} +if(str7.equals("DBALPC-")){return 31751000;} +if(str7.equals("DBAFP--")){return 31760000;} +if(str7.equals("DBAT---")){return 31770000;} +if(str7.equals("DBAFG--")){return 31780000;} +if(str7.equals("DBAD---")){return 31790000;} +if(str7.equals("DBAFF--")){return 317100000;} +if(str7.equals("DIPIB--")){return 31810000;} +if(str7.equals("DIPCO--")){return 31820000;} +if(str7.equals("DIPIS--")){return 31830000;} +if(str7.equals("DIPIT--")){return 31840000;} +if(str7.equals("DIPID--")){return 31850000;} +if(str7.equals("DIPTH--")){return 31860000;} +if(str7.equals("DIPFF--")){return 31870000;} +if(str3.equals("PXR")){return 31142000;} +if(str3.equals("PXT")){return 31141000;} +if(str4.equals("PFCU")){return 31131100;} +if(str3.equals("PFO")){return 31133000;} +if(str3.equals("PFS")){return 31134000;} +if(str4.equals("PFWU")){return 31132100;} +if(str3.equals("PFW")){return 31132000;} +if(str3.equals("PFC")){return 31131000;}} +if(c0.equals("W")&&c1.equals("O")){if(str10.equals("DHCF----L-")){return 32225100;} +if(str10.equals("DHCF-----A")){return 32225200;} +if(str10.equals("DHPBA---L-")){return 32231400;} +if(str10.equals("DHPBA----A")){return 32231500;} +if(str10.equals("DHPMO---L-")){return 32233400;} +if(str10.equals("DHPMO----A")){return 32233500;}} +if(c0.equals("W")&&c1.equals("O")){if(str7.equals("DIDID--")){return 32134000;} +if(str7.equals("DILOV--")){return 32151000;} +if(str7.equals("DILUC--")){return 32152000;} +if(str7.equals("DILOR--")){return 32153000;} +if(str7.equals("DILIEO-")){return 32154000;} +if(str7.equals("DILIEE-")){return 32155000;} +if(str7.equals("DILIER-")){return 32156000;} +if(str7.equals("DIOC---")){return 32161000;} +if(str7.equals("DIOCS--")){return 32162000;} +if(str7.equals("DIOL---")){return 32163000;} +if(str7.equals("DIOLF--")){return 32164000;} +if(str7.equals("DHDDL--")){return 32212000;} +if(str7.equals("DHDDC--")){return 32213000;} +if(str7.equals("DHDDA--")){return 32214000;} +if(str7.equals("DHCC---")){return 32221000;} +if(str7.equals("DHCI---")){return 32222000;} +if(str7.equals("DHCB---")){return 32223000;} +if(str7.equals("DHCW---")){return 32224000;} +if(str7.equals("DHPBP--")){return 32231700;} +if(str7.equals("-HPFF--")){return 32232400;} +if(str7.equals("-HHDR--")){return 322510000;} +if(str7.equals("DHPMD--")){return 32233100;} +if(str7.equals("DHPMRA-")){return 32233600;} +if(str7.equals("DHPMRB-")){return 32233700;} +if(str7.equals("DHPSPA-")){return 32234100;} +if(str7.equals("DHPSPB-")){return 32234200;} +if(str7.equals("DHPSPS-")){return 32234300;} +if(str7.equals("DHABP--")){return 32244200;} +if(str7.equals("DHALLA-")){return 32246000;} +if(str7.equals("DHHD---")){return 32253000;} +if(str7.equals("DHHDF--")){return 32254200;} +if(str7.equals("DHHDK--")){return 32255200;} +if(str7.equals("DHHDB--")){return 32259000;} +if(str7.equals("DHHDD--")){return 322512000;} +if(str7.equals("DTCCCFE")){return 32272000;} +if(str7.equals("DTCCCFF")){return 32273000;} +if(str7.equals("DL-RA--")){return 32530000;} +if(str7.equals("DMPA---")){return 32680000;} +if(str7.equals("DL-TA--")){return 32550000;} +if(str7.equals("DOBVA--")){return 32311000;} +if(str7.equals("DOBVB--")){return 32312000;} +if(str7.equals("DOBVC--")){return 32313000;} +if(str7.equals("DOBVD--")){return 32314000;} +if(str7.equals("DOBVE--")){return 32315000;} +if(str7.equals("DOBVF--")){return 32316000;} +if(str7.equals("DOBVG--")){return 32317000;} +if(str7.equals("DOBVH--")){return 32318000;} +if(str7.equals("DOBVI--")){return 32319000;} +if(str7.equals("DBSF---")){return 32321000;} +if(str7.equals("DBSG---")){return 32322000;} +if(str7.equals("DBSM---")){return 32323000;} +if(str7.equals("DBST---")){return 32324000;} +if(str7.equals("DGMSR--")){return 32411100;} +if(str7.equals("DGMSC--")){return 32411200;} +if(str7.equals("DGMSSVS")){return 32411300;} +if(str7.equals("DGMSSC-")){return 32411400;} +if(str7.equals("DGMSSM-")){return 32411500;} +if(str7.equals("DGMSSF-")){return 32411600;} +if(str7.equals("DGMSSVF")){return 32411700;} +if(str7.equals("DGMSIVF")){return 32411800;} +if(str7.equals("DGMSIF-")){return 32411900;} +if(str7.equals("DGMSIM-")){return 324111000;} +if(str7.equals("DGMSIC-")){return 324111100;} +if(str7.equals("DGMSB--")){return 324111200;} +if(str7.equals("DGMS-CO")){return 324111300;} +if(str7.equals("DGMS-PH")){return 324111400;} +if(str7.equals("DGMS-SH")){return 324111500;} +if(str7.equals("DGML---")){return 324111600;} +if(str7.equals("DGMN---")){return 324111700;} +if(str7.equals("DGMRS--")){return 32412100;} +if(str7.equals("DGMRM--")){return 32412200;} +if(str7.equals("DGMRR--")){return 32412300;} +if(str7.equals("DGMCL--")){return 32413100;} +if(str7.equals("DGMCM--")){return 32413200;} +if(str7.equals("DGMCH--")){return 32413300;} +if(str7.equals("DGMIBA-")){return 32414100;} +if(str7.equals("DGMIBB-")){return 32414200;} +if(str7.equals("DGMIBC-")){return 32414300;} +if(str7.equals("DGMIBD-")){return 32414400;} +if(str7.equals("DGMIBE-")){return 32414500;} +if(str7.equals("DGMBCA-")){return 32415100;} +if(str7.equals("DGMBCB-")){return 32415200;} +if(str7.equals("DGMBCC-")){return 32415300;} +if(str7.equals("DGMBTA-")){return 32416100;} +if(str7.equals("DGMBTB-")){return 32416200;} +if(str7.equals("DGMBTC-")){return 32416300;} +if(str7.equals("DGMBTD-")){return 32416400;} +if(str7.equals("DGMBTE-")){return 32416500;} +if(str7.equals("DGMBTF-")){return 32416600;} +if(str7.equals("DGMBTG-")){return 32416700;} +if(str7.equals("DGMBTH-")){return 32416800;} +if(str7.equals("DGMBTI-")){return 32416900;} +if(str7.equals("DL-SA--")){return 32540000;} +if(str7.equals("DMOA---")){return 32670000;} +if(str7.equals("DMCC---")){return 32620000;} +if(str7.equals("DMCA---")){return 32610000;} +if(str7.equals("DL-ML--")){return 32510000;} +if(str7.equals("DL-MA--")){return 32520000;} +if(str7.equals("DMCD---")){return 32630000;} +if(str7.equals("DL-O---")){return 32560000;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"isWeather",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside isWeather",exc));}else{throw exc;}} +return-1;},SetMeTOCProperties:function(tg){try{var symbolId=tg.get_SymbolId();switch(tg.get_LineType()){case 31141000:if(symbolId.length>=20) +{var setB=symbolId.substring(10);var entityCode=setB.substring(0,6);if(entityCode.equalsIgnoreCase("110401")) +{tg.set_LineStyle(2);}} +tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;case 32416200:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(127,255,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(127,255,0));break;case 32416800:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,80,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,80,0));break;case 32416900:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,48,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,48,0));break;case 32414100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(0,0,255));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(0,0,255));break;case 32416700:case 32414400:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,127,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,127,0));break;case 32415300:case 32414500:case 32413300:case 32412300:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,0,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,0,0));break;case 32416500:case 32415200:case 32414300:case 32413200:case 32412200:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,255,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,255,0));break;case 32416100:case 32415100:case 32414200:case 32413100:case 32412100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(0,255,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(0,255,0));break;case 324111700:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(230,230,230));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(230,230,230));break;case 324111600:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(220,220,220));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(220,220,220));break;case 324111500:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,220,220));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,220,220));break;case 324111400:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,190,190));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,190,190));break;case 324111300:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,150,150));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,150,150));break;case 324111200:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,0,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,0,0));break;case 324111100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(200,255,105));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(200,255,105));break;case 324111000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(0,255,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(0,255,0));break;case 32411900:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(25,255,230));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(25,255,230));break;case 32411800:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(0,215,255));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(0,215,255));break;case 32411700:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,255,220));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,255,220));break;case 32411600:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,255,140));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,255,140));break;case 32411500:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,235,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,235,0));break;case 32411400:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,215,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,215,0));break;case 32416600:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,207,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,207,0));break;case 32411300:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,180,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,180,0));break;case 32411200:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(100,130,255));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(100,130,255));break;case 32411100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));break;case 32311000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(26,153,55));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(26,153,55));break;case 32312000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(26,204,77));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(26,204,77));break;case 32416300:case 32313000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(128,255,51));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(128,255,51));break;case 32416400:case 32314000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(204,255,26));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(204,255,26));break;case 32315000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,255,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,255,0));break;case 32316000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,204,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,204,0));break;case 32317000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,128,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,128,0));break;case 32318000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(255,77,0));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,77,0));break;case 32319000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.RED);break;case 32630000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);tg.set_LineThickness(4);break;case 32560000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.ORANGE);break;case 32510000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.MAGENTA);tg.set_LineStyle(1);tg.set_LineThickness(1);break;case 32520000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.MAGENTA);tg.set_LineStyle(1);break;case 32244200:case 32620000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);tg.set_LineStyle(2);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.BLUE);break;case 322512000:case 32253000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);tg.set_LineStyle(2);tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(0,191,255));break;case 32233500:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(210,180,140));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(210,180,140));break;case 32233400:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);tg.set_LineThickness(4);break;case 32233100:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(205,153,63));tg.set_LineStyle(1);break;case 32225200:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(173,255,47));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(173,255,47));break;case 32225100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(173,255,47));break;case 32530000:case 32550000:case 32231400:case 32231500:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.MAGENTA);break;case 32680000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.GRAY);break;case 32224000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.WHITE);tg.set_LineStyle(1);break;case 32232400:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(245,245,220));tg.set_LineStyle(1);tg.set_LineThickness(3);break;case 32540000:case 32670000:case 32254200:case 32255200:case 32323000:case 32324000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(245,245,220));break;case 32223000:tg.set_LineThickness(5);tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(210,180,140));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,245,238));break;case 32214000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLUE);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.WHITE);break;case 31147000:case 31146000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.ORANGE);break;case 31133200:case 31133000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));break;case 31133100:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));break;case 31132300:case 31132200:case 31132000:tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.RED);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);break;case 31132100:case 31710000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);break;case 31131200:case 31131300:case 31131000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLUE);tg.set_FillColor(armyc2.c2sd.renderer.utilities.Color.BLUE);break;case 31131100:case 31720000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLUE);break;case 31730000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLUE);tg.set_LineStyle(2);break;case 32610000:case 32610001:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.MAGENTA);break;case 32222000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(210,180,140));tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(210,180,140));break;case 32234300:case 32234301:case 32273000:case 32273001:case 32272000:case 32272001:case 32234100:case 32234101:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);break;case 32321000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(211,211,211));tg.set_FillColor(null);break;case 32322000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(111,111,111));tg.set_FillColor(null);break;case 32259000:tg.set_LineStyle(1);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);tg.set_LineThickness(1);break;case 32234200:case 32234201:tg.set_LineStyle(1);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);break;case 32212000:case 32212001:case 32213000:case 32213001:case 32221000:case 32221001:case 32231700:case 32231701:tg.set_LineThickness(1);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GRAY);break;case 31760000:case 31430000:case 31430001:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);break;case 31770000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);tg.set_LineStyle(3);break;case 32233700:case 32233701:case 32155000:case 32155001:tg.set_LineStyle(1);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;case 31850000:case 31850001:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GREEN);break;case 32153000:case 32152000:case 32151000:case 31143000:case 31142000:case 32163000:case 32163001:case 32164000:case 32164001:case 32246000:case 31440000:case 31440001:case 32161000:case 32161001:case 32162000:case 32162001:case 31810000:case 31810001:case 31820000:case 31820001:case 32154000:case 32154001:case 32156000:case 32156001:case 322510000:case 32134000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;case 31144000:tg.set_LineStyle(4);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;case 31145000:tg.set_LineStyle(3);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;case 31860000:case 31860001:case 31830000:case 31830001:tg.set_LineStyle(1);tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.RED);break;case 31840000:case 31840001:tg.set_LineStyle(1);tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(160,32,240));break;case 31790000:case 31740000:tg.set_LineColor(new armyc2.c2sd.renderer.utilities.Color(165,42,42));break;case 31750000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GREEN);break;case 31751000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.GREEN);tg.set_LineStyle(3);break;case 31780000:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.YELLOW);break;case 32233600:case 32233601:tg.set_LineColor(armyc2.c2sd.renderer.utilities.Color.BLACK);break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"SetMeTOCProperties",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SetMeTOCProperties",exc));}else{throw exc;}}},ExtrapolatePointFromCurve:function(splinePoints,pt){var pt2=null;try{var dx=0;var dy=0;var m=1;var y=0;var x=pt.x;var j=0;for(j=0;j=x){dx=splinePoints.get(j+1).x-splinePoints.get(j).x;dy=splinePoints.get(j+1).y-splinePoints.get(j).y;m=dy/dx;y=splinePoints.get(j).y+(x-splinePoints.get(j).x)*m;pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);return pt2;} +if(splinePoints.get(j).x>=x&&splinePoints.get(j+1).x<=x){dx=splinePoints.get(j+1).x-splinePoints.get(j).x;dy=splinePoints.get(j+1).y-splinePoints.get(j).y;m=dy/dx;y=splinePoints.get(j).y+(x-splinePoints.get(j).x)*m;pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y);return pt2;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"ExtrapolatePointFromCurve",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ExtrapolatePointfromCurve",exc));}else{throw exc;}} +return pt2;},GetMeTOCShape:function(tg,shapes,rev){try{if(shapes===null) +return;var lineObject=null;var lineObject2=null;var splinePoints=new java.util.ArrayList();var splinePoints2=new java.util.ArrayList();var d=0;var j=0;var k=0;var l=0;var shape=null;var ptLast=tg.Pixels.get(tg.Pixels.size()-1);var twoSplines=null;var upperSpline=null;var lowerSpline=null;var originalPixels=null;var pixels=null;originalPixels=null;var partitions=null;armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetMeTOCProperties(tg);switch(tg.get_LineType()){case 31134000:case 31134100:case 31134200:case 31134300:case 31132300:case 31132200:case 31132000:case 31132100:case 31131100:case 31131000:case 31131200:case 31131300:case 31133000:case 31133100:case 31133200:case 31141000:case 31144000:case 31145000:case 31142000:case 31143000:case 31146000:case 31147000:case 31148000:case 31710000:case 31720000:case 31730000:case 31740000:case 31750000:case 31751000:case 31760000:case 31770000:case 31780000:case 31790000:case 317100000:case 31870000:case 32151000:case 32152000:case 32153000:case 32214000:case 32222000:case 32223000:case 32224000:case 32232400:case 32540000:case 32670000:case 32254200:case 32255200:case 32323000:case 32324000:case 32231500:case 32231400:case 32680000:case 32550000:case 32530000:case 322510000:case 32134000:case 32225200:case 32225100:case 32233100:case 32233400:case 32233500:case 32244200:case 32253000:case 32259000:case 322512000:case 32321000:case 32322000:case 32510000:case 32520000:case 32560000:case 32620000:case 32630000:case 32311000:case 32312000:case 32313000:case 32314000:case 32315000:case 32316000:case 32317000:case 32318000:case 32319000:case 32411100:case 32411200:case 32411300:case 32411400:case 32411500:case 32411600:case 32411700:case 32411800:case 32411900:case 324111000:case 324111100:case 324111200:case 324111300:case 324111400:case 324111500:case 324111600:case 324111700:case 32412100:case 32412200:case 32412300:case 32413100:case 32413200:case 32413300:case 32414100:case 32414200:case 32414300:case 32414400:case 32414500:case 32415100:case 32415200:case 32415300:case 32416100:case 32416200:case 32416300:case 32416400:case 32416500:case 32416600:case 32416700:case 32416800:case 32416900:armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(tg.get_LineType(),tg.Pixels,shapes,null,rev);break;case 31810000:case 31810001:case 31820000:case 31820001:case 31830000:case 31830001:case 31840000:case 31840001:case 31850000:case 31850001:case 31860000:case 31860001:case 32154000:case 32154001:case 32155000:case 32155001:case 32161000:case 32161001:case 32212000:case 32212001:case 32213000:case 32213001:case 32221000:case 32221001:case 32231700:case 32231701:case 32233600:case 32233601:case 32233700:case 32233701:case 32234100:case 32234101:case 32234200:case 32234201:case 32234300:case 32234301:case 32272000:case 32273000:case 32272001:case 32273001:case 32610000:case 32610001:case 31430000:case 31440000:case 31430001:case 31440001:lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);break;case 22612001:case 22623001:if(tg.get_FillColor()!==null&&tg.get_FillColor().getAlpha()>1){lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL);shape.setShape(lineObject2);shapes.add(shape);splinePoints.clear();} +lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetShapeProperties(tg,shapes,null);return;case 22612000:case 22623000:lineObject2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawSplines(tg,splinePoints);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());if(tg.get_FillColor()!==null&&tg.get_FillColor().getAlpha()>1){if(splinePoints!==null&&splinePoints.size()>0){shape.moveTo(splinePoints.get(0));for(j=1;jj) +array2=splinePoints2Arrays.get(j);else +break;if(splinePointsArrays.size()>=splinePoints2Arrays.size()){for(k=0;kk) +pt=array.get(k);else +break;pt2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.ExtrapolatePointFromCurve(array2,pt);if(pt2!==null){lineObject.moveTo(pt.x,pt.y);lineObject.lineTo(pt2.x,pt2.y);}}}else{for(k=0;kj) +array2=splinePoints2Arrays.get(j);else +break;if(splinePointsArrays.size()>=splinePoints2Arrays.size()){for(k=0;kk) +pt=array.get(k);else +break;pt2=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.ExtrapolatePointFromCurve(array2,pt);if(pt2!==null){lineObject.moveTo(pt.x,pt.y);lineObject.lineTo(pt2.x,pt2.y);}}}else{for(k=0;k0) +lineObject2.moveTo(splinePoints.get(0).x,splinePoints.get(0).y);else{lineObject2.moveTo(tg.Pixels.get(0).x,tg.Pixels.get(0).y);for(j=0;j=j-1) +lineObject2.lineTo(splinePoints.get(j).x,splinePoints.get(j).y);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shapes.add(shape);lineObject2=new armyc2.c2sd.graphics2d.GeneralPath();lineObject2.moveTo(splinePoints.get(n).x,splinePoints.get(n).y);for(j=n+1;j=j-1) +lineObject2.lineTo(splinePoints.get(j).x,splinePoints.get(j).y);} +shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shape.set_Style(1);shapes.add(shape);break;default:break;} +if(tg.get_LineType()!==32163000&&tg.get_LineType()!==32163001&&tg.get_LineType()!==32164000&&tg.get_LineType()!==32164001&&tg.get_LineType()!==32156000){if(splinePoints!==null&&splinePoints.size()>0){lineObject2=new armyc2.c2sd.graphics2d.GeneralPath();lineObject2.moveTo(splinePoints.get(splinePoints.size()-1).x,splinePoints.get(splinePoints.size()-1).y);lineObject2.lineTo(ptLast.x,ptLast.y);shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setShape(lineObject2);shape.set_Style(0);shapes.add(shape);}} +armyc2.c2sd.JavaTacticalRenderer.clsMETOC.SetShapeProperties(tg,shapes,null);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"GetMeTOCShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetMeTOCShape",exc));}else{throw exc;}}},GetImageFile:function(tg){var fileName="";try{switch(tg.get_LineType()){case 32232400:fileName="visualAssets/Weirs.png";break;case 32540000:fileName="visualAssets/SweptArea.png";break;case 32670000:fileName="visualAssets/OilRigField.png";break;case 32254200:fileName="visualAssets/FoulGround.png";break;case 32255200:fileName="visualAssets/Kelp.png";break;case 32324000:fileName="visualAssets/BeachSlopeSteep.png";break;case 32223000:fileName="visualAssets/BeigeStipple.png";break;case 32323000:fileName="visualAssets/BeachSlopeModerate.png";break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsMETOC._className,"GetImageFile",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetImageFile",exc));}else{throw exc;}} +return fileName;},SetShapeProperties:function(tg,shapes,bi){try{if(shapes===null){return;} +switch(tg.get_LineType()){case 32214000:return;default:break;} +var j=0;var shape=null;var stroke=null;var inFile=null;var bi2=null;var dash=null;var lineThickness=tg.get_LineThickness();var rect=null;var grid=null;var tp=tg.get_TexturePaint();var fileName=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetImageFile(tg);switch(tg.get_LineType()){case 31134000:case 31134100:case 31134200:case 31134300:for(j=0;j0) +tmpArray.get(tmpArray.size()-1).style=47;} +splinePoints2.addAll(tmpArray);splinePoints=tmpArray;switch(tg.get_LineType()){case 32272000:if(i===array.size()-2){if(splinePoints.size()>=2) +armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} +break;case 32273000:if(i===0&&splinePoints.size()>1){pt0=splinePoints.get(0);pt1=splinePoints.get(1);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,20);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,30);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt3,pt2,pt2,3,10);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt4,pt3,pt3,3,10);lineObject.moveTo(pt3.x,pt3.y);lineObject.lineTo(pt5.x,pt5.y);lineObject.moveTo(pt4.x,pt4.y);lineObject.lineTo(pt6.x,pt6.y);} +if(i===array.size()-2){if(splinePoints.size()>=2) +armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} +break;case 31440000:case 31430000:if(i===0&&splinePoints.size()>1){armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(1),splinePoints.get(0),10,lineObject);} +break;case 32273001:if(i===0&&splinePoints.size()>1){pt0=splinePoints.get(0);pt1=splinePoints.get(1);pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,10);pt3=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,20);pt4=armyc2.c2sd.JavaLineArray.lineutility.ExtendLineDouble(pt0,pt1,30);pt5=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt3,pt2,pt2,3,10);pt6=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt4,pt3,pt3,3,10);lineObject.moveTo(pt3.x,pt3.y);lineObject.lineTo(pt5.x,pt5.y);lineObject.moveTo(pt4.x,pt4.y);lineObject.lineTo(pt6.x,pt6.y);} +if(i===array.size()-2){lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j=2) +armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} +break;case 32272001:if(i===array.size()-2){lineObject=new armyc2.c2sd.graphics2d.GeneralPath();lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j=2) +armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(splinePoints.size()-2),tg.Pixels.get(tg.Pixels.size()-1),10,lineObject);} +break;case 31430001:case 31440001:if(i===0&&splinePoints.size()>1){armyc2.c2sd.JavaTacticalRenderer.clsMETOC.DrawArrow(splinePoints.get(1),splinePoints.get(0),10,lineObject);} +if(i===array.size()-2){lineObject.moveTo(Math.floor(splinePoints2.get(0).x),Math.floor(splinePoints2.get(0).y));for(j=1;j0) +return;var fillStyle=0;switch(tg.get_LineType()){case 22421000:shape.setFillColor(null);shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());break;case 24324100:case 24324300:case 24324200:case 24351000:case 24361000:case 24352000:case 24362000:case 24353000:case 24363000:case 23450000:case 23460000:case 23440000:case 22235000:fillStyle=3;if(tg.get_UseHatchFill()===true) +fillStyle=0;if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(fillStyle);shape.setFillColor(tg.get_FillColor());} +break;case 23115000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(0);shape.setFillColor(tg.get_FillColor());} +break;case 221310000:fillStyle=2;if(tg.get_UseHatchFill()===true) +fillStyle=0;if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());shape.set_Fillstyle(fillStyle);shape.setFillColor(tg.get_FillColor());} +break;case 23200001:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(1);shape.setFillColor(tg.get_LineColor());} +if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());} +break;case 22522100:case 23131200:case 23132000:case 22139000:case 211210000:case 23223000:case 23172000:case 23173000:case 23174000:case 23211000:case 23212000:case 23213000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(1);shape.setFillColor(tg.get_LineColor());} +if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(tg.get_LineStyle());shape.setLineColor(tg.get_LineColor());} +break;case 22310000:case 23157000:case 21700000:case 21710000:case 22528000:case 23191000:case 24222000:case 23224000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());} +break;case 22431100:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.set_Style(1);shape.setLineColor(tg.get_LineColor());shape.setFillColor(tg.get_FillColor());shape.set_Fillstyle(tg.get_FillStyle());} +break;case 22340000:case 22350000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==1){shape.set_Style(lineStyle);}}} +break;case 2237000:case 22330000:case 211200000:case 23192000:case 23225000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==1){shape.set_Style(lineStyle);}}} +break;case 22320000:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){shape.setLineColor(tg.get_LineColor());if(shapeStyle!==lineStyle){if(shapeStyle!==2){shape.set_Style(lineStyle);}}} +break;default:if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_FILL){shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());} +if(shape.getShapeType()===armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE){if(lineType!==22123000){shape.setLineColor(tg.get_LineColor());} +shape.set_Style(lineStyle);if(hasFill||armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType)||armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,null)){if(lineType!==243111000&&lineType!==243112000&&lineType!==15000001){shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());}} +switch(lineType){case 13000000:case 14000000:shape.set_Fillstyle(tg.get_FillStyle());shape.setFillColor(tg.get_FillColor());break;case 15000003:case 15000002:case 15000001:case 15000000:case 14000001:case 14000002:case 13000001:case 13000002:shape.setFillColor(null);break;default:break;}} +break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"ResolveModifierShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ResolveModifierShape",exc));}else{throw exc;}} +return;},GetOpaqueColor:function(color){var r=color.getRed();var g=color.getGreen();var b=color.getBlue();return new armyc2.c2sd.renderer.utilities.Color(r,g,b);},LinesWithFill:function(linetype){var result=false;try{switch(linetype){case 10000000:case 24326100:case 24222000:case 22330000:case 22522100:case 22121000:case 211400000:case 212600000:case 212500000:case 211600000:case 211900000:case 212100000:case 22122000:case 22123000:case 22124000:case 22125000:case 22421000:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22613000:case 23112000:case 23120000:case 23131100:case 23134000:case 231112000:case 231113000:case 231111000:case 22528000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 24250000:case 24211000:case 24221000:case 24223000:case 24225000:case 24224000:case 25211000:case 25212000:case 25221000:case 25222000:case 25223000:case 25225000:case 25224000:result=true;break;default:result=false;break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} +return result;},tweakFillColor:function(tg){try{if((armyc2.c2sd.JavaTacticalRenderer.clsUtility.isSameColor(tg.get_LineColor(),tg.get_FillColor())).valueOf()===false) +return;var fillColor=tg.get_FillColor();var r=fillColor.getRed();var g=fillColor.getGreen();var b=fillColor.getBlue();var alpha=fillColor.getAlpha();r*=0.9;g*=0.9;b*=0.9;alpha*=0.8;fillColor=new armyc2.c2sd.renderer.utilities.Color(r,g,b,alpha);tg.set_FillColor(fillColor);} +catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"tweakFillColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside tweakFillColor",exc));}else{throw exc;}} +return;},isSameColor:function(c1,c2){try{if(c1===null||c2===null) +return true;var r1=c1.getRed();var r2=c2.getRed();var g1=c1.getGreen();var g2=c2.getGreen();var b1=c1.getBlue();var b2=c2.getBlue();if(Math.abs(r1-r2)<5) +if(Math.abs(g1-g2)<5) +if(Math.abs(b1-b2)<5) +return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"isSameColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside isSameColor",exc));}else{throw exc;}} +return false;},getLineStroke:function(width,style,cap,round){var stroke=null;try{switch(style){case 0:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;case 1:var dash=[2*width,2*width,2*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dash,0);break;case 2:var dot=[0.1*width,2*width,0.1*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dot,0);break;case 3:var dashdot=[4*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdot,0);break;case 4:var dashdotdot=[2*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdotdot,0);break;default:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"getLineStroke",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getLineStroke",exc));}else{throw exc;}} +return stroke;},getLineStroke2:function(width,style,cap,round){var stroke=null;try{switch(style){case 0:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;case 1:var dash=[2*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dash,0);break;case 2:var dot=[0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dot,0);break;case 3:var dashdot=[4*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdot,0);break;case 4:var dashdotdot=[2*width,2*width,0.1*width,2*width,0.1*width,2*width];stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round,4,dashdotdot,0);break;default:stroke=new armyc2.c2sd.graphics2d.BasicStroke(width,cap,round);break;}} +catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"getLineStroke",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getLineStroke",exc));}else{throw exc;}} +return stroke;},SetShapeProperties:function(tg,shapes,bi){try{if(shapes===null){return;} +var j=0;var shape=null;var stroke=null;var dash=null;var lineThickness=tg.get_LineThickness();var shapeType=-1;var lineType=tg.get_LineType();var hasFill=armyc2.c2sd.JavaTacticalRenderer.clsUtility.LinesWithFill(lineType);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,null);var isClosedPolygon=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);if(tg.get_FillColor()===null) +{switch(tg.get_LineType()) +{case 22221000:case 22223000:case 22222000:case 22222001:case 22224000:case 22224001:case 22225000:shape=shapes.get(shapes.size()-1);shapes.clear();shapes.add(shape);break;case 21700000:case 22521100:case 22521200:case 22521300:case 22521420:case 22320000:case 22521410:case 21710000:var tempShapes=new java.util.ArrayList();for(j=0;j2){numSectors=Math.floor((tg.LatLongs.size()-2)/2);for(k=0;k2){var ptCenter=tg.LatLongs.get(0);var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var dist=0;var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();var rad=0;var temp="";for(var j=2;j0){radius=Clazz.newArray(n,0);}else{return null;} +if(lineType===243111000){for(var k=0;k0){count2=count;}else{count2=Math.floor(pixels.length/2);} +bolNoRepeats=false;do{bolNoRepeats=true;for(j=0;j3.141592653589793){dblAngle=dblAngle-6.283185307179586;} +if(dblAngle<-3.141592653589793){dblAngle=dblAngle+6.283185307179586;} +var dblWidth=30;locD.x=(locC.x+dblWidth*Math.cos(dblAngle));locD.y=(locC.y-dblWidth*Math.sin(dblAngle));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"ComputeLastPoint",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ComputeLastPoint",exc));}else{throw exc;}} +return locD;},GetSegments:function(pixels,segments,factor){try{var j=0;var m1=new armyc2.c2sd.JavaLineArray.ref();var m2=new armyc2.c2sd.JavaLineArray.ref();var numPoints=0;var bolVertical1=false;var bolVertical2=false;var pt0F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt1F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt2F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);segments[0]=true;numPoints=Math.floor(pixels.length/2);for(j=0;jfactor)&&(bolVertical2===false||Math.abs(m2.value[0])>factor)&&armyc2.c2sd.JavaTacticalRenderer.clsUtility.InYOrder(pt0F,pt1F,pt2F)===false){segments[j+1]=false;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"GetSegments",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetSegments",exc));}else{throw exc;}} +return;},SetLCColor:function(tg,shape){try{var affiliation=tg.get_Affiliation();if(affiliation!==null&&affiliation.equals("H")){if(shape.getLineColor()===armyc2.c2sd.renderer.utilities.Color.RED){shape.setLineColor(tg.get_LineColor());}else{shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}else{if(shape.getLineColor()!==armyc2.c2sd.renderer.utilities.Color.RED){shape.setLineColor(tg.get_LineColor());}else{shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.clsUtility._className,"SetLCColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SetLCColor",exc));}else{throw exc;}}},ReverseUSASLCPointsByQuadrant:function(tg){try{if(tg.Pixels.size()<2) +return;var quadrant=armyc2.c2sd.JavaLineArray.lineutility.GetQuadrantDouble(tg.Pixels.get(0),tg.Pixels.get(1));switch(tg.get_LineType()){case 22123000:case 22123001:if(tg.get_Affiliation()!==null&&tg.get_Affiliation().equals("H")){switch(quadrant){case 2:case 3:break;case 1:case 4:var n=tg.Pixels.size();var pts2=tg.Pixels.clone();for(var j=0;joriginalPixels.size()-1) +break;color=hmap.get(key);segPt0=originalPixels.get((key).intValue());segPt1=originalPixels.get((key).intValue()+1);for(j=0;jglyphSize||dist2>glyphSize||delta>20){hmapPixels.put(new Integer(j),tg.Pixels.get(j));hmapGeo.put(new Integer(j),tg.LatLongs.get(j));currentIndex=j;}}} +var pixels=new java.util.ArrayList();var geo=new java.util.ArrayList();for(j=0;j1){pPoints2.add(ptCenter);} +if(a12.value[0]0){brng12=brngA;brng21=6.283185307179586-brngB;}else{brng12=6.283185307179586-brngA;brng21=brngB;} +var alpha1=(brng13-brng12+3.141592653589793)%(6.283185307179586)-3.141592653589793;var alpha2=(brng21-brng23+3.141592653589793)%(6.283185307179586)-3.141592653589793;if(Math.sin(alpha1)===0&&Math.sin(alpha2)===0){return null;} +if(Math.sin(alpha1)*Math.sin(alpha2)<0){return null;} +var alpha3=Math.acos(-Math.cos(alpha1)*Math.cos(alpha2)+Math.sin(alpha1)*Math.sin(alpha2)*Math.cos(dist12));var dist13=Math.atan2(Math.sin(dist12)*Math.sin(alpha1)*Math.sin(alpha2),Math.cos(alpha2)+Math.cos(alpha1)*Math.cos(alpha3));var lat3=Math.asin(Math.sin(lat1)*Math.cos(dist13)+Math.cos(lat1)*Math.sin(dist13)*Math.cos(brng13));var dLon13=Math.atan2(Math.sin(brng13)*Math.sin(dist13)*Math.cos(lat1),Math.cos(dist13)-Math.sin(lat1)*Math.sin(lat3));var lon3=lon1+dLon13;lon3=(lon3+3.141592653589793)%(6.283185307179586)-3.141592653589793;ptResult=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.RadToDeg(lon3),armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.RadToDeg(lat3));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic._className,"IntersectLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside IntersectLines",exc));}else{throw exc;}} +return ptResult;},SegmentGeoPoints:function(geoPoints,interval,lineType){var resultPts=new java.util.ArrayList();try{switch(lineType){case 22350000:case 23350000:case 231117300:case 231117200:case 231117100:case 231116000:case 231115000:case 231114000:case 231113000:case 231112000:case 23112000:case 22123000:case 22122000:case 23134000:case 22624000:case 23113000:case 23115000:case 23114000:case 23131100:case 23131200:case 23132000:case 22134000:case 23330000:case 23111000:case 23111001:break;default:return geoPoints;} +var j=0;var k=0;var n=0;var pt0=null;var pt1=null;var pt=null;var dist=0;var az=0;var remainder=0;for(j=0;jmaxx){maxx=pt.x;}} +if(maxx-minx>180){spansIDL=true;} +if(!spansIDL){return geoPoints;} +normalizedPts=new java.util.ArrayList();for(j=0;jlrx) +lrx=pt.x;if(pt.y>uly) +uly=pt.y;if(pt.y16777215)alpha=(color>>>24);return alpha;};armyc2.c2sd.renderer.utilities.Color.getRedFromColor=function(color) +{var red=255;red=(color>>16)&0xFF;return red;};armyc2.c2sd.renderer.utilities.Color.getGreenFromColor=function(color) +{var green=255;green=(color>>8)&0xFF;return green;};armyc2.c2sd.renderer.utilities.Color.getBlueFromColor=function(color) +{var blue=255;if(color>16777215) +blue=color&0x000000FF;else +blue=color&0x0000FF;return blue;};armyc2.c2sd.renderer.utilities.Color.getColorFromHexString=function(hexValue) +{var hexAlphabet="0123456789ABCDEF";if(hexValue.charAt(0)==='#') +hexValue=hexValue.substring(1);if(hexValue.substring(0,2)===("0x")||hexValue.substring(0,2)===("0X")) +hexValue=hexValue.substring(2);hexValue=hexValue.toUpperCase();var count=hexValue.length,value=null,k=0,int1=0,int2=0;if(count===8||count===6) +{value=[];for(var i=0;i=_level) +{if(console!==undefined) +{message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ +this.getLevelName(level)+": "+message;console.info(message);}}},LogWarning:function(sourceClass,sourceMethod,message,level) +{if(level===undefined||level===null) +level=900;if(level>=_level) +{if(console!==undefined) +{message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ +this.getLevelName(level)+": "+message;console.warn(message);}}},LogException:function(sourceClass,sourceMethod,err,param,level) +{if(level===undefined||level===null) +level=1000;if(level>=_level) +{if(console!==undefined) +{var message=getDateString(new Date())+" "+sourceClass+" "+sourceMethod+"\n"+ +this.getLevelName(level)+": ";message+=err.name+": "+err.message;var stack=null;if(err.stack) +{stack=err.stack;} +if(!(stack)) +{if(err.filename&&err.lineno) +{stack=err.filename+" at line# "+err.lineno;}} +if(console.groupCollapsed) +{console.error(message);if(stack!==null) +{console.groupCollapsed("Stack Trace:");console.error(stack);if(console.dir&¶m) +{console.dir(param);} +console.groupEnd();}} +else +{if(stack!==null) +{message+="\n"+stack;} +console.error(message);if(console.dir&¶m) +{console.info(param);}}}}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.RendererException=function(message,throwable){throwable.message+=" - "+message;return throwable;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.MilStdSymbol=function(symbolID,uniqueID,coordinates,modifiers){var SymbolUtilties=armyc2.c2sd.renderer.utilities.SymbolUtilities;var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;this._Properties={};this._X_Altitude=null;this._AM_Distance=null;this._AN_Azimuth=null;this._symbolID="";this._UUID=null;this._SymbolShapes=null;this._ModifierShapes=null;this._Coordinates=null;this._UnitSize=0;this._scale=0;this._KeepUnitRatio=true;this._LineWidth=3;this._LineColor=null;this._FillColor=null;this._TextColor=null;this._TextBackgroundColor=null;this._Rotation=0.0;this._Outline=false;this._OutLineColor=null;this._OutLineWidth=0;this._symStd=0;this._UseLineInterpolation=true;this._DrawAffiliationModifierAsLabel=true;this._tp=null;this._Tag=null;this._AltitudeMode="";this._UseDashArray=false;this._UseFillPattern=false;this._PatternFillType=0;this._HideOptionalLabels=false;this._wasClipped=false;if(modifiers===undefined||modifiers===null) +modifiers={};else +this._Properties=modifiers;this._UUID=uniqueID;this._Coordinates=coordinates;this.setSymbolID(symbolID);this._LineColor=SymbolUtilties.getLineColorOfAffiliation(this._symbolID);this._TextColor=this._LineColor;if(SymbolUtilties.hasDefaultFill(this._symbolID)) +this._FillColor=SymbolUtilties.getFillColorOfAffiliation(this._symbolID);this._KeepUnitRatio=true;this._symStd=RendererSettings.getSymbologyStandard();this._DrawAffiliationModifierAsLabel=RendererSettings.getDrawAffiliationModifierAsLabel();this._UseLineInterpolation=RendererSettings.getUseLineInterpolation();this._OutLineWidth=RendererSettings.getSinglePointSymbolOutlineWidth();};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifier_AM_AN_X=function(modifier,value,index) +{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) +{var modifiers=null;if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) +{if(this._AM_Distance===null) +this._AM_Distance=[];modifiers=this._AM_Distance;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) +{if(this._AN_Azimuth===null) +this._AN_Azimuth=[];modifiers=this._AN_Azimuth;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) +{if(this._X_Altitude===null) +this._X_Altitude=[];modifiers=this._X_Altitude;} +if(index+1>modifiers.length) +{modifiers.push(value);} +else +{modifiers[index]=value;}}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifier=function(modifier,value,index) +{if(this._Properties===null) +{this._Properties={};} +else if(index===undefined) +{index=0;} +if(value!==undefined&&value!==null&&value!=="") +{if(!(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH||modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH)) +{this._Properties[modifier]=value;} +else +{this.setModifier_AM_AN_X(modifier,value,index);}}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbolID=function(value) +{var current=this._symbolID;try +{if(value!==null&&value!==""&¤t!==value){this._symbolID=value;} +if(armyc2.c2sd.renderer.utilities.SymbolUtilities.getAffiliation(value)===("H")){var basicID=armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolIDStrict(value);if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isObstacle(basicID)||basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")){this.setModifier("N","ENY");}}} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdSymbol","setSymbolID",err);}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setWasClipped=function(value) +{this._wasClipped=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getWasClipped=function() +{return this._wasClipped;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbologyStandard=function(symStd) +{this._symStd=symStd;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbologyStandard=function() +{return this._symStd;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setFillStyle=function(value) +{this._tp=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getFillStyle=function() +{return this._tp;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setUseLineInterpolation=function(value) +{this._UseLineInterpolation=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getUseLineInterpolation=function() +{return this._UseLineInterpolation;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifierMap=function(value) +{this._Properties=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifierMap=function() +{return this._Properties;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifier_AM_AN_X=function(modifier,index) +{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) +{if(this._AM_Distance!==null&&this._AM_Distance.length>index) +{return this._AM_Distance[index];} +else +return null;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) +{if(this._AN_Azimuth===null&&this._AN_Azimuth.length>index) +{return this._AN_Azimuth[index];} +else +return null;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) +{if(this._X_Altitude===null&&this._X_Altitude.length>index) +{return this._X_Altitude[index];} +else +return null;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifier=function(modifier,index) +{if(index===undefined) +{index=0;} +if(modifier==="AM"||modifier==="AN"||modifier==="XN") +{return this.getModifier_AM_AN_X(modifier,index);} +else if(this._Properties[modifier]!==undefined) +{return this._Properties[modifier];} +else +return null;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifiers_AM_AN_X=function(modifier) +{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) +{return this._AM_Distance;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) +{return this._AN_Azimuth;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) +{return this._X_Altitude;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifiers_AM_AN_X=function(modifier,values) +{if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE) +{this._AM_Distance=values;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.AN_AZIMUTH) +{this._AN_Azimuth=values;} +else if(modifier===armyc2.c2sd.renderer.utilities.ModifiersTG.X_ALTITUDE_DEPTH) +{this._X_Altitude=values;}};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setFillColor=function(value) +{this._FillColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getFillColor=function() +{return this._FillColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setLineWidth=function(value) +{this._LineWidth=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getLineWidth=function() +{return this._LineWidth;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setLineColor=function(value) +{this._LineColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getLineColor=function() +{return this._LineColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setTextColor=function(value) +{this._TextColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getTextColor=function() +{return this._TextColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setTextBackgroundColor=function(value) +{this._TextBackgroundColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getTextBackgroundColor=function() +{return this._TextBackgroundColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setOutlineColor=function(value) +{this._OutLineColor=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getOutlineColor=function() +{return this._OutLineColor;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setAltitudeMode=function(value) +{this._AltitudeMode=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getAltitudeMode=function() +{return this._AltitudeMode;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setUseDashArray=function(value) +{this._UseDashArray=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getUseDashArray=function() +{return this._UseDashArray;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setUseFillPattern=function(value) +{this._UseFillPattern=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getUseFillPattern=function() +{return this._UseFillPattern;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setPatternFillType=function(value) +{this._PatternFillType=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getPatternFillType=function() +{return this._PatternFillType;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setHideOptionalLabels=function(value) +{this._HideOptionalLabels=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getHideOptionalLabels=function() +{return this._HideOptionalLabels;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setTag=function(value) +{this._Tag=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getTag=function() +{return this._Tag;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setCoordinates=function(value) +{this._Coordinates=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getCoordinates=function() +{return this._Coordinates;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setModifierShapes=function(value) +{this._ModifierShapes=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getModifierShapes=function() +{return this._ModifierShapes;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.setSymbolShapes=function(value) +{this._SymbolShapes=value;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbolShapes=function() +{return this._SymbolShapes;};armyc2.c2sd.renderer.utilities.MilStdSymbol.prototype.getSymbolID=function() +{return this._symbolID;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ModifiersTG={A_SYMBOL_ICON:"A",B_ECHELON:"B",C_QUANTITY:"C",H_ADDITIONAL_INFO_1:"H",H1_ADDITIONAL_INFO_2:"H1",H2_ADDITIONAL_INFO_3:"H2",N_HOSTILE:"N",Q_DIRECTION_OF_MOVEMENT:"Q",S_OFFSET_INDICATOR:"S",T_UNIQUE_DESIGNATION_1:"T",T1_UNIQUE_DESIGNATION_2:"T1",V_EQUIP_TYPE:"V",W_DTG_1:"W",W1_DTG_2:"W1",X_ALTITUDE_DEPTH:"X",Y_LOCATION:"Y",AM_DISTANCE:"AM",AN_AZIMUTH:"AN",LENGTH:"Length",WIDTH:"Width",RADIUS:"Radius",ANGLE:"Angle",getModifierName:function(modifier) +{switch(modifier) +{case this.B_ECHELON:return"Echelon";case this.C_QUANTITY:return"Quantity";case this.H_ADDITIONAL_INFO_1:return"Additional Info 1";case this.H1_ADDITIONAL_INFO_2:return"Additional Info 2";case this.H2_ADDITIONAL_INFO_3:return"Additional Info 3";case this.N_HOSTILE:return"Hostile";case this.Q_DIRECTION_OF_MOVEMENT:return"Direction of Movement";case this.T_UNIQUE_DESIGNATION_1:return"Unique Designation 1";case this.T1_UNIQUE_DESIGNATION_2:return"Unique Designation 2";case this.V_EQUIP_TYPE:return"Equipment Type";case this.W_DTG_1:return"Date Time Group 1";case this.W1_DTG_2:return"Date Time Group 2";case this.X_ALTITUDE_DEPTH:return"Altitude Depth";case this.Y_LOCATION:return"Location";case this.AM_DISTANCE:return"Distance";case this.AN_AZIMUTH:return"Azimuth";default:return"";}}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.PointConversion=function(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight) +{this._scale=0;this._pixelWidth=0;this._PixelHeight=0;this._geoTop=0;this._geoLeft=0;this._geoBottom=0;this._geoRight=0;this._pixelMultiplierX=0;this._pixelMultiplierY=0;this._normalize=true;this.UpdateExtents(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight);};armyc2.c2sd.renderer.utilities.PointConversion.prototype.set_normalize=function(value) +{this._normalize=value;};armyc2.c2sd.renderer.utilities.PointConversion.prototype.UpdateExtents=function(pixelWidth,pixelHeight,geoTop,geoLeft,geoBottom,geoRight) +{this._pixelWidth=Number(pixelWidth);this._PixelHeight=Number(pixelHeight);this._geoTop=Number(geoTop);this._geoLeft=Number(geoLeft);this._geoBottom=Number(geoBottom);this._geoRight=Number(geoRight);this._pixelMultiplierX=(this._geoRight-this._geoLeft)/(this._pixelWidth);this._pixelMultiplierY=(this._geoTop-this._geoBottom)/(this._PixelHeight);if(this._geoRight-this._geoLeft<-180){this._pixelMultiplierX=(this._geoRight-this._geoLeft+360)/(this._pixelWidth);} +if(this._geoRight-this._geoLeft>180){this._pixelMultiplierX=(360-(this._geoRight-this._geoLeft))/(this._pixelWidth);} +if(this._geoTop180) +distanceInDegrees=Math.abs(distanceInDegrees-360);var distanceInMeters=(distanceInDegrees/360)*(40.075*1000000);var scale=(this._pixelWidth/distanceInMeters)*(1.0/96.0)*(1.0/39.37);this._scale=1.0/scale;};armyc2.c2sd.renderer.utilities.PointConversion.prototype.PixelsToGeo=function(pixel) +{var coords=new armyc2.c2sd.graphics2d.Point2D();var x=((pixel.getX()*this._pixelMultiplierX)+this._geoLeft);var y=(this._geoTop-(pixel.getY()*this._pixelMultiplierY));if(x>180)x-=360;if(x<-180)x+=360;coords.setLocation(x,y);return coords;};armyc2.c2sd.renderer.utilities.PointConversion.prototype.GeoToPixels=function(coord) +{var pixel=new armyc2.c2sd.graphics2d.Point2D();var x=0;var y=0;var temp;var calcValue=coord.getX()-this._geoLeft;if(this._normalize) +{if(calcValue<-180) +calcValue+=360;else if(calcValue>180) +calcValue-=360;} +temp=(calcValue/this._pixelMultiplierX);x=temp;temp=((this._geoTop-coord.getY())/this._pixelMultiplierY);y=temp;pixel.setLocation(x,y);return pixel;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.PointConverter3D=function(controlLong,controlLat,scale) +{this._controlLat=0,this._controlLong=0,this._scale=0,this._metersPerPixel=0;this._controlLat=Number(controlLat);this._controlLong=Number(controlLong);this._scale=Number(scale);this._metersPerPixel=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.metersPerPixel(scale);};armyc2.c2sd.renderer.utilities.PointConverter3D.prototype.PixelsToGeo=function(pixel) +{var pt2dGeo=null;var y=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.y2lat(pixel.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.x2long(pixel.getX(),this._scale,this._controlLong,y,this._metersPerPixel);pt2dGeo=new armyc2.c2sd.graphics2d.Point2D(x,y);return pt2dGeo;};armyc2.c2sd.renderer.utilities.PointConverter3D.prototype.GeoToPixels=function(coord) +{var ptPixels=null;var y=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.lat2y(coord.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=armyc2.c2sd.renderer.utilities.GeoPixelConversion3D.long2x(coord.getX(),this._scale,this._controlLong,coord.getY(),this._metersPerPixel);ptPixels=new armyc2.c2sd.graphics2d.Point2D(x,y);return ptPixels;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.RendererSettings=(function(){var _Version="0.3.30";var _SymbologyStandard=0,_UseLineInterpolation=true,_AutoCollapseModifiers=true,_TextBackgroundAutoColorThreshold=160,_TextOutlineWidth=1,_TextBackgroundMethod=2,_ColorLabelForeground=null,_ColorLabelBackground=null,_SymbolOutlineWidth=3,_UseCesium2DScaleModifiers=false,_3DMinScaleMultiplier=1.0,_3DMaxScaleMultiplier=1.0,_CenterOnHQStaff=true,_OCMType=1,_ModifierFontName="Arial, sans-serif",_ModifierFontSize=10,_ModifierFontStyle="bold",_ModifierFont="bold 10pt Arial, sans-serif",_MPModifierFont="bold 12pt Arial, sans-serif",_MPModifierFontName="Arial, sans-serif",_MPModifierFontSize=12,_MPModifierFontStyle="bold",_KMLLabelScale=1.0,_scaleEchelon=false,_DrawAffiliationModifierAsLabel=true,_DrawCountryCode=true,_SPFontSize=60,_UnitFontSize=50,_PixelSize=35,_DPI=90;_TwoLabelOnly=true,_friendlyUnitFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.FriendlyUnitFillColor,_hostileUnitFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.HostileUnitFillColor,_neutralUnitFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.NeutralUnitFillColor,_unknownUnitFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.UnknownUnitFillColor,_friendlyGraphicFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.FriendlyGraphicFillColor,_hostileGraphicFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.HostileGraphicFillColor,_neutralGraphicFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.NeutralGraphicFillColor,_unknownGraphicFillColor=armyc2.c2sd.renderer.utilities.AffiliationColors.UnknownGraphicFillColor,_friendlyUnitLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.FriendlyUnitLineColor,_hostileUnitLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.HostileUnitLineColor,_neutralUnitLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.NeutralUnitLineColor,_unknownUnitLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.UnknownUnitLineColor,_friendlyGraphicLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.FriendlyGraphicLineColor,_hostileGraphicLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.HostileGraphicLineColor,_neutralGraphicLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.NeutralGraphicLineColor,_unknownGraphicLineColor=armyc2.c2sd.renderer.utilities.AffiliationColors.UnknownGraphicLineColor;try +{if(document) +{armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_ModifierFont);armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_MPModifierFont);}} +catch(err) +{} +return{TextBackgroundMethod_NONE:0,TextBackgroundMethod_COLORFILL:1,TextBackgroundMethod_OUTLINE:2,TextBackgroundMethod_OUTLINE_QUICK:3,Symbology_2525B:0,Symbology_2525Bch2_USAS_13_14:0,Symbology_2525C:1,OperationalConditionModifierType_SLASH:0,OperationalConditionModifierType_BAR:1,getVersion:function() +{return _Version;},setOperationalConditionModifierType:function(operationalConditionModifierType) +{_OCMType=operationalConditionModifierType;},getOperationalConditionModifierType:function() +{return _OCMType;},setTextBackgroundMethod:function(textBackgroundMethod) +{_TextBackgroundMethod=textBackgroundMethod;},getTextBackgroundMethod:function() +{return _TextBackgroundMethod;},setSymbologyStandard:function(standard){_SymbologyStandard=standard;},getSymbologyStandard:function(){return _SymbologyStandard;},setUseLineInterpolation:function(value){_UseLineInterpolation=value;},getUseLineInterpolation:function(){return _UseLineInterpolation;},setDeviceDPI:function(value){_DPI=value;},getDeviceDPI:function(){return _DPI;},setAutoCollapseModifiers:function(value){_AutoCollapseModifiers=value;},getAutoCollapseModifiers:function(){return _AutoCollapseModifiers;},setUseCesium2DScaleModifiers:function(value){_UseCesium2DScaleModifiers=value;},getUseCesium2DScaleModifiers:function(){return _UseCesium2DScaleModifiers;},set3DMinScaleMultiplier:function(value){_3DMinScaleMultiplier=value;},get3DMinScaleMultiplier:function(){return _3DMinScaleMultiplier;},set3DMaxScaleMultiplier:function(value){_3DMaxScaleMultiplier=value;},get3DMaxScaleMultiplier:function(){return _3DMaxScaleMultiplier;},setCenterOnHQStaff:function(value){_CenterOnHQStaff=value;},getCenterOnHQStaff:function(){return _CenterOnHQStaff;},setTextOutlineWidth:function(width){_TextOutlineWidth=width;},getTextOutlineWidth:function(){return _TextOutlineWidth;},setDefaultPixelSize:function(size){_PixelSize=size;},getDefaultPixelSize:function(){return _PixelSize;},setLabelForegroundColor:function(value){_ColorLabelForeground=value;},getLabelForegroundColor:function(){return _ColorLabelForeground;},setLabelBackgroundColor:function(value){_ColorLabelBackground=value;},getLabelBackgroundColor:function(){return _ColorLabelBackground;},setTextBackgroundAutoColorThreshold:function(value){_TextBackgroundAutoColorThreshold=value;},getTextBackgroundAutoColorThreshold:function(){return _TextBackgroundAutoColorThreshold;},setSinglePointSymbolOutlineWidth:function(width){_SymbolOutlineWidth=width;if(width>0) +_SymbolOutlineWidth=(width*2)+1;else +_SymbolOutlineWidth=0;},getSinglePointSymbolOutlineWidth:function(){return _SymbolOutlineWidth;},setScaleEchelon:function(value){_scaleEchelon=value;},getScaleEchelon:function(){return _scaleEchelon;},setDrawAffiliationModifierAsLabel:function(value){_DrawAffiliationModifierAsLabel=value;},getDrawAffiliationModifierAsLabel:function(){return _DrawAffiliationModifierAsLabel;},setDrawCountryCode:function(value){_DrawCountryCode=value;},getDrawCountryCode:function(){return _DrawCountryCode;},setModifierFont:function(name,size,style,fontInfo){_ModifierFontName=name;_ModifierFontSize=size;if(style!=='bold'||style!=='normal') +{_ModifierFontStyle=style;} +else +{_ModifierFontStyle='bold';} +_ModifierFont=style+" "+size+"pt "+name;armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_ModifierFont,fontInfo);},getModifierFont:function(){return _ModifierFont;},getModifierFontName:function(){return _ModifierFontName;},getModifierFontSize:function(){return _ModifierFontSize;},getModifierFontStyle:function(){return _ModifierFontStyle;},setMPModifierFont:function(name,size,style,kmlLabelScale,fontInfo){_MPModifierFontName=name;_MPModifierFontSize=size;if(style!=='bold'||style!=='normal') +{_MPModifierFontStyle=style;} +else +{_MPModifierFontStyle='bold';} +if(kmlLabelScale) +{_KMLLabelScale=kmlLabelScale;} +else +{_KMLLabelScale=1.0;} +var tempSize=Math.round(size*_KMLLabelScale);_MPModifierFont=style+" "+tempSize+"pt "+name;armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_MPModifierFont,fontInfo);},getMPModifierFont:function(){return _MPModifierFont;},getMPModifierFontName:function(){return _MPModifierFontName;},getMPModifierFontSize:function(){return _MPModifierFontSize;},getMPModifierFontStyle:function(){return _MPModifierFontStyle;},getKMLLabelScale:function(){return _KMLLabelScale;},getFontInfo:function(){return{name:_ModifierFontName,size:_ModifierFontSize,style:_ModifierFontStyle,measurements:armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_ModifierFont)};},getMPFontInfo:function(){return{name:_MPModifierFontName,size:_MPModifierFontSize,style:_MPModifierFontStyle,measurements:armyc2.c2sd.renderer.utilities.RendererUtilities.measureFont(_MPModifierFont)};},getTwoLabelOnly:function(){return _TwoLabelOnly;},setTwoLabelOnly:function(TwoLabelOnly) +{_TwoLabelOnly=TwoLabelOnly;},getFriendlyUnitFillColor:function() +{return _friendlyUnitFillColor;},setFriendlyUnitFillColor:function(friendlyUnitFillColor) +{if(friendlyUnitFillColor!=null) +_friendlyUnitFillColor=friendlyUnitFillColor;},getHostileUnitFillColor:function(){return _hostileUnitFillColor;},setHostileUnitFillColor:function(hostileUnitFillColor){if(hostileUnitFillColor!=null) +_hostileUnitFillColor=hostileUnitFillColor;},getNeutralUnitFillColor:function(){return _neutralUnitFillColor;},setNeutralUnitFillColor:function(neutralUnitFillColor){if(neutralUnitFillColor!=null) +_neutralUnitFillColor=neutralUnitFillColor;},getUnknownUnitFillColor:function(){return _unknownUnitFillColor;},setUnknownUnitFillColor:function(unknownUnitFillColor){if(unknownUnitFillColor!=null) +_unknownUnitFillColor=unknownUnitFillColor;},getHostileGraphicFillColor:function(){return _hostileGraphicFillColor;},setHostileGraphicFillColor:function(hostileGraphicFillColor){if(hostileGraphicFillColor!=null) +_hostileGraphicFillColor=hostileGraphicFillColor;},getFriendlyGraphicFillColor:function(){return _friendlyGraphicFillColor;},setFriendlyGraphicFillColor:function(friendlyGraphicFillColor){if(friendlyGraphicFillColor!=null) +_friendlyGraphicFillColor=friendlyGraphicFillColor;},getNeutralGraphicFillColor:function(){return _neutralGraphicFillColor;},setNeutralGraphicFillColor:function(neutralGraphicFillColor){if(neutralGraphicFillColor!=null) +_neutralGraphicFillColor=neutralGraphicFillColor;},getUnknownGraphicFillColor:function(){return _unknownGraphicFillColor;},setUnknownGraphicFillColor:function(unknownGraphicFillColor){if(unknownGraphicFillColor!=null) +_unknownGraphicFillColor=unknownGraphicFillColor;},getFriendlyUnitLineColor:function(){return _friendlyUnitLineColor;},setFriendlyUnitLineColor:function(friendlyUnitLineColor){if(friendlyUnitLineColor!=null) +this._friendlyUnitLineColor=friendlyUnitLineColor;},getHostileUnitLineColor:function(){return _hostileUnitLineColor;},setHostileUnitLineColor:function(hostileUnitLineColor){if(hostileUnitLineColor!=null) +this._hostileUnitLineColor=hostileUnitLineColor;},getNeutralUnitLineColor:function(){return _neutralUnitLineColor;},setNeutralUnitLineColor:function(neutralUnitLineColor){if(neutralUnitLineColor!=null) +this._neutralUnitLineColor=neutralUnitLineColor;},getUnknownUnitLineColor:function(){return _unknownUnitLineColor;},setUnknownUnitLineColor:function(unknownUnitLineColor){if(unknownUnitLineColor!=null) +this._unknownUnitLineColor=unknownUnitLineColor;},getFriendlyGraphicLineColor:function(){return _friendlyGraphicLineColor;},setFriendlyGraphicLineColor:function(friendlyGraphicLineColor){if(friendlyGraphicLineColor!=null) +this._friendlyGraphicLineColor=friendlyGraphicLineColor;},getHostileGraphicLineColor:function(){return _hostileGraphicLineColor;},setHostileGraphicLineColor:function(hostileGraphicLineColor){if(hostileGraphicLineColor!=null) +this._hostileGraphicLineColor=hostileGraphicLineColor;},getNeutralGraphicLineColor:function(){return _neutralGraphicLineColor;},setNeutralGraphicLineColor:function(neutralGraphicLineColor){if(neutralGraphicLineColor!=null) +this._neutralGraphicLineColor=neutralGraphicLineColor;},getUnknownGraphicLineColor:function(){return _unknownGraphicLineColor;},setUnknownGraphicLineColor:function(unknownGraphicLineColor){if(unknownGraphicLineColor!=null) +this._unknownGraphicLineColor=unknownGraphicLineColor;},setGraphicPreferredAffiliationColors:function(friendlyGraphicLineColor,hostileGraphicLineColor,neutralGraphicLineColor,unknownGraphicLineColor,friendlyGraphicFillColor,hostileGraphicFillColor,neutralGraphicFillColor,unknownGraphicFillColor){setFriendlyGraphicLineColor(friendlyGraphicLineColor);setHostileGraphicLineColor(hostileGraphicLineColor);setNeutralGraphicLineColor(neutralGraphicLineColor);setUnknownGraphicLineColor(unknownGraphicLineColor);setFriendlyGraphicFillColor(friendlyGraphicFillColor);setHostileGraphicFillColor(hostileGraphicFillColor);setNeutralGraphicFillColor(neutralGraphicFillColor);setUnknownGraphicFillColor(unknownGraphicFillColor);},setUnitPreferredAffiliationColors:function(friendlyUnitLineColor,hostileUnitLineColor,neutralUnitLineColor,unknownUnitLineColor,friendlyUnitFillColor,hostileUnitFillColor,neutralUnitFillColor,unknownUnitFillColor){setFriendlyUnitLineColor(friendlyUnitLineColor);setHostileUnitLineColor(hostileUnitLineColor);setNeutralUnitLineColor(neutralUnitLineColor);setUnknownUnitLineColor(unknownUnitLineColor);setFriendlyUnitFillColor(friendlyUnitFillColor);setHostileUnitFillColor(hostileUnitFillColor);setNeutralUnitFillColor(neutralUnitFillColor);setUnknownUnitFillColor(unknownUnitFillColor);},getInstance:function(){return armyc2.c2sd.renderer.utilities.RendererSettings;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolUtilities={};armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance();armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolID=function(symbolID,symStd){var basic=symbolID;if(symbolID&&symbolID.length===15) +{var scheme=symbolID.charAt(0);if(scheme==='S'||scheme==='O'||scheme==='E') +{basic=scheme+'*'+basic.charAt(2)+'*'+basic.substring(4,10)+"*****";var i=symStd||0;for(;i<2;i++) +{var has=armyc2.c2sd.renderer.utilities.UnitDefTable.hasUnitDef(basic,i);var temp=null;if(has) +{i=3;} +else +{temp=basic.substr(0,10)+"H****";has=armyc2.c2sd.renderer.utilities.UnitDefTable.hasUnitDef(temp,i);if(has) +{basic=temp;i=3;} +else +{temp=basic.substr(0,10)+"MO***";has=armyc2.c2sd.renderer.utilities.UnitDefTable.hasUnitDef(temp,i);if(has) +{basic=temp;i=3;}}}}} +else if(scheme==='G') +{basic=scheme+'*'+basic.charAt(2)+'*'+basic.substring(4,10)+"****X";} +else if(scheme==='I') +{basic=scheme+'*'+basic.charAt(2)+'*'+basic.substring(4,10)+"--***";} +else +{basic=symbolID;}} +return basic;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolIDStrict=function(symbolID){var basic=symbolID;if(symbolID&&symbolID.length===15) +{var scheme=symbolID.charAt(0);if(scheme==='G') +{basic=scheme+'*'+basic.charAt(2)+'*'+basic.substring(4,10)+"****X";} +else if(scheme!=='W'&&scheme!=='B'&&scheme!=='P') +{basic=scheme+'*'+basic.charAt(2)+'*'+basic.substring(4,10)+"*****";}} +return basic;};armyc2.c2sd.renderer.utilities.SymbolUtilities.reconcileSymbolID=function(symbolID,isMultiPoint) +{if(isMultiPoint!==true) +isMultiPoint=false;var sb="";var codingScheme=symbolID.charAt(0);if(symbolID.indexOf("BS_")===0||symbolID.indexOf("BBS_")===0||symbolID.indexOf("PBS_")===0) +{return symbolID;} +if(symbolID.length<15) +{while(symbolID.length<15) +{symbolID+="-";}} +if(symbolID.length>15) +{symbolID=symbolID.substring(0,15);} +if(symbolID!==null&&symbolID.length===15) +{if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') +{sb+=(codingScheme);if(this.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));if(this.hasValidBattleDimension(symbolID)===false) +{sb="S"+sb.substring(1);sb+=('Z');} +else +sb+=(symbolID.charAt(2));if(this.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));} +else if(codingScheme==='G') +{sb+=(codingScheme);if(this.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));sb+=('G');if(this.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));if(isMultiPoint) +sb+=("GAG---");else +sb+=("GPP---");sb+=(symbolID.substring(10,15));} +else if(codingScheme==='W') +{return"SUZP-----------";} +else +{sb+=('S');if(this.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));if(this.hasValidBattleDimension(symbolID)===false) +{sb+=('Z');} +else +sb+=(symbolID.charAt(2));if(this.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));}} +else +{return"SUZP-----------";} +return sb;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidStatus=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) +{var status=SymbolID.charAt(3),codingScheme=SymbolID.charAt(0);if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') +{if(status==='A'||status==='P'||status==='C'||status==='D'||status==='X'||status==='F') +{return true;} +else +return false;} +else if(codingScheme==='G') +{if(status==='A'||status==='S'||status==='P'||status==='K') +{return true;} +else +return false;} +else if(codingScheme==='W') +{return true;} +return false;} +else +return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidAffiliation=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) +{var affiliation=SymbolID.charAt(1);if(affiliation==='P'||affiliation==='U'||affiliation==='A'||affiliation==='F'||affiliation==='N'||affiliation==='S'||affiliation==='H'||affiliation==='G'||affiliation==='W'||affiliation==='M'||affiliation==='D'||affiliation==='L'||affiliation==='J'||affiliation==='K') +return true;else +return false;} +else +return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidCodingScheme=function(symbolID){if(symbolID!==null&&symbolID.length>0) +{var codingScheme=symbolID.charAt(0);if(codingScheme==='S'||codingScheme==='G'||codingScheme==='W'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') +{return true;} +else +{return false;}} +else +{return false;}};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidBattleDimension=function(SymbolID){if(SymbolID!==null&&SymbolID.length>=10) +{var codingScheme=SymbolID.charAt(0),bd=SymbolID.charAt(2);if(codingScheme==='S') +{if(bd==='P'||bd==='A'||bd==='G'||bd==='S'||bd==='U'||bd==='F'||bd==='Z') +return true;else +return false;} +else if(codingScheme==='O') +{if(bd==='V'||bd==='L'||bd==='O'||bd==='I'||bd==='P'||bd==='G'||bd==='R') +return true;else +return false;} +else if(codingScheme==='E') +{if(bd==='I'||bd==='N'||bd==='O'||bd==='F') +return true;else +return false;} +else if(codingScheme==='G') +{if(bd==='T'||bd==='G'||bd==='M'||bd==='F'||bd==='S'||bd==='O') +{return true;} +else +return false;} +else if(codingScheme==='W') +{return true;} +else if(codingScheme==='I') +{if(bd==='P'||bd==='A'||bd==='G'||bd==='S'||bd==='U'||bd==='Z') +return true;else +return false;} +else +return false;} +else +return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isLetter=function(str) +{var returnVal=true,len=str.length,code=0;for(var i=0;i=65&&code<=90)||(code>=97&&code<=122)) +{returnVal=false;break;}} +return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasValidCountryCode=function(symbolID) +{if(this.isLetter(symbolID.substring(12,14))) +return true;else +return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getDateLabel=function(date){var strDate=null,day,hour,min,sec,zulu,month,strMonth,year,strYear,months;if(date instanceof Date) +{day=date.getDate();hour=date.getHours();min=date.getMinutes();sec=date.getSeconds();zulu=date.getTimezoneOffset();if(zulu!==0){zulu=zulu/-60;} +month=date.getMonth();year=date.getFullYear();months=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];strMonth=months[month];strYear=year.toString();strYear=strYear.substr(2,2);strDate=this.formatNumberLength(day,2)+this.formatNumberLength(hour,2)+this.formatNumberLength(min,2)+this.formatNumberLength(sec,2)+this.getZuluCharacter(zulu)+strMonth+strYear;} +return strDate;};armyc2.c2sd.renderer.utilities.SymbolUtilities.formatNumberLength=function(number,length){var r="";r=r+number;while(r.length-1) +returnVal=true;break;default:returnVal=false;}} +else if(tgModifier===(ModifiersTG.AN_AZIMUTH)) +{switch(dc) +{case SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} +else +{if(sd.modifiers.indexOf(tgModifier+".")>-1) +returnVal=true;}} +return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfAffiliation=function(symbolID){var retColor=null,basicSymbolID=this.getBasicSymbolIDStrict(symbolID);if((symbolID===null)||(symbolID===(""))) +{return retColor;} +if(this.isTacticalGraphic(symbolID)) +{if(this.isWeather(symbolID)) +{retColor=this.getLineColorOfWeather(symbolID);} +else if(this.isObstacle(symbolID)) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getNeutralGraphicLineColor();} +else if(this.isEMSNaturalEvent(symbolID)) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicLineColor();} +else if((this.isNBC(symbolID))&&(basicSymbolID===("G*M*NR----****X")||basicSymbolID===("G*M*NC----****X")||basicSymbolID===("G*M*NB----****X"))) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicLineColor();} +else +{var switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicLineColor();} +else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) +{if(this.getBasicSymbolIDStrict(symbolID)===("G*G*GLC---****X")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicLineColor();} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getHostileGraphicLineColor();}} +else if(switchChar===("N")||switchChar===("L")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getNeutralGraphicLineColor();} +else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) +{if(symbolID.substring(0,8).equals("WOS-HDS-")) +{retColor=armyc2.c2sd.renderer.utilities.Color.GRAY;} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownGraphicLineColor();}} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicLineColor();}}} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyUnitLineColor();} +return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getFillColorOfAffiliation=function(symbolID){var retColor=null,basicSymbolID=this.getBasicSymbolIDStrict(symbolID);var AffiliationColors=armyc2.c2sd.renderer.utilities.AffiliationColors;var switchChar;if((symbolID===null)||(symbolID===(""))) +{return retColor;} +if(basicSymbolID===("G*M*NZ----****X")||basicSymbolID===("G*M*NEB---****X")||basicSymbolID===("G*M*NEC---****X")) +{retColor=AffiliationColors.UnknownUnitFillColor;retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownUnitFillColor();} +else if(this.isTacticalGraphic(symbolID)&&!this.isTGSPWithFill(symbolID)) +{if(basicSymbolID===("G*M*NZ----****X")||basicSymbolID===("G*M*NEB---****X")||basicSymbolID===("G*M*NEC---****X")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownUnitFillColor();} +else +{switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyGraphicFillColor();} +else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getHostileGraphicFillColor();} +else if(switchChar===("N")||switchChar===("L")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getNeutralGraphicFillColor();} +else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FFFACD");} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownGraphicFillColor();}}} +else +{switchChar=symbolID.charAt(1);if(switchChar===("F")||switchChar===("A")||switchChar===("D")||switchChar===("M")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getFriendlyUnitFillColor();} +else if(switchChar===("H")||switchChar===("S")||switchChar===("J")||switchChar===("K")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getHostileUnitFillColor();} +else if(switchChar===("N")||switchChar===("L")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getNeutralUnitFillColor();} +else if(switchChar===("U")||switchChar===("P")||switchChar===("O")||switchChar===("G")||switchChar===("W")) +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownUnitFillColor();} +else +{retColor=armyc2.c2sd.renderer.utilities.SymbolUtilities.rendererSettings.getUnknownUnitFillColor();}} +return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfWeather=function(symbolID){var retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;if(symbolID===("WAS-WSGRL-P----")||symbolID===("WAS-WSGRMHP----")||symbolID===("WAS-PL----P----")||symbolID===("WAS-PC----P----")||symbolID===("WAS-WSIC--P----")||symbolID===("WAS-WSPLL-P----")||symbolID===("WAS-WSPLM-P----")||symbolID===("WAS-WSPLH-P----")||symbolID===("WAS-WST-NPP----")||symbolID===("WAS-WSTMR-P----")||symbolID===("WAS-WSTHR-P----")||symbolID===("WAS-WSTMH-P----")||symbolID===("WAS-WSTHH-P----")||symbolID===("WAS-WST-FCP----")||symbolID===("WAS-WST-SQP----")||symbolID===("WAS-WST-LGP----")||symbolID===("WAS-WSFGFVP----")||symbolID===("WAS-WSFGFOP----")||symbolID===("WAS-WSTSD-P----")||symbolID===("WAS-WSTSS-P----")||symbolID===("WAS-WSTSH-P----")||symbolID===("WAS-WSRFL-P----")||symbolID===("WAS-WSRFMHP----")||symbolID===("WAS-WSDFL-P----")||symbolID===("WAS-WSDFMHP----")||symbolID===("WOS-HHDMDBP----")||symbolID===("WOS-HHDMDFP----")||symbolID.substring(0,7)===("WA-DPFW")||symbolID===("WA-DBAIF----A--")||symbolID===("WA-DBAFP----A--")||symbolID===("WA-DBAT-----A--")||symbolID===("WA-DIPIS---L---")||symbolID===("WA-DIPTH---L---")||symbolID===("WA-DWJ-----L---")||symbolID===("WO-DGMSB----A--")||symbolID===("WO-DGMRR----A--")||symbolID===("WO-DGMCH----A--")||symbolID===("WO-DGMIBE---A--")||symbolID===("WO-DGMBCC---A--")||symbolID===("WO-DOBVI----A--")) +{retColor=armyc2.c2sd.renderer.utilities.Color.RED;} +else if(symbolID===("WAS-PH----P----")||symbolID===("WAS-PA----P----")||symbolID===("WA-DBAMV----A--")||symbolID===("WA-DBATB----A--")||symbolID.substring(0,5)===("WAS-T")||symbolID.substring(0,7)===("WA-DPFC")||symbolID===("WO-DGMIBA---A--")) +{retColor=armyc2.c2sd.renderer.utilities.Color.BLUE;} +else if(symbolID===("WAS-WSFGPSP----")||symbolID===("WAS-WSFGCSP----")||symbolID===("WAS-WSFGP-P----")||symbolID===("WAS-WSFGSVP----")||symbolID===("WAS-WSFGSOP----")||symbolID===("WA-DBAFG----A--")||symbolID===("WO-DGMRM----A--")||symbolID===("WO-DGMCM----A--")||symbolID===("WO-DGMIBC---A--")||symbolID===("WO-DGMBCB---A--")||symbolID===("WO-DGMBTE---A--")||symbolID===("WAS-WSBR--P----")) +{retColor=armyc2.c2sd.renderer.utilities.Color.YELLOW;} +else if(symbolID===("WAS-WSFU--P----")||symbolID===("WAS-WSHZ--P----")||symbolID===("WAS-WSDSLMP----")||symbolID===("WAS-WSDSS-P----")||symbolID===("WAS-WSDD--P----")||symbolID===("WA-DBAD-----A--")||symbolID===("WAS-WSBD--P----")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#A52A2A");} +else if(symbolID===("WA-DBALPNC--A--")||symbolID===("WA-DBALPC---A--")||symbolID===("WA-DIPID---L---")||symbolID===("WO-DGMSIM---A--")||symbolID===("WO-DGMRS----A--")||symbolID===("WO-DGMCL----A--")||symbolID===("WO-DGMIBB---A--")||symbolID===("WO-DGMBCA---A--")||symbolID===("WAS-WSR-LIP----")||symbolID===("WAS-WSR-LCP----")||symbolID===("WAS-WSR-MIP----")||symbolID===("WAS-WSR-MCP----")||symbolID===("WAS-WSR-HIP----")||symbolID===("WAS-WSR-HCP----")||symbolID===("WAS-WSRSL-P----")||symbolID===("WAS-WSRSMHP----")||symbolID===("WAS-WSRST-P----")||symbolID===("WAS-WSD-LIP----")||symbolID===("WAS-WSD-LCP----")||symbolID===("WAS-WSD-MIP----")||symbolID===("WAS-WSD-MCP----")||symbolID===("WAS-WSD-HIP----")||symbolID===("WAS-WSD-HCP----")||symbolID===("WAS-WSM-L-P----")||symbolID===("WAS-WSM-MHP----")||symbolID===("WAS-WSMSL-P----")||symbolID===("WAS-WSMSMHP----")||symbolID===("WAS-WSS-LIP----")||symbolID===("WAS-WSS-LCP----")||symbolID===("WAS-WSS-MIP----")||symbolID===("WAS-WSS-MCP----")||symbolID===("WAS-WSS-HIP----")||symbolID===("WAS-WSS-HCP----")||symbolID===("WAS-WSSBLMP----")||symbolID===("WAS-WSSBH-P----")||symbolID===("WAS-WSSG--P----")||symbolID===("WAS-WSSSL-P----")||symbolID===("WAS-WSSSMHP----")||symbolID===("WAS-WSUKP-P----")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#00FF00");} +else if(symbolID===("WO-DHCF----L---")||symbolID===("WO-DHCF-----A--")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#ADFF2F");} +else if(symbolID===("WOS-HDS---P----")||symbolID===("WOS-HHDF--P----")||symbolID===("WO-DHHDF----A--")||symbolID===("WOS-HPFS--P----")||symbolID===("WOS-HPFS---L---")||symbolID===("WOS-HPFF----A--")||symbolID===("WO-DHDDL---L---")||symbolID===("WO-DHDDC---L---")||symbolID===("WO-DHCC----L---")||symbolID===("WO-DHPBP---L---")||symbolID===("WO-DHPMO---L---")||symbolID===("WO-DHPSPA--L---")||symbolID===("WO-DHPSPB--L---")||symbolID===("WO-DHPSPS--L---")||symbolID===("WO-DHHDK--P----")||symbolID===("WO-DHHDK----A--")||symbolID===("WO-DHHDB---L---")||symbolID===("WO-DTCCCFE-L---")||symbolID===("WO-DTCCCFF-L---")||symbolID===("WOS-TCCTD-P----")||symbolID===("WO-DHCW-----A--")||symbolID===("WO-DMOA-----A--")||symbolID===("WO-DHCW-----A--")) +retColor=armyc2.c2sd.renderer.utilities.Color.GRAY;else if(symbolID===("WO-DBSM-----A--")||symbolID===("WO-DBSF-----A--")||symbolID===("WO-DGMN-----A--")) +{retColor=new armyc2.c2sd.renderer.utilities.Color(230,230,230);} +else if(symbolID===("WO-DBSG-----A--")||symbolID==="WO-DBST-----A--") +{retColor=new armyc2.c2sd.renderer.utilities.Color(169,169,169);} +else if(symbolID===("WAS-WSVE--P----")||symbolID===("WAS-WSVA--P----")||symbolID===("WAS-WST-LVP----")||symbolID===("WAS-WSF-LVP----")) +{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} +else if(symbolID===("WOS-HPBA--P----")||symbolID===("WOS-HPBA---L---")||symbolID===("WOS-HPBA----A--")||symbolID===("WOS-HPCP--P----")||symbolID===("WOS-HPFH--P----")||symbolID===("WOS-HPM-FC-L---")||symbolID===("WOS-HABM--P----")||symbolID===("WOS-HAL---P----")||symbolID===("WA-DIPIT---L---")||symbolID===("WOS-TCCTG-P----")||symbolID===("WO-DL-ML---L---")||symbolID===("WOS-HPM-FC-L---")||symbolID===("WO-DL-RA---L---")||symbolID===("WO-DHPBA---L---")||symbolID===("WO-DMCA----L---")||symbolID===("WO-DHPBA----A--")||symbolID===("WO-DL-MA----A--")||symbolID===("WO-DL-SA----A--")||symbolID===("WO-DL-TA----A--")||symbolID===("WO-DGMSR----A--")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FF00FF");} +else if(symbolID.substring(0,7)===("WA-DPFO")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#E29FFF");} +else if(symbolID===("WA-DPXITCZ-L---")||symbolID===("WO-DL-O-----A--")||symbolID===("WA-DPXCV---L---")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#FF7F00");} +else if(symbolID===("WA-DBAI-----A--")||symbolID.indexOf("WAS-IC")===0||symbolID.indexOf("WAS-IR")===0||symbolID.indexOf("WAS-IM")===0) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#806010");} +else if(symbolID===("WO-DHCI-----A--")||symbolID===("WO-DHCB-----A--")||symbolID===("WO-DHPMO----A--")||symbolID===("WO-DHCI-----A--")) +{retColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString("#D2B06A");} +else if(symbolID===("WO-DOBVA----A--")) +{retColor=new armyc2.c2sd.renderer.utilities.Color(26,153,77);} +else if(symbolID===("WO-DGMBTI---A--")) +{retColor=new armyc2.c2sd.renderer.utilities.Color(255,48,0);} +else if(symbolID===("WO-DGMBTH---A--")) +{retColor=new armyc2.c2sd.renderer.utilities.Color(255,80,0);} +else if(symbolID===("WO-DGMBTG---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,127,0);} +else if(symbolID===("WO-DGMBTF---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,207,0);} +else if(symbolID===("WO-DGMBTA---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(48,255,0);} +else if(symbolID===("WO-DGML-----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(220,220,220);} +else if(symbolID===("WO-DGMS-SH--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,220,220);} +else if(symbolID===("WO-DGMS-PH--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,190,190);} +else if(symbolID===("WO-DOBVC----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(128,255,51);} +else if(symbolID===("WO-DOBVE----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,255,0);} +else if(symbolID===("WO-DGMS-CO--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,150,150);} +else if(symbolID===("WO-DGMBTC---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(175,255,0);} +else if(symbolID===("WO-DGMBTD---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(207,255,0);} +else if(symbolID===("WO-DGMBTB---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(127,255,0);} +else if(symbolID===("WO-DGMIBD---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,127,0);} +else if(symbolID===("WO-DGMSIF---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(25,255,230);} +else if(symbolID===("WO-DGMSIVF--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(0,215,255);} +else if(symbolID===("WO-DGMSSVF--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,255,220);} +else if(symbolID===("WO-DGMSSF---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,255,140);} +else if(symbolID===("WO-DGMSSM---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,235,0);} +else if(symbolID===("WO-DGMSSC---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,215,0);} +else if(symbolID===("WO-DGMSSVS--A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,180,0);} +else if(symbolID===("WO-DGMSIC---A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(200,255,105);} +else if(symbolID===("WO-DGMSC----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(100,130,255);} +else if(symbolID===("WO-DOBVH----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,77,0);} +else if(symbolID===("WO-DOBVG----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,128,0);} +else if(symbolID===("WO-DOBVF----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(255,204,0);} +else if(symbolID===("WO-DOBVD----A--")){retColor=new armyc2.c2sd.renderer.utilities.Color(204,255,26);} +else +{retColor=armyc2.c2sd.renderer.utilities.Color.BLACK;} +return retColor;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getFillColorOfWeather=function(symbolID){if(symbolID===("WOS-HPM-R-P----")) +return new armyc2.c2sd.renderer.utilities.Color(148,48,0);else if(symbolID===("WOS-HPD---P----")) +return new armyc2.c2sd.renderer.utilities.Color(148,48,0);else if(symbolID===("WO-DHCB-----A--")) +return new armyc2.c2sd.renderer.utilities.Color(249,243,241);else if(symbolID===("WOS-HABB--P----")) +return new armyc2.c2sd.renderer.utilities.Color(255,0,255);else if(symbolID===("WOS-HHRS--P----")) +return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-HHDS--P----")) +return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-HHDWB-P----")) +return new armyc2.c2sd.renderer.utilities.Color(0,204,255);else if(symbolID===("WOS-TCCTG-P----")) +return new armyc2.c2sd.renderer.utilities.Color(210,176,106);else if(symbolID===("WO-DHCW-----A--")) +return new armyc2.c2sd.renderer.utilities.Color(255,255,255);else if(symbolID===("WO-DHABP----A--")||symbolID===("WO-DMCC-----A--")) +{return new armyc2.c2sd.renderer.utilities.Color(0,0,255);} +else if((symbolID==="WO-DHHD-----A--")||symbolID==="WO-DHHDD----A--"||symbolID==="WO-DHDDA----A--") +{return new armyc2.c2sd.renderer.utilities.Color(0,191,255);} +else if(symbolID===("WO-DHPMD----A--")) +return new armyc2.c2sd.renderer.utilities.Color(188,153,58);else if(symbolID===("WO-DHCF----L---")||symbolID===("WO-DHCF-----A--")) +{return new armyc2.c2sd.renderer.utilities.Color(173,255,47);} +else return null;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getColorFromHexString=function(hexValue) +{var hexAlphabet="0123456789ABCDEF";if(hexValue.charAt(0)==='#') +hexValue=hexValue.substring(1);if(hexValue.substring(0,2)===("0x")||hexValue.substring(0,2)===("0X")) +hexValue=hexValue.substring(2);hexValue=hexValue.toUpperCase();var count=hexValue.length,value=null,k=0,int1=0,int2=0;if(count===8||count===6) +{value=[];for(var i=0;i5&&(hierarchy.indexOf("5.X.10")===0||hierarchy.indexOf("5.X.11")===0||hierarchy.indexOf("5.X.12")===0||hierarchy.indexOf("5.X.13")===0||hierarchy.indexOf("5.X.14")===0)) +{return true;} +else +return false;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isMOOTW=function(strSymbolID){if(strSymbolID.charAt(0)===('O')) +{return true;} +else +{return false;}};armyc2.c2sd.renderer.utilities.SymbolUtilities.isSTBOPS=function(strSymbolID){if(strSymbolID.substring(0,1)===('O')) +{return true;} +else +{return false;}};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEvent=function(strSymbolID) +{var arr=null;var category=strSymbolID.charAt(2);var strBasicSymbolID=this.getBasicSymbolIDStrict(strSymbolID);if(this.isMOOTW(strSymbolID)||(this.isEMS(strSymbolID)&&(category==='I'||category==='N'||category==='O'))) +return true;else +{arr=["S*G*EXI---*****","S*G*EXI---MO***"];var arrLength=arr.length;for(var i=0;i0)||(basicCode.substring(0,5)===("E*O*E")&&basicCode.indexOf("----*****")>0)||basicCode===("E*F*BA----*****")||basicCode===("E*F*LF----*****")||basicCode===("E*F*MA----*****")||basicCode===("E*F*MC----*****")) +{blRetVal=true;}} +return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMS=function(strSymbolID){return(strSymbolID[0]==='E');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMSNaturalEvent=function(strSymbolID){return(strSymbolID.charAt(0)==='E'&&strSymbolID.charAt(2)==='N');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMSIncident=function(strSymbolID){return(strSymbolID.charAt(0)==='E'&&strSymbolID.charAt(2)==='I');};armyc2.c2sd.renderer.utilities.SymbolUtilities.isEMSInstallation=function(strSymbolID){var blRetVal=false;if(strSymbolID.charAt(0)==='E') +{if(strSymbolID.charAt(2)==='O'&&strSymbolID.charAt(4)==='D'&&(strSymbolID.charAt(6)==='C'||strSymbolID.charAt(5)==='K')) +{blRetVal=true;} +else if(strSymbolID.charAt(2)==='F'&&strSymbolID.substring(4,6)!=="BA") +{blRetVal=true;} +else if(strSymbolID.charAt(2)==='O') +{if(strSymbolID.charAt(4)==='A') +{switch(strSymbolID.charAt(5)) +{case'C':case'D':case'G':case'J':case'K':case'L':case'M':blRetVal=true;break;default:break;}} +else if(strSymbolID.charAt(4)=='B') +{switch(strSymbolID.charAt(5)) +{case'C':case'E':case'F':case'G':case'H':case'I':case'K':case'L':blRetVal=true;break;default:break;}} +else if(strSymbolID.charAt(4)=='C') +{switch(strSymbolID.charAt(5)) +{case'D':case'E':blRetVal=true;break;default:break;}}}} +return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isInstallation=function(strSymbolID){var blRetVal=false;if(strSymbolID.charAt(0)==='S') +{blRetVal=(strSymbolID.charAt(2)==='G')&&(strSymbolID.charAt(4)==='I');} +else if(strSymbolID.charAt(0)===('E')) +{blRetVal=this.isEMSInstallation(strSymbolID);} +return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isSIGINT=function(strSymbolID){var blRetVal=((strSymbolID.charAt(0)===('I')));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isFeintDummyInstallation=function(strSymbolID){var blRetVal=(strSymbolID.charAt(10)===('H')&&strSymbolID.charAt(11)===('B'));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasInstallationModifier=function(strSymbolID){var blRetVal=(strSymbolID.charAt(10)===('H'));return blRetVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.getAffiliation=function(strSymbolID){return strSymbolID.charAt(1);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getStatus=function(strSymbolID){return strSymbolID.charAt(3);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getEchelon=function(strSymbolID){return strSymbolID.charAt(11);};armyc2.c2sd.renderer.utilities.SymbolUtilities.getUnitAffiliationModifier=function(symbolID,symStd){var textChar=null,affiliation=null;if(symStd===undefined) +{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} +affiliation=symbolID.charAt(1);if(affiliation===('F')||affiliation===('H')||affiliation===('U')||affiliation===('N')||affiliation===('P')) +{textChar=null;} +else if(affiliation===('A')||affiliation===('S')) +{if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525B) +textChar="?";else +textChar=null;} +else if(affiliation===('J')) +textChar="J";else if(affiliation===('K')) +textChar="K";else if(affiliation===('D')||affiliation===('L')||affiliation===('G')||affiliation===('W')) +textChar="X";else if(affiliation===('M')) +{if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525B) +textChar="X?";else +textChar="X";} +if(symStd===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525C) +{if(symbolID.charAt(4)==='W'&&symbolID.charAt(0)==='S'&&symbolID.charAt(5)==='M') +{var temp=symbolID.substring(6,8);if(temp==="GX"||temp==="MX"||temp==="FX"||temp==="SX"||temp.charAt(0)==="X") +textChar="X";else +textChar=null;}} +return textChar;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasAMmodifierWidth=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolIDStrict(symbolID);if(symStd===undefined) +{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} +var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolIDStrict(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) +{var dc=sd.drawCategory;switch(dc) +{case SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:returnVal=true;break;case SymbolDefTable.DRAW_CATEGORY_LINE:if(sd.modifiers.indexOf(armyc2.c2sd.renderer.utilities.ModifiersTG.AM_DISTANCE+".")>-1) +returnVal=true;break;default:returnVal=false;}} +return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasAMmodifierRadius=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolIDStrict(symbolID);if(symStd===undefined) +{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} +var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolIDStrict(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) +{var dc=sd.drawCategory;switch(dc) +{case SymbolDefTable.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} +return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.hasANmodifier=function(symbolID,symStd){var sd=null,returnVal=false,basic=this.getBasicSymbolIDStrict(symbolID);if(symStd===undefined) +{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} +var SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;basic=this.getBasicSymbolIDStrict(symbolID);sd=SymbolDefTable.getSymbolDef(basic,symStd);if(sd!==null) +{var dc=sd.drawCategory;switch(dc) +{case SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:returnVal=true;break;default:returnVal=false;}} +return returnVal;};armyc2.c2sd.renderer.utilities.SymbolUtilities.isMultiPoint=function(symbolID,symStd){return armyc2.c2sd.renderer.utilities.SymbolDefTable.isMultiPoint(symbolID,symStd);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ShapeInfo=function(shape,shapeType) +{var _Shape=null,stroke=null,gp=null,fillStyle=null,texturePaint=null,_shapeType=-1,lineColor=null,fillColor=null,lineWidth=2,affineTransform=null,_TextLayout=null,_Position=null,_ModifierString=null,_ModifierStringPosition=null,_ModifierStringAngle=0,_Tag=null,_justify=armyc2.c2sd.renderer.utilities.ShapeInfo.justify_left,_Polylines=null;if(shapeType) +{_shapeType=shapeType;} +if(shape) +{_Shape=shape;}};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getShape=function() +{return this._Shape;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setShape=function(value) +{this._Shape=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setModifierString=function(value) +{this._ModifierString=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getModifierString=function() +{return this._ModifierString;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setModifierStringPosition=function(value) +{this._ModifierStringPosition=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getModifierStringPosition=function() +{return this._ModifierStringPosition;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getGlyphPosition=function() +{return this._Position;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setGlyphPosition=function(value) +{this._Position=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setModifierStringAngle=function(value) +{this._ModifierStringAngle=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getModifierStringAngle=function() +{return this._ModifierStringAngle;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setTag=function(value) +{this._Tag=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getTag=function() +{return this._Tag;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setLineColor=function(value) +{this.lineColor=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getLineColor=function() +{return this.lineColor;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setFillColor=function(value) +{this.fillColor=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getFillColor=function() +{return this.fillColor;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setAffineTransform=function(value) +{this.affineTransform=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getAffineTransform=function() +{return this.affineTransform;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setStroke=function(value) +{this.stroke=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getStroke=function() +{return this.stroke;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getTexturePaint=function() +{return this.texturePaint;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setTexturePaint=function(value) +{this.texturePaint=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getFillStyle=function() +{return this.fillStyle;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setFillStyle=function(value) +{this.fillStyle=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setTextLayout=function(value) +{this._TextLayout=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getTextLayout=function() +{return this._TextLayout;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setShapeType=function(value) +{this._shapeType=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getShapeType=function() +{return this._shapeType;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setPolylines=function(value) +{this._Polylines=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getPolylines=function() +{return this._Polylines;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.setTextJustify=function(value) +{this._justify=value;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getTextJustify=function() +{return this._justify;};armyc2.c2sd.renderer.utilities.ShapeInfo.prototype.getBounds=function() +{var temp=null;if(this._Shape!==null) +{temp=this._Shape.getBounds();if(this._Shape instanceof armyc2.c2sd.graphics2d.GeneralPath) +{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_OUTLINE) +{if(this.lineColor!==null&&this.stroke!==null){var bs=this.stroke;if(bs!==null&&bs.getLineWidth()>2) +temp.grow(Math.floor(Math.round(bs.getLineWidth())/2),Math.floor(Math.round(bs.getLineWidth())/2));}} +else +{if(lineColor!==null&&stroke!==null) +{var bs=this.stroke;if(bs!==null&&bs.getLineWidth()>2) +temp.grow(Math.round(bs.getLineWidth())-1,Math.round(bs.getLineWidth())-1);}}}} +if(this._TextLayout!==null&&this._Position!==null){temp=_TextLayout.getPixelBounds(null,this._Position.getX(),this._Position.getY());}else if(this._TextLayout!==null){temp=new armyc2.c2sd.graphics2d.Rectangle(0,0,0,0);temp.setRect(this._TextLayout.getBounds());}else +return null;if(this.affineTransform!==null){var sTemp=temp;sTemp=this.affineTransform.createTransformedShape(temp);temp=sTemp.getBounds();} +return temp;};armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_POLYLINE=0;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL=1;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_MODIFIER=2;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_MODIFIER_FILL=3;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_FRAME=4;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_FILL=5;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_SYMBOL1=6;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_SYMBOL2=7;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_DISPLAY_MODIFIER=8;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_ECHELON=9;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_AFFILIATION_MODIFIER=10;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_HQ_STAFF=11;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_FILL=12;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_FRAME=13;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_Q_MODIFIER=14;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_TG_SP_OUTLINE=15;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_SINGLE_POINT_OUTLINE=16;armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_UNIT_OUTLINE=17;armyc2.c2sd.renderer.utilities.ShapeInfo.justify_left=0;armyc2.c2sd.renderer.utilities.ShapeInfo.justify_center=1;armyc2.c2sd.renderer.utilities.ShapeInfo.justify_right=2;armyc2.c2sd.renderer.utilities.ShapeInfoTextLayout=function(textLayout,position) +{var si=armyc2.c2sd.renderer.utilities.ShapeInfo();si.setTextLayout(textLayout);si.setGlyphPosition(position);};armyc2.c2sd.renderer.utilities.ShapeInfoGlyphVector=function(glyphVector,position) +{var si=armyc2.c2sd.renderer.utilities.ShapeInfo();si.setGlyphPosition(position);};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolDefTable=(function(){var symbolMapB=null,symbolMapC=null,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;return{DRAW_CATEGORY_DONOTDRAW:0,DRAW_CATEGORY_LINE:1,DRAW_CATEGORY_AUTOSHAPE:2,DRAW_CATEGORY_POLYGON:3,DRAW_CATEGORY_ARROW:4,DRAW_CATEGORY_ROUTE:5,DRAW_CATEGORY_TWOPOINTLINE:6,DRAW_CATEGORY_POINT:8,DRAW_CATEGORY_TWOPOINTARROW:9,DRAW_CATEGORY_SUPERAUTOSHAPE:15,DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:16,DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:17,DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:18,DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:19,DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:20,DRAW_CATEGORY_3D_AIRSPACE:40,DRAW_CATEGORY_UNKNOWN:99,xmlDoc:null,init:function() +{var i,data=null,symbol=null,symbols,count;if(symbolMapB===null&&armyc2.c2sd.renderer.xml.SymbolConstantsB!==undefined) +{symbols=armyc2.c2sd.renderer.xml.SymbolConstantsB.SYMBOLCONSTANTS.SYMBOL;armyc2.c2sd.renderer.xml.SymbolConstantsB=null;symbolMapB={};count=symbols.length;for(i=0;i1) +{returnVal=true;} +else +{switch(sd.drawCategory) +{case this.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:case this.DRAW_CATEGORY_ROUTE:returnVal=true;break;default:returnVal=false;}} +return returnVal;}else{return false;}} +else if(symbolID.substring(0,3)==="BS_"||symbolID.substring(0,4)==="BBS_"||symbolID.substring(0,4)==="PBS_") +{return true;} +else +{return false;}}};}());var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.Angle=function() +{};org.gavaghan.geodesy.Angle.toRadians=function(degrees){return degrees*0.017453292519943295;};org.gavaghan.geodesy.Angle.toDegrees=function(radians){return radians/0.017453292519943295;};org.gavaghan.geodesy.Angle.PiOver180=0.017453292519943295;var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.Ellipsoid=function() +{this.mSemiMajorAxis=0;this.mSemiMinorAxis=0;this.mFlattening=0;this.mInverseFlattening=0;var semiMajor=arguments[0];var semiMinor=arguments[1];var flattening=arguments[2];var inverseFlattening=arguments[3];this.mSemiMajorAxis=semiMajor;this.mSemiMinorAxis=semiMinor;this.mFlattening=flattening;this.mInverseFlattening=inverseFlattening;this.getSemiMajorAxis=function(){return this.mSemiMajorAxis;};this.getSemiMinorAxis=function(){return this.mSemiMinorAxis;};this.getFlattening=function(){return this.mFlattening;};this.getInverseFlattening=function(){return this.mInverseFlattening;};};org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF=function(semiMajor,inverseFlattening){var f=1.0/inverseFlattening;var b=(1.0-f)*semiMajor;return new org.gavaghan.geodesy.Ellipsoid(semiMajor,b,f,inverseFlattening);};org.gavaghan.geodesy.Ellipsoid.fromAAndF=function(semiMajor,flattening){var inverseF=1.0/flattening;var b=(1.0-flattening)*semiMajor;return new org.gavaghan.geodesy.Ellipsoid(semiMajor,b,flattening,inverseF);};org.gavaghan.geodesy.Ellipsoid.WGS84=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378137.0,298.257223563);org.gavaghan.geodesy.Ellipsoid.GRS80=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378137.0,298.257222101);org.gavaghan.geodesy.Ellipsoid.GRS67=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378160.0,298.25);org.gavaghan.geodesy.Ellipsoid.ANS=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378160.0,298.25);org.gavaghan.geodesy.Ellipsoid.WGS72=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378135.0,298.26);org.gavaghan.geodesy.Ellipsoid.Clarke1858=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378293.645,294.26);org.gavaghan.geodesy.Ellipsoid.Clarke1880=org.gavaghan.geodesy.Ellipsoid.fromAAndInverseF(6378249.145,293.465);org.gavaghan.geodesy.Ellipsoid.Sphere=org.gavaghan.geodesy.Ellipsoid.fromAAndF(6371000,0.0);var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticCalculator=function() +{this.TwoPi=6.283185307179586;this.calculateEndingGlobalCoordinates=function(ellipsoid,start,startBearing,distance){return org.gavaghan.geodesy.GeodeticCalculator.calculateEndingGlobalCoordinates(ellipsoid,start,startBearing,distance,null);};this.calculateGeodeticCurve=function(ellipsoid,start,end){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var lambda1=org.gavaghan.geodesy.Angle.toRadians(start.getLongitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var lambda2=org.gavaghan.geodesy.Angle.toRadians(end.getLongitude());var a2=a*a;var b2=b*b;var a2b2b2=(a2-b2)/b2;var omega=lambda2-lambda1;var tanphi1=Math.tan(phi1);var tanU1=(1.0-f)*tanphi1;var U1=Math.atan(tanU1);var sinU1=Math.sin(U1);var cosU1=Math.cos(U1);var tanphi2=Math.tan(phi2);var tanU2=(1.0-f)*tanphi2;var U2=Math.atan(tanU2);var sinU2=Math.sin(U2);var cosU2=Math.cos(U2);var sinU1sinU2=sinU1*sinU2;var cosU1sinU2=cosU1*sinU2;var sinU1cosU2=sinU1*cosU2;var cosU1cosU2=cosU1*cosU2;var lambda=omega;var A=0.0;var B=0.0;var sigma=0.0;var deltasigma=0.0;var lambda0;var converged=false;for(var i=0;i<20;i++){lambda0=lambda;var sinlambda=Math.sin(lambda);var coslambda=Math.cos(lambda);var sin2sigma=(cosU2*sinlambda*cosU2*sinlambda)+(cosU1sinU2-sinU1cosU2*coslambda)*(cosU1sinU2-sinU1cosU2*coslambda);var sinsigma=Math.sqrt(sin2sigma);var cossigma=sinU1sinU2+(cosU1cosU2*coslambda);sigma=Math.atan2(sinsigma,cossigma);var sinalpha=(sin2sigma===0)?0.0:cosU1cosU2*sinlambda/sinsigma;var alpha=Math.asin(sinalpha);var cosalpha=Math.cos(alpha);var cos2alpha=cosalpha*cosalpha;var cos2sigmam=cos2alpha===0.0?0.0:cossigma-2*sinU1sinU2/cos2alpha;var u2=cos2alpha*a2b2b2;var cos2sigmam2=cos2sigmam*cos2sigmam;A=1.0+u2/16384*(4096+u2*(-768+u2*(320-175*u2)));B=u2/1024*(256+u2*(-128+u2*(74-47*u2)));deltasigma=B*sinsigma*(cos2sigmam+B/4*(cossigma*(-1+2*cos2sigmam2)-B/6*cos2sigmam*(-3+4*sin2sigma)*(-3+4*cos2sigmam2)));var C=f/16*cos2alpha*(4+f*(4-3*cos2alpha));lambda=omega+(1-C)*f*sinalpha*(sigma+C*sinsigma*(cos2sigmam+C*cossigma*(-1+2*cos2sigmam2)));var change=Math.abs((lambda-lambda0)/lambda);if((i>1)&&(change<0.0000000000001)){converged=true;break;}} +var s=b*A*(sigma-deltasigma);var alpha1;var alpha2;if(!converged){if(phi1>phi2){alpha1=180.0;alpha2=0.0;}else if(phi1=360.0) +alpha1-=360.0;if(alpha2>=360.0) +alpha2-=360.0;return new org.gavaghan.geodesy.GeodeticCurve(s,alpha1,alpha2);};this.calculateGeodeticMeasurement=function(refEllipsoid,start,end){var elev1=start.getElevation();var elev2=end.getElevation();var elev12=(elev1+elev2)/2.0;var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var phi12=(phi1+phi2)/2.0;var refA=refEllipsoid.getSemiMajorAxis();var f=refEllipsoid.getFlattening();var a=refA+elev12*(1.0+f*Math.sin(phi12));var ellipsoid=org.gavaghan.geodesy.Ellipsoid.fromAAndF(a,f);var start1=new org.gavaghan.geodesy.GlobalCoordinates(start.getLatitude(),start.getLongitude());var end1=new org.gavaghan.geodesy.GlobalCoordinates(end.getLatitude(),end.getLongitude());var averageCurve=org.gavaghan.geodesy.GeodeticCalculator.calculateGeodeticCurve(ellipsoid,start1,end1);return new org.gavaghan.geodesy.GeodeticMeasurement(averageCurve,elev2-elev1);};};org.gavaghan.geodesy.GeodeticCalculator.calculateEndingGlobalCoordinates=function(ellipsoid,start,startBearing,distance,endBearing){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var aSquared=a*a;var bSquared=b*b;var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var alpha1=org.gavaghan.geodesy.Angle.toRadians(startBearing);var cosAlpha1=Math.cos(alpha1);var sinAlpha1=Math.sin(alpha1);var s=distance;var tanU1=(1.0-f)*Math.tan(phi1);var cosU1=1.0/Math.sqrt(1.0+tanU1*tanU1);var sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var sin2Alpha=sinAlpha*sinAlpha;var cos2Alpha=1-sin2Alpha;var uSquared=cos2Alpha*(aSquared-bSquared)/bSquared;var A=1+(uSquared/16384)*(4096+uSquared*(-768+uSquared*(320-175*uSquared)));var B=(uSquared/1024)*(256+uSquared*(-128+uSquared*(74-47*uSquared)));var deltaSigma;var sOverbA=s/(b*A);var sigma=sOverbA;var sinSigma;var prevSigma=sOverbA;var sigmaM2;var cosSigmaM2;var cos2SigmaM2;for(;;){sigmaM2=2.0*sigma1+sigma;cosSigmaM2=Math.cos(sigmaM2);cos2SigmaM2=cosSigmaM2*cosSigmaM2;sinSigma=Math.sin(sigma);var cosSignma=Math.cos(sigma);deltaSigma=B*sinSigma*(cosSigmaM2+(B/4.0)*(cosSignma*(-1+2*cos2SigmaM2)-(B/6.0)*cosSigmaM2*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM2)));sigma=sOverbA+deltaSigma;if(Double.isNaN(sigma)||Double.isNaN(prevSigma)){throw new RuntimeException("Point values may be the same; approximation convereged to NaN");} +if(Math.abs(sigma-prevSigma)<0.0000000000001) +break;prevSigma=sigma;} +sigmaM2=2.0*sigma1+sigma;cosSigmaM2=Math.cos(sigmaM2);cos2SigmaM2=cosSigmaM2*cosSigmaM2;var cosSigma=Math.cos(sigma);sinSigma=Math.sin(sigma);var phi2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1.0-f)*Math.sqrt(sin2Alpha+Math.pow(sinU1*sinSigma-cosU1*cosSigma*cosAlpha1,2.0)));var lambda=Math.atan2(sinSigma*sinAlpha1,(cosU1*cosSigma-sinU1*sinSigma*cosAlpha1));var C=(f/16)*cos2Alpha*(4+f*(4-3*cos2Alpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cosSigmaM2+C*cosSigma*(-1+2*cos2SigmaM2)));var alpha2=Math.atan2(sinAlpha,-sinU1*sinSigma+cosU1*cosSigma*cosAlpha1);var latitude=org.gavaghan.geodesy.Angle.toDegrees(phi2);var longitude=start.getLongitude()+org.gavaghan.geodesy.Angle.toDegrees(L);if((endBearing!==null)&&(endBearing.length>0)){endBearing[0]=org.gavaghan.geodesy.Angle.toDegrees(alpha2);} +return new org.gavaghan.geodesy.GlobalCoordinates(latitude,longitude);};org.gavaghan.geodesy.GeodeticCalculator.calculateGeodeticCurve=function(ellipsoid,start,end){var a=ellipsoid.getSemiMajorAxis();var b=ellipsoid.getSemiMinorAxis();var f=ellipsoid.getFlattening();var phi1=org.gavaghan.geodesy.Angle.toRadians(start.getLatitude());var lambda1=org.gavaghan.geodesy.Angle.toRadians(start.getLongitude());var phi2=org.gavaghan.geodesy.Angle.toRadians(end.getLatitude());var lambda2=org.gavaghan.geodesy.Angle.toRadians(end.getLongitude());var a2=a*a;var b2=b*b;var a2b2b2=(a2-b2)/b2;var omega=lambda2-lambda1;var tanphi1=Math.tan(phi1);var tanU1=(1.0-f)*tanphi1;var U1=Math.atan(tanU1);var sinU1=Math.sin(U1);var cosU1=Math.cos(U1);var tanphi2=Math.tan(phi2);var tanU2=(1.0-f)*tanphi2;var U2=Math.atan(tanU2);var sinU2=Math.sin(U2);var cosU2=Math.cos(U2);var sinU1sinU2=sinU1*sinU2;var cosU1sinU2=cosU1*sinU2;var sinU1cosU2=sinU1*cosU2;var cosU1cosU2=cosU1*cosU2;var lambda=omega;var A=0.0;var B=0.0;var sigma=0.0;var deltasigma=0.0;var lambda0;var converged=false;for(var i=0;i<20;i++){lambda0=lambda;var sinlambda=Math.sin(lambda);var coslambda=Math.cos(lambda);var sin2sigma=(cosU2*sinlambda*cosU2*sinlambda)+(cosU1sinU2-sinU1cosU2*coslambda)*(cosU1sinU2-sinU1cosU2*coslambda);var sinsigma=Math.sqrt(sin2sigma);var cossigma=sinU1sinU2+(cosU1cosU2*coslambda);sigma=Math.atan2(sinsigma,cossigma);var sinalpha=(sin2sigma===0)?0.0:cosU1cosU2*sinlambda/sinsigma;var alpha=Math.asin(sinalpha);var cosalpha=Math.cos(alpha);var cos2alpha=cosalpha*cosalpha;var cos2sigmam=cos2alpha===0.0?0.0:cossigma-2*sinU1sinU2/cos2alpha;var u2=cos2alpha*a2b2b2;var cos2sigmam2=cos2sigmam*cos2sigmam;A=1.0+u2/16384*(4096+u2*(-768+u2*(320-175*u2)));B=u2/1024*(256+u2*(-128+u2*(74-47*u2)));deltasigma=B*sinsigma*(cos2sigmam+B/4*(cossigma*(-1+2*cos2sigmam2)-B/6*cos2sigmam*(-3+4*sin2sigma)*(-3+4*cos2sigmam2)));var C=f/16*cos2alpha*(4+f*(4-3*cos2alpha));lambda=omega+(1-C)*f*sinalpha*(sigma+C*sinsigma*(cos2sigmam+C*cossigma*(-1+2*cos2sigmam2)));var change=Math.abs((lambda-lambda0)/lambda);if((i>1)&&(change<0.0000000000001)){converged=true;break;}} +var s=b*A*(sigma-deltasigma);var alpha1;var alpha2;if(!converged){if(phi1>phi2){alpha1=180.0;alpha2=0.0;}else if(phi1=360.0) +alpha1-=360.0;if(alpha2>=360.0) +alpha2-=360.0;return new org.gavaghan.geodesy.GeodeticCurve(s,alpha1,alpha2);};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticCurve=function() +{this.mEllipsoidalDistance=0;this.mAzimuth=0;this.mReverseAzimuth=0;var ellipsoidalDistance=arguments[0];var azimuth=arguments[1];var reverseAzimuth=arguments[2];this.mEllipsoidalDistance=ellipsoidalDistance;this.mAzimuth=azimuth;this.mReverseAzimuth=reverseAzimuth;this.getEllipsoidalDistance=function(){return this.mEllipsoidalDistance;};this.getAzimuth=function(){return this.mAzimuth;};this.getReverseAzimuth=function(){return this.mReverseAzimuth;};this.toString=function(){var buffer="";buffer+="s=";buffer+=this.mEllipsoidalDistance;buffer+=";a12=";buffer+=this.mAzimuth;buffer+=";a21=";buffer+=this.mReverseAzimuth;buffer+=";";return buffer;};};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GeodeticMeasurement=function() +{this.mElevationChange=0;this.mP2P=0;this.mEllipsoidalDistance=0;this.mAzimuth=0;this.mReverseAzimuth=0;var ellipsoidalDistance;var azimuth;var reverseAzimuth;var elevationChange;if(arguments.length===4) +{ellipsoidalDistance=arguments[0];azimuth=arguments[1];reverseAzimuth=arguments[2];elevationChange=arguments[3];this.mEllipsoidalDistance=ellipsoidalDistance;this.mAzimuth=azimuth;this.mReverseAzimuth=reverseAzimuth;this.mElevationChange=elevationChange;this.mP2P=Math.sqrt(ellipsoidalDistance*ellipsoidalDistance+this.mElevationChange*this.mElevationChange);} +if(arguments.length===2) +{var averageCurve=arguments[0];elevationChange=arguments[1];this.mEllipsoidalDistance=averageCurve.getEllipsoidalDistance();this.mAzimuth=averageCurve.getAzimuth();this.mReverseAzimuth=averageCurve.getReverseAzimuth();this.mElevationChange=elevationChange;} +this.getElevationChange=function(){return this.mElevationChange;};this.getPointToPointDistance=function(){return this.mP2P;};this.toString=function(){var buffer="";buffer+="s=";buffer+=this.mEllipsoidalDistance;buffer+=";a12=";buffer+=this.mAzimuth;buffer+=";a21=";buffer+=this.mReverseAzimuth;buffer+=";";buffer+=("elev12=");buffer+=(this.mElevationChange);buffer+=(";p2p=");buffer+=(this.mP2P);return buffer;};};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GlobalCoordinates=function() +{this.mLatitude=0;this.mLongitude=0;var latitude=arguments[0];var longitude=arguments[1];this.mLatitude=latitude;this.mLongitude=longitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);this.canonicalize=function() +{this.mLatitude=(this.mLatitude+180)%360;if(this.mLatitude<0) +this.mLatitude+=360;this.mLatitude-=180;if(this.mLatitude>90){this.mLatitude=180-this.mLatitude;this.mLongitude+=180;}else if(this.mLatitude<-90){this.mLatitude=-180-this.mLatitude;this.mLongitude+=180;} +this.mLongitude=((this.mLongitude+180)%360);if(this.mLongitude<=0) +this.mLongitude+=360;this.mLongitude-=180;};this.getLatitude=function(){return this.mLatitude;};this.setLatitude=function(latitude){this.mLatitude=latitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);};this.getLongitude=function(){return this.mLongitude;};this.setLongitude=function(longitude){this.mLongitude=longitude;org.gavaghan.geodesy.GlobalCoordinates.canonicalize(this);};this.compareTo=function(other){var retval;if(this.mLongitudeother.mLongitude) +retval=1;else if(this.mLatitudeother.mLatitude) +retval=1;else +retval=0;return retval;};this.hashCode=function(){return(Math.round((this.mLongitude*this.mLatitude*1000000+1021)))*1000033;};this.equals=function(obj){if(!(Clazz.instanceOf(obj,org.gavaghan.geodesy.GlobalCoordinates))) +return false;var other=obj;return(this.mLongitude===other.mLongitude)&&(this.mLatitude===other.mLatitude);};this.toString=function(){var buffer="";buffer+=(Math.abs(this.mLatitude));buffer+=(((this.mLatitude>=0)?'N':'S')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=(Math.abs(this.mLongitude));buffer+=(((this.mLongitude>=0)?'E':'W')).charCodeAt(0);buffer+=((';')).charCodeAt(0);return buffer;};};org.gavaghan.geodesy.GlobalCoordinates.canonicalize=function(that) +{that.mLatitude=(that.mLatitude+180)%360;if(that.mLatitude<0) +that.mLatitude+=360;that.mLatitude-=180;if(that.mLatitude>90){that.mLatitude=180-that.mLatitude;that.mLongitude+=180;}else if(that.mLatitude<-90){that.mLatitude=-180-that.mLatitude;that.mLongitude+=180;} +that.mLongitude=((that.mLongitude+180)%360);if(that.mLongitude<=0) +that.mLongitude+=360;that.mLongitude-=180;};var org=org||{};org.gavaghan=org.gavaghan||{};org.gavaghan.geodesy=org.gavaghan.geodesy||{};org.gavaghan.geodesy.GlobalPosition=function() +{this.mElevation=0;this.mLatitude=0;this.mLongitude=0;var latitude;var longitude;var elevation;if(arguments.length===3) +{latitude=arguments[0];longitude=arguments[1];elevation=arguments[2];this.mLatitude=latitude;this.mLongitude=longitude;org.gavaghan.geodesy.GlobalPosition.canonicalize(this);this.mElevation=elevation;} +if(arguments.length===2) +{var coords=arguments[0];elevation=arguments[1];this.mLatitude=coords.getLatitude();this.mLongitude=coords.getLongitude();org.gavaghan.geodesy.GlobalPosition.canonicalize(this);this.mElevation=elevation;} +this.getElevation=function(){return this.mElevation;};this.setElevation=function(elevation){this.mElevation=elevation;};this.compareTo=function(other){var retval;if(this.mLongitudeother.mLongitude) +retval=1;else if(this.mLatitudeother.mLatitude) +retval=1;else +retval=0;if(retval===0){if(this.mElevationother.mElevation) +retval=1;} +return retval;};this.hashCode=function(){var hash=Clazz.superCall(this,org.gavaghan.geodesy.GlobalPosition,"hashCode",[]);if(this.mElevation!==0) +hash*=Math.round(this.mElevation);return hash;};this.equals=function(obj){if(!(Clazz.instanceOf(obj,org.gavaghan.geodesy.GlobalPosition))) +return false;var other=obj;return(this.mElevation===other.mElevation)&&(Clazz.superCall(this,org.gavaghan.geodesy.GlobalPosition,"equals",[other]));};this.toString=function(){var buffer="";buffer+=(Math.abs(this.mLatitude));buffer+=(((this.mLatitude>=0)?'N':'S')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=(Math.abs(this.mLongitude));buffer+=(((this.mLongitude>=0)?'E':'W')).charCodeAt(0);buffer+=((';')).charCodeAt(0);buffer+=("elevation=");buffer+=(Double.toString(this.mElevation));buffer+=("m");return buffer;};this.canonicalize=function(){this.mLatitude=(this.mLatitude+180)%360;if(this.mLatitude<0) +this.mLatitude+=360;this.mLatitude-=180;if(this.mLatitude>90){this.mLatitude=180-this.mLatitude;this.mLongitude+=180;}else if(this.mLatitude<-90){this.mLatitude=-180-this.mLatitude;this.mLongitude+=180;} +this.mLongitude=((this.mLongitude+180)%360);if(this.mLongitude<=0) +this.mLongitude+=360;this.mLongitude-=180;};this.getLatitude=function(){return this.mLatitude;};this.getLongitude=function(){return this.mLongitude;};};org.gavaghan.geodesy.GlobalPosition.canonicalize=function(obj){obj.mLatitude=(obj.mLatitude+180)%360;if(obj.mLatitude<0) +obj.mLatitude+=360;obj.mLatitude-=180;if(obj.mLatitude>90){obj.mLatitude=180-obj.mLatitude;obj.mLongitude+=180;}else if(obj.mLatitude<-90){obj.mLatitude=-180-obj.mLatitude;obj.mLongitude+=180;} +obj.mLongitude=((obj.mLongitude+180)%360);if(obj.mLongitude<=0) +this.mLongitude+=360;obj.mLongitude-=180;};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoArc=function() +{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} +var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoArc.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distancerightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} +var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){count++;var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoArc.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D(0,0).distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} +break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} +it.next();}} +this.path.append(newPath,true);this.toPoints.add(point);};this.getToPoints=function(){return this.toPoints;};this.closePath=function(){var pt0=this.toPoints.get(0);var pt1=this.toPoints.get(this.toPoints.size()-1);if(pt0===null||pt1===null) +return;if(this.toPoints.size()>0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.geoCalc=null;var pivot=arguments[0];var widthMeters=arguments[1];var heightMeters=arguments[2];var leftAzimuth=arguments[3];var rightAzimuth=arguments[4];var maxDistanceMeters=arguments[5];var flatnessDistanceMeters=arguments[6];var limit=arguments[7];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;this.flatnessDistanceMeters=flatnessDistanceMeters;this.limit=limit;this.moveTo(pivot);this.arcTo(pivot,widthMeters,heightMeters,leftAzimuth,rightAzimuth);this.closePath();};sec.geo.GeoArc.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoBlock=function() +{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.simplify=function(){var pi=this.path.getPathIterator(null);var pts=pi.getPoints();var newPts=new java.util.ArrayList();var j=0;var style=-1;var lastStyle=-1;var nextstyle=-1;var currentPt=null;var lastPt=null;for(j=0;j0){lastStyle=pts.get(j-1).style;lastPt=pts.get(j-1);} +if(lastStyle===1&&style===0){if(currentPt.x===lastPt.x&¤tPt.y===lastPt.y) +continue;} +newPts.add(currentPt);} +pi.setPathIterator(newPts);};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} +var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.geoCalc=null;var p1=arguments[0];var p2=arguments[1];var widthMeters=arguments[2];var maxDistanceMeters=arguments[3];var flatnessDistanceMeters=arguments[4];var limit=arguments[5];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;var c1=this.toGlobalCoord(p1);var c2=this.toGlobalCoord(p2);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,c2);var a1=curve.getAzimuth();var a2=curve.getReverseAzimuth();var radius=widthMeters/2;if(p1.x===p2.x&&p1.y===p2.y) +return;var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,a1-90,radius);this.moveToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c2,a2+90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c2,a2-90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock.REFERENCE_ELLIPSOID,c1,a1+90,radius);this.lineToLatLong(c.getLongitude(),c.getLatitude());this.closePath();};sec.geo.GeoBlock.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoBlock2=function() +{this.moveTo=function(point){this.path.moveTo(point.x,point.y);this.toPoints.add(point);};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){this.moveTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} +var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at,flatness){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};this.simplify=function(){var pi=this.path.getPathIterator(null);var pts=pi.getPoints();var newPts=new java.util.ArrayList();var j=0;var style=-1;var lastStyle=-1;var nextstyle=-1;var currentPt=null;var lastPt=null;for(j=0;j0){lastStyle=pts.get(j-1).style;lastPt=pts.get(j-1);} +if(lastStyle===1&&style===0){if(currentPt.x===lastPt.x&¤tPt.y===lastPt.y)continue;} +newPts.add(currentPt);} +pi.setPathIterator(newPts);};this.path=null;this.toPoints=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.geoCalc=null;var p1=arguments[0];var p2=arguments[1];var leftWidthMeters=arguments[2];var rightWidthMeters=arguments[3];var maxDistanceMeters=arguments[4];var flatnessDistanceMeters=arguments[5];var limit=arguments[6];this.path=new armyc2.c2sd.graphics2d.GeneralPath();this.toPoints=new java.util.ArrayList();this.geoCalc=new org.gavaghan.geodesy.GeodeticCalculator();this.maxDistanceMeters=maxDistanceMeters;var c1=this.toGlobalCoord(p1);var c2=this.toGlobalCoord(p2);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,c2);var a1=curve.getAzimuth();var a2=curve.getReverseAzimuth();var leftRadius=leftWidthMeters;var rightRadius=rightWidthMeters;if(p1.x===p2.x&&p1.y===p2.y) +return;var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,a1-90,leftRadius);this.moveToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c2,a2+90,leftRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c2,a2-90,rightRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoBlock2.REFERENCE_ELLIPSOID,c1,a1+90,rightRadius);this.lineToLatLong(c.getLongitude(),c.getLatitude());this.closePath();};sec.geo.GeoBlock2.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoEllipse=function() +{this.arcTo=function(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var arc;if(leftAzimuthDegrees>rightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} +var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoEllipse.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D().distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} +break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} +it.next();}} +this.path.append(newPath,true);this.toPoints.add(point);};this.lineTo=function(point){var newPath=new armyc2.c2sd.graphics2d.GeneralPath();var lastPoint=new sec.geo.GeoPoint();if(this.toPoints.size()>0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} +var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoEllipse.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distance0){lastPoint=this.toPoints.get(this.toPoints.size()-1);newPath.moveTo(lastPoint.x,lastPoint.y);} +var start=this.toGlobalCoord(lastPoint);var end=this.toGlobalCoord(point);var curve=this.geoCalc.calculateGeodeticCurve(sec.geo.GeoPath.REFERENCE_ELLIPSOID,start,end);var distance=this.maxDistanceMeters;while(distancerightAzimuthDegrees){arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs((360-leftAzimuthDegrees)+rightAzimuthDegrees),0);}else{arc=new armyc2.c2sd.graphics2d.Arc2D(-widthMeters/2,-heightMeters/2,widthMeters,heightMeters,leftAzimuthDegrees-90,Math.abs(leftAzimuthDegrees-rightAzimuthDegrees),0);} +var point=null;if(pivot!==null){var it=new armyc2.c2sd.graphics2d.FlatteningPathIterator(arc.getPathIterator(null),this.flatnessDistanceMeters,this.limit);while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var x=strokePoints[0];var y=strokePoints[1];var azimuth=org.gavaghan.geodesy.Angle.toDegrees(Math.atan2(x,y));var coord=new org.gavaghan.geodesy.GlobalCoordinates(pivot.getLatitude(),pivot.getLongitude());var c=this.geoCalc.calculateEndingGlobalCoordinates(sec.geo.GeoPath.REFERENCE_ELLIPSOID,coord,azimuth,new armyc2.c2sd.graphics2d.Point2D(0,0).distance(x,y));switch(type){case 0:newPath.moveTo(c.getLongitude(),c.getLatitude());var startPoint=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());if(this.toPoints.size()>0&&!startPoint.equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(startPoint);} +break;case 1:newPath.lineTo(c.getLongitude(),c.getLatitude());point=new sec.geo.GeoPoint(c.getLongitude(),c.getLatitude());break;} +it.next();}} +this.path.append(newPath,true);this.toPoints.add(point);};this.getToPoints=function(){return this.toPoints;};this.closePath=function(){if(this.toPoints.size()>0&&!this.toPoints.get(0).equals(this.toPoints.get(this.toPoints.size()-1))){this.lineTo(this.toPoints.get(0));}};this.getPathIterator=function(at){return this.path.getPathIterator(at);};this.toString=function(){return this.toPoints.toString();};this.toGlobalCoord=function(point){return new org.gavaghan.geodesy.GlobalCoordinates(point.getLatitude(),point.getLongitude());};};sec.geo.GeoPath.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.GeoPoint=function() +{this.x=0;this.y=0;if(arguments.length===2) +{var longitudeDegrees=arguments[0];var latitudeDegrees=arguments[1];this.x=longitudeDegrees;this.y=latitudeDegrees;} +this.getLatitude=function(){return this.y;};this.setLatitude=function(latitudeDegrees){this.y=latitudeDegrees;};this.getLongitude=function(){return this.x;};this.setLongitude=function(longitudeDegrees){this.x=longitudeDegrees;};this.toString=function(){return this.x+","+this.y;};this.equals=function(x1,y1) +{if(x1===this.x&&y1===this.y) +return true;else +return false;};this.equals=function(p) +{if(p.x===this.x&&p.y===this.y) +return true;else +return false;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.ShapeObject=function() +{this.type=-1;this.geoEllipse=null;this.geoPath=null;this.geoArc=null;this.geoBlock=null;this.geoBlock2=null;this.geoPoint=null;this.area=null;this.geoCalc=null;var obj=null;if(arguments.length===1) +obj=arguments[0];if(Clazz.instanceOf(obj,sec.geo.GeoArc)) +{this.geoArc=obj;this.type=0;} +else if(Clazz.instanceOf(obj,sec.geo.GeoPath)) +{this.geoPath=obj;this.type=4;} +else if(Clazz.instanceOf(obj,sec.geo.GeoEllipse)) +{this.geoEllipse=obj;this.type=3;} +else if(Clazz.instanceOf(obj,sec.geo.GeoBlock)) +{this.geoBlock=obj;this.type=1;} +else if(Clazz.instanceOf(obj,sec.geo.GeoBlock2)) +{this.geoBlock2=obj;this.type=2;} +else if(Clazz.instanceOf(obj,sec.geo.GeoPoint)) +{this.geoPoint=obj;this.type=5;} +else if(Clazz.instanceOf(obj,armyc2.c2sd.graphics2d.Area)){this.area=obj;this.type=6;} +this.arcTo=function(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees){switch(this.type){case 3:this.geoEllipse.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;case 0:this.geoArc.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;case 4:this.geoPath.arcTo(pivot,widthMeters,heightMeters,leftAzimuthDegrees,rightAzimuthDegrees);break;default:break;}};this.getPathIterator=function(at){switch(this.type){case 3:return this.geoEllipse.getPathIterator(at);case 4:return this.geoPath.getPathIterator(at);case 1:return this.geoBlock.getPathIterator(at);case 2:return this.geoBlock2.getPathIterator(at,0);case 0:return this.geoArc.getPathIterator(at);default:return null;}};this.moveTo=function(point){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.moveTo(point);break;case 4:this.geoPath.moveTo(point);break;case 1:this.geoBlock.moveTo(point);break;case 2:this.geoBlock2.moveTo(point);break;default:break;}};this.moveToLatLong=function(longitudeDegrees,latitudeDegrees){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 4:this.geoPath.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 1:this.geoBlock.moveToLatLong(longitudeDegrees,latitudeDegrees);break;case 2:this.geoBlock2.moveToLatLong(longitudeDegrees,latitudeDegrees);break;default:break;}};this.lineTo=function(point){switch(this.type){case 3:break;case 5:break;case 0:this.geoArc.lineTo(point);break;case 4:this.geoPath.lineTo(point);break;case 1:this.geoBlock.lineTo(point);break;case 2:this.geoBlock2.lineTo(point);break;default:break;}};this.lineToLatLong=function(longitudeDegrees,latitudeDegrees){this.lineTo(new sec.geo.GeoPoint(longitudeDegrees,latitudeDegrees));};this.closePath=function(){switch(this.type){case 0:this.geoArc.closePath();break;case 1:this.geoBlock.closePath();break;case 2:this.geoBlock2.closePath();break;case 4:this.geoPath.closePath();;break;default:break;}};};sec.geo.ShapeObject.GEOARC=0;sec.geo.ShapeObject.GEOBLOCK=1;sec.geo.ShapeObject.GEOBLOCK2=2;sec.geo.ShapeObject.GEOELLIPSE=3;sec.geo.ShapeObject.GEOPATH=4;sec.geo.ShapeObject.GEOPOINT=5;sec.geo.ShapeObject.AREA=6;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.AExtObject=function() +{this.type=-1;this.orbit=null;this.cake=null;this.circle=null;this.point=null;this.radarc=null;this.polyarc=null;this.polygon=null;this.line=null;this.route=null;this.track=null;var obj=arguments[0];if(Clazz.instanceOf(obj,Integer)) +{this.type=(obj).intValue();switch(this.type){case 1:this.line=new sec.geo.shape.Line();break;case 2:this.orbit=new sec.geo.shape.Orbit();break;case 5:this.radarc=new sec.geo.shape.Radarc();break;case 0:this.cake=new sec.geo.shape.Cake();break;default:break;}} +else if(Clazz.instanceOf(obj,sec.geo.shape.Line)){this.line=obj;this.type=1;}else if(Clazz.instanceOf(obj,sec.geo.shape.Route)){this.route=obj;this.type=8;}else if(Clazz.instanceOf(obj,sec.geo.shape.Polygon)){this.polygon=obj;this.type=7;}else if(Clazz.instanceOf(obj,sec.geo.shape.Radarc)){this.radarc=obj;this.type=5;}else if(Clazz.instanceOf(obj,sec.geo.shape.Polyarc)){this.polyarc=obj;this.type=6;}else if(Clazz.instanceOf(obj,sec.geo.shape.Orbit)){this.orbit=obj;this.type=2;}else if(Clazz.instanceOf(obj,sec.geo.shape.Cake)){this.cake=obj;this.type=0;}else if(Clazz.instanceOf(obj,sec.geo.shape.Circle)){this.circle=obj;this.type=4;}else if(Clazz.instanceOf(obj,sec.geo.shape.Point)){this.point=obj;this.type=3;}else if(Clazz.instanceOf(obj,sec.geo.shape.Track)){this.track=obj;this.type=9;} +this.getElements=function() +{if(this.track!==null) +return this.track.elements;else if(this.cake!==null) +return this.cake.elements;else +return null;};this.setMaxDistance=function(maxDistanceMeters){switch(this.type){case 2:this.orbit.setMaxDistance(maxDistanceMeters);break;case 4:this.circle.setMaxDistance(maxDistanceMeters);break;case 5:this.radarc.setMaxDistance(maxDistanceMeters);break;case 6:this.polyarc.setMaxDistance(maxDistanceMeters);break;case 7:this.polygon.setMaxDistance(maxDistanceMeters);break;case 8:this.route.setMaxDistance(maxDistanceMeters);break;case 1:this.line.setMaxDistance(maxDistanceMeters);break;case 4:this.circle.setMaxDistance(maxDistanceMeters);break;default:break;}};this.addPoint=function(point){switch(this.type){case 1:this.line.addPoint(point);break;case 5:break;case 2:this.orbit.addPoint(point);break;case 6:this.polyarc.addPoint(point);break;case 7:this.polygon.addPoint(point);break;case 8:this.route.addPoint(point);break;default:break;} +return;};this.setFlatness=function(flatnessDistanceMeters){switch(this.type){case 1:this.line.setFlatness(flatnessDistanceMeters);break;case 2:this.orbit.setFlatness(flatnessDistanceMeters);break;case 4:this.circle.setFlatness(flatnessDistanceMeters);break;case 5:this.radarc.setFlatness(flatnessDistanceMeters);break;case 6:this.polyarc.setFlatness(flatnessDistanceMeters);break;case 7:this.polygon.setFlatness(flatnessDistanceMeters);break;case 8:this.route.setFlatness(flatnessDistanceMeters);break;default:break;} +this.shapeChanged();};this.setLimit=function(limit){switch(this.type){case 1:this.line.setLimit(limit);break;case 2:this.orbit.setLimit(limit);break;case 4:this.circle.setLimit(limit);break;case 5:this.radarc.setLimit(limit);break;case 6:this.polyarc.setLimit(limit);break;case 7:this.polygon.setLimit(limit);break;case 8:this.route.setLimit(limit);break;default:break;} +this.shapeChanged();};this.getMinAltitude=function(){switch(this.type){case 1:return this.line.getMinAltitude();case 2:return this.orbit.getMinAltitude();case 4:return this.circle.getMinAltitude();case 6:return this.polyarc.getMinAltitude();case 7:return this.polygon.getMinAltitude();case 8:return this.route.getMinAltitude();case 5:return this.radarc.getMinAltitude();default:return-1;}};this.getMaxAltitude=function(){switch(this.type){case 1:return this.line.getMaxAltitude();case 2:return this.orbit.getMaxAltitude();case 4:return this.circle.getMaxAltitude();case 6:return this.polyarc.getMaxAltitude();case 7:return this.polygon.getMaxAltitude();case 8:return this.route.getMaxAltitude();case 5:return this.radarc.getMaxAltitude();default:return-1;} +return-1;};this.getAltitudeMode=function(){switch(this.type){case 1:return this.line.getAltitudeMode();case 2:return this.orbit.getAltitudeMode();case 4:return this.circle.getAltitudeMode();case 6:return this.polyarc.getAltitudeMode();case 7:return this.polygon.getAltitudeMode();case 8:return this.route.getAltitudeMode();case 5:return this.radarc.getAltitudeMode();default:return sec.geo.kml.KmlOptions.AltitudeMode.ABSOLUTE;}};this.getPathIterator=function(at){switch(this.type){case 1:return this.line.getShape().getPathIterator(at);case 2:return this.orbit.getShape().getPathIterator(at);case 7:return this.polygon.getShape().getPathIterator(at);case 6:return this.polyarc.getShape().getPathIterator(at);case 4:return this.circle.getShape().getPathIterator(at);case 5:return this.radarc.getShape().getPathIterator(at);case 8:return this.route.getShape().getPathIterator(at);default:return null;}};this.shapeChanged=function(){switch(this.type){case 7:this.polygon.shapeChanged();break;case 2:this.orbit.shapeChanged();break;case 8:this.route.shapeChanged();break;case 5:this.radarc.shapeChanged();break;case 6:this.polyarc.shapeChanged();break;default:break;}};};sec.geo.shape.AExtObject.CAKE=0;sec.geo.shape.AExtObject.LINE=1;sec.geo.shape.AExtObject.ORBIT=2;sec.geo.shape.AExtObject.POINT=3;sec.geo.shape.AExtObject.CIRCLE=4;sec.geo.shape.AExtObject.RADARC=5;sec.geo.shape.AExtObject.POLYARC=6;sec.geo.shape.AExtObject.POLYGON=7;sec.geo.shape.AExtObject.ROUTE=8;sec.geo.shape.AExtObject.TRACK=9;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Cake=function() +{this.elements=new java.util.ArrayList();this.pivot=new sec.geo.GeoPoint();this.addLayer=function(layer) +{if(Clazz.instanceOf(layer,sec.geo.shape.Polyarc)) +{layer.setPivot(this.pivot);this.elements.add(layer);} +else if(Clazz.instanceOf(layer,sec.geo.shape.Radarc)) +{layer.setPivot(this.pivot);this.elements.add(layer);} +else +{throw new IllegalArgumentException();}};this.setPivot=function(pivot) +{this.pivot=pivot;for(var j=0;j0){path.lineTo(this.points.get(i));}else{path.moveTo(this.points.get(i));}} +return new sec.geo.ShapeObject(path);};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} +return this.shape;};this.shapeChanged=function(){this.shape=null;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Orbit=function() +{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.altitudeMode=null;this.shape=null;this.limit=0;this.widthMeters=0;this.points=null;this.points=new java.util.ArrayList();this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.addPoint=function(point){this.points.add(point);this.shapeChanged();};this.addPoints=function(points){this.points.addAll(points);this.shapeChanged();};this.setWidth=function(widthMeters){this.widthMeters=widthMeters;this.shapeChanged();};this.createShape=function(){var orbit=new sec.sun.awt.geom.Area();var previousPoint=null;var point;var j=0;for(j=0;j0){path.lineTo(this.points.get(i));}else{path.moveTo(this.points.get(i));}} +path.closePath();return new sec.geo.ShapeObject(path);};this.shapeChanged=function(){this.shape=null;};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} +return this.shape;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Radarc=function() +{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.shape=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.minRadiusMeters=0;this.leftAzimuthDegrees=0;this.rightAzimuthDegrees=0;this.pivot=null;this.radiusMeters=0;this.altitudeMode=null;this.limit=0;this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.setRightAzimuthDegrees=function(rightAzimuthDegrees){this.rightAzimuthDegrees=rightAzimuthDegrees;this.shapeChanged();};this.setLeftAzimuthDegrees=function(leftAzimuthDegrees){this.leftAzimuthDegrees=leftAzimuthDegrees;this.shapeChanged();};this.setMinRadius=function(minRadiusMeters){this.minRadiusMeters=minRadiusMeters;this.shapeChanged();};this.shapeChanged=function(){this.shape=null;};this.createShape=function(){var arc=new sec.geo.GeoArc(this.pivot,this.radiusMeters*2,this.radiusMeters*2,this.leftAzimuthDegrees,this.rightAzimuthDegrees,this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);var arcObj=new sec.geo.ShapeObject(arc);var shape1=new sec.sun.awt.geom.Area(arcObj);var ellipse=new sec.geo.GeoEllipse(this.pivot,this.minRadiusMeters*2,this.minRadiusMeters*2,this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);var ellipseObj=new sec.geo.ShapeObject(ellipse);shape1.subtract(new sec.sun.awt.geom.Area(ellipseObj));return shape1;};this.getMinAltitude=function(){return this.minAltitudeMeters;};this.setMinAltitude=function(minAltitudeMeters){this.minAltitudeMeters=minAltitudeMeters;this.shapeChanged();};this.getMaxAltitude=function(){return this.maxAltitudeMeters;};this.setMaxAltitude=function(maxAltitudeMeters){this.maxAltitudeMeters=maxAltitudeMeters;this.shapeChanged();};this.setMaxDistance=function(maxDistanceMeters){this.maxDistanceMeters=maxDistanceMeters;this.shapeChanged();};this.setFlatness=function(flatnessDistanceMeters){this.flatnessDistanceMeters=flatnessDistanceMeters;this.shapeChanged();};this.setLimit=function(limit){this.limit=limit;this.shapeChanged();};this.getAltitudeMode=function(){return this.altitudeMode;};this.setAltitudeMode=function(altitudeMode){this.altitudeMode=altitudeMode;};this.setRadius=function(radiusMeters){this.radiusMeters=radiusMeters;this.shapeChanged();};this.setPivot=function(pivot){this.pivot=pivot;this.shapeChanged();};this.getShape=function(){if(this.shape===null){this.shape=this.createShape();} +return this.shape;};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.shape=sec.geo.shape||{};sec.geo.shape.Polyarc=function() +{this.minAltitudeMeters=0;this.maxAltitudeMeters=0;this.shape=null;this.maxDistanceMeters=0;this.flatnessDistanceMeters=0;this.limit=0;this.pivot=null;this.radiusMeters=0;this.leftAzimuthDegrees=0;this.rightAzimuthDegrees=0;this.altitudeMode=null;this.points=null;this.points=new java.util.ArrayList();this.maxDistanceMeters=100000;this.flatnessDistanceMeters=1;this.limit=4;this.addPoint=function(point) +{this.points.add(point);this.shapeChanged();};this.addPoints=function(points) +{this.points.addAll(points);this.shapeChanged();};this.setRadius=function(radiusMeters) +{this.radiusMeters=radiusMeters;this.shapeChanged();};this.setPivot=function(pivot) +{this.pivot=pivot;this.shapeChanged();};this.setRightAzimuthDegrees=function(rightAzimuthDegrees) +{this.rightAzimuthDegrees=rightAzimuthDegrees;this.shapeChanged();};this.setLeftAzimuthDegrees=function(leftAzimuthDegrees) +{this.leftAzimuthDegrees=leftAzimuthDegrees;this.shapeChanged();};this.createShape=function() +{var path=new sec.geo.GeoPath(this.maxDistanceMeters,this.flatnessDistanceMeters,this.limit);for(var i=0;i1){return false;}} +return true;};this.isRectangular=function(){var size=this.curves.size();if(size===0){return true;} +if(size>3){return false;} +var c1=this.curves.get(1);var c2=this.curves.get(2);if(c1.getOrder()!==1||c2.getOrder()!==1){return false;} +if(c1.getXTop()!==c1.getXBot()||c2.getXTop()!==c2.getXBot()){return false;} +if(c1.getYTop()!==c2.getYTop()||c1.getYBot()!==c2.getYBot()){return false;} +return true;};this.isSingular=function(){if(this.curves.size()<3){return true;} +var enum_=this.curves.elements();enum_.nextElement();while(enum_.hasMoreElements()){if((enum_.nextElement()).getOrder()===0){return false;}} +return true;};this.invalidateBounds=function(){this.cachedBounds=null;};this.equals=function(other){if(other===this){return true;} +if(other===null){return false;} +var c=new sec.sun.awt.geom.SomeOp(3).calculate(this.curves,other.curves);return c.isEmpty();};this.getPathIterator=function(at){return new sec.sun.awt.geom.AreaIterator(this.curves,at);};};sec.sun.awt.geom.Area.pathToCurves=function(pi) +{var curves=new sec.sun.awt.geom.Vector();var windingRule=pi.getWindingRule();var coords=new Array(23);var movx=0;var movy=0;var curx=0;var cury=0;var newx;var newy;while(!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(movx>0) +movx-=360;if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);curx=movx=coords[0];cury=movy=coords[1];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(movx>0) +movx-=360;} +sec.sun.awt.geom.Curve.insertMove(curves,movx,movy);break;case 1:newx=coords[0];newy=coords[1];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(newx>0) +newx-=360;if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,newx,newy);curx=newx;cury=newy;break;case 2:newx=coords[2];newy=coords[3];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertQuad(curves,curx,cury,coords);curx=newx;cury=newy;break;case 3:newx=coords[4];newy=coords[5];if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertCubic(curves,curx,cury,coords);curx=newx;cury=newy;break;case 4:if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(movx>0) +movx-=360;if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);curx=movx;cury=movy;break;} +pi.next();} +if(sec.sun.awt.geom.Area.normalizeGeoPoints===true) +{if(movx>0) +movx-=360;if(curx>0) +curx-=360;} +sec.sun.awt.geom.Curve.insertLine(curves,curx,cury,movx,movy);var operator2=null;if(windingRule===0){operator2=new sec.sun.awt.geom.AreaOp2(0);}else{operator2=new sec.sun.awt.geom.AreaOp2(1);} +var emptyCurves=new sec.sun.awt.geom.Vector();return operator2.calculate(curves,emptyCurves);};sec.sun.awt.geom.Area.normalizeGeoPoints=true;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.AreaIterator=function() +{this.transform=null;this.curves=null;this.index=0;this.prevcurve=null;this.thiscurve=null;var curves;var at;if(arguments.length===2) +{curves=arguments[0];at=arguments[1];this.curves=curves;this.transform=at;if(curves.size()>=1){this.thiscurve=curves.get(0);}} +this.getWindingRule=function(){return 1;};this.isDone=function(){return(this.prevcurve===null&&this.thiscurve===null);};this.next=function(){if(this.prevcurve!==null){this.prevcurve=null;}else{this.prevcurve=this.thiscurve;this.index++;if(this.index=left;cur--){e=edgelist[cur];if(e.getCurve().getYBot()>y){if(next>cur){edgelist[next]=e;} +next--;}} +left=next+1;if(left>=right){if(right>=numedges){break;} +y=edgelist[right].getCurve().getYTop();if(y>yrange[0]){sec.sun.awt.geom.AreaOp2.finalizeSubCurves(subcurves,chains);} +yrange[0]=y;} +while(righty){break;} +right++;} +yrange[1]=edgelist[left].getCurve().getYBot();if(righty){yrange[1]=y;}} +if(false){System.out.println("current line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curleft;next--){var prevedge=edgelist[next-1];var ordering=e.compareTo(prevedge,yrange);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping to "+yrange[1]+" from "+yrange[0]);} +if(ordering>=0){if(ordering===0){var eq=prevedge.getEquivalence();if(eq===0){eq=nexteq++;prevedge.setEquivalence(eq);} +e.setEquivalence(eq);} +break;} +edgelist[next]=prevedge;} +edgelist[next]=e;} +if(false){System.out.println("current sorted line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curfurthesty){longestmatch=e;furthesty=y;}}while(++cur0){edges.add(new sec.sun.awt.geom.Edge(c,curvetag));}}};sec.sun.awt.geom.AreaOp2.finalizeSubCurves=function(subcurves,chains){var numchains=chains.size();if(numchains===0){return;} +if((numchains&1)!==0){throw new InternalError("Odd number of chains!");} +var endlist=new Array(numchains);chains.toArray(endlist);for(var i=1;ilow&&sec.sun.awt.geom.Arrays.compare(dest[j-1],dest[j])>0;j--) +sec.sun.awt.geom.Arrays.swap(dest,j,j-1);return;} +var destLow=low;var destHigh=high;low+=off;high+=off;var mid=(low+high)>>>1;if(mid===45) +{sec.sun.awt.geom.Arrays.test=3;} +sec.sun.awt.geom.Arrays.mergeSort(dest,src,low,mid,-off);sec.sun.awt.geom.Arrays.mergeSort(dest,src,mid,high,-off);if(sec.sun.awt.geom.Arrays.compare(src[mid-1],src[mid])<=0){System.arraycopy(src,low,dest,destLow,length);} +for(i=destLow,p=low,q=mid;i=high||p=y1){return false;} +if(x0>=this.xhi&&x1>=this.xhi){return false;} +if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} +var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} +if(xstart>this.xlo||xend>this.xlo){return true;} +this.record(ystart,yend,direction);return false;};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} +var from=0;while(fromthis.yranges[from+1]){from+=2;} +var to=from;while(fromyhl){ystart=yhl;yhl=ylh;ylh=ystart;} +if(yll!==ylh){this.yranges[to++]=yll;this.yranges[to++]=ylh;} +ystart=yhl;yend=yhh;} +if(ystart>=yend){break;}} +if(to=this.yranges.length){var newranges=Clazz.newArray(to+10,0);System.arraycopy(this.yranges,0,newranges,0,to);this.yranges=newranges;} +this.yranges[to++]=ystart;this.yranges[to++]=yend;} +this.limit=to;};};sec.sun.awt.geom.Crossings.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.CrossingsObject=function() +{this.limit=0;this.yranges=null;this.xlo=0;this.ylo=0;this.xhi=0;this.yhi=0;this.crosscounts=null;this.evenOdd=null;this.crossings=null;this.nonZero=null;this.type=-1;this.tmp=null;this.yranges=Clazz.newArray(10,0);this.tmp=new sec.sun.awt.geom.Vector();var xlo=arguments[0];var ylo=arguments[1];var xhi=arguments[2];var yhi=arguments[3];var type=arguments[4];this.xlo=xlo;this.ylo=ylo;this.xhi=xhi;this.yhi=yhi;this.type=type;switch(type){case 0:this.crossings=new sec.sun.awt.geom.Crossings(xlo,ylo,xhi,yhi);break;case 1:this.nonZero=new sec.sun.awt.geom.NonZero(xlo,ylo,xhi,yhi);this.crosscounts=Clazz.newArray(Math.floor(this.yranges.length/2),0);break;case 2:this.evenOdd=new sec.sun.awt.geom.EvenOdd(xlo,ylo,xhi,yhi);break;} +this.getXLo=function(){switch(this.type){case 0:return this.crossings.getXLo();case 2:return this.evenOdd.getXLo();case 1:return this.nonZero.getXLo();default:return-1;}};this.getYLo=function(){switch(this.type){case 0:return this.crossings.getYLo();case 2:return this.evenOdd.getYLo();case 1:return this.nonZero.getYLo();default:return-1;}};this.getXHi=function(){switch(this.type){case 0:return this.crossings.getXHi();case 2:return this.evenOdd.getXHi();case 1:return this.nonZero.getXHi();default:return-1;}};this.getYHi=function(){switch(this.type){case 0:return this.crossings.getYHi();case 2:return this.evenOdd.getYHi();case 1:return this.nonZero.getYHi();default:return-1;}};this.isEmpty=function(){switch(this.type){case 0:return this.crossings.isEmpty();case 2:return this.evenOdd.isEmpty();case 1:return this.nonZero.isEmpty();default:return true;}};this.record=function(ystart,yend,direction){switch(this.type){case 0:this.crossings.record(ystart,yend,direction);case 2:this.evenOdd.record(ystart,yend,direction);case 1:this.nonZero.record(ystart,yend,direction);default:return;}};this.accumulateLine=function(x0,y0,x1,y1){switch(this.type){case 0:return this.crossings.accumulateLine(x0,y0,x1,y1);case 2:return this.evenOdd.accumulateLine(x0,y0,x1,y1);case 1:return this.nonZero.accumulateLine(x0,y0,x1,y1);default:return false;}};this.accumulateQuad=function(x0,y0,coords){if(y0this.yhi&&coords[1]>this.yhi&&coords[3]>this.yhi){return false;} +if(x0>this.xhi&&coords[0]>this.xhi&&coords[2]>this.xhi){return false;} +if(x0coords[3]){this.record(Math.max(coords[3],this.ylo),Math.min(y0,this.yhi),-1);} +return false;} +sec.sun.awt.geom.Curve.insertQuad(this.tmp,x0,y0,coords);var enum_=this.tmp.elements();while(enum_.hasMoreElements()){var c=enum_.nextElement();if(c.accumulateCrossings(this)){return true;}} +this.tmp.clear();return false;};this.accumulateCubic=function(x0,y0,coords){if(y0this.yhi&&coords[1]>this.yhi&&coords[3]>this.yhi&&coords[5]>this.yhi){return false;} +if(x0>this.xhi&&coords[0]>this.xhi&&coords[2]>this.xhi&&coords[4]>this.xhi){return false;} +if(x0y1) +{curves.add(new sec.sun.awt.geom.Order1(x1,y1,x0,y0,-1));}};sec.sun.awt.geom.Curve.insertQuad=function(curves,x0,y0,coords){var y1=coords[3];if(y0>y1){sec.sun.awt.geom.Order2.insert(curves,coords,coords[2],y1,coords[0],coords[1],x0,y0,-1);}else if(y0===y1&&y0===coords[1]){return;}else{sec.sun.awt.geom.Order2.insert(curves,coords,x0,y0,coords[0],coords[1],coords[2],y1,1);}};sec.sun.awt.geom.Curve.insertCubic=function(curves,x0,y0,coords){var y1=coords[5];if(y0>y1){sec.sun.awt.geom.Order3.insert(curves,coords,coords[4],y1,coords[2],coords[3],coords[0],coords[1],x0,y0,-1);}else if(y0===y1&&y0===coords[1]&&y0===coords[3]){return;}else{sec.sun.awt.geom.Order3.insert(curves,coords,x0,y0,coords[0],coords[1],coords[2],coords[3],coords[4],y1,1);}};sec.sun.awt.geom.Curve.pointCrossingsForPath=function(pi,px,py){if(pi.isDone()){return 0;} +var coords=Clazz.newArray(6,0);if(pi.currentSegment(coords)!==0){return-1;} +pi.next();var movx=coords[0];var movy=coords[1];var curx=movx;var cury=movy;var endx;var endy;var crossings=0;while(!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} +movx=curx=coords[0];movy=cury=coords[1];break;case 1:endx=coords[0];endy=coords[1];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,endx,endy);curx=endx;cury=endy;break;case 2:endx=coords[2];endy=coords[3];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,curx,cury,coords[0],coords[1],endx,endy,0);curx=endx;cury=endy;break;case 3:endx=coords[4];endy=coords[5];crossings+=sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,curx,cury,coords[0],coords[1],coords[2],coords[3],endx,endy,0);curx=endx;cury=endy;break;case 4:if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} +curx=movx;cury=movy;break;} +pi.next();} +if(cury!==movy){crossings+=sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,curx,cury,movx,movy);} +return crossings;};sec.sun.awt.geom.Curve.pointCrossingsForLine=function(px,py,x0,y0,x1,y1){if(py=y0&&py>=y1) +return 0;if(px>=x0&&px>=x1) +return 0;if(px=xintercept) +return 0;return(y0=y0&&py>=yc&&py>=y1) +return 0;if(px>=x0&&px>=xc&&px>=x1) +return 0;if(px=y0){if(py=y1) +return-1;} +return 0;} +if(level>52) +return sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,x0,y0,x1,y1);var x0c=(x0+xc)/2;var y0c=(y0+yc)/2;var xc1=(xc+x1)/2;var yc1=(yc+y1)/2;xc=(x0c+xc1)/2;yc=(y0c+yc1)/2;if(Double.isNaN(xc)||Double.isNaN(yc)){return 0;} +return(sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,x0,y0,x0c,y0c,xc,yc,level+1)+sec.sun.awt.geom.Curve.pointCrossingsForQuad(px,py,xc,yc,xc1,yc1,x1,y1,level+1));};sec.sun.awt.geom.Curve.pointCrossingsForCubic=function(px,py,x0,y0,xc0,yc0,xc1,yc1,x1,y1,level){if(py=y0&&py>=yc0&&py>=yc1&&py>=y1) +return 0;if(px>=x0&&px>=xc0&&px>=xc1&&px>=x1) +return 0;if(px=y0){if(py=y1) +return-1;} +return 0;} +if(level>52) +return sec.sun.awt.geom.Curve.pointCrossingsForLine(px,py,x0,y0,x1,y1);var xmid=(xc0+xc1)/2;var ymid=(yc0+yc1)/2;xc0=(x0+xc0)/2;yc0=(y0+yc0)/2;xc1=(xc1+x1)/2;yc1=(yc1+y1)/2;var xc0m=(xc0+xmid)/2;var yc0m=(yc0+ymid)/2;var xmc1=(xmid+xc1)/2;var ymc1=(ymid+yc1)/2;xmid=(xc0m+xmc1)/2;ymid=(yc0m+ymc1)/2;if(Double.isNaN(xmid)||Double.isNaN(ymid)){return 0;} +return(sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,x0,y0,xc0,yc0,xc0m,yc0m,xmid,ymid,level+1)+sec.sun.awt.geom.Curve.pointCrossingsForCubic(px,py,xmid,ymid,xmc1,ymc1,xc1,yc1,x1,y1,level+1));};sec.sun.awt.geom.Curve.rectCrossingsforPath=function(pi,rxmin,rymin,rxmax,rymax){if(rxmax<=rxmin||rymax<=rymin){return 0;} +if(pi.isDone()){return 0;} +var coords=Clazz.newArray(6,0);if(pi.currentSegment(coords)!==0){return-1;} +pi.next();var curx;var cury;var movx;var movy;var endx;var endy;curx=movx=coords[0];cury=movy=coords[1];var crossings=0;while(crossings!==-2147483648&&!pi.isDone()){switch(pi.currentSegment(coords)){case 0:if(curx!==movx||cury!==movy){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} +movx=curx=coords[0];movy=cury=coords[1];break;case 1:endx=coords[0];endy=coords[1];crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,endx,endy);curx=endx;cury=endy;break;case 2:endx=coords[2];endy=coords[3];crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,curx,cury,coords[0],coords[1],endx,endy,0);curx=endx;cury=endy;break;case 3:endx=coords[4];endy=coords[5];crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,curx,cury,coords[0],coords[1],coords[2],coords[3],endx,endy,0);curx=endx;cury=endy;break;case 4:if(curx!==movx||cury!==movy){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} +curx=movx;cury=movy;break;} +pi.next();} +if(crossings!==-2147483648&&(curx!==movx||cury!==movy)){crossings=sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,curx,cury,movx,movy);} +return crossings;};sec.sun.awt.geom.Curve.rectCrossingsForLine=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1){if(y0>=rymax&&y1>=rymax) +return crossings;if(y0<=rymin&&y1<=rymin) +return crossings;if(x0<=rxmin&&x1<=rxmin) +return crossings;if(x0>=rxmax&&x1>=rxmax){if(y0=rymax) +crossings++;}else if(y1=rymax) +crossings--;} +return crossings;} +if((x0>rxmin&&x0rymin&&y0rxmin&&x1rymin&&y1rymax){xi0+=((rymax-y0)*(x1-x0)/(y1-y0));} +var xi1=x1;if(y1rymax){xi1+=((rymax-y1)*(x0-x1)/(y0-y1));} +if(xi0<=rxmin&&xi1<=rxmin) +return crossings;if(xi0>=rxmax&&xi1>=rxmax){if(y0=rymax) +crossings++;}else if(y1=rymax) +crossings--;} +return crossings;} +return-2147483648;};sec.sun.awt.geom.Curve.rectCrossingsForQuad=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc,yc,x1,y1,level){if(y0>=rymax&&yc>=rymax&&y1>=rymax) +return crossings;if(y0<=rymin&&yc<=rymin&&y1<=rymin) +return crossings;if(x0<=rxmin&&xc<=rxmin&&x1<=rxmin) +return crossings;if(x0>=rxmax&&xc>=rxmax&&x1>=rxmax){if(y0rymin) +crossings++;if(y0=rymax) +crossings++;}else if(y1rymin) +crossings--;if(y1=rymax) +crossings--;} +return crossings;} +if((x0rxmin&&y0rymin)||(x1rxmin&&y1rymin)){return-2147483648;} +if(level>52){return sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1);} +var x0c=(x0+xc)/2;var y0c=(y0+yc)/2;var xc1=(xc+x1)/2;var yc1=(yc+y1)/2;xc=(x0c+xc1)/2;yc=(y0c+yc1)/2;if(Double.isNaN(xc)||Double.isNaN(yc)){return 0;} +crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x0c,y0c,xc,yc,level+1);if(crossings!==-2147483648){crossings=sec.sun.awt.geom.Curve.rectCrossingsForQuad(crossings,rxmin,rymin,rxmax,rymax,xc,yc,xc1,yc1,x1,y1,level+1);} +return crossings;};sec.sun.awt.geom.Curve.rectCrossingsForCubic=function(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc0,yc0,xc1,yc1,x1,y1,level){if(y0>=rymax&&yc0>=rymax&&yc1>=rymax&&y1>=rymax){return crossings;} +if(y0<=rymin&&yc0<=rymin&&yc1<=rymin&&y1<=rymin){return crossings;} +if(x0<=rxmin&&xc0<=rxmin&&xc1<=rxmin&&x1<=rxmin){return crossings;} +if(x0>=rxmax&&xc0>=rxmax&&xc1>=rxmax&&x1>=rxmax){if(y0rymin) +crossings++;if(y0=rymax) +crossings++;}else if(y1rymin) +crossings--;if(y1=rymax) +crossings--;} +return crossings;} +if((x0>rxmin&&x0rymin&&y0rxmin&&x1rymin&&y152){return sec.sun.awt.geom.Curve.rectCrossingsForLine(crossings,rxmin,rymin,rxmax,rymax,x0,y0,x1,y1);} +var xmid=(xc0+xc1)/2;var ymid=(yc0+yc1)/2;xc0=(x0+xc0)/2;yc0=(y0+yc0)/2;xc1=(xc1+x1)/2;yc1=(yc1+y1)/2;var xc0m=(xc0+xmid)/2;var yc0m=(yc0+ymid)/2;var xmc1=(xmid+xc1)/2;var ymc1=(ymid+yc1)/2;xmid=(xc0m+xmc1)/2;ymid=(yc0m+ymc1)/2;if(Double.isNaN(xmid)||Double.isNaN(ymid)){return 0;} +crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,x0,y0,xc0,yc0,xc0m,yc0m,xmid,ymid,level+1);if(crossings!==-2147483648){crossings=sec.sun.awt.geom.Curve.rectCrossingsForCubic(crossings,rxmin,rymin,rxmax,rymax,xmid,ymid,xmc1,ymc1,xc1,yc1,x1,y1,level+1);} +return crossings;};sec.sun.awt.geom.Curve.round=function(v){return v;};sec.sun.awt.geom.Curve.orderof=function(x1,x2){if(x1x2){return 1;} +return 0;};sec.sun.awt.geom.Curve.signeddifbits=function(y1,y2){return(Double.doubleToLongBits(y1)-Double.doubleToLongBits(y2));};sec.sun.awt.geom.Curve.diffbits=function(y1,y2){return Math.abs(Double.doubleToLongBits(y1)-Double.doubleToLongBits(y2));};sec.sun.awt.geom.Curve.prev=function(v){return Double.longBitsToDouble(Double.doubleToLongBits(v)-1);};sec.sun.awt.geom.Curve.next=function(v){return Double.longBitsToDouble(Double.doubleToLongBits(v)+1);};sec.sun.awt.geom.Curve.fairlyClose=function(v1,v2){return(Math.abs(v1-v2)=this.getYTop()&&y=xhi){return false;} +var xlo=c.getXLo();var ylo=c.getYLo();var yhi=c.getYHi();var y0=this.getYTop();var y1=this.getYBot();var tstart;var ystart;var tend;var yend;if(y0=yhi){return false;} +ystart=y0;tstart=0;} +if(y1>yhi){yend=yhi;tend=this.TforY(yhi);}else{yend=y1;tend=1;} +var hitLo=false;var hitHi=false;while(true){var x=this.XforT(tstart);if(xxlo){return true;} +hitLo=true;}else{if(hitLo){return true;} +hitHi=true;} +if(tstart>=tend){break;} +tstart=this.nextVertical(tstart,tend);} +if(hitLo){c.record(ystart,yend,this.getDirection());} +return false;};this.refineTforY=function(t0,yt0,y0){var t1=1;while(true){var th=(t0+t1)/2;if(th===t0||th===t1){return t1;} +var y=this.YforT(th);if(yy0){t1=th;}else{return t1;}}};this.findIntersect=function(that,yrange,ymin,slevel,tlevel,s0,xs0,ys0,s1,xs1,ys1,t0,xt0,yt0,t1,xt1,yt1){if(ys0>yt1||yt0>ys1){return false;} +if(Math.min(xs0,xs1)>Math.max(xt0,xt1)||Math.max(xs0,xs1)0.0010){var s=(s0+s1)/2;var xs=this.XforT(s);var ys=this.YforT(s);if(s===s0||s===s1){System.out.println("s0 = "+s0);System.out.println("s1 = "+s1);throw new InternalError("no s progress!");} +if(t1-t0>0.0010){var t=(t0+t1)/2;var xt=that.XforT(t);var yt=that.YforT(t);if(t===t0||t===t1){System.out.println("t0 = "+t0);System.out.println("t1 = "+t1);throw new InternalError("no t progress!");} +if(ys>=yt0&&yt>=ys0){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s0,xs0,ys0,s,xs,ys,t0,xt0,yt0,t,xt,yt)){return true;}} +if(ys>=yt){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s0,xs0,ys0,s,xs,ys,t,xt,yt,t1,xt1,yt1)){return true;}} +if(yt>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s,xs,ys,s1,xs1,ys1,t0,xt0,yt0,t,xt,yt)){return true;}} +if(ys1>=yt&&yt1>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel+1,s,xs,ys,s1,xs1,ys1,t,xt,yt,t1,xt1,yt1)){return true;}}}else{if(ys>=yt0){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel,s0,xs0,ys0,s,xs,ys,t0,xt0,yt0,t1,xt1,yt1)){return true;}} +if(yt1>=ys){if(this.findIntersect(that,yrange,ymin,slevel+1,tlevel,s,xs,ys,s1,xs1,ys1,t0,xt0,yt0,t1,xt1,yt1)){return true;}}}}else if(t1-t0>0.0010){var t=(t0+t1)/2;var xt=that.XforT(t);var yt=that.YforT(t);if(t===t0||t===t1){System.out.println("t0 = "+t0);System.out.println("t1 = "+t1);throw new InternalError("no t progress!");} +if(yt>=ys0){if(this.findIntersect(that,yrange,ymin,slevel,tlevel+1,s0,xs0,ys0,s1,xs1,ys1,t0,xt0,yt0,t,xt,yt)){return true;}} +if(ys1>=yt){if(this.findIntersect(that,yrange,ymin,slevel,tlevel+1,s0,xs0,ys0,s1,xs1,ys1,t,xt,yt,t1,xt1,yt1)){return true;}}}else{var xlk=xs1-xs0;var ylk=ys1-ys0;var xnm=xt1-xt0;var ynm=yt1-yt0;var xmk=xt0-xs0;var ymk=yt0-ys0;var det=xnm*ylk-ynm*xlk;if(det!==0){var detinv=1/det;var s=(xnm*ymk-ynm*xmk)*detinv;var t=(xlk*ymk-ylk*xmk)*detinv;if(s>=0&&s<=1&&t>=0&&t<=1){s=s0+s*(s1-s0);t=t0+t*(t1-t0);if(s<0||s>1||t<0||t>1){System.out.println("Uh oh!");} +var y=(this.YforT(s)+that.YforT(t))/2;if(y<=yrange[1]&&y>yrange[0]){yrange[1]=y;return true;}}}} +return false;};this.compareTo=function(that,yrange){if(this.order===1){return this.order1.compareTo(that,yrange);} +var y0=yrange[0];var y1=yrange[1];y1=Math.min(Math.min(y1,this.getYBot()),that.getYBot());if(y1<=yrange[0]){System.err.println("this === "+this);System.err.println("that === "+that);System.out.println("target range = "+yrange[0]+"=>"+yrange[1]);throw new InternalError("backstepping from "+yrange[0]+" to "+y1);} +yrange[1]=y1;if(this.getXMax()<=that.getXMin()){if(this.getXMin()===that.getXMax()){return 0;} +return-1;} +if(this.getXMin()>=that.getXMax()){return 1;} +var s0=this.TforY(y0);var ys0=this.YforT(s0);if(ys0maxbump){bump=maxbump;}}else{y-=bump;while(true){bump/=2;var newy=y+bump;if(newy<=y){break;} +if(sec.sun.awt.geom.Curve.fairlyClose(this.XforY(newy),that.XforY(newy))){y=newy;}} +break;} +y+=bump;} +if(y>y0){if(y"+yrange[1]);System.err.println("s y range is "+ys0+"=>"+ysh);System.err.println("t y range is "+yt0+"=>"+yth);System.err.println("ymin is "+ymin);return 0;}else{throw t;}} +if(yshyrange[0]){if(yshyrange[0]){if(ythcurve.getYBot()){throw new InternalError("bad curvelink ["+this.ytop+"=>"+this.ybot+"] for "+curve);} +this.absorb=function(link){return this.absorb2(link.curve,link.ytop,link.ybot,link.etag);};this.absorb2=function(curve,ystart,yend,etag){if(this.curve!==curve||this.etag!==etag||this.ybotyend) +{return false;} +if(ystartcurve.getYBot()) +{throw new InternalError("bad curvelink ["+ystart+"=>"+yend+"] for "+curve);} +this.ytop=Math.min(this.ytop,ystart);this.ybot=Math.max(this.ybot,yend);return true;};this.isEmpty=function(){return(this.ytop===this.ybot);};this.getCurve=function(){return this.curve;};this.getSubCurve=function(){if(this.ytop===this.curve.getYTop()&&this.ybot===this.curve.getYBot()) +{return this.curve.getWithDirection(this.etag);} +return this.curve.getSubCurve(this.ytop,this.ybot,this.etag);};this.getMoveto=function(){var order0=new sec.sun.awt.geom.Order0(this.getXTop(),this.getYTop());return new sec.sun.awt.geom.CurveObject(order0);};this.getXTop=function(){return this.curve.XforY(this.ytop);};this.getYTop=function(){return this.ytop;};this.getXBot=function(){return this.curve.XforY(this.ybot);};this.getYBot=function(){return this.ybot;};this.getX=function(){return this.curve.XforY(this.ytop);};this.getEdgeTag=function(){return this.etag;};this.setNext=function(link){this.next=link;};this.getNext=function(){return this.next;};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.EOWindOp=function() +{this.inside=false;this.newRow=function(){this.inside=false;};this.classify=function(e){var newInside=!this.inside;this.inside=newInside;return(newInside?1:-1);};this.getState=function(){return(this.inside?1:-1);};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.NZWindOp=function() +{this.count=0;this.newRow=function(){this.count=0;};this.classify=function(e){var newCount=this.count;var type=(newCount===0?1:0);newCount+=e.getCurve().getDirection();this.count=newCount;return(newCount===0?-1:type);};this.getState=function(){return((this.count===0)?-1:1);};};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Edge=function() +{this.curve=null;this.ctag=0;this.etag=0;this.activey=0;this.equivalence=0;this.lastEdge=null;this.lastResult=0;this.lastLimit=0;var c=arguments[0];var ctag=arguments[1];var etag=0;if(arguments.length===3) +etag=arguments[2];this.curve=c;this.ctag=ctag;this.etag=etag;this.getCurve=function(){return this.curve;};this.getCurveTag=function(){return this.ctag;};this.getEdgeTag=function(){return this.etag;};this.setEdgeTag=function(etag){this.etag=etag;};this.getEquivalence=function(){return this.equivalence;};this.setEquivalence=function(eq){this.equivalence=eq;};this.compareTo=function(other,yrange){if(other===this.lastEdge&&yrange[0]this.lastLimit){yrange[1]=this.lastLimit;} +return this.lastResult;} +if(this===other.lastEdge&&yrange[0]other.lastLimit){yrange[1]=other.lastLimit;} +return 0-other.lastResult;} +var ret=this.curve.compareTo(other.curve,yrange);this.lastEdge=other;this.lastLimit=yrange[1];this.lastResult=ret;return ret;};this.record=function(yend,etag){this.activey=yend;this.etag=etag;};this.isActiveFor=function(y,etag){return(this.etag===etag&&this.activey>=y);};this.toString=function(){return("Edge["+this.curve+", "+(this.ctag===0?"L":"R")+", "+(this.etag===1?"I":(this.etag===-1?"O":"N"))+"]");};};sec.sun.awt.geom.Edge.INIT_PARTS=4;sec.sun.awt.geom.Edge.GROW_PARTS=10;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Enumeration=function() +{this._vector=null;this.currentIndex=0;var vector=arguments[0];this._vector=vector;this.nextElement=function(){if(this.currentIndex=yend);};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} +var from=0;while(fromthis.yranges[from+1]){from+=2;} +var to=from;while(fromyhl){ystart=yhl;yhl=ylh;ylh=ystart;} +if(yll!==ylh){this.yranges[to++]=yll;this.yranges[to++]=ylh;} +ystart=yhl;yend=yhh;} +if(ystart>=yend){break;}} +if(to=this.yranges.length){var newranges=Clazz.newArray(to+10,0);System.arraycopy(this.yranges,0,newranges,0,to);this.yranges=newranges;} +this.yranges[to++]=ystart;this.yranges[to++]=yend;} +this.limit=to;};this.getXLo=function(){return this.xlo;};this.getYLo=function(){return this.ylo;};this.getXHi=function(){return this.xhi;};this.getYHi=function(){return this.yhi;};this.isEmpty=function(){return(this.limit===0);};this.accumulateLine=function(x0,y0,x1,y1){if(y0<=y1){return this.accumulateLine2(x0,y0,x1,y1,1);}else{return this.accumulateLine2(x1,y1,x0,y0,-1);}};this.accumulateLine2=function(x0,y0,x1,y1,direction){if(this.yhi<=y0||this.ylo>=y1){return false;} +if(x0>=this.xhi&&x1>=this.xhi){return false;} +if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} +var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} +if(xstart>this.xlo||xend>this.xlo){return true;} +this.record(ystart,yend,direction);return false;};};sec.sun.awt.geom.EvenOdd.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.NonZero=function() +{this.limit=0;this.yranges=null;this.xlo=0;this.ylo=0;this.xhi=0;this.yhi=0;this.crosscounts=null;this.yranges=Clazz.newArray(10,0);var xlo=arguments[0];var ylo=arguments[1];var xhi=arguments[2];var yhi=arguments[3];this.xlo=xlo;this.ylo=ylo;this.xhi=xhi;this.yhi=yhi;this.crosscounts=Clazz.newArray(Math.floor(this.yranges.length/2),0);this.covers=function(ystart,yend){var i=0;while(i=yhi){continue;} +if(ystart=yend);};this.remove=function(cur){this.limit-=2;var rem=this.limit-cur;if(rem>0){System.arraycopy(this.yranges,cur+2,this.yranges,cur,rem);System.arraycopy(this.crosscounts,Math.floor(cur/2)+1,this.crosscounts,Math.floor(cur/2),Math.floor(rem/2));}};this.insert=function(cur,lo,hi,dir){var rem=this.limit-cur;var oldranges=this.yranges;var oldcounts=this.crosscounts;if(this.limit>=this.yranges.length){this.yranges=Clazz.newArray(this.limit+10,0);System.arraycopy(oldranges,0,this.yranges,0,cur);this.crosscounts=Clazz.newArray(Math.floor((this.limit+10)/2),0);System.arraycopy(oldcounts,0,this.crosscounts,0,Math.floor(cur/2));} +if(rem>0){System.arraycopy(oldranges,cur,this.yranges,cur+2,rem);System.arraycopy(oldcounts,Math.floor(cur/2),this.crosscounts,Math.floor(cur/2)+1,Math.floor(rem/2));} +this.yranges[cur+0]=lo;this.yranges[cur+1]=hi;this.crosscounts[Math.floor(cur/2)]=dir;this.limit+=2;};this.record=function(ystart,yend,direction){if(ystart>=yend){return;} +var cur=0;while(curthis.yranges[cur+1]){cur+=2;} +if(cur=y1){return false;} +if(x0>=this.xhi&&x1>=this.xhi){return false;} +if(y0===y1){return(x0>=this.xlo||x1>=this.xlo);} +var xstart;var ystart;var xend;var yend;var dx=(x1-x0);var dy=(y1-y0);if(y0=this.xhi&&xend>=this.xhi){return false;} +if(xstart>this.xlo||xend>this.xlo){return true;} +this.record(ystart,yend,direction);return false;};};sec.sun.awt.geom.NonZero.debug=false;var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Order0=function() +{this.x=0;this.y=0;this.direction=-1;this._parent=null;var x=arguments[0];var y=arguments[1];this.direction=1;this.x=x;this.y=y;this.getOrder=function(){return 0;};this.getXTop=function(){return this.x;};this.getYTop=function(){return this.y;};this.getXBot=function(){return this.x;};this.getYBot=function(){return this.y;};this.getXMin=function(){return this.x;};this.getxMax=function(){return this.x;};this.getX0=function(){return this.x;};this.getY0=function(){return this.y;};this.getX1=function(){return this.x;};this.getY1=function(){return this.y;};this.XforY=function(y){return y;};this.TforY=function(y){return 0;};this.XforT=function(t){return this.x;};this.YforT=function(t){return this.y;};this.dXforT=function(t,deriv){return 0;};this.dYforT=function(t,deriv){return 0;};this.nextVertical=function(t0,t1){return t1;};this.crossingsFor=function(x,y){return 0;};this.accumulateCrossings=function(c){return(this.x>c.getXLo()&&this.xc.getYLo()&&this.y=this.y1){return this.x1;} +return(this.x0+(y-this.y0)*(this.x1-this.x0)/(this.y1-this.y0));};this.TforY=function(y){if(y<=this.y0){return 0;} +if(y>=this.y1){return 1;} +return(y-this.y0)/(this.y1-this.y0);};this.XforT=function(t){return this.x0+t*(this.x1-this.x0);};this.YforT=function(t){return this.y0+t*(this.y1-this.y0);};this.dXforT=function(t,deriv){switch(deriv){case 0:return this.x0+t*(this.x1-this.x0);case 1:return(this.x1-this.x0);default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return this.y0+t*(this.y1-this.y0);case 1:return(this.y1-this.y0);default:return 0;}};this.nextVertical=function(t0,t1){return t1;};this.accumulateCrossings=function(c){var xlo=c.getXLo();var ylo=c.getYLo();var xhi=c.getXHi();var yhi=c.getYHi();if(this.xmin>=xhi){return false;} +var xstart;var ystart;var xend;var yend;if(this.y0=yhi){return false;} +ystart=this.y0;xstart=this.x0;} +if(this.y1>yhi){yend=yhi;xend=this.XforY(yhi);}else{yend=this.y1;xend=this.x1;} +if(xstart>=xhi&&xend>=xhi){return false;} +if(xstart>xlo||xend>xlo){return true;} +c.record(ystart,yend,this.direction);return false;};this.enlarge=function(r){r.add(this.x0,this.y0);r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir) +{if(ystart===this.y0&¥d===this.y1) +{return this.getWithDirection(dir);} +if(this.x0===this.x1) +{return new sec.sun.awt.geom.Order1(this.x0,ystart,this.x1,yend,dir);} +var num=this.x0-this.x1;var denom=this.y0-this.y1;var xstart=(this.x0+(ystart-this.y0)*num/denom);var xend=(this.x0+(yend-this.y0)*num/denom);return new sec.sun.awt.geom.Order1(xstart,ystart,xend,yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order1(this.x0,this.y0,this.x1,this.y1,-this.direction);};this.compareTo=function(other,yrange){var curve=other;var c1=curve.getCurve();if(yrange[1]<=yrange[0]){throw new InternalError("yrange already screwed up...");} +yrange[1]=Math.min(Math.min(yrange[1],this.y1),c1.y1);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping from "+yrange[0]+" to "+yrange[1]);} +if(this.xmax<=c1.xmin){return(this.xmin===c1.xmax)?0:-1;} +if(this.xmin>=c1.xmax){return 1;} +var dxa=this.x1-this.x0;var dya=this.y1-this.y0;var dxb=c1.x1-c1.x0;var dyb=c1.y1-c1.y0;var denom=dxb*dya-dxa*dyb;var y;if(denom!==0){var num=((this.x0-c1.x0)*dya*dyb-this.y0*dxa*dyb+c1.y0*dxb*dya);y=num/denom;if(y<=yrange[0]){y=Math.min(this.y1,c1.y1);}else{if(yy1){cy0=y1;} +this.x0=x0;this.y0=y0;this.cx0=cx0;this.cy0=cy0;this.x1=x1;this.y1=y1;this.xmin=Math.min(Math.min(x0,x1),cx0);this.xmax=Math.max(Math.max(x0,x1),cx0);this.xcoeff0=x0;this.xcoeff1=cx0+cx0-x0-x0;this.xcoeff2=x0-cx0-cx0+x1;this.ycoeff0=y0;this.ycoeff1=cy0+cy0-y0-y0;this.ycoeff2=y0-cy0-cy0+y1;this.getOrder=function(){return 2;};this.getXTop=function(){return this.x0;};this.getYTop=function(){return this.y0;};this.getXBot=function(){return this.x1;};this.getYBot=function(){return this.y1;};this.getXMin=function(){return this.xmin;};this.getXMax=function(){return this.xmax;};this.getX0=function(){return(this.direction===1)?this.x0:this.x1;};this.getY0=function(){return(this.direction===1)?this.y0:this.y1;};this.getCX0=function(){return this.cx0;};this.getCY0=function(){return this.cy0;};this.getx1=function(){return(this.direction===-1)?this.x0:this.x1;};this.getY1=function(){return(this.direction===-1)?this.y0:this.y1;};this.XforY=function(y){if(y<=this.y0){return this.x0;} +if(y>=this.y1){return this.x1;} +return this.XforT(this.TforY(y));};this.TforY=function(y){if(y<=this.y0){return 0;} +if(y>=this.y1){return 1;} +return sec.sun.awt.geom.Order2.TforY(y,this.ycoeff0,this.ycoeff1,this.ycoeff2);};this.XforT=function(t){return(this.xcoeff2*t+this.xcoeff1)*t+this.xcoeff0;};this.YforT=function(t){return(this.ycoeff2*t+this.ycoeff1)*t+this.ycoeff0;};this.dXforT=function(t,deriv){switch(deriv){case 0:return(this.xcoeff2*t+this.xcoeff1)*t+this.xcoeff0;case 1:return 2*this.xcoeff2*t+this.xcoeff1;case 2:return 2*this.xcoeff2;default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return(this.ycoeff2*t+this.ycoeff1)*t+this.ycoeff0;case 1:return 2*this.ycoeff2*t+this.ycoeff1;case 2:return 2*this.ycoeff2;default:return 0;}};this.nextVertical=function(t0,t1){var t=-this.xcoeff1/(2*this.xcoeff2);if(t>t0&&t0&&t<1){r.add(this.XforT(t),this.YforT(t));} +r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir){var t0;var t1;if(ystart<=this.y0){if(yend>=this.y1){return this.getWithDirection(dir);} +t0=0;}else{t0=sec.sun.awt.geom.Order2.TforY(ystart,this.ycoeff0,this.ycoeff1,this.ycoeff2);} +if(yend>=this.y1){t1=1;}else{t1=sec.sun.awt.geom.Order2.TforY(yend,this.ycoeff0,this.ycoeff1,this.ycoeff2);} +var eqn=Clazz.newArray(10,0);eqn[0]=this.x0;eqn[1]=this.y0;eqn[2]=this.cx0;eqn[3]=this.cy0;eqn[4]=this.x1;eqn[5]=this.y1;if(t1<1){sec.sun.awt.geom.Order2.split(eqn,0,t1);} +var i;if(t0<=0){i=0;}else{sec.sun.awt.geom.Order2.split(eqn,0,t0/t1);i=4;} +return new sec.sun.awt.geom.Order2(eqn[i+0],ystart,eqn[i+2],eqn[i+3],eqn[i+4],yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order2(this.x0,this.y0,this.cx0,this.cy0,this.x1,this.y1,-this.direction);};this.getSegment=function(coords){coords[0]=this.cx0;coords[1]=this.cy0;if(this.direction===1){coords[2]=this.x1;coords[3]=this.y1;}else{coords[2]=this.x0;coords[3]=this.y0;} +return 2;};this.controlPointString=function(){return("("+sec.sun.awt.geom.Curve.round(this.cx0)+", "+sec.sun.awt.geom.Curve.round(this.cy0)+"), ");};this.setParent=function(parent){this._parent=parent;};this.getParent=function(){return this._parent;};};sec.sun.awt.geom.Order2.TforY=function(y,ycoeff0,ycoeff1,ycoeff2){ycoeff0-=y;if(ycoeff2===0.0){var root=-ycoeff0/ycoeff1;if(root>=0&&root<=1){return root;}}else{var d=ycoeff1*ycoeff1-4.0*ycoeff2*ycoeff0;if(d>=0.0){d=Math.sqrt(d);if(ycoeff1<0.0){d=-d;} +var q=(ycoeff1+d)/-2.0;var root=q/ycoeff2;if(root>=0&&root<=1){return root;} +if(q!==0.0){root=ycoeff0/q;if(root>=0&&root<=1){return root;}}}} +var y0=ycoeff0;var y1=ycoeff0+ycoeff1+ycoeff2;return(0<(y0+y1)/2)?0.0:1.0;};sec.sun.awt.geom.Order2.split=function(coords,pos,t){var x0;var y0;var cx;var cy;var x1;var y1;coords[pos+8]=x1=coords[pos+4];coords[pos+9]=y1=coords[pos+5];cx=coords[pos+2];cy=coords[pos+3];x1=cx+(x1-cx)*t;y1=cy+(y1-cy)*t;x0=coords[pos+0];y0=coords[pos+1];x0=x0+(cx-x0)*t;y0=y0+(cy-y0)*t;cx=x0+(x1-x0)*t;cy=y0+(y1-y0)*t;coords[pos+2]=x0;coords[pos+3]=y0;coords[pos+4]=cx;coords[pos+5]=cy;coords[pos+6]=x1;coords[pos+7]=y1;};sec.sun.awt.geom.Order2.getHorizontalParams=function(c0,cp,c1,ret){if(c0<=cp&&cp<=c1){return 0;} +c0-=cp;c1-=cp;var denom=c0+c1;if(denom===0){return 0;} +var t=c0/denom;if(t<=0||t>=1){return 0;} +ret[0]=t;return 1;};sec.sun.awt.geom.Order2.addInstance=function(curves,x0,y0,cx0,cy0,x1,y1,direction){if(y0>y1){curves.add(new sec.sun.awt.geom.Order2(x1,y1,cx0,cy0,x0,y0,-direction));}else if(y1>y0){curves.add(new sec.sun.awt.geom.Order2(x0,y0,cx0,cy0,x1,y1,direction));}};sec.sun.awt.geom.Order2.insert=function(curves,tmp,x0,y0,cx0,cy0,x1,y1,direction){var numparams=sec.sun.awt.geom.Order2.getHorizontalParams(y0,cy0,y1,tmp);if(numparams===0){sec.sun.awt.geom.Order2.addInstance(curves,x0,y0,cx0,cy0,x1,y1,direction);return;} +var t=tmp[0];tmp[0]=x0;tmp[1]=y0;tmp[2]=cx0;tmp[3]=cy0;tmp[4]=x1;tmp[5]=y1;sec.sun.awt.geom.Order2.split(tmp,0,t);var i0=(direction===1)?0:4;var i1=4-i0;sec.sun.awt.geom.Order2.addInstance(curves,tmp[i0],tmp[i0+1],tmp[i0+2],tmp[i0+3],tmp[i0+4],tmp[i0+5],direction);sec.sun.awt.geom.Order2.addInstance(curves,tmp[i1],tmp[i1+1],tmp[i1+2],tmp[i1+3],tmp[i1+4],tmp[i1+5],direction);};var sec=sec||{};sec.sun=sec.sun||{};sec.sun.awt=sec.sun.awt||{};sec.sun.awt.geom=sec.sun.awt.geom||{};sec.sun.awt.geom.Order3=function() +{this.x0=0;this.y0=0;this.cx0=0;this.cy0=0;this.cx1=0;this.cy1=0;this.x1=0;this.y1=0;this.xmin=0;this.xmax=0;this.xcoeff0=0;this.xcoeff1=0;this.xcoeff2=0;this.xcoeff3=0;this.ycoeff0=0;this.ycoeff1=0;this.ycoeff2=0;this.ycoeff3=0;this.direction=-1;this.TforY1=0;this.YforT1=0;this.TforY2=0;this.YforT2=0;this.TforY3=0;this.YforT3=0;this._parent=null;var x0=arguments[0];var y0=arguments[1];var cx0=arguments[2];var cy0=arguments[3];var cx1=arguments[4];var cy1=arguments[5];var x1=arguments[6];var y1=arguments[7];var direction=arguments[8];this.direction=direction;if(cy0y1)cy1=y1;this.x0=x0;this.y0=y0;this.cx0=cx0;this.cy0=cy0;this.cx1=cx1;this.cy1=cy1;this.x1=x1;this.y1=y1;this.xmin=Math.min(Math.min(x0,x1),Math.min(cx0,cx1));this.xmax=Math.max(Math.max(x0,x1),Math.max(cx0,cx1));this.xcoeff0=x0;this.xcoeff1=(cx0-x0)*3.0;this.xcoeff2=(cx1-cx0-cx0+x0)*3.0;this.xcoeff3=x1-(cx1-cx0)*3.0-x0;this.ycoeff0=y0;this.ycoeff1=(cy0-y0)*3.0;this.ycoeff2=(cy1-cy0-cy0+y0)*3.0;this.ycoeff3=y1-(cy1-cy0)*3.0-y0;this.YforT1=this.YforT2=this.YforT3=y0;this.getOrder=function(){return 3;};this.getXTop=function(){return this.x0;};this.getYTop=function(){return this.y0;};this.getXBot=function(){return this.x1;};this.getYBot=function(){return this.y1;};this.getXMin=function(){return this.xmin;};this.getXMax=function(){return this.xmax;};this.getX0=function(){return(this.direction===1)?this.x0:this.x1;};this.getY0=function(){return(this.direction===1)?this.y0:this.y1;};this.getCX0=function(){return(this.direction===1)?this.cx0:this.cx1;};this.getCY0=function(){return(this.direction===1)?this.cy0:this.cy1;};this.getCX1=function(){return(this.direction===-1)?this.cx0:this.cx1;};this.getCY1=function(){return(this.direction===-1)?this.cy0:this.cy1;};this.getX1=function(){return(this.direction===-1)?this.x0:this.x1;};this.getY1=function(){return(this.direction===-1)?this.y0:this.y1;};this.TforY=function(y){if(y<=this.y0)return 0;if(y>=this.y1)return 1;if(y===this.YforT1)return this.TforY1;if(y===this.YforT2)return this.TforY2;if(y===this.YforT3)return this.TforY3;if(this.ycoeff3===0.0){return sec.sun.awt.geom.Order2.TforY(y,this.ycoeff0,this.ycoeff1,this.ycoeff2);} +var a=this.ycoeff2/this.ycoeff3;var b=this.ycoeff1/this.ycoeff3;var c=(this.ycoeff0-y)/this.ycoeff3;var roots=0;var Q=(a*a-3.0*b)/9.0;var R=(2.0*a*a*a-9.0*a*b+27.0*c)/54.0;var R2=R*R;var Q3=Q*Q*Q;var a_3=a/3.0;var t;if(R2y){t1=t;}else{break;}}} +if(t>=0){this.TforY3=this.TforY2;this.YforT3=this.YforT2;this.TforY2=this.TforY1;this.YforT2=this.YforT1;this.TforY1=t;this.YforT1=y;} +return t;};this.refine=function(a,b,c,target,t){if(t<-0.1||t>1.1){return-1;} +var y=this.YforT(t);var t0;var t1;if(y=t1){useslope=false;continue;} +t=t2;} +y=this.YforT(t);if(ytarget){t1=t;}else{break;}} +var verbose=false;if(false&&t>=0&&t<=1){y=this.YforT(t);var tdiff=sec.sun.awt.geom.Curve.diffbits(t,origt);var ydiff=sec.sun.awt.geom.Curve.diffbits(y,origy);var yerr=sec.sun.awt.geom.Curve.diffbits(y,target);if(yerr>0||(verbose&&tdiff>0)){System.out.println("target was y = "+target);System.out.println("original was y = "+origy+", t = "+origt);System.out.println("final was y = "+y+", t = "+t);System.out.println("t diff is "+tdiff);System.out.println("y diff is "+ydiff);System.out.println("y error is "+yerr);var tlow=sec.sun.awt.geom.Curve.prev(t);var ylow=this.YforT(tlow);var thi=sec.sun.awt.geom.Curve.next(t);var yhi=this.YforT(thi);if(Math.abs(target-ylow)1)?-1:t;};this.XforY=function(y){if(y<=this.y0){return this.x0;} +if(y>=this.y1){return this.x1;} +return this.XforT(this.TforY(y));};this.XforT=function(t){return(((this.xcoeff3*t)+this.xcoeff2)*t+this.xcoeff1)*t+this.xcoeff0;};this.YforT=function(t){return(((this.ycoeff3*t)+this.ycoeff2)*t+this.ycoeff1)*t+this.ycoeff0;};this.dXforT=function(t,deriv){switch(deriv){case 0:return(((this.xcoeff3*t)+this.xcoeff2)*t+this.xcoeff1)*t+this.xcoeff0;case 1:return((3*this.xcoeff3*t)+2*this.xcoeff2)*t+this.xcoeff1;case 2:return(6*this.xcoeff3*t)+2*this.xcoeff2;case 3:return 6*this.xcoeff3;default:return 0;}};this.dYforT=function(t,deriv){switch(deriv){case 0:return(((this.ycoeff3*t)+this.ycoeff2)*t+this.ycoeff1)*t+this.ycoeff0;case 1:return((3*this.ycoeff3*t)+2*this.ycoeff2)*t+this.ycoeff1;case 2:return(6*this.ycoeff3*t)+2*this.ycoeff2;case 3:return 6*this.ycoeff3;default:return 0;}};this.nextVertical=function(t0,t1){var eqn=[this.xcoeff1,2*this.xcoeff2,3*this.xcoeff3];var numroots=sec.sun.awt.geom.Curve.solveQuadratic(eqn,eqn);for(var i=0;it0&&eqn[i]0&&t<1){r.add(this.XforT(t),this.YforT(t));}} +r.add(this.x1,this.y1);};this.getWithDirection=function(direction){return(this.direction===direction?this:this.getReversedCurve());};this.getSubCurve=function(ystart,yend,dir){if(ystart<=this.y0&¥d>=this.y1){return this.getWithDirection(dir);} +var eqn=Clazz.newArray(14,0);var t0;var t1;t0=this.TforY(ystart);t1=this.TforY(yend);eqn[0]=this.x0;eqn[1]=this.y0;eqn[2]=this.cx0;eqn[3]=this.cy0;eqn[4]=this.cx1;eqn[5]=this.cy1;eqn[6]=this.x1;eqn[7]=this.y1;if(t0>t1){var t=t0;t0=t1;t1=t;} +if(t1<1){sec.sun.awt.geom.Order3.split(eqn,0,t1);} +var i;if(t0<=0){i=0;}else{sec.sun.awt.geom.Order3.split(eqn,0,t0/t1);i=6;} +return new sec.sun.awt.geom.Order3(eqn[i+0],ystart,eqn[i+2],eqn[i+3],eqn[i+4],eqn[i+5],eqn[i+6],yend,dir);};this.getReversedCurve=function(){return new sec.sun.awt.geom.Order3(this.x0,this.y0,this.cx0,this.cy0,this.cx1,this.cy1,this.x1,this.y1,-this.direction);};this.getSegment=function(coords){if(this.direction===1){coords[0]=this.cx0;coords[1]=this.cy0;coords[2]=this.cx1;coords[3]=this.cy1;coords[4]=this.x1;coords[5]=this.y1;}else{coords[0]=this.cx1;coords[1]=this.cy1;coords[2]=this.cx0;coords[3]=this.cy0;coords[4]=this.x0;coords[5]=this.y0;} +return 3;};this.controlPointString=function(){return(("("+sec.sun.awt.geom.Curve.round(this.getCX0())+", "+sec.sun.awt.geom.Curve.round(this.getCY0())+"), ")+("("+sec.sun.awt.geom.Curve.round(this.getCX1())+", "+sec.sun.awt.geom.Curve.round(this.getCY1())+"), "));};this.setParent=function(parent){this._parent=parent;};this.getParent=function(){return this._parent;};};sec.sun.awt.geom.Order3.insert=function(curves,tmp,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction){var numparams=sec.sun.awt.geom.Order3.getHorizontalParams(y0,cy0,cy1,y1,tmp);if(numparams===0){sec.sun.awt.geom.Order3.addInstance(curves,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction);return;} +tmp[3]=x0;tmp[4]=y0;tmp[5]=cx0;tmp[6]=cy0;tmp[7]=cx1;tmp[8]=cy1;tmp[9]=x1;tmp[10]=y1;var t=tmp[0];if(numparams>1&&t>tmp[1]){tmp[0]=tmp[1];tmp[1]=t;t=tmp[0];} +sec.sun.awt.geom.Order3.split(tmp,3,t);if(numparams>1){t=(tmp[1]-t)/(1-t);sec.sun.awt.geom.Order3.split(tmp,9,t);} +var index=3;if(direction===-1){index+=numparams*6;}while(numparams>=0){sec.sun.awt.geom.Order3.addInstance(curves,tmp[index+0],tmp[index+1],tmp[index+2],tmp[index+3],tmp[index+4],tmp[index+5],tmp[index+6],tmp[index+7],direction);numparams--;if(direction===1){index+=6;}else{index-=6;}}};sec.sun.awt.geom.Order3.addInstance=function(curves,x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction){if(y0>y1){curves.add(new sec.sun.awt.geom.Order3(x1,y1,cx1,cy1,cx0,cy0,x0,y0,-direction));}else if(y1>y0){curves.add(new sec.sun.awt.geom.Order3(x0,y0,cx0,cy0,cx1,cy1,x1,y1,direction));}};sec.sun.awt.geom.Order3.getHorizontalParams=function(c0,cp0,cp1,c1,ret) +{if(c0<=cp0&&cp0<=cp1&&cp1<=c1) +{return 0;} +c1-=cp1;cp1-=cp0;cp0-=c0;ret[0]=cp0;ret[1]=(cp1-cp0)*2;ret[2]=(c1-cp1-cp1+cp0);var numroots=sec.sun.awt.geom.Curve.solveQuadratic(ret,ret);var j=0;for(var i=0;i0&&t<1){if(j=left;cur--){e=edgelist[cur];if(e.getCurve().getYBot()>y){if(next>cur){edgelist[next]=e;} +next--;}} +left=next+1;if(left>=right){if(right>=numedges){break;} +y=edgelist[right].getCurve().getYTop();if(y>yrange[0]){sec.sun.awt.geom.SomeOp.finalizeSubCurves(subcurves,chains);} +yrange[0]=y;} +while(righty){break;} +right++;} +yrange[1]=edgelist[left].getCurve().getYBot();if(righty){yrange[1]=y;}} +if(false){System.out.println("current line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curleft;next--){var prevedge=edgelist[next-1];var ordering=e.compareTo(prevedge,yrange);if(yrange[1]<=yrange[0]){throw new InternalError("backstepping to "+yrange[1]+" from "+yrange[0]);} +if(ordering>=0){if(ordering===0){var eq=prevedge.getEquivalence();if(eq===0){eq=nexteq++;prevedge.setEquivalence(eq);} +e.setEquivalence(eq);} +break;} +edgelist[next]=prevedge;} +edgelist[next]=e;} +if(false){System.out.println("current sorted line: y = ["+yrange[0]+", "+yrange[1]+"]");for(cur=left;curfurthesty){longestmatch=e;furthesty=y;}} +while(++cur0) +{edges.add(new sec.sun.awt.geom.Edge(c,curvetag));}}};sec.sun.awt.geom.SomeOp.finalizeSubCurves=function(subcurves,chains) +{var numchains=chains.size();if(numchains===0){return;} +if((numchains&1)!==0){throw new InternalError("Odd number of chains!");} +var endlist=new Array(numchains);chains.toArray(endlist);for(var i=1;ij) +obj[j]=this._vector.get(j);else +obj[j]=null;}};this.add=function(obj) +{this._vector.add(obj);};this.clear=function() +{this._vector.clear();};};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlOptions=function() +{this.mode="absolute";this.fromString=function(a){return a;throw new IllegalArgumentException("No AltitudeMode with mode \""+a+"\" found");};this.toString=function(){return this.mode;};this.getMode=function(){return this.mode;};};sec.geo.kml.KmlOptions.AltitudeMode={ABSOLUTE:"absolute",RELATIVE_TO_GROUND:"relativeToGround",RELATIVE_TO_SEA_FLOOR:"relativeToSeaFloor",CLAMP_TO_GROUND:"clampToGround",CLAMP_TO_SEA_FLOOR:"clampToSeaFloor"};var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlPolygon=function() +{this.points=null;this.altitudeMode=null;this.altitudeModeField="#ALTITUDEMODE#";this.PREFIX=null;this.SUFFIX="\t\t\t\t\t\n\t\t\t\t\n";this.PREFIX=""+" \n"+" 1\n"+" "+this.altitudeModeField+"\n"+" ";this.SUFFIX=""+" \n"+" \n";this.altitudeMode=sec.geo.kml.KmlOptions.AltitudeMode.ABSOLUTE;this.points=new java.util.ArrayList();if(arguments.length===2) +{var points=arguments[0];var altitudeMode=arguments[1];this.points.addAll(points);this.altitudeMode=altitudeMode;} +this.addPoint=function(point){this.points.add(point);};this.addPoints=function(points){this.points.addAll(points);};this.toString=function(){var sb=new sec.geo.utilities.StringBuilder();sb.append(this.PREFIX);sb.append(this.toCoordString());sb.append(this.SUFFIX);var altitudeModeIndex=sb.indexOf(this.altitudeModeField);var altitudeModeLength=this.altitudeModeField.length;if(this.altitudeMode!==null) +sb.replace(altitudeModeIndex,altitudeModeIndex+altitudeModeLength,this.altitudeMode.toString());return sb.toString();};this.toCoordString=function(){var sb=new sec.geo.utilities.StringBuilder();var orderedPoints=this.getPointsCounterClockwise();if(orderedPoints===null) +return"";var point;for(var j=0;j0){result=this.reverse(result);return result;}else +return result;};this.getPointOrder=function(){if(this.points===null||this.points.size()<3) +return 0;var n=this.points.size();var j;var k;var count=0;var z;for(var i=0;i0) +count++;} +if(count>0) +return-1;else if(count<0) +return 1;else +return 0;};this.subList=function(al,fromIndex,toIndex){var result=new java.util.ArrayList();var j=0;for(j=fromIndex;j=0;j--) +result.add(al.get(j));return result;};};sec.geo.kml.KmlPolygon.REFERENCE_ELLIPSOID=org.gavaghan.geodesy.Ellipsoid.WGS84;var sec=sec||{};sec.geo=sec.geo||{};sec.geo.kml=sec.geo.kml||{};sec.geo.kml.KmlRenderer=function() +{this.colorDefault="ff003fff";this.descriptionField="#DESCRIPTION#";this.extendedData="#EXTENDEDDATA#";this.colorField="#COLOR#";this.nameField="#NAME#";this.idField="#ID#";this.placemarkidField="#PLACEMARKID#";this.KML_START=null;this.KML_END="\n";this.PLACEMARK_START=null;this.PLACEMARK_END="\t\t\t\n\t\t\n";this.DEFAULT_EXDAT="#ID##SHAPETYPE##LAT##LON##ALT#";this.DEFAULT_BLSTY="";this.KML_START="\n";this.PLACEMARK_START="\t\t\n"+" \n"+" "+this.nameField+"\n"+" "+this.descriptionField+"\n"+" "+this.extendedData+"\n"+" \n";this.KML_START="\n";this.KML_END="\n";this.PLACEMARK_START=""+" \n"+" \n"+" "+this.nameField+"\n"+" "+this.descriptionField+"\n"+" "+this.extendedData+"\n"+" \n";this.PLACEMARK_END=""+" \n"+" \n";this.DEFAULT_EXDAT="#ID##SHAPETYPE##LAT##LON##ALT#";this.DEFAULT_BLSTY="";this.renderPolygons=function(ext){var polys=new java.util.ArrayList();ext.setMaxDistance(200000);ext.setFlatness(2);ext.setLimit(8);var perimeterPoints=new java.util.ArrayList();var it=null;var ait=null;var oit=ext.getPathIterator(null);if(Clazz.instanceOf(oit,armyc2.c2sd.graphics2d.PathIterator)) +it=oit;else if(Clazz.instanceOf(oit,sec.sun.awt.geom.AreaIterator)) +ait=oit;var pre=null;if(it!==null){while(!it.isDone()){var strokePoints=Clazz.newArray(6,0);var type=it.currentSegment(strokePoints);var longitudeDegrees=strokePoints[0];var latitudeDegrees=strokePoints[1];switch(type){case 0:case 1:if(pre!==null){var ps=new java.util.ArrayList();ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));polys.add(new sec.geo.kml.KmlPolygon(ps,ext.getAltitudeMode()));} +pre=new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees);perimeterPoints.add(pre);} +it.next();}}else if(ait!==null){while(!ait.isDone()){var strokePoints=Clazz.newArray(6,0);var type=ait.currentSegment(strokePoints);var longitudeDegrees=strokePoints[0];var latitudeDegrees=strokePoints[1];switch(type){case 0:case 1:if(pre!==null){var ps=new java.util.ArrayList();ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMaxAltitude()));ps.add(new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees,ext.getMinAltitude()));ps.add(new sec.geo.shape.Point(pre.getLongitude(),pre.getLatitude(),ext.getMinAltitude()));polys.add(new sec.geo.kml.KmlPolygon(ps,ext.getAltitudeMode()));} +pre=new sec.geo.shape.Point(longitudeDegrees,latitudeDegrees);perimeterPoints.add(pre);} +ait.next();}} +if(perimeterPoints.size()>0){if(perimeterPoints.get(0).equals(perimeterPoints.get(perimeterPoints.size()-1))){polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMinAltitude()),ext.getAltitudeMode()));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMaxAltitude()),ext.getAltitudeMode()));}else{perimeterPoints.add(perimeterPoints.get(0));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMinAltitude()),ext.getAltitudeMode()));polys.add(new sec.geo.kml.KmlPolygon(this.transformPoints(perimeterPoints,ext.getMaxAltitude()),ext.getAltitudeMode()));}} +return polys;};this.getPlacemarkKml=function(ext,id,name,description,lineColor,fillColor){try{var sb=new sec.geo.utilities.StringBuilder();var polys=this.renderPolygons(ext);sb.append(this.PLACEMARK_START);var placemarkIdIndex=sb.indexOf(this.placemarkidField);var placemarkIdLength=this.placemarkidField.length;if(id!==null){sb.replace(placemarkIdIndex,placemarkIdIndex+placemarkIdLength,id+"_mg");} +var descriptionIndex=sb.indexOf(this.descriptionField);var descriptionLength=this.descriptionField.length;if(description!==null) +sb.replace(descriptionIndex,descriptionIndex+descriptionLength,"");var colorIndex=sb.indexOf(this.colorField);var colorLength=this.colorField.length;if(fillColor!==null){sb.replace(colorIndex,colorIndex+colorLength,fillColor);}else +sb.replace(colorIndex,colorIndex+colorLength,this.colorDefault);var lineColorIndex=sb.indexOf2(this.colorField,colorIndex+colorLength);if(lineColor!==null){sb.replace(lineColorIndex,lineColorIndex+colorLength,lineColor);}else +sb.replace(lineColorIndex,lineColorIndex+colorLength,this.colorDefault);var nameIndex=sb.indexOf(this.nameField);var nameLength=this.nameField.length;if(name!==null) +sb.replace(nameIndex,nameIndex+nameLength,"");for(var j=0;j' ++'' ++'' ++'' ++'';var svgBeachSlopeSteep='' ++'' ++'' ++'' ++'' ++'';var svgBeigeStipple='' ++'' ++'';var svgFoulGround='' ++'#' ++'#' ++'';var svgKelp='' ++'' ++'' ++'';var svgRigField='' ++'' ++'' ++'' ++'' ++'';var svgSweptArea='' ++'' ++'';var svgWeirs='' ++'' ++'' ++'' ++'' ++'';var svgCrossHatchSmall='' ++'' ++'' ++'' ++'';var svgCrossHatchMedium='' ++'' ++'' ++'' ++'';var svgCrossHatchLarge='' ++'' ++'' ++'' ++'';var svgHatch='' ++'' ++'';var _document=null;if(document) +{_document=document;patternBeachSlopeModerate=new Image();patternBeachSlopeSteep=new Image();patternBeigeStipple=new Image();patternFoulGround=new Image();patternKelp=new Image();patternRigField=new Image();patternSweptArea=new Image();patternWeirs=new Image();patternBeachSlopeModerate.src=duriBeachSlopeModerate;patternBeachSlopeSteep.src=duriBeachSlopeSteep;patternBeigeStipple.src=duriBeigeStipple;patternFoulGround.src=duriFoulGround;patternKelp.src=duriKelp;patternRigField.src=duriRigField;patternSweptArea.src=duriSweptArea;patternWeirs.src=duriWeirs;} +return{PatternSolid:0,PatternCrossHatch:8,PatternForwardHatch:2,PatternBackwardHatch:3,PatternVerticalHatch:4,PatternHorizontalHatch:5,getCanvasFillStylePattern:function(pattern,lineColor,fillColor,lineWidth) +{var imagePattern=null;var duri=null;if(pattern.charAt&&pattern.charAt(0)==="W") +{if(pattern==="WO-DBSM-----A--") +return patternBeachSlopeModerate;else if(pattern==="WO-DBST-----A--") +return patternBeachSlopeSteep;else if(pattern==="WO-DHCB-----A--") +return patternBeigeStipple;else if(pattern==="WO-DHHDF----A--") +return patternFoulGround;else if(pattern==="WO-DHHDK----A--") +return patternKelp;else if(pattern==="WO-DMOA-----A--") +return patternRigField;else if(pattern==="WO-DL-SA----A--") +return patternSweptArea;else if(pattern==="WOS-HPFF----A--") +return patternWeirs;} +else if(_document&&pattern>0&&pattern<9) +{imagePattern=_document.createElement('canvas');imagePattern.id=pattern+"";if(pattern<8) +{imagePattern.width=15;imagePattern.height=15;} +else +{imagePattern.width=15;imagePattern.height=15;} +var ctx=imagePattern.getContext("2d");ctx.lineWidth=1;ctx.strokeStyle=lineColor;if(pattern>1&&pattern<6) +{if(pattern===2) +{ctx.beginPath();ctx.moveTo(15,15);ctx.lineTo(-1,-1);ctx.moveTo(1,16);ctx.lineTo(-1,14);ctx.moveTo(14,-1);ctx.lineTo(16,1);ctx.stroke();} +else if(pattern===3) +{ctx.beginPath();ctx.moveTo(-1,16);ctx.lineTo(16,-1);ctx.moveTo(14,16);ctx.lineTo(16,14);ctx.moveTo(-1,1);ctx.lineTo(1,-1);ctx.stroke();} +else if(pattern===4) +{ctx.beginPath();ctx.moveTo(3,0);ctx.lineTo(3,15);ctx.stroke();} +else if(pattern===5) +{ctx.beginPath();ctx.moveTo(0,4);ctx.lineTo(15,4);ctx.stroke();}} +else if(pattern===8) +{ctx.beginPath();ctx.moveTo(-1,16);ctx.lineTo(16,-1);ctx.moveTo(14,16);ctx.lineTo(16,14);ctx.moveTo(-1,1);ctx.lineTo(1,-1);ctx.moveTo(15,15);ctx.lineTo(-1,-1);ctx.moveTo(1,16);ctx.lineTo(-1,14);ctx.moveTo(14,-1);ctx.lineTo(16,1);ctx.stroke();} +return imagePattern;} +return null;},getSVGFillStylePattern:function(pattern,lineColor,alpha,lineWidth) +{var svgPattern=null;if(pattern.charAt&&pattern.charAt(0)==="W") +{if(pattern==="WO-DBSM-----A--") +return svgBeachSlopeModerate;else if(pattern==="WO-DBST-----A--") +return svgBeachSlopeSteep;else if(pattern==="WO-DHCB-----A--") +return svgBeigeStipple;else if(pattern==="WO-DHHDF----A--") +return svgFoulGround;else if(pattern==="WO-DHHDK----A--") +return svgKelp;else if(pattern==="WO-DMOA-----A--") +return svgRigField;else if(pattern==="WO-DL-SA----A--") +return svgSweptArea;else if(pattern==="WOS-HPFF----A--") +return svgWeirs;} +else +{if(pattern===2) +{svgPattern=svgHatch.replace("rotate(45 0 0)","rotate(-45 0 0)");} +else if(pattern===3) +{svgPattern=svgHatch+"";} +else if(pattern===8) +{svgPattern=svgCrossHatchMedium+"";} +else if(pattern===4) +{svgPattern=svgHatch.replace("rotate(45 0 0)","rotate(0 0 0)");} +else if(pattern===5) +{svgPattern=svgHatch.replace("rotate(45 0 0)","rotate(90 0 0)");} +if(svgPattern) +{svgPattern=svgPattern.replace("black",lineColor);} +return svgPattern;} +return null;},isMETOCWithFillPattern:function(symbolID) +{var returnVal=false;if(symbolID.charAt(0)==="W") +{switch(symbolID) +{case"WO-DBSM-----A--":case"WO-DBST-----A--":case"WO-DHCB-----A--":case"WO-DHHDF----A--":case"WO-DHHDK----A--":case"WO-DMOA-----A--":case"WO-DL-SA----A--":case"WOS-HPFF----A--":returnVal=true;break;default:break;}} +return returnVal;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.RendererUtilities=(function(){var pastTextMeasurements={};var fullFontMeasurements={};var pastIdealOutlineColors={};var FillPatterns=armyc2.c2sd.renderer.utilities.FillPatterns||null;var _canvas=null;var _ctx=null;if(document&&document.createElement) +{_canvas=document.createElement("canvas");_canvas.width=100;_canvas.height=100;} +if(_canvas&&_canvas.getContext) +{_ctx=_canvas.getContext('2d');_ctx.textBaseline='top';} +else +{pastTextMeasurements["bold 9pt Arial, sans-serif"]={width:0,height:10,descent:2,fullHeight:12};pastTextMeasurements["bold 10pt Arial, sans-serif"]={width:0,height:11,descent:3,fullHeight:14};pastTextMeasurements["bold 12pt Arial, sans-serif"]={width:0,height:13,descent:3,fullHeight:16};pastTextMeasurements["bold 9pt Arial, serif"]={width:0,height:10,descent:2,fullHeight:12};pastTextMeasurements["bold 10pt Arial, serif"]={width:0,height:11,descent:3,fullHeight:14};pastTextMeasurements["bold 12pt Arial, serif"]={width:0,height:13,descent:3,fullHeight:16};pastTextMeasurements["normal 16pt Arial"]={width:0,height:16,descent:4,fullHeight:20};} +function scanForCharTopAndBottom(pixels,width,height,widthLimit) +{var top=-1,bottom=-1;var row=0,col=0;var hit=false;for(row=0;row3) +{var backupFonts=arrFont.slice(3);for(var i=0;iarialWidth&&spWidth>arialWidth&&tgWidth>arialWidth) +returnVal=true;return returnVal;},getCanvasFillStylePattern:function(pattern,lineColor,fillColor,lineWidth) +{if(FillPatterns) +{return FillPatterns.getCanvasFillStylePattern(pattern,lineColor,fillColor,lineWidth);} +else +{return null;}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ImageInfo=function(image,centerPoint,symbolBounds,bounds){this._canvas=image;this._center=centerPoint;this._symbolBounds=symbolBounds;this._bounds=bounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.toDataUrl=function(){return this._canvas.toDataURL();};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.toSVG=function(){var width=this.getImageBounds().getWidth();var height=this.getImageBounds().getHeight();var dataUri=this.toDataUrl();var svgTxt=[];svgTxt.push('');svgTxt.push('');return svgTxt.join("");};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getImage=function(){return this._canvas;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getCenterPoint=function(){return this._center;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSymbolBounds=function(){return this._symbolBounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getImageBounds=function(){return this._bounds;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSquareIcon=function(){var iwidth,iheight,x,y;var width=this._bounds.getWidth();var height=this._bounds.getHeight();if(this._bounds.getWidth()>this._bounds.getHeight()) +{iwidth=this._bounds.getWidth();iheight=this._bounds.getWidth();x=0;y=(iheight-height)/2;} +else if(this._bounds.getWidth()height-point.getY()) +{height=(point.getY()*2.0);y=0;} +else +{height=((height-point.getY())*2);y=((height/2)-point.getY());} +if(point.getX()>width-point.getX()) +{width=(point.getX()*2.0);x=0;} +else +{width=((width-point.getX())*2);x=((width/2)-point.getX());} +bi=document.createElement('canvas');bi.width=width;bi.height=height;var ctx=bi.getContext('2d');ctx.drawImage(image,x,y);} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("ImageInfo","getCenteredImage",err);} +return bi;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getCenteredImageInfo=function(){var image=this._canvas,bi=null,ii=null,x=0,y=0,height=image.height,width=image.width,point=this._center;try +{if(point.getY()>height-point.getY()) +{height=(point.getY()*2.0);y=0;} +else +{height=((height-point.getY())*2);y=((height/2)-point.getY());} +if(point.getX()>width-point.getX()) +{width=(point.getX()*2.0);x=0;} +else +{width=((width-point.getX())*2);x=((width/2)-point.getX());} +bi=document.createElement('canvas');bi.width=width;bi.height=height;var ctx=bi.getContext('2d');ctx.drawImage(image,x,y);var center=point.clone();center.shift(x,y);var symbolBounds=this._symbolBounds.clone();symbolBounds.shift(x,y);var bounds=new armyc2.s2sd.renderer.so.Rectangle(0,0,width,height);ii=new armyc2.c2sd.renderer.utilities.ImageInfo(bi,center,symbolBounds,bounds);} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("ImageInfo","getCenteredImage",err);} +return ii;};armyc2.c2sd.renderer.utilities.ImageInfo.prototype.getSquareImageInfo=function(){var iwidth,iheight,x,y;var width=this._bounds.getWidth();var height=this._bounds.getHeight();var ii=null;if(this._bounds.getWidth()>this._bounds.getHeight()) +{iwidth=this._bounds.getWidth();iheight=this._bounds.getWidth();x=0;y=(iheight-height)/2;} +else if(this._bounds.getWidth()0) +{var bounds=new armyc2.c2sd.renderer.so.Rectangle(this.bounds.x-outlineOffset,this.bounds.y-outlineOffset,this.bounds.width+outlineOffset*2,this.bounds.height+outlineOffset*2);return bounds;} +else +{return this.bounds;}};armyc2.c2sd.renderer.utilities.TextInfo.prototype.getText=function(){return this.text;};armyc2.c2sd.renderer.utilities.TextInfo.prototype.getLocation=function(){return this.location;};armyc2.c2sd.renderer.utilities.TextInfo.prototype.outlineText=function(context){var thickness=armyc2.c2sd.renderer.utilities.RendererSettings.getTextOutlineWidth();for(var i=1;i<=thickness;i++) +{if(i%2!==0) +{context.fillText(this.text,this.location.getX()-i,this.location.getY()-i);context.fillText(this.text,this.location.getX()+i,this.location.getY()-i);context.fillText(this.text,this.location.getX()-i,this.location.getY()+i);context.fillText(this.text,this.location.getX()+i,this.location.getY()+i);} +else +{context.fillText(this.text,this.location.getX()-i,this.location.getY());context.fillText(this.text,this.location.getX()+i,this.location.getY());context.fillText(this.text,this.location.getX(),this.location.getY()+i);context.fillText(this.text,this.location.getX(),this.location.getY()-i);}}};armyc2.c2sd.renderer.utilities.TextInfo.prototype.strokeText=function(context){context.strokeText(this.text,this.location.getX(),this.location.getY());};armyc2.c2sd.renderer.utilities.TextInfo.prototype.fillText=function(context){context.fillText(this.text,this.location.getX(),this.location.getY());};armyc2.c2sd.renderer.utilities.TextInfo.prototype.createBuffer=function(width,height) +{var buffer=document.createElement('canvas');buffer.width=width;buffer.height=height;return buffer;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.ModifiersUnits={A_SYMBOL_ICON:"A",B_ECHELON:"B",C_QUANTITY:"C",D_TASK_FORCE_INDICATOR:"D",E_FRAME_SHAPE_MODIFIER:"E",F_REINFORCED_REDUCED:"F",G_STAFF_COMMENTS:"G",H_ADDITIONAL_INFO_1:"H",H1_ADDITIONAL_INFO_2:"H1",H2_ADDITIONAL_INFO_3:"H2",J_EVALUATION_RATING:"J",K_COMBAT_EFFECTIVENESS:"K",L_SIGNATURE_EQUIP:"L",M_HIGHER_FORMATION:"M",N_HOSTILE:"N",P_IFF_SIF:"P",Q_DIRECTION_OF_MOVEMENT:"Q",R_MOBILITY_INDICATOR:"R",R2_SIGNIT_MOBILITY_INDICATOR:"R2",S_HQ_STAFF_OR_OFFSET_INDICATOR:"S",T_UNIQUE_DESIGNATION_1:"T",T1_UNIQUE_DESIGNATION_2:"T1",V_EQUIP_TYPE:"V",W_DTG_1:"W",W1_DTG_2:"W1",X_ALTITUDE_DEPTH:"X",Y_LOCATION:"Y",Z_SPEED:"Z",AA_SPECIAL_C2_HQ:"AA",AB_FEINT_DUMMY_INDICATOR:"AB",AC_INSTALLATION:"AC",AD_PLATFORM_TYPE:"AD",AE_EQUIPMENT_TEARDOWN_TIME:"AE",AF_COMMON_IDENTIFIER:"AF",AG_AUX_EQUIP_INDICATOR:"AG",AH_AREA_OF_UNCERTAINTY:"AH",AI_DEAD_RECKONING_TRAILER:"AI",AJ_SPEED_LEADER:"AJ",AK_PAIRING_LINE:"AK",AL_OPERATIONAL_CONDITION:"AL",AO_ENGAGEMENT_BAR:"AO",CC_COUNTRY_CODE:"CC",CN_CPOF_NAME_LABEL:"CN",SCC_SONAR_CLASSIFICATION_CONFIDENCE:"SCC",getModifierName:function(modifier) +{switch(modifier) +{case this.B_ECHELON:return"Echelon";case this.C_QUANTITY:return"Quantity";case this.F_REINFORCED_REDUCED:return"Reinforce Reduced";case this.G_STAFF_COMMENTS:return"Staff Comments";case this.H_ADDITIONAL_INFO_1:return"Additional Info 1";case this.H1_ADDITIONAL_INFO_2:return"Additional Info 2";case this.H2_ADDITIONAL_INFO_3:return"Additional Info 3";case this.J_EVALUATION_RATING:return"Evaluation Rating";case this.K_COMBAT_EFFECTIVENESS:return"Combat Effectiveness";case this.L_SIGNATURE_EQUIP:return"Signature Equipment";case this.M_HIGHER_FORMATION:return"Higher Formation";case this.N_HOSTILE:return"Hostile";case this.P_IFF_SIF:return"IFF SIF";case this.Q_DIRECTION_OF_MOVEMENT:return"Direction of Movement";case this.R_MOBILITY_INDICATOR:return"Mobility Indicator";case this.R2_SIGNIT_MOBILITY_INDICATOR:return"Signals Intelligence Mobility Indicator";case this.T_UNIQUE_DESIGNATION_1:return"Unique Designation 1";case this.T1_UNIQUE_DESIGNATION_2:return"Unique Designation 2";case this.V_EQUIP_TYPE:return"Equipment Type";case this.W_DTG_1:return"Date Time Group 1";case this.W1_DTG_2:return"Date Time Group 2";case this.X_ALTITUDE_DEPTH:return"Altitude Depth";case this.Y_LOCATION:return"Location";case this.Z_SPEED:return"Speed";case this.AA_SPECIAL_C2_HQ:return"Special C2 HQ";case this.AD_PLATFORM_TYPE:return"Platform Type";case this.AE_EQUIPMENT_TEARDOWN_TIME:return"Equipment Teardown Time";case this.AF_COMMON_IDENTIFIER:return"Common Identifier";case this.SCC_SONAR_CLASSIFICATION_CONFIDENCE:return"Sonar Classification Confidence";default:return"";}}};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SinglePointLookupInfo=function(basicSymbolID,description,mappingP,mappingA,width,height){var _SymbolID=basicSymbolID,_Description=description,_mappingP=mappingP,_mappingA=mappingA,_width=width,_height=height;this.getBasicSymbolIDStrict=function(){return _SymbolID;};this.getDescription=function(){return _Description;};this.getMappingA=function(){return _mappingA;};this.getMappingP=function(){return _mappingP;};this.getWidth=function(){return _width;};this.getHeight=function(){return _height;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.UnitFontLookupInfo=function(basicSymbolID,description,mapping1U,mapping1F,mapping1N,mapping1H,mapping1Color,mapping2,mapping2Color){var _SymbolID=basicSymbolID,_Description=description,_mapping1U=mapping1U,_mapping1F=mapping1F,_mapping1N=mapping1N,_mapping1H=mapping1H,_mapping1Color=mapping1Color,_mapping2=mapping2,_mapping2Color=mapping2Color;this.getBasicSymbolID=function(){return _SymbolID;};this.getDescription=function(){return _Description;};this.getMapping1=function(symbolID){var affiliation=symbolID.charAt(1);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +return _mapping1F;else if(affiliation==='H'||affiliation==='S') +return _mapping1H;if(affiliation==='N'||affiliation==='L') +return _mapping1N;else +return _mapping1U;};this.getMapping2=function(){return _mapping2;};this.getColor1=function(){return _mapping1Color;};this.getColor2=function(){return _mapping2Color;};};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.TacticalGraphicLookup=(function(){var symbols=null,symbolMap=null,parser,spMappingXml={"TACTICALGRAPHICS":{"SYMBOL":[{"ID":"G*T*B-----****X","M":"2001",},{"ID":"G*T*H-----****X","M":"2002",},{"ID":"G*T*Y-----****X","M":"2003",},{"ID":"G*T*C-----****X","M":"2004",},{"ID":"G*T*X-----****X","M":"2005",},{"ID":"G*T*J-----****X","M":"2006",},{"ID":"G*T*K-----****X","M":"2007",},{"ID":"G*T*KF----****X","M":"2008",},{"ID":"G*T*L-----****X","M":"2009",},{"ID":"G*T*T-----****X","M":"2011",},{"ID":"G*T*F-----****X","M":"2012",},{"ID":"G*T*A-----****X","M":"2013",},{"ID":"G*T*AS----****X","M":"2014",},{"ID":"G*T*E-----****X","M":"2016",},{"ID":"G*T*O-----****X","M":"2018",},{"ID":"G*T*P-----****X","M":"2019",},{"ID":"G*T*R-----****X","M":"2020",},{"ID":"G*T*Q-----****X","M":"2021",},{"ID":"G*T*M-----****X","M":"2022",},{"ID":"G*T*S-----****X","M":"2023",},{"ID":"G*T*US----****X","M":"2024",},{"ID":"G*T*UG----****X","M":"2025",},{"ID":"G*T*UC----****X","M":"2026",},{"ID":"G*T*Z-----****X","M":"2027",},{"ID":"G*T*W-----****X","M":"2028",},{"ID":"G*T*WP----****X","M":"2029",},{"ID":"G*T*V-----****X","M":"2016",},{"ID":"G*T*2-----****X","M":"2016",},{"ID":"G*G*GLB---****X","M":"2030",},{"ID":"G*G*GLF---****X","M":"2031",},{"ID":"G*G*GLC---****X","M":"2032",},{"ID":"G*G*GLP---****X","M":"2033",},{"ID":"G*G*GLL---****X","M":"2034",},{"ID":"G*G*GAG---****X","M":"2035",},{"ID":"G*G*GAA---****X","M":"2036",},{"ID":"G*G*GAE---****X","M":"2037",},{"ID":"G*G*GAF---****X","M":"2038",},{"ID":"G*G*GAD---****X","M":"2039",},{"ID":"G*G*GAX---****X","M":"2040",},{"ID":"G*G*GAL---****X","M":"2041",},{"ID":"G*G*GAP---****X","M":"2042",},{"ID":"G*G*GAS---****X","M":"2043",},{"ID":"G*G*GAY---****X","M":"2044",},{"ID":"G*G*GAZ---****X","M":"2045",},{"ID":"G*G*ALC---****X","M":"2046",},{"ID":"G*G*ALM---****X","M":"2047",},{"ID":"G*G*ALS---****X","M":"2048",},{"ID":"G*G*ALU---****X","M":"2049",},{"ID":"G*G*ALL---****X","M":"2050",},{"ID":"G*G*AAR---****X","M":"2051",},{"ID":"G*G*AAF---2525C","M":"2052",},{"ID":"G*G*AAF---****X","M":"2053",},{"ID":"G*G*AAH---****X","M":"2054",},{"ID":"G*G*AAM---****X","M":"2055",},{"ID":"G*G*AAML--****X","M":"2056",},{"ID":"G*G*AAMH--****X","M":"2057",},{"ID":"G*G*AAW---****X","M":"2058",},{"ID":"G*G*PD----****X","M":"2059",},{"ID":"G*G*PA----****X","M":"2060",},{"ID":"G*G*PF----****X","M":"2061",},{"ID":"G*G*PM----****X","M":"2062",},{"ID":"G*G*PY----****X","M":"2063",},{"ID":"G*G*PC----****X","M":"2064",},{"ID":"G*G*DLF---****X","M":"2065",},{"ID":"G*G*DLP---****X","M":"2066",},{"ID":"G*G*DAB---****X","M":"2067",},{"ID":"G*G*DABP--****X","M":"2068",},{"ID":"G*G*DAE---****X","M":"2069",},{"ID":"G*G*OLAV--****X","M":"2070",},{"ID":"G*G*OLAA--****X","M":"2071",},{"ID":"G*G*OLAR--****X","M":"2072",},{"ID":"G*G*OLAGM-****X","M":"2073",},{"ID":"G*G*OLAGS-****X","M":"2074",},{"ID":"G*G*OLKA--****X","M":"2075",},{"ID":"G*G*OLKGM-****X","M":"2076",},{"ID":"G*G*OLKGS-****X","M":"2077",},{"ID":"G*G*OLF---****X","M":"2078",},{"ID":"G*G*OLI---****X","M":"2079",},{"ID":"G*G*OLL---****X","M":"2080",},{"ID":"G*G*OLT---****X","M":"2081",},{"ID":"G*G*OLC---****X","M":"2082",},{"ID":"G*G*OLP---****X","M":"2083",},{"ID":"G*G*OAA---****X","M":"2084",},{"ID":"G*G*OAK---****X","M":"2085",},{"ID":"G*G*OAF---****X","M":"2086",},{"ID":"G*G*OAS---****X","M":"2087",},{"ID":"G*G*OAO---****X","M":"2088",},{"ID":"G*G*OAP---****X","M":"2089",},{"ID":"G*G*SLA---****X","M":"2090",},{"ID":"G*G*SLH---****X","M":"2091",},{"ID":"G*G*SLR---****X","M":"2092",},{"ID":"G*G*SLB---****X","M":"2093",},{"ID":"G*G*SAO---****X","M":"2094",},{"ID":"G*G*SAA---****X","M":"2095",},{"ID":"G*G*SAE---****X","M":"2096",},{"ID":"G*G*SAN---****X","M":"2097",},{"ID":"G*G*SAT---****X","M":"2098",},{"ID":"G*M*OGB---****X","M":"2099",},{"ID":"G*M*OGL---****X","M":"2100",},{"ID":"G*M*OGZ---****X","M":"2101",},{"ID":"G*M*OGF---****X","M":"2102",},{"ID":"G*M*OGR---****X","M":"2103",},{"ID":"G*M*OS----****X","M":"2104",},{"ID":"G*M*OADU--****X","M":"2105",},{"ID":"G*M*OADC--****X","M":"2106",},{"ID":"G*M*OAR---****X","M":"2107",},{"ID":"G*M*OAW---****X","M":"2108",},{"ID":"G*M*OMC---****X","M":"2109",},{"ID":"G*M*OFD---****X","M":"2110",},{"ID":"G*M*OFG---****X","M":"2111",},{"ID":"G*M*OFA---****X","M":"2112",},{"ID":"G*M*OEB---****X","M":"2113",},{"ID":"G*M*OEF---****X","M":"2114",},{"ID":"G*M*OET---****X","M":"2115",},{"ID":"G*M*OED---****X","M":"2116",},{"ID":"G*M*OU----****X","M":"2117",},{"ID":"G*M*ORP---****X","M":"2118",},{"ID":"G*M*ORS---****X","M":"2119",},{"ID":"G*M*ORA---****X","M":"2120",},{"ID":"G*M*ORC---****X","M":"2121",},{"ID":"G*M*OT----****X","M":"2122",},{"ID":"G*M*OWU---****X","M":"2123",},{"ID":"G*M*OWS---****X","M":"2124",},{"ID":"G*M*OWD---****X","M":"2125",},{"ID":"G*M*OWA---****X","M":"2126",},{"ID":"G*M*OWL---****X","M":"2127",},{"ID":"G*M*OWH---****X","M":"2128",},{"ID":"G*M*OWCS--****X","M":"2129",},{"ID":"G*M*OWCD--****X","M":"2130",},{"ID":"G*M*OWCT--****X","M":"2131",},{"ID":"G*M*OHO---****X","M":"2133",},{"ID":"G*M*BDE---****X","M":"2134",},{"ID":"G*M*BDD---****X","M":"2135",},{"ID":"G*M*BDI---****X","M":"2136",},{"ID":"G*M*BCA---****X","M":"2137",},{"ID":"G*M*BCB---****X","M":"2138",},{"ID":"G*M*BCF---****X","M":"2139",},{"ID":"G*M*BCE---****X","M":"2140",},{"ID":"G*M*BCD---****X","M":"2141",},{"ID":"G*M*BCL---****X","M":"2142",},{"ID":"G*M*BCR---****X","M":"2143",},{"ID":"G*M*SL----****X","M":"2144",},{"ID":"G*M*SW----****X","M":"2145",},{"ID":"G*M*SP----****X","M":"2146",},{"ID":"G*M*NM----****X","M":"2147",},{"ID":"G*M*NR----****X","M":"2148",},{"ID":"G*M*NB----****X","M":"2149",},{"ID":"G*M*NC----****X","M":"2150",},{"ID":"G*M*NL----****X","M":"2151",},{"ID":"G*F*LT----****X","M":"2152",},{"ID":"G*F*LTS---****X","M":"2153",},{"ID":"G*F*LTF---****X","M":"2154",},{"ID":"G*F*LCF---****X","M":"2155",},{"ID":"G*F*LCC---****X","M":"2156",},{"ID":"G*F*LCN---****X","M":"2157",},{"ID":"G*F*LCR---****X","M":"2158",},{"ID":"G*F*LCM---****X","M":"2159",},{"ID":"G*F*AT----****X","M":"2160",},{"ID":"G*F*ATR---****X","M":"2161",},{"ID":"G*F*ATC---****X","M":"2162",},{"ID":"G*F*ATG---****X","M":"2163",},{"ID":"G*F*ATS---****X","M":"2164",},{"ID":"G*F*ATB---****X","M":"2165",},{"ID":"G*F*ACSI--****X","M":"2166",},{"ID":"G*F*ACSR--****X","M":"2167",},{"ID":"G*F*ACSC--****X","M":"2168",},{"ID":"G*F*ACAI--****X","M":"2169",},{"ID":"G*F*ACAR--****X","M":"2170",},{"ID":"G*F*ACAC--****X","M":"2171",},{"ID":"G*F*ACFI--****X","M":"2172",},{"ID":"G*F*ACFR--****X","M":"2173",},{"ID":"G*F*ACFC--****X","M":"2174",},{"ID":"G*F*ACNI--****X","M":"2175",},{"ID":"G*F*ACNR--****X","M":"2176",},{"ID":"G*F*ACNC--****X","M":"2177",},{"ID":"G*F*ACRI--****X","M":"2178",},{"ID":"G*F*ACRR--****X","M":"2179",},{"ID":"G*F*ACRC--****X","M":"2180",},{"ID":"G*F*ACPR--****X","M":"2181",},{"ID":"G*F*ACPC--****X","M":"2182",},{"ID":"G*F*AZII--****X","M":"2183",},{"ID":"G*F*AZIR--****X","M":"2184",},{"ID":"G*F*AZIC--****X","M":"2185",},{"ID":"G*F*AZXI--****X","M":"2186",},{"ID":"G*F*AZXR--****X","M":"2187",},{"ID":"G*F*AZXC--****X","M":"2188",},{"ID":"G*F*AZSI--****X","M":"2189",},{"ID":"G*F*ACEI--****X","M":"2189",},{"ID":"G*F*AZSR--****X","M":"2190",},{"ID":"G*F*ACER--****X","M":"2190",},{"ID":"G*F*AZSC--****X","M":"2191",},{"ID":"G*F*ACEC--****X","M":"2191",},{"ID":"G*F*AZCI--****X","M":"2192",},{"ID":"G*F*AZCR--****X","M":"2193",},{"ID":"G*F*AZCC--****X","M":"2194",},{"ID":"G*F*AZDI--****X","M":"2195",},{"ID":"G*F*ACDI--****X","M":"2195",},{"ID":"G*F*AZDR--****X","M":"2196",},{"ID":"G*F*ACDR--****X","M":"2196",},{"ID":"G*F*AZDC--****X","M":"2197",},{"ID":"G*F*ACDC--****X","M":"2197",},{"ID":"G*F*AZFI--****X","M":"2217",},{"ID":"G*F*AZFR--****X","M":"2218",},{"ID":"G*F*AZFC--****X","M":"1052",},{"ID":"G*F*AZZI--****X","M":"2198",},{"ID":"G*F*ACZI--****X","M":"2198",},{"ID":"G*F*AZZR--****X","M":"2199",},{"ID":"G*F*ACZR--****X","M":"2199",},{"ID":"G*F*AZZC--****X","M":"2200",},{"ID":"G*F*ACZC--****X","M":"2200",},{"ID":"G*F*AZBI--****X","M":"2201",},{"ID":"G*F*ACBI--****X","M":"2201",},{"ID":"G*F*AZBR--****X","M":"2202",},{"ID":"G*F*ACBR--****X","M":"2202",},{"ID":"G*F*AZBC--****X","M":"2203",},{"ID":"G*F*ACBC--****X","M":"2203",},{"ID":"G*F*AZVI--****X","M":"2204",},{"ID":"G*F*ACVI--****X","M":"2204",},{"ID":"G*F*AZVR--****X","M":"2205",},{"ID":"G*F*ACVR--****X","M":"2205",},{"ID":"G*F*AZVC--****X","M":"2206",},{"ID":"G*F*ACVC--****X","M":"2206",},{"ID":"G*F*ACT---****X","M":"2210",},{"ID":"G*F*AXC---****X","M":"2207",},{"ID":"G*F*AXS---****X","M":"2208",},{"ID":"G*F*AKBC--****X","M":"2219",},{"ID":"G*F*AKBI--****X","M":"2220",},{"ID":"G*F*AKBR--****X","M":"2221",},{"ID":"G*F*AKPC--****X","M":"2222",},{"ID":"G*F*AKPI--****X","M":"2223",},{"ID":"G*F*AKPR--****X","M":"2224",},{"ID":"G*S*LCM---****X","M":"2226",},{"ID":"G*S*LCH---****X","M":"2227",},{"ID":"G*S*LRM---****X","M":"2228",},{"ID":"G*S*LRA---****X","M":"2229",},{"ID":"G*S*LRO---****X","M":"2230",},{"ID":"G*S*LRT---****X","M":"2231",},{"ID":"G*S*LRW---****X","M":"2232",},{"ID":"G*S*AD----****X","M":"2233",},{"ID":"G*S*AE----****X","M":"2234",},{"ID":"G*S*AR----****X","M":"2235",},{"ID":"G*S*AH----****X","M":"2236",},{"ID":"G*S*ASB---****X","M":"2237",},{"ID":"G*S*ASD---****X","M":"2238",},{"ID":"G*S*ASR---****X","M":"2239",},{"ID":"G*O*HN----****X","M":"2240",},{"ID":"G*O*B-----****X","M":"2241",},{"ID":"G*O*BE----****X","M":"2242",},{"ID":"G*O*BA----****X","M":"2243",},{"ID":"G*O*BT----****X","M":"2244",},{"ID":"G*O*BO----****X","M":"2245",},{"ID":"WA-DPFC----L---","M":"3000",},{"ID":"WA-DPFCU---L---","M":"3001",},{"ID":"WA-DPFC-FG-L---","M":"3002",},{"ID":"WA-DPFC-FY-L---","M":"3003",},{"ID":"WA-DPFW----L---","M":"3004",},{"ID":"WA-DPFWU---L---","M":"3005",},{"ID":"WA-DPFW-FG-L---","M":"3006",},{"ID":"WA-DPFW-FY-L---","M":"3007",},{"ID":"WA-DPFO----L---","M":"3008",},{"ID":"WA-DPFOU---L---","M":"3009",},{"ID":"WA-DPFO-FY-L---","M":"3010",},{"ID":"WA-DPFS----L---","M":"3011",},{"ID":"WA-DPFSU---L---","M":"3012",},{"ID":"WA-DPFS-FG-L---","M":"3013",},{"ID":"WA-DPFS-FY-L---","M":"3014",},{"ID":"WA-DPXT----L---","M":"3015",},{"ID":"WA-DPXR----L---","M":"3016",},{"ID":"WA-DPXSQ---L---","M":"3017",},{"ID":"WA-DPXIL---L---","M":"3018",},{"ID":"WA-DPXSH---L---","M":"3019",},{"ID":"WA-DPXITCZ-L---","M":"3020",},{"ID":"WA-DPXCV---L---","M":"3021",},{"ID":"WA-DPXITD--L---","M":"3022",},{"ID":"WAS-WP----P----","M":"3023",},{"ID":"WA-DWJ-----L---","M":"3030",},{"ID":"WA-DWS-----L---","M":"3031",},{"ID":"WA-DWSTSWA--A--","M":"3032",},{"ID":"WA-DBAIF----A--","M":"3034",},{"ID":"WA-DBAMV----A--","M":"3035",},{"ID":"WA-DBATB----A--","M":"3036",},{"ID":"WA-DBAI-----A--","M":"3037",},{"ID":"WA-DBALPNC--A--","M":"3038",},{"ID":"WA-DBALPC---A--","M":"3039",},{"ID":"WA-DBAFP----A--","M":"3040",},{"ID":"WA-DBAT-----A--","M":"3041",},{"ID":"WA-DBAFG----A--","M":"3042",},{"ID":"WA-DBAD-----A--","M":"3043",},{"ID":"WA-DBAFF----A--","M":"3044",},{"ID":"WA-DIPIB---L---","M":"3045",},{"ID":"WA-DIPCO---L---","M":"3046",},{"ID":"WA-DIPIS---L---","M":"3047",},{"ID":"WA-DIPIT---L---","M":"3048",},{"ID":"WA-DIPID---L---","M":"3049",},{"ID":"WA-DIPTH---L---","M":"3050",},{"ID":"WA-DIPFF---L---","M":"3051",},{"ID":"WO-DILOV---L---","M":"3052",},{"ID":"WO-DILUC---L---","M":"3053",},{"ID":"WO-DILOR---L---","M":"3054",},{"ID":"WO-DILIEO--L---","M":"3055",},{"ID":"WO-DILIEE--L---","M":"3056",},{"ID":"WO-DILIER--L---","M":"3057",},{"ID":"WO-DIOC----L---","M":"3058",},{"ID":"WO-DIOCS---L---","M":"3059",},{"ID":"WO-DIOL----L---","M":"3060",},{"ID":"WO-DIOLF---L---","M":"3061",},{"ID":"WO-DHDDL---L---","M":"3062",},{"ID":"WO-DHDDC---L---","M":"3063",},{"ID":"WO-DHDDA----A--","M":"3064",},{"ID":"WO-DHCC----L---","M":"3065",},{"ID":"WO-DHCI-----A--","M":"3066",},{"ID":"WO-DHCB-----A--","M":"3067",},{"ID":"WO-DHCW-----A--","M":"3068",},{"ID":"WO-DHCF----L---","M":"3069",},{"ID":"WO-DHCF-----A--","M":"3070",},{"ID":"WO-DHPBA---L---","M":"3071",},{"ID":"WO-DHPBA----A--","M":"3072",},{"ID":"WO-DHPBP---L---","M":"3073",},{"ID":"WOS-HPFF----A--","M":"3074",},{"ID":"WO-DHPMD----A--","M":"3075",},{"ID":"WO-DHPMO---L---","M":"3076",},{"ID":"WO-DHPMO----A--","M":"3077",},{"ID":"WO-DHPMRA--L---","M":"3078",},{"ID":"WO-DHPMRB--L---","M":"3079",},{"ID":"WO-DHPSPA--L---","M":"3080",},{"ID":"WO-DHPSPB--L---","M":"3081",},{"ID":"WO-DHPSPS--L---","M":"3082",},{"ID":"WO-DHABP----A--","M":"3083",},{"ID":"WO-DHALLA--L---","M":"3084",},{"ID":"WO-DHHD-----A--","M":"3085",},{"ID":"WO-DHHDF----A--","M":"3200",},{"ID":"WO-DHHDK----A--","M":"3201",},{"ID":"WO-DHHDB---L---","M":"3086",},{"ID":"WOS-HHDR---L---","M":"3087",},{"ID":"WO-DHHDD----A--","M":"3089",},{"ID":"WO-DTCCCFE-L---","M":"3090",},{"ID":"WO-DTCCCFF-L---","M":"3091",},{"ID":"WO-DOBVA----A--","M":"3092",},{"ID":"WO-DOBVB----A--","M":"3092",},{"ID":"WO-DOBVC----A--","M":"3092",},{"ID":"WO-DOBVD----A--","M":"3092",},{"ID":"WO-DOBVE----A--","M":"3092",},{"ID":"WO-DOBVF----A--","M":"3092",},{"ID":"WO-DOBVG----A--","M":"3092",},{"ID":"WO-DOBVH----A--","M":"3092",},{"ID":"WO-DOBVI----A--","M":"3092",},{"ID":"WO-DBSF-----A--","M":"3093",},{"ID":"WO-DBSG-----A--","M":"3094",},{"ID":"WO-DBSM-----A--","M":"3095",},{"ID":"WO-DBST-----A--","M":"3096",},{"ID":"WO-DGMSR----A--","M":"3097",},{"ID":"WO-DGMSC----A--","M":"3098",},{"ID":"WO-DGMSSVS--A--","M":"3098",},{"ID":"WO-DGMSSC---A--","M":"3098",},{"ID":"WO-DGMSSM---A--","M":"3098",},{"ID":"WO-DGMSSF---A--","M":"3098",},{"ID":"WO-DGMSSVF--A--","M":"3098",},{"ID":"WO-DGMSIVF--A--","M":"3098",},{"ID":"WO-DGMSIF---A--","M":"3098",},{"ID":"WO-DGMSIM---A--","M":"3098",},{"ID":"WO-DGMSIC---A--","M":"3098",},{"ID":"WO-DGMSB----A--","M":"3098",},{"ID":"WO-DGMS-CO--A--","M":"3098",},{"ID":"WO-DGMS-PH--A--","M":"3098",},{"ID":"WO-DGMS-SH--A--","M":"3098",},{"ID":"WO-DGML-----A--","M":"3098",},{"ID":"WO-DGMN-----A--","M":"3098",},{"ID":"WO-DGMRS----A--","M":"3098",},{"ID":"WO-DGMRM----A--","M":"3098",},{"ID":"WO-DGMRR----A--","M":"3098",},{"ID":"WO-DGMCL----A--","M":"3098",},{"ID":"WO-DGMCM----A--","M":"3098",},{"ID":"WO-DGMCH----A--","M":"3098",},{"ID":"WO-DGMIBA---A--","M":"3098",},{"ID":"WO-DGMIBB---A--","M":"3098",},{"ID":"WO-DGMIBC---A--","M":"3098",},{"ID":"WO-DGMIBD---A--","M":"3098",},{"ID":"WO-DGMIBE---A--","M":"3098",},{"ID":"WO-DGMBCA---A--","M":"3098",},{"ID":"WO-DGMBCB---A--","M":"3098",},{"ID":"WO-DGMBCC---A--","M":"3098",},{"ID":"WO-DGMBTA---A--","M":"3098",},{"ID":"WO-DGMBTB---A--","M":"3098",},{"ID":"WO-DGMBTC---A--","M":"3098",},{"ID":"WO-DGMBTD---A--","M":"3098",},{"ID":"WO-DGMBTE---A--","M":"3098",},{"ID":"WO-DGMBTF---A--","M":"3098",},{"ID":"WO-DGMBTG---A--","M":"3098",},{"ID":"WO-DGMBTH---A--","M":"3098",},{"ID":"WO-DGMBTI---A--","M":"3098",},{"ID":"WO-DL-ML---L---","M":"3099",},{"ID":"WO-DL-MA----A--","M":"3100",},{"ID":"WO-DL-RA---L---","M":"3101",},{"ID":"WO-DL-SA----A--","M":"3102",},{"ID":"WO-DL-TA----A--","M":"3103",},{"ID":"WO-DL-O-----A--","M":"3104",},{"ID":"WO-DMCA----L---","M":"3105",},{"ID":"WO-DMCC-----A--","M":"3106",},{"ID":"WO-DMCD----L---","M":"3107",},{"ID":"WO-DMOA-----A--","M":"3108",},{"ID":"WO-DMPA----L---","M":"3109",},{"ID":"CYLINDER-------","M":"900",},{"ID":"ORBIT----------","M":"900",},{"ID":"ROUTE----------","M":"900",},{"ID":"POLYGON--------","M":"900",},{"ID":"RADARC---------","M":"900",},{"ID":"POLYARC--------","M":"900",},{"ID":"CAKE-----------","M":"900",},{"ID":"TRACK----------","M":"900",},{"ID":"CURTAIN--------","M":"900",}]}};return{init:function() +{var i,data=null,symbol=null,count;if(symbolMap===null) +{symbols=spMappingXml.TACTICALGRAPHICS.SYMBOL;spMappingXml=null;symbolMap={};this.parser=null;count=symbols.length;for(i=0;i1) +{returnVal=true;} +else +{switch(sd.drawCategory) +{case this.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:case this.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE:case this.DRAW_CATEGORY_ROUTE:returnVal=true;break;default:returnVal=false;}} +return returnVal;}else{return false;}} +else if(symbolID.substring(0,3)==="BS_"||symbolID.substring(0,4)==="BBS_"||symbolID.substring(0,4)==="PBS_") +{return true;} +else +{return false;}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.UnitDefTable=(function(){var symbolMapB=null,symbolMapC=null,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;return{xmlDoc:null,init:function() +{var i,data=null,symbol=null,symbols,count;if(symbolMapB===null&&armyc2.c2sd.renderer.xml.UnitConstantsB!==undefined) +{symbols=armyc2.c2sd.renderer.xml.UnitConstantsB.UNITCONSTANTS.SYMBOL;armyc2.c2sd.renderer.xml.UnitConstantsB=null;symbolMapB={};count=symbols.length;for(i=0;i=10) +{scheme=SymbolID.charAt(0);affiliation=SymbolID.charAt(1);battleDimension=SymbolID.charAt(2);status=SymbolID.charAt(3);grdtrkSubset=SymbolID.charAt(4);if(symStd===undefined) +{symStd=RendererSettings.getSymbologyStandard();} +if(scheme==='S') +{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{if(battleDimension==='F'||battleDimension==='G') +{if(battleDimension==='F'||(battleDimension==='G'&&(grdtrkSubset==='U'||grdtrkSubset==='I'||grdtrkSubset==='0'||grdtrkSubset==='-'))) +{returnVal=803;} +else if(battleDimension==='G'&&grdtrkSubset==='E') +{returnVal=812;} +else +returnVal=803;} +else if(battleDimension==='A') +{returnVal=819;} +else if(battleDimension==='S') +{returnVal=this.getSeaSurfaceFill(SymbolID);} +else if(battleDimension==='U') +{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=819;else +returnVal=843;} +else +{returnVal=812;}} +else if(affiliation==='H'||affiliation==='S') +{if(battleDimension==='F'||battleDimension==='G') +{returnVal=806;} +else if(battleDimension==='A') +{returnVal=816;} +else if(battleDimension==='S') +{returnVal=this.getSeaSurfaceFill(SymbolID);} +else if(battleDimension==='U') +{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=816;else +returnVal=840;} +else +{returnVal=806;}} +else if(affiliation==='N'||affiliation==='L') +{if(battleDimension==='F'||battleDimension==='G') +{returnVal=809;} +else if(battleDimension==='A') +{returnVal=822;} +else if(battleDimension==='S') +{returnVal=this.getSeaSurfaceFill(SymbolID);} +else if(battleDimension==='U') +{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=822;else +returnVal=846;} +else +{returnVal=809;}} +else +{if(battleDimension==='Z'||battleDimension==='G'||battleDimension==='F') +{returnVal=800;} +else if(battleDimension==='A') +{returnVal=825;} +else if(battleDimension==='S') +{returnVal=this.getSeaSurfaceFill(SymbolID);} +else if(battleDimension==='U') +{returnVal=this.getSubSurfaceFill(SymbolID,symStd);} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=825;else +returnVal=849;} +else +returnVal=FillIndexUG;}} +else if(scheme==='E') +{if(battleDimension!=='N') +{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{if(SymbolUtilities.isEMSEquipment(SymbolID)) +returnVal=812;else +returnVal=803;} +else if(affiliation==='H'||affiliation==='S') +{returnVal=806;} +else if(affiliation==='N'||affiliation==='L') +{returnVal=809;} +else +{returnVal=800;}} +else +{returnVal=-1;}} +else if(scheme==='I') +{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{if(battleDimension==='Z') +{returnVal=812;} +else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') +{if(scheme==='I') +returnVal=812;else +returnVal=803;} +else if(battleDimension==='A') +{returnVal=819;} +else if(battleDimension==='U') +{returnVal=831;} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=819;else +returnVal=843;} +else +{if(scheme==='I') +returnVal=812;else +returnVal=803;}} +if(affiliation==='H'||affiliation==='S') +{if(battleDimension==='Z') +{returnVal=806;} +else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') +{returnVal=806;} +else if(battleDimension==='A') +{returnVal=816;} +else if(battleDimension==='U') +{returnVal=828;} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=816;else +returnVal=840;} +else +{returnVal=806;}} +if(affiliation==='N'||affiliation==='L') +{if(battleDimension==='Z') +{returnVal=809;} +else if(battleDimension==='F'||battleDimension==='G'||battleDimension==='S') +{returnVal=809;} +else if(battleDimension==='A') +{returnVal=822;} +else if(battleDimension==='U') +{returnVal=834;} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=822;else +returnVal=846;} +else +{returnVal=809;}} +else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') +{if(battleDimension==='Z'||battleDimension==='G'||battleDimension==='S'||battleDimension==='F') +{returnVal=800;} +else if(battleDimension==='A') +{returnVal=825;} +else if(battleDimension==='U') +{returnVal=837;} +else if(battleDimension==='P') +{if(symStd===0) +returnVal=825;else +returnVal=849;} +else +{returnVal=800;}}} +else +{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{if(SymbolID.substring(0,3)==="OFI"&&SymbolID.substring(4,10)===("T-----")) +{returnVal=FillIndexFGE;} +else +{returnVal=803;}} +else if(affiliation==='H'||affiliation==='S') +{returnVal=806;} +else if(affiliation==='N'||affiliation==='L') +{returnVal=809;} +else +{returnVal=800;}}} +else +{returnVal=800;} +return returnVal+57000;},getFrameCode:function(SymbolID,fillCode,symStd){var returnVal=0,status=SymbolID.charAt(3);if(status==='A') +returnVal=fillCode+2;else +returnVal=fillCode+1;if(symStd===undefined) +symStd=RendererSettings.getSymbologyStandard();if(symStd>RendererSettings.Symbology_2525B&&status==='A') +{var affiliation=SymbolID.charAt(1);switch(affiliation) +{case'P':case'A':case'S':case'G':case'M':returnVal--;break;}} +if(returnVal===847) +returnVal=852;if(SymbolUtilities.isSeaSurface(SymbolID)) +{returnVal=this.getSeaSurfaceFrame(SymbolID,fillCode);} +if(SymbolUtilities.isSubSurface(SymbolID)) +{returnVal=this.getSubSurfaceFrame(SymbolID,fillCode);} +return returnVal;},getSeaSurfaceFill:function(SymbolID){var affiliation="U",affiliation=SymbolID.charAt(1);if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*S*O-----*****")) +{return 2016;} +else +{if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{return FillIndexFS;} +else if(affiliation==='H'||affiliation==='S') +{return FillIndexHS;} +else if(affiliation==='N'||affiliation==='L') +{return FillIndexNS;} +else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') +{return FillIndexUS;} +else +{return FillIndexUG;}}},getSubSurfaceFill:function(SymbolID,symStd){var affiliation=0,status=0,returnVal=831;try +{if(symStd===undefined) +{symStd=RendererSettings.getSymbologyStandard();} +affiliation=SymbolID.charAt(1);status=SymbolID.charAt(3);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{returnVal=831;} +else if(affiliation==='H'||affiliation==='S') +{returnVal=828;} +else if(affiliation==='N'||affiliation==='L') +{returnVal=834;} +else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') +{returnVal=837;} +if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*X-----*****")) +{if(status==='A') +returnVal=returnVal+2;else +returnVal++;} +if(symStd===RendererSettings.Symbology_2525C) +{if(SymbolID.indexOf("WM")===4||SymbolID.indexOf("WDM")===4||SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*E-----*****")||SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*V-----*****")) +{returnVal++;if(status==='A') +returnVal++;} +else if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*ND----*****")) +{returnVal=2121;}} +else +{if(SymbolID.indexOf("WM")===4) +{if(SymbolID.indexOf("----",6)===6||SymbolID.indexOf("D---",6)===6) +returnVal=2059;else if(SymbolID.indexOf("G---",6)===6) +returnVal=2062;else if(SymbolID.indexOf("GD--",6)===6) +returnVal=2064;else if(SymbolID.indexOf("M---",6)===6) +returnVal=2073;else if(SymbolID.indexOf("MD--",6)===6) +returnVal=2075;else if(SymbolID.indexOf("F---",6)===6) +returnVal=2084;else if(SymbolID.indexOf("FD--",6)===6) +returnVal=2086;else if(SymbolID.indexOf("O---",6)===6||SymbolID.indexOf("OD--",6)===6) +returnVal=2094;} +else if(SymbolID.indexOf("WDM")===4) +{returnVal=2115;} +else if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*ND----*****")) +{returnVal=2121;}}} +catch(exc) +{return FillIndexUU;} +return returnVal;},getSeaSurfaceFrame:function(SymbolID,fillCode){var returnVal=fillCode+1;if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*S*O-----*****")) +returnVal=-1;else +{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') +return fillCode+2;else +return fillCode+1;} +return returnVal;},getSubSurfaceFrame:function(SymbolID,fillCode){var returnVal=fillCode+1;try +{if(RendererSettings.getSymbologyStandard()===RendererSettings.Symbology_2525C) +{if(SymbolID.indexOf("WM")===4||SymbolID.indexOf("WDM")===4||SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*E-----*****")||SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*V-----*****")||SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*X-----*****")) +{returnVal=-1;} +else if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*ND----*****")) +{returnVal=-1;} +else +{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') +return fillCode+2;else +return fillCode+1;}} +else +{if(SymbolID.indexOf("WM")===4) +{returnVal=-1;} +else if(SymbolID.indexOf("WDM")===4) +{returnVal=-1;} +else if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*ND----*****")) +{returnVal=-1;} +else if(SymbolUtilities.getBasicSymbolIDStrict(SymbolID)===("S*U*X-----*****")) +{returnVal=-1;} +else +{if(SymbolID.charAt(3)==='A'||SymbolID.charAt(3)==='a') +return fillCode+2;else +return fillCode+1;}}} +catch(exc) +{return fillCode;} +return returnVal;},getUnitRatioHeight:function(charIndex){var characterIndex=charIndex-57000;if(characterIndex===FillIndexHP||characterIndex===FillIndexHA||characterIndex===FillIndexHU||characterIndex===(FillIndexHU+1)||characterIndex===(FillIndexHU+2)||characterIndex===FillIndexUP||characterIndex===FillIndexUA||characterIndex===FillIndexUU||characterIndex===(FillIndexUU+1)||characterIndex===(FillIndexUU+2)) +{return 1.3;} +else if(characterIndex===FillIndexHZ||characterIndex===FillIndexHG||characterIndex===FillIndexHGE||characterIndex===FillIndexHS||characterIndex===FillIndexHF||characterIndex===FillIndexUZ||characterIndex===FillIndexUG||characterIndex===FillIndexUGE||characterIndex===FillIndexUS||characterIndex===FillIndexUF) +{return 1.44;} +else if(characterIndex===FillIndexFGE||characterIndex===FillIndexFP||characterIndex===FillIndexFA||characterIndex===FillIndexFU||characterIndex===(FillIndexFU+1)||characterIndex===(FillIndexFU+2)||characterIndex===FillIndexFZ||characterIndex===FillIndexFS||characterIndex===FillIndexNP||characterIndex===FillIndexNA||characterIndex===FillIndexNU||characterIndex===(FillIndexNU+1)||characterIndex===(FillIndexNU+2)) +{return 1.2;} +else if(characterIndex===FillIndexNZ||characterIndex===FillIndexNG||characterIndex===FillIndexNGE||characterIndex===FillIndexNS||characterIndex===FillIndexNF) +{return 1.1;} +else if(characterIndex===FillIndexFG||characterIndex===FillIndexFGE) +{return 1.0;} +else +{return 1.2;}},getUnitRatioWidth:function(charIndex){var characterIndex=charIndex-57000;if(characterIndex===FillIndexUP||characterIndex===FillIndexUA||characterIndex===FillIndexUU||characterIndex===FillIndexUU+1||characterIndex===FillIndexUU+2||characterIndex===FillIndexFG||characterIndex===FillIndexFF) +{return 1.5;} +else if(characterIndex===FillIndexHZ||characterIndex===FillIndexHG||characterIndex===FillIndexHGE||characterIndex===FillIndexHS||characterIndex===FillIndexHF||characterIndex===FillIndexUZ||characterIndex===FillIndexUG||characterIndex===FillIndexUGE||characterIndex===FillIndexUS||characterIndex===FillIndexUF) +{return 1.44;} +else if(characterIndex===FillIndexFZ||characterIndex===FillIndexFGE||characterIndex===FillIndexFS) +{return 1.2;} +else +{return 1.1;}}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SymbolDimensions={};armyc2.c2sd.renderer.utilities.SymbolDimensions.getUnitBounds=function(charIndex,fontSize){var Rectangle=armyc2.c2sd.renderer.so.Rectangle,index=charIndex-57000;var rect=null;switch(index) +{case 800:case 801:case 802:rect=new Rectangle(0,0,60.8,60.8);break;case 803:case 804:case 805:rect=new Rectangle(0,0,62.547,44.52632);break;case 806:case 807:case 808:rect=new Rectangle(0,0,62.5,62.5);break;case 809:case 810:case 811:rect=new Rectangle(0,0,47.6085,47.6085);break;case 812:case 813:case 814:rect=new Rectangle(0,0,51.0625,51.0625);break;case 816:case 817:case 818:case 840:case 841:case 842:rect=new Rectangle(0,8,47.8463,53);break;case 819:case 820:case 821:case 843:case 844:case 845:rect=new Rectangle(0,7,46.6,48);break;case 822:case 823:case 824:case 846:case 847:case 848:rect=new Rectangle(0,6,47,48);break;case 825:case 826:case 827:case 849:case 850:case 851:rect=new Rectangle(0,5,64.7,56);break;case 828:case 829:case 830:rect=new Rectangle(0,-8,47.8463,53);break;case 831:case 832:case 833:rect=new Rectangle(0,-5,46.6,49);break;case 834:case 835:case 836:rect=new Rectangle(0,-5,46.5,48);break;case 837:case 838:case 839:rect=new Rectangle(0,-5,64.7,58);break;case 2059:case 2062:case 2064:case 2073:case 2075:case 2084:case 2086:case 2094:case 2115:case 2121:rect=new Rectangle(0,-5,35,43);break;default:rect=new Rectangle(0,0,65,65);break;} +var ratio=1;if(fontSize!==50) +{ratio=fontSize/50;rect=new Rectangle(0,Math.ceil(rect.y*ratio),Math.ceil(rect.width*ratio),Math.ceil(rect.height*ratio));} +return rect;};armyc2.c2sd.renderer.utilities.SymbolDimensions.getSymbolBounds=function(symbolID,symStd,fontSize){var spli=armyc2.c2sd.renderer.utilities.SinglePointLookup.getSPLookupInfo(symbolID,symStd);var Rectangle=armyc2.c2sd.renderer.so.Rectangle;var rect=new Rectangle(0,0,spli.width,spli.height);if(fontSize!==60) +{var ratio=fontSize/60;rect=new Rectangle(0,0,Math.round(rect.width*ratio),Math.round(rect.height*ratio));} +return rect;};armyc2.c2sd.renderer.utilities.SymbolDimensions.getSymbolCenter=function(symbolID,bounds){var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID),center=new armyc2.c2sd.renderer.so.Point(bounds.width/2,bounds.height/2);if(basicID==="G*G*GPUUB-****X"||basicID==="G*G*GPUUL-****X"||basicID==="G*G*GPUUS-****X"||basicID==="G*G*GPRI--****X"||basicID==="G*G*GPWE--****X"||basicID==="G*G*GPWG--****X"||basicID==="G*G*GPWM--****X"||basicID==="G*G*GPP---****X"||basicID==="G*G*GPPC--****X"||basicID==="G*G*GPPL--****X"||basicID==="G*G*GPPP--****X"||basicID==="G*G*GPPR--****X"||basicID==="G*G*GPPA--****X"||basicID==="G*G*APD---****X"||basicID==="G*G*OPP---****X"||basicID.substring(0,7)==="G*M*OAO"||basicID==="G*M*BCP---****X"||basicID==="G*F*PCS---****X"||basicID==="G*F*PCB---****X"||basicID==="G*F*PCR---****X"||basicID==="G*F*PCH---****X"||basicID==="G*F*PCL---****X"||basicID.substring(0,5)==="G*S*P"||basicID==="G*O*ED----****X"||basicID==="G*O*EP----****X"||basicID==="G*O*EV----****X"||basicID==="G*O*SB----****X"||basicID==="G*O*SBM---****X"||basicID==="G*O*SBN---****X"||basicID==="G*G*GPPN--****X"||basicID==="G*S*PX----****X"||basicID==="G*O*ES----****X"||SymbolUtilities.isNBC(basicID)||SymbolUtilities.isDeconPoint(basicID)||SymbolUtilities.isCheckPoint(basicID)) +{center.x=bounds.width/2;center.y=bounds.height;} +else if(SymbolUtilities.isSonobuoy(basicID)) +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.75);} +else if((basicID.substring(0,7)==="G*G*GPO"&&basicID.substring(7,8)!=="-")) +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.33);} +else if(basicID==="G*M*OMD---****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.28);} +else if(basicID.substring(0,7)==="G*G*DPO") +{if(basicID.substring(7,8)==="C") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.55);} +else +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.65);}} +else if(basicID==="G*G*GPWD--****X"||basicID==="G*G*PN----****X"||basicID==="G*M*OB----****X"||basicID==="G*M*OME---****X"||basicID==="G*M*OMW---****X"||basicID==="G*M*OMP---****X"||basicID==="G*M*OHTL--****X"||basicID==="G*M*OHTH--****X"||basicID==="G*O*HM----****X"||basicID==="G*O*HI----****X"||basicID==="G*O*SM----****X") +{if(basicID==="G*G*GPWD--****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.87);} +if(basicID==="G*G*PN----****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.69);} +if(basicID==="G*M*OB----****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.79);} +if(basicID==="G*M*OME---****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.77);} +if(basicID==="G*M*OMW---****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.3);} +if(basicID==="G*M*OMP---****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.64);} +if(basicID==="G*M*OHTL--****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.88);} +if(basicID==="G*M*OHTH--****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.90);} +if(basicID==="G*O*HM----****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.65);} +if(basicID==="G*O*HI----****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.58);} +if(basicID==="G*O*SM----****X") +{center.x=0;center.y=Math.round(bounds.height*0.5);}} +else if(basicID==="G*O*SS----****X") +{center.x=bounds.width/2;center.y=Math.round(bounds.height*0.45);} +else +{center.x=bounds.width/2;center.y=bounds.height/2;} +return center;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2={intersectPoint:function(pt0,pt1,currentEdge) +{var ptIntersect=null;try{var edgePt1=currentEdge.getP1();var edgePt2=currentEdge.getP2();var edge_x=0;var edge_y=0;var m=0;var deltaX=0;var deltaY=0;if(Math.abs(edgePt1.getX()-edgePt2.getX())=ul.getY()&¤t.getY()>=ul.getY()){ptsResult.add(current);} +if(previous.getY()>=ul.getY()&¤t.getY()=ul.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ul,ur);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +ptsResult.add(current);tg.set_WasClipped(true);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipTop",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipTop",exc));}else{throw exc;}} +return ptsResult;},clipBottom:function(tg,pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var ulx=0;var uly=0;var lrx=0;var lry=0;ulx=clipBounds.getMinX();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,lry);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;jlr.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ll,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +tg.set_WasClipped(true);} +if(previous.getY()>lr.getY()&¤t.getY()>lr.getY()){continue;} +if(previous.getY()>lr.getY()&¤t.getY()<=lr.getY()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ll,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +ptsResult.add(current);tg.set_WasClipped(true);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipBottom",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipBottom",exc));}else{throw exc;}} +return ptsResult;},clipRight:function(tg,pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var uly=0;var lrx=0;var lry=0;uly=clipBounds.getMinY();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ur=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,uly);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;jlr.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ur,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +tg.set_WasClipped(true);} +if(previous.getX()>lr.getX()&¤t.getX()>lr.getX()){continue;} +if(previous.getX()>lr.getX()&¤t.getX()<=lr.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ur,lr);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +ptsResult.add(current);tg.set_WasClipped(true);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipRight",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipRight",exc));}else{throw exc;}} +return ptsResult;},clipLeft:function(tg,pts,clipBounds){var ptsResult=new java.util.ArrayList();try{var ulx=0;var uly=0;var lry=0;ulx=clipBounds.getMinX();uly=clipBounds.getMinY();lry=clipBounds.getMaxY();var ul=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,uly);var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx,lry);var j=0;var current=null;var previous=null;var intersectPt=null;var edge;for(j=0;j=ll.getX()&¤t.getX()>=ll.getX()){ptsResult.add(current);} +if(previous.getX()>=ll.getX()&¤t.getX()=ll.getX()){edge=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(ul,ll);intersectPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.intersectPoint(previous,current,edge);if(intersectPt!==null){ptsResult.add(intersectPt);} +ptsResult.add(current);tg.set_WasClipped(true);}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"clipLeft",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside clipLeft",exc));}else{throw exc;}} +return ptsResult;},AddBoundaryPointsForLines:function(polygon,clipBounds){var result=0;try{var ulx=0;var uly=0;var lrx=0;var lry=0;ulx=clipBounds.getMinX();uly=clipBounds.getMinY();lrx=clipBounds.getMaxX();lry=clipBounds.getMaxY();var ul=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx+10,uly+10);var ur=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx-10,uly+10);var ll=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ulx+10,lry-10);var lr=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(lrx-10,lry-10);var pt0=polygon.get(0);var ptn=polygon.get(polygon.size()-1);var addToFront=new Boolean(false);var addToEnd=new Boolean(false);if(pt0.getY()lrx){polygon.add(0,lr);addToFront=new Boolean(true);}else if(pt0.getY()>lry){polygon.add(0,lr);addToFront=new Boolean(true);} +if(ptn.getY()lrx){polygon.add(lr);addToEnd=new Boolean(true);}else if(ptn.getY()>lry){polygon.add(lr);addToEnd=new Boolean(true);} +if(addToFront.valueOf()===false&&addToEnd.valueOf()===false){result=0;} +if(addToFront.valueOf()===true&&addToEnd.valueOf()===false){result=1;} +if(addToFront.valueOf()===false&&addToEnd.valueOf()===true){result=2;} +if(addToFront.valueOf()===true&&addToEnd.valueOf()===true){result=3;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"AddBoundaryPointsForLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddBoundaryPointsForLines",exc));}else{throw exc;}} +return result;},closeAreaTG:function(tg){try{if(tg.Pixels===null||tg.Pixels.isEmpty()) +return;var pt0=tg.Pixels.get(0);var ptn=tg.Pixels.get(tg.Pixels.size()-1);if(pt0.x!==ptn.x||pt0.y!==ptn.y) +tg.Pixels.add(pt0);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"closeAreaTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside closeAreaTG",exc));}else{throw exc;}} +return;},fillDMA:function(tg,clipBounds){var shapes=new java.util.ArrayList();try{switch(tg.get_LineType()){case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 23131200:case 23132000:break;default:return shapes;} +var shape=null;var j=0;var tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();var n=0;n=tg.Pixels.size();for(j=0;j=300).valueOf()){dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x);dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x);dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x);var start=-1;var end=-1;if(dist0>=dist1&&dist0>=dist2){start=0;end=99;}else if(dist1>=dist0&&dist1>=dist2){start=100;end=199;}else{start=200;end=299;} +shape.moveTo(tg.Pixels.get(start));for(j=start;j<=end;j++) +shape.lineTo(tg.Pixels.get(j));} +break;case 23120000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();if(tg.Pixels!==null&&tg.Pixels.size()>2){tg2.Pixels.add(tg.Pixels.get(n-3));tg2.Pixels.add(tg.Pixels.get(n-2));tg2.Pixels.add(tg.Pixels.get(n-1));tg2.Pixels.add(tg.Pixels.get(n-3));shape.moveTo(tg2.Pixels.get(0));for(j=1;j1) +{shapes.add(shape);} +else +return null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} +return shapes;},ClipPolygon:function(tg,clipBounds){var poly=new java.util.ArrayList();try{var polygon=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.POINT2toPoint2D(tg.Pixels);var isClosed=new Boolean(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType()));var hashMap=new java.util.HashMap();var j=0;for(j=0;j0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;case 3:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;}} +if(isClosed.valueOf()===true){if(poly.size()>2){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}else{if(poly.size()>1) +{tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);} +else +{tg.Pixels=new java.util.ArrayList();}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"ClipPolygon",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon",exc));}else{throw exc;}} +return poly;},ClipPolygon2:function(polygon,clipBounds,isClosed){var poly=new java.util.ArrayList();try{var addedLinePoints=0;if((isClosed).valueOf()){if(polygon.size()>0) +polygon.remove(polygon.size()-1);isClosed=new Boolean(true);}else{addedLinePoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.AddBoundaryPointsForLines(polygon,clipBounds);} +poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipRight(null,polygon,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipTop(null,poly,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipLeft(null,poly,clipBounds);poly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.clipBottom(null,poly,clipBounds);if(isClosed.valueOf()===true){if(poly.size()>0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;case 3:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2._className,"ClipPolygon2",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon2",exc));}else{throw exc;}} +return poly;},_className:"clsClipPolygon2"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad={AddBoundaryPointsForLines:function(polygon,clipBounds){var result=0;try{var pt02d=polygon.get(0);var ptLast2d=polygon.get((polygon.size()-1));var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt02d.getX(),pt02d.getY());var ptLast=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(ptLast2d.getX(),ptLast2d.getY());var nearestPt=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D();var clipArray=new armyc2.c2sd.graphics2d.Polygon();var j=0;var minDist=1.7976931348623157E308;var dist=0;var sidePt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var addToFront=new Boolean(false);var addToEnd=new Boolean(false);for(j=0;j1){clipBoundsPoint=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(clipBounds.get(index-2).getX(),clipBounds.get(index-2).getY());}else if(index===1){clipBoundsPoint=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(clipBounds.get(0).getX(),clipBounds.get(0).getY());} +if(Math.abs(pt2.getX()-pt1.getX())<1) +pt2.setLocation(pt2.getX()+1,pt2.getY());if(Math.abs(pt2.getY()-pt1.getY())<1) +pt2.setLocation(pt2.getX(),pt2.getY()+1);for(j=0;j=300).valueOf()){dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x);dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x);dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x);var start=-1;var end=-1;if(dist0>=dist1&&dist0>=dist2){start=0;end=99;}else if(dist1>=dist0&&dist1>=dist2){start=100;end=199;}else{start=200;end=299;} +shape.moveTo(tg.Pixels.get(start));for(j=start;j<=end;j++) +shape.lineTo(tg.Pixels.get(j));} +break;case 23120000:shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setFillColor(tg.get_FillColor());tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();if(tg.Pixels!==null&&tg.Pixels.size()>2){tg2.Pixels.add(tg.Pixels.get(n-3));tg2.Pixels.add(tg.Pixels.get(n-2));tg2.Pixels.add(tg.Pixels.get(n-1));tg2.Pixels.add(tg.Pixels.get(n-3));shape.moveTo(tg2.Pixels.get(0));for(j=1;j1){shapes.add(shape);}else +return null;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"LinesWithFill",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside LinesWithFill",exc));}else{throw exc;}} +return shapes;},closeAreaTG:function(tg){try{if(tg.Pixels===null||tg.Pixels.isEmpty()) +return;var pt0=tg.Pixels.get(0);var ptn=tg.Pixels.get(tg.Pixels.size()-1);if(pt0.x!==ptn.x||pt0.y!==ptn.y) +tg.Pixels.add(pt0);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"closeAreaTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside closeAreaTG",exc));}else{throw exc;}} +return;},fillDMA:function(tg,clipBounds){var shapes=new java.util.ArrayList();try{switch(tg.get_LineType()){case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 23131200:case 23132000:break;default:return shapes;} +var shape=null;var j=0;var tg2=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg2.set_LineType(22131000);tg2.Pixels=new java.util.ArrayList();var n=0;n=tg.Pixels.size();for(j=0;j0){poly.add(poly.get(0));}}else{switch(addedLinePoints){case 0:break;case 1:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +break;case 2:if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;case 3:if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(0);} +if(poly.size()>0){poly.remove(poly.size()-1);} +if(poly.size()>0){poly.remove(poly.size()-1);} +break;}} +if(isClosed.valueOf()===true){if(poly.size()>2){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}else{if(poly.size()>1){tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap);}else{tg.Pixels=new java.util.ArrayList();}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad._className,"ClipPolygon",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ClipPolygon",exc));}else{throw exc;}} +return poly;},_className:"clsClipQuad"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer={setClientCoords:function(milStd,tg){try{var latLongs=new java.util.ArrayList();var j=0;var coords=milStd.getCoordinates();var pt2d=null;var pt2=null;for(j=0;j0) +tg.set_H(Double.toString((X.get(0)).doubleValue()));if(X!==null&&X.size()>1) +tg.set_H1(Double.toString((X.get(1)).doubleValue()));break;case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:var pt=tg.LatLongs.get(0);var pt2d0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt.x,pt.y);var pt2d0Pixels=converter.GeoToPixels(pt2d0);var pt0Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d0Pixels.getX(),pt2d0Pixels.getY());var dist=10000;var pt2=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt,dist,0);var pt2d1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);var pt2d1Pixels=converter.GeoToPixels(pt2d1);var pt1Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d1Pixels.getX(),pt2d1Pixels.getY());var distPixels=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0Pixels,pt1Pixels);var pixelsPerMeter=distPixels/dist;AM=milStd.getModifiers_AM_AN_X("AM");if(AM!==null){var H2="";for(j=0;j0){for(j=0;jmaxWidth) +maxWidth=temp;}} +maxWidthMeters=maxWidth;maxWidth*=pixelsPerMeter/2;}} +if(tg.get_H2()!==null&&tg.get_H2().isEmpty()===false){if(strRadii!==null&&strRadii.length>0){var pixels=0;for(j=0;jj){if(strRadii.length>j){if(!Double.isNaN(Double.parseDouble(strRadii[j]))){pixels=Double.parseDouble(strRadii[j])*pixelsPerMeter/2;tg.Pixels.get(j).style=Math.floor(pixels);}else +tg.Pixels.get(j).style=Math.floor(maxWidth);}else +tg.Pixels.get(j).style=Math.floor(maxWidth);}}}} +tg.set_H2(Double.toString(maxWidthMeters)+"m");X=milStd.getModifiers_AM_AN_X("XN");if(X!==null&&X.size()>0) +tg.set_H(Double.toString((X.get(0)).doubleValue()));if(X!==null&&X.size()>1) +tg.set_H1(Double.toString((X.get(1)).doubleValue()));break;default:break;} +switch(lineType){case 24361000:case 24363000:case 24362000:X=milStd.getModifiers_AM_AN_X("XN");strH1="";if(X!==null){strH1=Double.toString((X.get(0)).doubleValue());tg.set_H1(strH1);} +break;default:break;} +if(lineType===243111000){AM=milStd.getModifiers_AM_AN_X("AM");X=milStd.getModifiers_AM_AN_X("XN");strH2="";strH1="";if(AM!==null){for(j=0;j0){var strT1=Double.toString((AM.get(0)).doubleValue());tg.set_T1(strT1);} +break;default:break;} +if(lineType===24311000||lineType===14000001||lineType===14000002){AM=milStd.getModifiers_AM_AN_X("AM");AN=milStd.getModifiers_AM_AN_X("AN");if(AM.length<2) +AM[1]=AM[0];if(AM!==null&&AM.size()>1&&AN!==null&&AN.size()>0){strT1=Double.toString((AM.get(0)).doubleValue());var strH=Double.toString((AM.get(1)).doubleValue());tg.set_T1(strT1);tg.set_H(strH);var strH2=Double.toString((AN.get(0)).doubleValue());tg.set_H2(strH2);}} +milStd.setFillColor(tg.get_FillColor());milStd.setLineColor(tg.get_LineColor());milStd.setLineWidth(tg.get_LineThickness());milStd.setFillStyle(tg.get_TexturePaint());}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","createMilStdSymboFromTGLight",new armyc2.c2sd.renderer.utilities.RendererException("Failed to set geo points or pixels for "+tg.get_SymbolId(),exc));}else{throw exc;}} +return milStd;},createTGLightFromMilStdSymbol:function(milStd,converter){var tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();var modifiersTG=armyc2.c2sd.renderer.utilities.ModifiersTG;try{var symbolId=milStd.getSymbolID();var std=milStd.getSymbologyStandard();tg.setSymbologyStandard(std);armyc2.c2sd.JavaTacticalRenderer.clsUtility.initializeLinetypes(std);tg.set_SymbolId(symbolId);var useLineInterpolation=milStd.getUseLineInterpolation();tg.set_UseLineInterpolation(useLineInterpolation);var lineType=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.getRevDLinetype(tg);if(lineType===23200000&&converter._scale>=250000) +lineType=23200001;tg.set_LineType(lineType);var status=tg.get_Status();if(status!==null&&status.equals("A")){if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isBasicShape(lineType)===false) +tg.set_LineStyle(1);if(lineType===23131200) +tg.set_LineStyle(2);} +tg.set_VisibleModifiers(true);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setClientCoords(milStd,tg);tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);var instance=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance();var fontName=instance.getModifierFontName();var fontSize=instance.getModifierFontSize();var fontStyle=instance.getModifierFontStyle();tg.set_Font(new armyc2.c2sd.graphics2d.Font(fontName,fontStyle,fontSize));tg.set_FillColor(milStd.getFillColor());tg.set_LineColor(milStd.getLineColor());tg.set_LineThickness(milStd.getLineWidth());tg.set_TexturePaint(milStd.getFillStyle());if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isBasicShape(lineType)) +tg.set_Fillstyle(milStd.getPatternFillType());tg.set_FontBackColor(armyc2.c2sd.renderer.utilities.Color.WHITE);tg.set_TextColor(tg.get_LineColor());if(milStd.getModifier("W")!==null){tg.set_DTG(milStd.getModifier("W"));} +if(milStd.getModifier("W1")!==null){tg.set_DTG1(milStd.getModifier("W1"));} +if(milStd.getModifier("H")!==null) +tg.set_H(milStd.getModifier("H"));if(milStd.getModifier("H1")!==null) +tg.set_H1(milStd.getModifier("H1"));if(milStd.getModifier("H2")!==null) +tg.set_H2(milStd.getModifier("H2"));if(milStd.getModifier("T")!==null) +tg.set_Name(milStd.getModifier("T"));if(milStd.getModifier("T1")!==null) +tg.set_T1(milStd.getModifier("T1"));if(milStd.getModifier("Y")!==null) +tg.set_Location(milStd.getModifier("Y"));if(milStd.getModifier("N")!==null) +tg.set_N(milStd.getModifier("N"));tg.set_UseDashArray(milStd.getUseDashArray());tg.set_UseHatchFill(milStd.getUseFillPattern());tg.set_HideOptionalLabels(milStd.getHideOptionalLabels());var isClosedArea=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);if(lineType===23111000&&tg.Pixels.size()===2) +{var pt0=tg.Pixels.get(0);var pt1=tg.Pixels.get(1);var p0=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,2,5);var p1=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,2,5);var p2=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt1,3,5);var p3=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0,pt1,pt0,3,5);tg.Pixels.clear();tg.Pixels.add(p0);tg.Pixels.add(p1);tg.Pixels.add(p2);tg.Pixels.add(p3);tg.LatLongs=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.PixelsToLatLong(tg.Pixels,converter);} +if(isClosedArea){armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels);armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs);} +var altitudeLabel=milStd.getAltitudeMode();if(altitudeLabel===null||altitudeLabel.isEmpty()) +altitudeLabel="MSL";var x_alt=0;var n_alt=0;var strXAlt="";if(lineType===13000000||lineType===13000001||lineType===13000002) +{var AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);var AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);var r=0;var b=0;if(AM.length===1) +{r=AM[0];AM.push(r);AM.push[0];} +else if(AM.length===2) +{r=AM[0];b=AM[1];AM[1]=r;AM.push(b);} +if(AN===null) +AN=new Array();if(AN.length<1) +AN[0]=0;if(lineType===13000002) +AM[1]=AM[0];if(AM!==null&&AM.length>=2&&AN!==null&&AN.length>=1) +{tg.set_H1(Double.toString(AM[0]));tg.set_H2(Double.toString(AM[1]));tg.set_T1(Double.toString(AN[0]));var ptAzimuth=new armyc2.c2sd.JavaLineArray.POINT2(0,0);ptAzimuth.x=AN[0];var ptCenter=tg.Pixels.get(0);var pt0=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(tg.LatLongs.get(0),AM[0],90);var pt1=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(tg.LatLongs.get(0),AM[1],0);var pt02d=new armyc2.c2sd.graphics2d.Point2D(pt0.x,pt0.y);var pt12d=new armyc2.c2sd.graphics2d.Point2D(pt1.x,pt1.y);pt02d=converter.GeoToPixels(pt02d);pt12d=converter.GeoToPixels(pt12d);pt0=new armyc2.c2sd.JavaLineArray.POINT2(pt02d.getX(),pt02d.getY());pt1=new armyc2.c2sd.JavaLineArray.POINT2(pt12d.getX(),pt12d.getY());tg.Pixels=new java.util.ArrayList();tg.Pixels.add(ptCenter);tg.Pixels.add(pt0);tg.Pixels.add(pt1);tg.Pixels.add(ptAzimuth);} +if(AM!==null&&AM.length>2) +{var dist=AM[2];tg.set_H(Double.toString(AM[2]));var pt0=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(tg.LatLongs.get(0),dist,45);var pt02d=new armyc2.c2sd.graphics2d.Point2D(tg.LatLongs.get(0).x,tg.LatLongs.get(0).y);var pt12d=new armyc2.c2sd.graphics2d.Point2D(pt0.x,pt0.y);pt02d=converter.GeoToPixels(pt02d);pt12d=converter.GeoToPixels(pt12d);pt0=new armyc2.c2sd.JavaLineArray.POINT2(pt02d.getX(),pt02d.getY());var pt1=new armyc2.c2sd.JavaLineArray.POINT2(pt12d.getX(),pt12d.getY());dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);tg.Pixels.get(0).style=dist;var useAM2=false;useAM2=true;if(useAM2) +tg.Pixels.get(0).style=AM[2];}} +if(lineType===243112000) +{var AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);var AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);var X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(AM!==null) +{var strT1="";for(var j=0;jmaxLong) +maxLong=tg.LatLongs.get(j).x;if(tg.LatLongs.get(j).ymaxLat) +maxLat=tg.LatLongs.get(j).y;} +tg.LatLongs=new java.util.ArrayList();tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,maxLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(maxLong,maxLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(maxLong,minLat));tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,minLat));if(lineType===15000004) +tg.LatLongs.add(new armyc2.c2sd.JavaLineArray.POINT2(minLong,maxLat));tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);} +switch(lineType){case 15000001:case 15000000:case 15000003:var H2=null;var dist=0;var pt0;var pt1;var AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);if(AM!==null&&AM.length>0){H2=AM[0].toString();tg.set_H2(H2);} +if(H2!==null&&!H2.isEmpty()) +for(j=0;jj){if(!Double.isNaN(Double.parseDouble(H2))){if(j===0){dist=Double.parseDouble(H2);pt0=new armyc2.c2sd.JavaLineArray.POINT2(tg.LatLongs.get(0));pt1=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,dist,45);var pt02d=new armyc2.c2sd.graphics2d.Point2D();pt02d.x=pt0.x;pt02d.y=pt0.y;pt12d=new armyc2.c2sd.graphics2d.Point2D();pt12d.x=pt1.x;pt12d.y=pt1.y;pt02d=converter.GeoToPixels(pt02d);pt12d=converter.GeoToPixels(pt12d);pt0.x=pt02d.getX();pt0.y=pt02d.getY();pt1.x=pt12d.getX();pt1.y=pt12d.getY();dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0,pt1);} +tg.Pixels.get(j).style=Math.round(dist);}else +tg.Pixels.get(j).style=0;}} +break;default:break;} +switch(lineType){case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:case 24322100:case 24322200:case 24322300:X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(X!==null&&X.length>0) +{x_alt=X[0]*armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.feetPerMeter;x_alt*=10.0;x_alt=Math.round(x_alt);n_alt=x_alt;x_alt=n_alt/10.0;strXAlt=Double.toString(x_alt)+" ft. "+altitudeLabel;tg.set_H(strXAlt);} +if(X!==null&&X.length>1) +{x_alt=X[1]*armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.feetPerMeter;x_alt*=10.0;x_alt=Math.round(x_alt);n_alt=x_alt;x_alt=n_alt/10.0;strXAlt=Double.toString(x_alt)+" ft. "+altitudeLabel;tg.set_H1(strXAlt);} +break;case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:var pt=tg.LatLongs.get(0);var pt2d0=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt.x,pt.y);var pt2d0Pixels=converter.GeoToPixels(pt2d0);var pt0Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d0Pixels.getX(),pt2d0Pixels.getY());var dist=10000;var pt2=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt,dist,0);var pt2d1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);var pt2d1Pixels=converter.GeoToPixels(pt2d1);var pt1Pixels=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt2d1Pixels.getX(),pt2d1Pixels.getY());var distPixels=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0Pixels,pt1Pixels);var pixelsPerMeter=distPixels/dist;AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);if(AM!==null){var H2="";for(j=0;j0){for(j=0;jmaxWidth) +maxWidth=temp;}} +maxWidthMeters=maxWidth;maxWidth*=pixelsPerMeter/2;}} +if(tg.get_H2()!==null&&tg.get_H2().isEmpty()===false){if(strRadii!==null&&strRadii.length>0){var pixels=0;for(j=0;jj){if(strRadii.length>j){if(!Double.isNaN(Double.parseDouble(strRadii[j]))){pixels=Double.parseDouble(strRadii[j])*pixelsPerMeter/2;tg.Pixels.get(j).style=Math.floor(pixels);tg.LatLongs.get(j).style=Math.floor(pixels);}else +{tg.Pixels.get(j).style=Math.floor(maxWidth);tg.LatLongs.get(j).style=Math.floor(maxWidth);}}else +{tg.Pixels.get(j).style=Math.floor(maxWidth);tg.LatLongs.get(j).style=Math.floor(maxWidth);}}}}} +tg.set_H2(Double.toString(maxWidthMeters)+"m");X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);if(X!==null&&X.length>0) +{x_alt=X[0]*armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.feetPerMeter;x_alt*=10.0;x_alt=Math.round(x_alt);n_alt=x_alt;x_alt=n_alt/10.0;strXAlt=Double.toString(x_alt)+" ft. "+altitudeLabel;tg.set_H(strXAlt);} +if(X!==null&&X.length>1) +{x_alt=X[1]*armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.feetPerMeter;x_alt*=10.0;x_alt=Math.round(x_alt);n_alt=x_alt;x_alt=n_alt/10.0;strXAlt=Double.toString(x_alt)+" ft. "+altitudeLabel;tg.set_H1(strXAlt);} +break;default:break;} +if(lineType===25200101) +{AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);if(AM!==null&&AM.length>1){var H=AM[0].toString();tg.set_H(H);var T1=AM[1].toString();tg.set_T1(T1);} +if(AN!==null&&AN.length>0){var H2=AN[0].toString();tg.set_H2(H2);}} +switch(lineType) +{case 24361000:case 24363000:case 24362000:X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);strH1="";if(X!==null&&X.length>0) +{x_alt=X[0]*armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.feetPerMeter;x_alt*=10.0;x_alt=Math.round(x_alt);n_alt=x_alt;x_alt=n_alt/10.0;strXAlt=Double.toString(x_alt)+" ft. "+altitudeLabel;tg.set_H1(strXAlt);} +break;default:break;} +if(lineType===243111000) +{AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);X=milStd.getModifiers_AM_AN_X(modifiersTG.X_ALTITUDE_DEPTH);var strH2="";strH1="";if(AM!==null) +{for(j=0;j0){var strT1=AM[0];tg.set_T1(strT1);} +else if(lineType===15000002&&tg.LatLongs.size()>1){var dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(tg.LatLongs.get(0),tg.LatLongs.get(1),null,null);var strT1=Double.toString(dist);tg.set_T1(strT1);} +break;default:break;} +if(lineType===24311000||lineType===14000001||lineType===14000002){AM=milStd.getModifiers_AM_AN_X(modifiersTG.AM_DISTANCE);AN=milStd.getModifiers_AM_AN_X(modifiersTG.AN_AZIMUTH);if(lineType===14000002) +{var r=AM[0];var b=0;if(AM.length===1) +{AM.push(r);AM.push(b);} +else if(AM.length===2) +{b=AM[1];AM[1]=r;AM.push(b);} +else if(AM.length===3) +AM[1]=AM[0];} +if(AN===null||AN===undefined) +AN=new Array();if(AN.length<1) +AN[0]=0;if(AM!==null&&AM.length>1&&AN!==null&&AN.length>0) +{strT1=AM[0];var strH=AM[1];tg.set_T1(strT1);tg.set_H(strH);strH2=AN[0];tg.set_H2(strH2);} +if(AM!==null&&AM.length>2) +{var strH1=AM[2];tg.set_H1(strH1);} +if(AM!==null&&AM.length<=2) +{tg.set_H1('0');}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","createTGLightfromMilStdSymbol",new armyc2.c2sd.renderer.utilities.RendererException("Failed to build multipoint TG for "+milStd.getSymbolID(),exc));}else{throw exc;}} +return tg;},render:function(symbol,converter){try{var tg=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(symbol,converter);var shapeInfos=new java.util.ArrayList();var modifierShapeInfos=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterPoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.GetLineArray(tg,converter,shapeInfos,modifierShapeInfos);symbol.setModifierShapes(modifierShapeInfos);symbol.setSymbolShapes(shapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","render",new armyc2.c2sd.renderer.utilities.RendererException("Failed to render "+symbol.getSymbolID(),exc));}else{throw exc;}} +return;},render_TG:function(tg,converter,shapeInfos,modifierShapeInfos){try{var lineType=-1;var isClosedArea=false;armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var symbolId=tg.get_SymbolId();lineType=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(symbolId);if(lineType<0){lineType=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId);} +isClosedArea=armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(lineType);if(isClosedArea){armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.Pixels);armyc2.c2sd.JavaTacticalRenderer.clsUtility.ClosePolygon(tg.LatLongs);} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterPoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.GetLineArray(tg,converter,shapeInfos,modifierShapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","render",new armyc2.c2sd.renderer.utilities.RendererException("Failed to render "+tg.get_SymbolId(),exc));}else{throw exc;}} +return;},GetLineArray:function(tg,converter,shapeInfos,modifierShapeInfos){try{var shapes=new java.util.ArrayList();var modifierShapes=new java.util.ArrayList();var lineType=tg.get_LineType();var minPoints2=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetMinPoints(lineType);var minPoints=new armyc2.c2sd.JavaLineArray.ref();var channelPoints=new java.util.ArrayList();var bolChange1=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,minPoints);var bolMeTOC=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(tg.get_SymbolId());tg.modifiers=new java.util.ArrayList();var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo(tg,g2d,null,converter);var rev=tg.getSymbologyStandard();var hatchShape=null;if(converter===null) +armyc2.c2sd.JavaTacticalRenderer.clsUtility.getHatchShape(tg,bi);if(tg.Pixels.size()0){try{armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetMeTOCShape(tg,shapes,rev);}catch(ex){if(Clazz.instanceOf(ex)){armyc2.c2sd.JavaTacticalRenderer.clsUtility.WriteFile("Error in ClsMETOC.GetMeTOCShape");}else{throw ex;}}}else{if(armyc2.c2sd.JavaLineArray.CELineArray.CIsChannel(lineType)===0){if(lineType!==23111001){tg.Pixels=armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(lineType,tg.Pixels,shapes,null,rev);armyc2.c2sd.JavaTacticalRenderer.Modifier2.GetIntegralTextShapes(tg,g2d,shapes);} +if(lineType===23111001){var tempShapes=null;var partitions=armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility.GetPartitions2(tg);var pixels=null;var l=0;var k=0;for(l=0;lmaxx) +maxx=pt.x;if(maxNegX===0&&pt.x<0) +maxNegX=pt.x;if(maxNegX<0&&pt.x<0&&pt.x>maxNegX) +maxNegX=pt.x;if(pt.ycoordsTop) +coordsTop=pt.y;} +var coordSpanIDL=false;if(maxx===180||minx===-180) +coordSpanIDL=true;if(maxx-minx>=180) +{coordSpanIDL=true;coordsLeft=maxx;coordsRight=maxNegX;}else +{coordsLeft=minx;coordsRight=maxx;} +if(br.y<=coordsBottom&&coordsBottom<=tl.y) +intersects=true;else if(coordsBottom<=br.y&&br.y<=coordsTop) +intersects=true;else +return false;intersects=false;var boxSpanIDL=false;if(tl.x===180||tl.x===-180||br.x===180||br.x===-180) +boxSpanIDL=true;else if(Math.abs(br.x-tl.x)>180) +boxSpanIDL=true;if(coordSpanIDL&&boxSpanIDL) +intersects=true;else if(!coordSpanIDL&&!boxSpanIDL) +{if(coordsLeft<=tl.x&&tl.x<=coordsRight) +intersects=true;if(coordsLeft<=br.x&&br.x<=coordsRight) +intersects=true;if(tl.x<=coordsLeft&&coordsLeft<=br.x) +intersects=true;if(tl.x<=coordsRight&&coordsRight<=br.x) +intersects=true;} +else if(!coordSpanIDL&&boxSpanIDL) +{if(tl.x1) +{var tg1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetCircularRangeFanFillTG(tg);tg1.set_Fillstyle(savefillStyle);tg1.set_SymbolId(tg.get_SymbolId());if(clipBounds!==null) +{rangeFanFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg1,converter,(isTextFlipped).valueOf(),clipBounds);} +else if(clipPoints!==null) +{rangeFanFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg1,converter,(isTextFlipped).valueOf(),clipPoints);} +else if(clipArea===null) +{rangeFanFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg1,converter,(isTextFlipped).valueOf(),clipBounds);} +if(rangeFanFillShapes!==null) +{shapes.addAll(0,rangeFanFillShapes);}}} +else +{armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.getAutoshapeFillShape(tg,shapes);} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(),shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.addAbatisFill(tg,shapes);if(shapes!==null&&linesWithFillShapes!==null&&linesWithFillShapes.size()>0) +shapes.addAll(0,linesWithFillShapes);var bPostClip=false;bPostClip=true;if(bPostClip===true) +{if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===false&&clipBounds!==null) +{shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);} +else if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===false&&clipPoints!==null) +{shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipPoints);}} +this.resolvePostClippedShapes(tg,shapes);if(modifierShapeInfos!==null){var textSpecs=new java.util.ArrayList();armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,(isTextFlipped).valueOf(),converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.buildHatchFills2(tg,shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);if(clipBounds!==null) +{armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipBounds);} +else if(clipPoints!==null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipPoints);else if(clipArea===null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.SetShapeInfosPolylines(tg,shapeInfos,clipBounds);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render_GE",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render_GE",exc));}else{throw exc;}} +return;},resolvePostClippedShapes:function(tg,shapes) +{switch(tg.get_LineType()) +{case 15000003:case 15000002:case 15000001:case 15000000:case 14000001:case 14000002:case 13000001:case 13000002:break;default:return;} +var fillColor=tg.get_FillColor();shapes.get(0).setFillColor(fillColor);shapes.get(1).setFillColor(null);var fillStyle=tg.get_FillStyle();shapes.get(0).set_Fillstyle(0);shapes.get(1).set_Fillstyle(fillStyle);return;},setHostileLC:function(tg){try{var usas1314=new Boolean(true);var pts=new java.util.ArrayList();var j=0;switch(tg.get_LineType()){case 22123000:if(usas1314.valueOf()===false) +break;if(tg.get_Affiliation()!==null&&!tg.get_Affiliation().equals("H")) +break;pts=tg.Pixels.clone();for(j=0;j=250000&&tg.get_SymbolId().length<=15) +tg.set_LineType(23200001);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"getScale",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getScale",exc));}else{throw exc;}} +return scale;},setClip:function(clipBounds,clipRect,clipArray){try{if(clipBounds===null){return false;}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle2D)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle2D)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(armyc2.c2sd.graphics2d.Rectangle)){clipRect.setRect(clipBounds);}else if(clipBounds.getClass().isAssignableFrom(java.util.ArrayList)){clipArray.addAll(clipBounds);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"setClip",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside setClip",exc));}else{throw exc;}} +return true;},render:function(mss,converter,clipBounds){try{var shapeInfos=new java.util.ArrayList();var modifierShapeInfos=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.render(mss,converter,shapeInfos,modifierShapeInfos,clipBounds);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("render",exc));}else{throw exc;}}},render:function(mss,converter,shapeInfos,modifierShapeInfos,clipBounds){try{var clipRect=new armyc2.c2sd.graphics2d.Rectangle2D();var clipArray=new java.util.ArrayList();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setClip(clipBounds,clipRect,clipArray);var rev=mss.getSymbologyStandard();armyc2.c2sd.JavaTacticalRenderer.clsUtility.initializeLinetypes(rev);var tg=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(mss,converter);armyc2.c2sd.JavaLineArray.CELineArray.setClient("generic");armyc2.c2sd.JavaTacticalRenderer.clsUtility.setRevC(tg);var scale=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.getScale(tg,converter,clipBounds);var linetype=tg.get_LineType();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.RemoveDuplicatePoints(tg);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.SegmentGeoPoints(tg,converter,1);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.FilterAXADPoints(tg,converter);armyc2.c2sd.JavaTacticalRenderer.clsUtility.FilterVerticalSegments(tg);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype,null);var isTextFlipped=false;var farLeftPixels=new java.util.ArrayList();var farRightPixels=new java.util.ArrayList();if(isChange1Area===false) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetFarPixels(tg,converter,farLeftPixels,farRightPixels);var shapesLeft=new java.util.ArrayList();var shapesRight=new java.util.ArrayList();var shapes=null;var textSpecsLeft=null;var textSpecsRight=null;textSpecsLeft=new java.util.ArrayList();textSpecsRight=new java.util.ArrayList();if(farLeftPixels.size()>0){tg.Pixels=farLeftPixels;shapesLeft=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsLeft,isTextFlipped,null);} +if(farRightPixels.size()>0){tg.Pixels=farRightPixels;shapesRight=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsRight,isTextFlipped,null);} +var textSpecs=new java.util.ArrayList();if(shapesLeft.isEmpty()||shapesRight.isEmpty()){var linesWithFillShapes=null;if(clipArray!==null&&!clipArray.isEmpty()) +linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.LinesWithFill(tg,clipArray);else if(clipRect!==null&&clipRect.getWidth()!==0) +linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,clipRect);else +linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,null);if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===true&&clipBounds!==null){if(clipArray!==null&&!clipArray.isEmpty()) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipArray);else if(clipRect!==null&&clipRect.getWidth()!==0) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipRect);tg.LatLongs=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.PixelsToLatLong(tg.Pixels,converter);} +armyc2.c2sd.JavaTacticalRenderer.clsUtility.InterpolatePixels(tg);tg.modifiers=new java.util.ArrayList();armyc2.c2sd.JavaTacticalRenderer.Modifier2.AddModifiersGeo(tg,g2d,clipBounds,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.FilterPoints2(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.ClearPixelsStyle(tg);var rangeFanFillShapes=null;var savefillStyle=tg.get_FillStyle();if(linetype===243111000) +tg.set_Fillstyle(0);shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);switch(linetype){case 243111000:case 243112000:var tg1=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetCircularRangeFanFillTG(tg);tg1.set_Fillstyle(savefillStyle);rangeFanFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg1,converter,isTextFlipped,clipBounds);if(rangeFanFillShapes!==null){shapes.addAll(0,rangeFanFillShapes);} +break;default:break;} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(),shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.addAbatisFill(tg,shapes);if(shapes!==null&&linesWithFillShapes!==null&&linesWithFillShapes.size()>0) +shapes.addAll(0,linesWithFillShapes);if(shapes!==null&&shapes.size()>0){armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,isTextFlipped,null);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);mss.setModifierShapes(modifierShapeInfos);}}else{shapes=shapesLeft;shapes.addAll(shapesRight);if(textSpecs!==null){textSpecs.addAll(textSpecsLeft);textSpecs.addAll(textSpecsRight);}} +if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===false&&clipBounds!==null){shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);mss.setSymbolShapes(shapeInfos);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render",exc));}else{throw exc;}} +return;},render:function(tg,converter,shapeInfos,modifierShapeInfos,clipBounds){try{armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.setHostileLC(tg);var isChange1Area=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null);var isTextFlipped=false;var farLeftPixels=new java.util.ArrayList();var farRightPixels=new java.util.ArrayList();if(isChange1Area===false) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetFarPixels(tg,converter,farLeftPixels,farRightPixels);var bi=new armyc2.c2sd.graphics2d.BufferedImage(8,8,2);var g2d=bi.createGraphics();var shapesLeft=new java.util.ArrayList();var shapesRight=new java.util.ArrayList();var shapes=null;var textSpecsLeft=null;var textSpecsRight=null;textSpecsLeft=new java.util.ArrayList();textSpecsRight=new java.util.ArrayList();if(farLeftPixels.size()>0){tg.Pixels=farLeftPixels;shapesLeft=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsLeft,isTextFlipped,null);} +if(farRightPixels.size()>0){tg.Pixels=farRightPixels;shapesRight=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecsRight,isTextFlipped,null);} +var textSpecs=new java.util.ArrayList();if(shapesLeft.isEmpty()||shapesRight.isEmpty()){var linesWithFillShapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.LinesWithFill(tg,clipBounds);if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===true&&clipBounds!==null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.GetLineArray(tg,converter,isTextFlipped,clipBounds);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.LinesWithSeparateFill(tg.get_LineType(),shapes);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.addAbatisFill(tg,shapes);if(shapes!==null&&linesWithFillShapes!==null&&linesWithFillShapes.size()>0) +shapes.addAll(0,linesWithFillShapes);if(shapes!==null&&shapes.size()>0){armyc2.c2sd.JavaTacticalRenderer.Modifier2.DisplayModifiers2(tg,g2d,textSpecs,isTextFlipped,null);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(modifierShapeInfos,textSpecs);}}else{shapes=shapesLeft;shapes.addAll(shapesRight);if(textSpecs!==null){textSpecs.addAll(textSpecsLeft);textSpecs.addAll(textSpecsRight);}} +if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.canClipPoints(tg).valueOf()===false&&clipBounds!==null) +shapes=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.postClipShapes(tg,shapes,clipBounds);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.Shape2ToShapeInfo(shapeInfos,shapes);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside render",exc));}else{throw exc;}}},getCMLineType:function(SymbolSet,entityCode) +{try +{var symbolSet=Integer.parseInt(SymbolSet);if(symbolSet.valueOf()!==25){return-1;} +var code=Integer.parseInt(entityCode);var nCode=code.valueOf();var TacticalLines=new armyc2.c2sd.JavaLineArray.TacticalLines();switch(nCode){case 200101:case 200201:return TacticalLines.LAUNCH_AREA;case 120100:return TacticalLines.AO;case 120200:return TacticalLines.NAI;case 120300:return TacticalLines.TAI;case 120400:return TacticalLines.AIRFIELD;case 151401:return TacticalLines.AIRAOA;case 151402:return TacticalLines.AAAAA;case 151403:return TacticalLines.MAIN;case 151404:case 151405:case 151407:case 151408:return TacticalLines.SPT;case 151406:return TacticalLines.AAFNT;case 110101:case 110102:case 110103:return TacticalLines.BOUNDARY;case 110200:return TacticalLines.LL;case 120101:return TacticalLines.AO;case 120102:return TacticalLines.NAI;case 120103:return TacticalLines.TAI;case 120104:return TacticalLines.AIRFIELD;case 140100:case 140101:case 140102:case 140103:case 140104:return TacticalLines.FLOT;case 140200:return TacticalLines.LC;case 140300:return TacticalLines.PL;case 140400:case 140401:return TacticalLines.PL;case 140500:return TacticalLines.PDF;case 140601:return TacticalLines.DIRATKAIR;case 140602:return TacticalLines.DIRATKGND;case 140603:case 140604:case 140606:case 140607:return TacticalLines.DIRATKSPT;case 140605:return TacticalLines.DIRATKFNT;case 140700:return TacticalLines.FCL;case 140800:return TacticalLines.IL;case 140900:return TacticalLines.LOA;case 141000:return TacticalLines.LOD;case 141100:return TacticalLines.LDLC;case 141200:return TacticalLines.PLD;case 150101:case 150102:case 150103:case 150104:case 200401:return TacticalLines.PEN;case 150200:case 150300:case 150301:case 150302:case 150400:return TacticalLines.ASSY;case 150501:case 150502:case 150503:return TacticalLines.GENERAL;case 150600:return TacticalLines.DZ;case 150700:return TacticalLines.EZ;case 150800:return TacticalLines.LZ;case 150900:return TacticalLines.PZ;case 151000:return TacticalLines.FORT;case 151100:return TacticalLines.LAA;case 151200:case 151201:return TacticalLines.BATTLE;case 151202:return TacticalLines.PNO;case 151204:return TacticalLines.CONTAIN;case 151205:return TacticalLines.RETAIN;case 151300:return TacticalLines.EA;case 151203:return TacticalLines.STRONG;case 151500:return TacticalLines.ASSAULT;case 151600:return TacticalLines.ATKPOS;case 151700:return TacticalLines.OBJ;case 151801:case 151802:return TacticalLines.ENCIRCLE;case 151900:return TacticalLines.PEN;case 152000:return TacticalLines.ATKBYFIRE;case 152100:return TacticalLines.SPTBYFIRE;case 152200:return TacticalLines.SARA;case 141300:return TacticalLines.AIRHEAD;case 141400:return TacticalLines.BRDGHD;case 141500:return TacticalLines.HOLD;case 141600:return TacticalLines.RELEASE;case 141700:return TacticalLines.AMBUSH;case 170100:case 170101:return TacticalLines.AC;case 170200:return TacticalLines.LLTR;case 170300:return TacticalLines.MRR;case 170400:return TacticalLines.MRR;case 170500:return TacticalLines.SAAFR;case 170600:return TacticalLines.MRR;case 170700:return TacticalLines.UAV;case 170800:return TacticalLines.PEN;case 170900:return TacticalLines.HIDACZ;case 171000:return TacticalLines.ROZ;case 171100:case 171200:case 171300:case 171400:case 171500:return TacticalLines.ROZ;case 171600:return TacticalLines.MEZ;case 171700:return TacticalLines.LOMEZ;case 171800:return TacticalLines.HIMEZ;case 171900:return TacticalLines.FAADZ;case 172000:return TacticalLines.WFZ;case 190100:case 190200:return TacticalLines.FSCL;case 200202:case 200402:case 240804:return TacticalLines.FSA_RECTANGULAR;case 200300:return TacticalLines.FSA_CIRCULAR;case 220100:return TacticalLines.BEARING;case 220101:return TacticalLines.ELECTRO;case 220102:return TacticalLines.BEARING;case 220103:case 220104:return TacticalLines.ACOUSTIC;case 220105:return TacticalLines.TORPEDO;case 220106:return TacticalLines.OPTICAL;case 218400:return TacticalLines.NAVIGATION;case 220107:case 220108:return TacticalLines.BEARING;case 230100:case 230200:return TacticalLines.DECEIVE;case 240101:return TacticalLines.ACA;case 240102:return TacticalLines.ACA_RECTANGULAR;case 240103:return TacticalLines.ACA_CIRCULAR;case 240201:return TacticalLines.FFA;case 240202:return TacticalLines.FFA_RECTANGULAR;case 240203:return TacticalLines.FFA_CIRCULAR;case 240301:return TacticalLines.NFA;case 240302:return TacticalLines.NFA_RECTANGULAR;case 240303:return TacticalLines.NFA_CIRCULAR;case 240401:return TacticalLines.RFA;case 240402:return TacticalLines.RFA_RECTANGULAR;case 240403:return TacticalLines.RFA_CIRCULAR;case 240501:return TacticalLines.PAA_RECTANGULAR;case 240502:return TacticalLines.PAA_CIRCULAR;case 260100:return TacticalLines.FSCL;case 260200:return TacticalLines.CFL;case 260300:return TacticalLines.NFL;case 260400:return TacticalLines.FSCL;case 260500:return TacticalLines.RFL;case 260600:return TacticalLines.MFP;case 240701:return TacticalLines.LINTGT;case 240702:return TacticalLines.LINTGTS;case 240703:return TacticalLines.FPF;case 240801:return TacticalLines.AT;case 240802:return TacticalLines.RECTANGULAR;case 240803:return TacticalLines.CIRCULAR;case 240805:return TacticalLines.SERIES;case 240806:case 240807:return TacticalLines.SMOKE;case 240808:return TacticalLines.BOMB;case 241001:return TacticalLines.FSA;case 241002:return TacticalLines.FSA_RECTANGULAR;case 241003:return TacticalLines.FSA_CIRCULAR;case 241101:return TacticalLines.ATI;case 241102:return TacticalLines.ATI_RECTANGULAR;case 241103:return TacticalLines.ATI_CIRCULAR;case 241201:return TacticalLines.CFFZ;case 241202:return TacticalLines.CFFZ_RECTANGULAR;case 241203:return TacticalLines.CFFZ_CIRCULAR;case 241301:return TacticalLines.CENSOR;case 241302:return TacticalLines.CENSOR_RECTANGULAR;case 241303:return TacticalLines.CENSOR_CIRCULAR;case 241401:return TacticalLines.CFZ;case 241402:return TacticalLines.CFZ_RECTANGULAR;case 241403:return TacticalLines.CFZ_CIRCULAR;case 241501:return TacticalLines.DA;case 241502:return TacticalLines.DA_RECTANGULAR;case 241503:return TacticalLines.DA_CIRCULAR;case 241601:return TacticalLines.SENSOR;case 241602:return TacticalLines.SENSOR_RECTANGULAR;case 241603:return TacticalLines.SENSOR_CIRCULAR;case 241701:return TacticalLines.TBA;case 241702:return TacticalLines.TBA_RECTANGULAR;case 241703:return TacticalLines.TBA_CIRCULAR;case 241801:return TacticalLines.TVAR;case 241802:return TacticalLines.TVAR_RECTANGULAR;case 241803:return TacticalLines.TVAR_CIRCULAR;case 241901:return TacticalLines.ZOR;case 241902:return TacticalLines.ZOR_RECTANGULAR;case 241903:return TacticalLines.ZOR_CIRCULAR;case 242000:return TacticalLines.TGMF;case 242100:return TacticalLines.RANGE_FAN;case 242200:return TacticalLines.RANGE_FAN_SECTOR;case 242301:return TacticalLines.KILLBOXBLUE;case 242302:return TacticalLines.KILLBOXBLUE_RECTANGULAR;case 242303:return TacticalLines.KILLBOXBLUE_CIRCULAR;case 242304:return TacticalLines.KILLBOXPURPLE;case 242305:return TacticalLines.KILLBOXPURPLE_RECTANGULAR;case 242306:return TacticalLines.KILLBOXPURPLE_CIRCULAR;case 270100:return TacticalLines.BELT;case 270200:return TacticalLines.ZONE;case 270300:return TacticalLines.OBSFAREA;case 270400:return TacticalLines.OBSAREA;case 270501:return TacticalLines.MNFLDBLK;case 270502:return TacticalLines.MNFLDDIS;case 270503:return TacticalLines.MNFLDFIX;case 270504:return TacticalLines.TURN;case 270601:return TacticalLines.EASY;case 270602:return TacticalLines.BYDIF;case 270603:return TacticalLines.BYIMP;case 271100:return TacticalLines.GAP;case 271201:return TacticalLines.PLANNED;case 271202:return TacticalLines.ESR1;case 271203:return TacticalLines.ESR2;case 271204:return TacticalLines.ROADBLK;case 280100:return TacticalLines.ABATIS;case 290100:return TacticalLines.LINE;case 290201:return TacticalLines.ATDITCH;case 290202:return TacticalLines.ATDITCHC;case 290203:return TacticalLines.ATDITCHM;case 290204:return TacticalLines.ATWALL;case 290301:return TacticalLines.UNSP;case 290302:return TacticalLines.SFENCE;case 290303:return TacticalLines.DFENCE;case 290304:return TacticalLines.DOUBLEA;case 290305:return TacticalLines.LWFENCE;case 290306:return TacticalLines.HWFENCE;case 290307:return TacticalLines.SINGLEC;case 290308:return TacticalLines.DOUBLEC;case 290309:return TacticalLines.TRIPLE;case 290600:return TacticalLines.MFLANE;case 270706:return TacticalLines.DUMMY;case 270707:return TacticalLines.DEPICT;case 270800:return TacticalLines.MINED;case 270900:return TacticalLines.DMA;case 270901:return TacticalLines.DMAF;case 271000:return TacticalLines.UXO;case 290400:return TacticalLines.CLUSTER;case 290500:return TacticalLines.TRIP;case 282003:return TacticalLines.OVERHEAD_WIRE;case 271300:return TacticalLines.ASLTXING;case 271400:return TacticalLines.BRIDGE;case 271500:return TacticalLines.FORDSITE;case 271600:return TacticalLines.FORDIF;case 290700:return TacticalLines.FERRY;case 290800:return TacticalLines.RAFT;case 290900:return TacticalLines.FORTL;case 291000:return TacticalLines.FOXHOLE;case 272100:return TacticalLines.MSDZ;case 272200:return TacticalLines.DRCL;case 310100:return TacticalLines.DHA;case 310200:return TacticalLines.EPW;case 310300:return TacticalLines.FARP;case 310400:return TacticalLines.RHA;case 310500:return TacticalLines.RSA;case 310600:return TacticalLines.BSA;case 310700:return TacticalLines.DSA;case 330100:return TacticalLines.CONVOY;case 330200:return TacticalLines.HCONVOY;case 330300:return TacticalLines.MSR;case 330301:return TacticalLines.ONEWAY;case 330302:return TacticalLines.TWOWAY;case 330303:return TacticalLines.ALT;case 330400:return TacticalLines.ASR;case 330401:return TacticalLines.ONEWAY;case 330402:return TacticalLines.TWOWAY;case 330403:return TacticalLines.ALT;case 340100:return TacticalLines.BLOCK;case 340200:return TacticalLines.BREACH;case 340300:return TacticalLines.BYPASS;case 340400:return TacticalLines.CANALIZE;case 340500:return TacticalLines.CLEAR;case 340600:return TacticalLines.CATK;case 340700:return TacticalLines.CATKBYFIRE;case 340800:return TacticalLines.DELAY;case 341000:return TacticalLines.DISRUPT;case 341100:return TacticalLines.FIX;case 341200:return TacticalLines.FOLLA;case 341300:return TacticalLines.FOLSP;case 341500:return TacticalLines.ISOLATE;case 341700:return TacticalLines.OCCUPY;case 341800:return TacticalLines.PENETRATE;case 341900:return TacticalLines.RIP;case 342000:return TacticalLines.RETIRE;case 342100:return TacticalLines.SECURE;case 342201:return TacticalLines.COVER;case 342202:return TacticalLines.GUARD;case 342203:return TacticalLines.SCREEN;case 342300:return TacticalLines.SEIZE;case 342400:return TacticalLines.WITHDRAW;case 342500:return TacticalLines.WDRAWUP;case 300100:return TacticalLines.FSCL;default:break;} +return-1;} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getCMLineType",exc));}else{throw exc;}}},setTGProperties:function(tg) +{try +{if(tg.get_SymbolId().length<20){return;} +var setA=tg.get_SymbolId().substring(0,10);var setB=tg.get_SymbolId().substring(10);var symbolSet=setA.substring(4,6);var nSymbolSet=Integer.parseInt(symbolSet);if(nSymbolSet.valueOf()!==25){return;} +var entity=setB.substring(0,6);var code=Integer.parseInt(entity);var nCode=code.valueOf();switch(nCode) +{case 140101:break;case 140102:tg.set_LineStyle(1);break;case 140103:break;case 140104:case 140607:case 150102:case 150104:tg.set_LineStyle(1);break;case 140604:case 140401:case 220104:case 240807:case 151405:case 150400:tg.set_LineStyle(1);break;case 151802:case 140606:case 150501:case 150502:case 150503:break;case 151407:tg.set_Name("");break;case 151408:tg.set_Name("");tg.set_LineStyle(1);break;case 200101:tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(255,155,0,191));break;case 200201:case 200202:tg.set_FillColor(new armyc2.c2sd.renderer.utilities.Color(85,119,136,191));break;case 270100:tg.set_T1("");break;case 290301:case 290305:case 290306:case 290307:case 290308:case 290309:armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.reversePointsRevD(tg);break;default:break;}} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside setTGProperties",exc));}else{throw exc;}}},reversePointsRevD:function(tg){try{var j=0;var pts=null;if(tg.get_SymbolId().length<20){return;} +var setB=tg.get_SymbolId().substring(10);var entityCode=setB.substring(0,6);var code=Integer.parseInt(entityCode);var nCode=code.valueOf();switch(nCode){case 290301:case 290305:case 290306:case 290307:case 290308:case 290309:if(tg.Pixels!==null){pts=tg.Pixels.clone();for(j=0;j15) +{var setA=symbolId.substring(0,10);var setB=symbolId.substring(10);var code=setB.substring(0,6);var symbolSet=setA.substring(4,6);var nSymbol=Integer.parseInt(symbolSet);if(nSymbol.valueOf()===25){linetype=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.getCMLineType(symbolSet,code);}else if(nSymbol.valueOf()===45||nSymbol.valueOf()===46){linetype=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.getWeatherLinetype(symbolSet,code);}}else +{linetype=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetLinetypeFromString(symbolId);} +tg.set_LineType(linetype);} +catch(exc) +{if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer._className,"render",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getRevDLinetype",exc));}else{throw exc;}} +return linetype;},_className:"clsRenderer",feetPerMeter:3.28084};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2={getMSRShapes:function(tg,shapes){try{var linetype=tg.get_LineType();if(linetype!=25221000&&linetype!=25222000) +return;var hmap=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getMSRSegmentColors(tg);var shape=null;var stroke=null;if(tg.get_Client().equalsIgnoreCase("ge")) +stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke2(tg.get_LineThickness(),tg.get_LineStyle(),1,1);else +stroke=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getLineStroke(tg.get_LineThickness(),tg.get_LineStyle(),1,1);var j=0;var color=null;var segShape=null;shape=new armyc2.c2sd.JavaLineArray.Shape2(armyc2.c2sd.JavaLineArray.Shape2.SHAPE_TYPE_POLYLINE);shape.setLineColor(tg.get_LineColor());shape.setStroke(stroke);var lastColor=null;var dist=0;var dist2=0;var pt0=null;var pt1=null;var lastPt=null;for(j=0;j10){shape.lineTo(pt1);lastPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);}else{dist2=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(lastPt,pt1);if(dist2>10){shape.lineTo(pt1);lastPt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1);}}}}} +if(segShape!==null) +shapes.add(segShape);if(!shape.getShape().getPathIterator().getPoints().isEmpty()) +shapes.add(shape);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2._className,"getMSRShapes",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside getMSRShapes",exc));}else{throw exc;}}},GetLineArray:function(tg,converter,isTextFlipped,clipBounds){var shapes=new java.util.ArrayList();try{if(tg.Pixels===null||tg.Pixels.isEmpty()) +return null;var x=0;var y=0;var width=0;var height=0;var clipBounds2=null;var rev=tg.getSymbologyStandard();var clipRect=null;var clipArray=null;if(clipBounds!==null){if(clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle2D||clipBounds instanceof armyc2.c2sd.graphics2d.Rectangle){clipRect=clipBounds;x=clipRect.getMinX()-50;y=clipRect.getMinY()-50;width=clipRect.getWidth()+100;height=clipRect.getHeight()+100;clipBounds2=new armyc2.c2sd.graphics2d.Rectangle2D(x,y,width,height);} +else if(clipBounds instanceof java.util.ArrayList) +{clipArray=clipBounds;clipBounds2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.getMBR(clipArray);}} +var lineType=tg.get_LineType();var minPoints2=armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetMinPoints(lineType);var minPoints=new armyc2.c2sd.JavaLineArray.ref();var bolResult=armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(lineType,minPoints);var bolMeTOC=armyc2.c2sd.JavaTacticalRenderer.clsMETOC.IsWeather(tg.get_SymbolId());var pts=new java.util.ArrayList();var usas1314=new Boolean(true);var j=0;switch(tg.get_LineType()){case 22612000:case 22623000:case 22612001:case 22623001:if(tg.Pixels.size()<2) +return null;if((usas1314).valueOf()) +break;pts.add(tg.Pixels.get(0));for(j=2;j0){if(tg.Pixels.size()<2) +return null;try{armyc2.c2sd.JavaTacticalRenderer.clsMETOC.GetMeTOCShape(tg,shapes,rev);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2._className,"GetLineArray",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetLineArray",exc));}else{throw exc;}}}else{if(tg.Pixels.size()<2) +if(lineType!==12000000) +return null;if(armyc2.c2sd.JavaLineArray.CELineArray.CIsChannel(lineType)===0){if(lineType===25222000||lineType===25221000){armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer2.getMSRShapes(tg,shapes);} +else if(lineType!==23111001){tg.Pixels=armyc2.c2sd.JavaLineArray.arraysupport.GetLineArray2(lineType,tg.Pixels,shapes,clipBounds2,rev,converter);}else if(lineType===23111001){var tempShapes=null;var partitions=armyc2.c2sd.JavaTacticalRenderer.clsChannelUtility.GetPartitions2(tg);var pixels=null;var l=0;var k=0;for(l=0;lminSpikeDistance){lastGoodPt=currentPt;pts.add(currentPt);ptsGeo.add(currentPtGeo);foundGoodPt=true;}else{if(j===tg.Pixels.size()-1){pts.set(pts.size()-1,currentPt);ptsGeo.set(ptsGeo.size()-1,currentPtGeo);}} +break;default:if(dist>minSpikeDistance||j===tg.Pixels.size()-1){lastGoodPt=currentPt;pts.add(currentPt);ptsGeo.add(currentPtGeo);foundGoodPt=true;} +break;}} +if(foundGoodPt===true){tg.Pixels=pts;tg.LatLongs=ptsGeo;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterPoints",exc));}else{throw exc;}}},PixelsToLatLong:function(pts,converter){var j=0;var pt=null;var ptGeo=null;var ptsGeo=new java.util.ArrayList();for(j=0;jpt0pt1dist){pts.add(pt0);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(pt0.x),Math.floor(pt0.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);pt1=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0,pt1,relativeDist);pts.add(pt1);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(pt1.x),Math.floor(pt1.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);}else{foundGoodPoint=true;pts=tg.Pixels;ptsGeo=tg.LatLongs;} +if(foundGoodPoint===false){for(j=2;jpt0pt1dist)continue;else{pts.add(ptj);ptsGeo.add(ptjGeo);foundGoodPoint=true;}}} +pts.add(controlPt);pt=new armyc2.c2sd.graphics2d.Point(Math.floor(controlPt.x),Math.floor(controlPt.y));pt1Geo2d=converter.PixelsToGeo(pt);pt1geo=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pt1Geo2d.getX(),pt1Geo2d.getY());ptsGeo.add(pt1geo);} +var lastGoodPt=pts.get(1);var currentPt=null;var currentPtGeo=null;var dist=0;tg.Pixels=new java.util.ArrayList();tg.LatLongs=new java.util.ArrayList();for(j=0;j<2;j++){tg.Pixels.add(pts.get(j));tg.LatLongs.add(ptsGeo.get(j));} +for(j=2;j5){lastGoodPt=currentPt;tg.Pixels.add(currentPt);tg.LatLongs.add(currentPtGeo);}} +tg.Pixels.add(pts.get(pts.size()-1));tg.LatLongs.add(ptsGeo.get(ptsGeo.size()-1));}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterAXADPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterAXADPoints",exc));}else{throw exc;}} +return;},RemoveDuplicatePoints:function(tg){try{switch(tg.get_LineType()){case 22221000:case 22222000:case 22223000:case 22224000:case 22225000:break;default:if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.isAutoshape(tg))return;} +switch(tg.get_LineType()){case 21700000:case 21710000:case 22320000:case 22521100:case 22521200:case 22521300:case 22521420:case 22521410:return;case 22121000:case 25221000:case 25222000:var strH=tg.get_H();if(strH!==null&&!strH.isEmpty()){var strs=strH.split(",");if(strs.length>1) +return;} +return;default:break;} +var linetype=tg.get_LineType();if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(linetype,null))return;var minSize=2;if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType())===true) +minSize=3;var ptCurrent=null;var ptLast=null;for(var j=1;jminSize) +{tg.Pixels.remove(j);tg.LatLongs.remove(j);j=1;}}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsUtility","FilterVerticalSegments",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside FilterVerticalSegments",exc));}else{throw exc;}} +return;},BestFitConverter:function(latLongs){var converter=null;try{var j=0;var pixelWidth=1000;var pixelHeight=1000;var geoTop=2.2250738585072014E-308;var geoBottom=1.7976931348623157E308;var geoLeft=1.7976931348623157E308;var geoRight=2.2250738585072014E-308;for(j=0;jgeoTop)geoTop=latLongs.get(j).y;if(latLongs.get(j).ygeoRight)geoRight=latLongs.get(j).x;if(latLongs.get(j).xxmax)xmax=pt.getX();if(pt.getY()<=ymin)ymin=pt.getY();if(pt.getY()>ymax)ymax=pt.getY();} +rect=new armyc2.c2sd.graphics2d.Rectangle2D(xmin,ymin,xmax-xmin,ymax-ymin);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility._className,"AddBoundaryPointsForLines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside AddBoundaryPointsForLines",exc));}else{throw exc;}} +return rect;},_className:"clsUtility"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};var vincenty=vincenty||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF={BuildDummyShapeSpec:function(){var shape=new armyc2.c2sd.renderer.utilities.ShapeInfo(null);try{var tx=new armyc2.c2sd.graphics2d.AffineTransform();tx.setToIdentity();var gp=new armyc2.c2sd.graphics2d.GeneralPath();shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.WHITE);shape.setFillColor(null);shape.setStroke(new armyc2.c2sd.graphics2d.BasicStroke());shape.setTexturePaint(null);gp.moveTo(-1000,-1000);gp.lineTo(-1001,-1001);shape.setShape(gp);shape.setAffineTransform(tx);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"BuidDummyShapeSpec",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside BuildDummyShapeSpec",exc));} +else{throw exc;}} +return shape;},isValidShapeSpec:function(shape){if(shape===null) +return false;if(shape.getLineColor()===null&&shape.getFillColor()===null) +return false;if(shape.getShape()===null) +return false;if(shape.getStroke()===null) +return false;if(shape.getAffineTransform()===null) +return false;return true;},SetLCColor:function(tg,shape){try{var affiliation=tg.get_Affiliation();if(affiliation.equals("H")){if(shape.getLineColor()===armyc2.c2sd.renderer.utilities.Color.RED) +shape.setLineColor(tg.get_LineColor());else +shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}else{if(shape.getLineColor()!==armyc2.c2sd.renderer.utilities.Color.RED) +shape.setLineColor(tg.get_LineColor());else +shape.setLineColor(armyc2.c2sd.renderer.utilities.Color.RED);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"SetLCColor",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SetLCColor",exc));}else{throw exc;}}},ValidateShapeSpecs:function(originalShapes,clipRect){var shapes=null;try{var shape=null;if(originalShapes===null||originalShapes.length===0){shapes=new Array(0);}else{var j=0;var newShapes=new java.util.ArrayList();for(j=0;j0){shapes=new Array(newShapes.size());shapes=newShapes.toArray(shapes);}else{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildDummyShapeSpec();shapes=new Array(1);shapes[0]=shape;}}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"ValidateShapeSpecs",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside ValidateShapeSpecs",exc));}else{throw exc;}} +return shapes;},PointLatLongToPixels:function(ptLatLong,converter){var pt=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();try{var x=ptLatLong.x;var y=ptLatLong.y;var pt2dGeo=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(x,y);var ptPixels=converter.GeoToPixels(pt2dGeo);pt.x=ptPixels.getX();pt.y=ptPixels.getY();pt.style=ptLatLong.style;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"PointLatLongToPixels",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside PointLatLongToPixels",exc));}else{throw exc;}} +return pt;},GetNumericFields:function(tg,lineType,radius,width,length,attitude){try{if(lineType===243111001) +return;var dist=0;var a12=new armyc2.c2sd.JavaLineArray.ref();var a21=new armyc2.c2sd.JavaLineArray.ref();var pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(0,0);radius.value=Clazz.newArray(1,0);width.value=Clazz.newArray(1,0);attitude.value=Clazz.newArray(1,0);length.value=Clazz.newArray(1,0);switch(lineType){case 13000001:attitude.value[0]=Double.parseDouble(tg.get_T1());width.value[0]=Double.parseDouble(tg.get_H1());length.value[0]=Double.parseDouble(tg.get_H2());radius.value[0]=Double.parseDouble(tg.get_H());break;case 15000002:case 24312000:case 24321300:case 24323300:case 24324300:case 24325300:case 24326200:case 24331300:case 24332300:case 24333300:case 24334300:case 24335300:case 24336300:case 24337300:case 24338300:case 24339300:case 24322300:case 24353000:case 24363000:radius.value[0]=Double.parseDouble(tg.get_T1());break;case 24311000:case 14000001:case 14000002:length.value[0]=Double.parseDouble(tg.get_T1());width.value[0]=Double.parseDouble(tg.get_H());attitude.value[0]=Double.parseDouble(tg.get_H2())*(0.05625);radius.value[0]=Double.parseDouble(tg.get_H1());var std=tg.getSymbologyStandard();if(std===armyc2.c2sd.renderer.utilities.RendererSettings.Symbology_2525C) +attitude.value[0]=Double.parseDouble(tg.get_H2());break;case 24326101:case 24321200:case 24323200:case 24322200:case 24324200:case 24325200:case 24331200:case 24332200:case 24333200:case 24334200:case 24335200:case 24336200:case 24337200:case 24338200:case 24339200:case 24352000:case 24362000:if(tg.LatLongs.size()>=2){if(tg.LatLongs.size()>=2){pt0=tg.LatLongs.get(0);pt1=tg.LatLongs.get(1);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(pt0,pt1,a12,a21);attitude.value[0]=a12.value[0];}} +width.value[0]=Double.parseDouble(tg.get_T1());break;case 25200101:if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isNumber(tg.get_T1())) +length.value[0]=Double.parseDouble(tg.get_T1());if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isNumber(tg.get_H())) +width.value[0]=Double.parseDouble(tg.get_H());if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isNumber(tg.get_H2())) +attitude.value[0]=Double.parseDouble(tg.get_H2());break;default:break;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetNumericFields",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetNumericFields",exc));}else{throw exc;}}},TransformPixels:function(tg,clipBounds){try{var top=clipBounds.getMaxY();var bottom=clipBounds.getMinY();var xfm=null;var pt2d=null;var j=0;var pt2=null;for(j=0;jmaxX) +maxX=tg.Pixels.get(j).x;} +var degWidth=(maxX-minX)*degLonPerPixel;if(Math.abs(degWidth)<180) +return;var midX=Math.abs(180/degLonPerPixel);var x=0;var y=0;for(j=0;jmidX){x-=2*midX;} +farLeftPixels.add(armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(x,y));} +for(j=0;j1){pt1=tg.LatLongs.get(1);}else{pt1=tg.LatLongs.get(0);} +var pPoints=null;var ptCenter=this.PointLatLongToPixels(pt0,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetNumericFields(tg,lineType,radius,width,length,attitude);switch(lineType){case 25200101:var ellipsePts=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.getGeoEllipse(pt0,width.value[0],length.value[0],attitude.value[0]);for(j=0;j1) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.RangeFanOrientation(tg,lineType,converter);break;case 243112000:armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetSectorRangeFan(tg,converter);armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.RangeFanOrientation(tg,lineType,converter);break;case 243111001:armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetSectorRangeFan(tg,converter);break;case 13000000:case 13000001:case 13000002:var buffer=parseFloat(tg.get_H());var center=tg.LatLongs.get(0);var semiMajor=parseFloat(tg.get_H1());var semiMinor=parseFloat(tg.get_H2());var rotation=90-parseFloat(tg.get_T1());var ellipse=new EllipseGeometry({center:Cartesian3.fromDegrees(center.x,center.y),semiMajorAxis:semiMajor+buffer,semiMinorAxis:semiMinor+buffer,rotation:CesiumMath.toRadians(rotation)});var geometry=EllipseGeometry.createGeometry(ellipse);var cartesian;var longitude;var latitude;var cartographic;var pt0,pt;var x,y,z;for(j=0;j0) +lastPt=tg.Pixels.get(k-1);if(beginLine){if(k===0) +shape.set_Style(currentPt.style);if(k>0) +if(currentPt.style===5&&lastPt.style===5) +shape.lineTo(currentPt);shape.moveTo(currentPt);beginLine=false;}else{shape.lineTo(currentPt);if(currentPt.style===5||currentPt.style===10){beginLine=true;if(linetype===243111001&&kmaxx){maxx=max;maxIndex=k;}}}catch(e){if(Clazz.instanceOf(e,NumberFormatException)){return null;}else{throw e;}} +var strLeft=leftRightMinMax[4*maxIndex];var strRight=leftRightMinMax[4*maxIndex+1];var strMin=leftRightMinMax[4*maxIndex+2];var strMax=leftRightMinMax[4*maxIndex+3];strLeftRightMinMax=strLeft+","+strRight+","+strMin+","+strMax;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetMaxSector",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetMaxSector",exc));}else{throw exc;}} +return strLeftRightMinMax;},GetCircularRangeFanFillTG:function(tg){var tg1=null;try{tg1=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg1.set_VisibleModifiers(true);tg1.set_LineThickness(0);tg1.set_FillColor(tg.get_FillColor());tg1.set_Fillstyle(tg.get_FillStyle());tg1.LatLongs=new java.util.ArrayList();tg1.Pixels=new java.util.ArrayList();tg1.LatLongs.add(tg.LatLongs.get(0));tg1.Pixels.add(tg.Pixels.get(0));tg1.Pixels.add(tg.Pixels.get(1));tg1.set_LineType(243111001);var strH2=tg.get_H2();if(tg.get_LineType()!==243111000){tg1.set_H2(strH2);return tg1;} +var H2=strH2.split(",");var leftRightMinMax="";var j=0;for(j=0;j0) +leftRightMinMax+=",";leftRightMinMax+="0,0,"+H2[j]+","+H2[j+1];} +tg1.set_H2(leftRightMinMax);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"GetCircularRangeFanFillTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside GetCircularRangeFanFillTG",exc));}else{throw exc;}} +return tg1;},addCircularRangeFanFillShapesFromTG:function(tgShapes,fillShapes){try{tgShapes.addAll(0,fillShapes);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"addCircularRangeFanFillShapesFromTG",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside addCircularRangeFanFillShapesFromTG",exc));}else{throw exc;}}},GetSectorRangeFan:function(tg,converter){var circle=false;try{var ptCenter=tg.LatLongs.get(0);var k=0;var l=0;var numSectors=0;armyc2.c2sd.JavaTacticalRenderer.clsUtility.GetSectorRadiiFromPoints(tg);var pPoints=new java.util.ArrayList();var pPointsInnerArc=new java.util.ArrayList();var pPointsOuterArc=new java.util.ArrayList();var sectorPoints=new java.util.ArrayList();var allPoints=new java.util.ArrayList();var pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt2=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var H2=tg.get_H2();var leftRightMinMax=H2.split(",");var left=0;var right=0;var min=0;var max=0;numSectors=Math.floor(leftRightMinMax.length/4);if(numSectors<1){return false;} +if(numSectors*4!==leftRightMinMax.length){return false;} +try{for(k=0;k=0;l--){pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pPointsOuterArc.get(l));sectorPoints.add(pt1);} +pt1=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(pPointsInnerArc.get(0));pt1.style=5;sectorPoints.add(pt1);for(l=0;l1){pt1=tg.LatLongs.get(1);dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(pt0,pt1,a12,a21);orientation=a12.value[0];}else{var strLeftRightMinMax=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.GetMaxSector(tg);var sector=strLeftRightMinMax.split(",");var left=Double.parseDouble(sector[0]);var right=Double.parseDouble(sector[1]);var min=Double.parseDouble(sector[2]);var max=Double.parseDouble(sector[3]);while(left>360) +left-=360;while(right>360) +right-=360;while(left<0) +left+=360;while(right<0) +right+=360;if(left>right) +orientation=(left-360+right)/2;else +orientation=(left+right)/2;dist=max;} +radius=dist*1.1;var pt0F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var pt1F=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptBaseF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptLeftF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptRightF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();var ptTipF=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2();pt0=tg.LatLongs.get(0);pt0F=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(pt0,converter);pt1=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,radius,orientation);pt1F=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.PointLatLongToPixels(pt1,converter);dist=armyc2.c2sd.JavaLineArray.lineutility.CalcDistanceDouble(pt0F,pt1F);var base=10;if(dist<100) +base=dist/10;if(base<5) +base=5;var basex2=2*base;ptBaseF=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0F,pt1F,dist+base);ptTipF=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble(pt0F,pt1F,dist+basex2);ptLeftF=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0F,ptBaseF,ptBaseF,0,base);ptRightF=armyc2.c2sd.JavaLineArray.lineutility.ExtendDirectedLine(pt0F,ptBaseF,ptBaseF,1,base);tg.Pixels.add(pt0F);ptTipF.style=5;tg.Pixels.add(ptTipF);tg.Pixels.add(ptLeftF);ptTipF.style=0;tg.Pixels.add(ptTipF);tg.Pixels.add(ptRightF);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"RangeFanOrientation",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside RangeFanOrientation",exc));}else{throw exc;}}},ClearPixelsStyle:function(tg){try{switch(tg.get_LineType()){case 15000001:case 15000000:case 15000003:case 22224000:case 22222000:case 22224001:case 22222001:case 22225000:case 22221000:case 22223000:case 13000000:case 13000001:case 13000002:return;default:break;} +for(var j=0;j0) +return true;var linetype=tg.get_LineType();switch(linetype){case 2237000:case 23120000:case 22612000:case 22623000:case 22122000:case 22123000:case 22124000:case 22125000:case 22131000:case 11000000:case 10000000:case 22132000:case 22133000:case 22432000:case 22134000:case 22135000:case 22136000:case 22137000:case 22138000:case 221310000:case 22231000:case 22232000:case 22233000:case 22234000:case 22234100:case 22234200:case 22235000:case 22330000:case 221311000:case 22340000:case 22350000:case 22421000:case 22431000:case 22431100:case 22522100:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22528000:case 22531000:case 22532000:case 22535000:case 22536000:case 22613000:case 22621000:case 22622000:case 22624000:case 22625000:case 22626000:case 23111000:case 23111001:case 23112000:case 23113000:case 23115000:case 23114000:case 23131100:case 23131200:case 23132000:case 23134000:case 23162000:case 23164000:case 23180000:case 231111000:case 231112000:case 231113000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 23350000:case 23440000:case 23450000:case 23460000:case 23490000:case 24250000:case 24211000:case 24260000:case 24221000:case 24222000:case 23200000:case 23200001:case 24223000:case 24225000:case 24224000:case 24330000:case 24313000:case 24314000:case 24315000:case 24321100:case 24322100:case 24323100:case 24324100:case 24325100:case 243100000:case 24331100:case 24332100:case 24336100:case 24333100:case 24334100:case 24335100:case 24337100:case 24338100:case 24339100:case 24351000:case 24361000:case 25223000:case 25225000:case 25224000:case 25310000:case 25320000:case 25330000:case 25340000:case 25351000:case 25352000:case 25353000:case 24226000:return true;case 22121000:case 25221000:case 25222000:return false;default:return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"canClipPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside canClipPoints",exc));}else{throw exc;}} +return false;},LinesWithSeparateFill:function(linetype,shapes){if(shapes===null) +return false;switch(linetype){case 23410000:case 22612000:case 22623000:return true;case 23114000:case 23115000:case 23350000:case 23113000:case 22134000:case 22624000:case 23111001:case 23111000:case 22340000:case 22350000:case 211100000:case 22121000:case 22122000:case 22123000:case 22124000:case 22125000:case 22330000:case 22522100:case 22522210:case 22522220:case 22523000:case 22525000:case 22526000:case 22527000:case 22528000:case 22613000:case 23112000:case 23120000:case 23131100:case 23131200:case 23132000:case 23134000:case 23172000:case 231111000:case 231112000:case 231113000:case 231114000:case 231115000:case 231116000:case 231117100:case 231117200:case 231117300:case 23330000:case 24250000:case 24211000:case 24221000:case 24222000:case 24223000:case 24225000:case 24224000:case 25221000:case 25222000:case 25223000:case 25225000:case 25224000:case 22222000:case 22222001:case 22224000:case 22224001:case 22221000:case 22223000:case 22225000:var shape=null;if(shapes!==null&&shapes.size()>0){for(var j=0;j1) +{tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg.set_LineType(22124000);tg.Pixels=pts2;if(clipBounds!==null) +{pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);} +else if(clipPoints!==null&&!clipPoints.isEmpty()) +pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipPoints);if(pts2d!==null&&pts2d.size()>1) +{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildShapeFromPoints(pts2d);gp.append(shape,false);} +pts2.clear();pts2.add(pt);} +else +pts2.add(pt);break;case 1:pts2.add(pt);break;default:pts2.add(pt);break;}} +if(pts2.size()>1){tg=new armyc2.c2sd.JavaTacticalRenderer.TGLight();tg.set_LineType(22124000);tg.Pixels=pts2;if(clipBounds!==null) +pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tg,clipBounds);else if(clipPoints!==null) +pts2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipQuad.ClipPolygon(tg,clipPoints);if(pts2d!==null&&pts2d.size()>1) +{shape=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.BuildShapeFromPoints(pts2d);gp.append(shape,false);} +tg0.set_WasClipped(tg.get_WasClipped());} +shapeSpec2=new armyc2.c2sd.JavaLineArray.Shape2(shapeSpec.getShapeType());shapeSpec2.setLineColor(shapeSpec.getLineColor());shapeSpec2.setFillColor(shapeSpec.getFillColor());shapeSpec2.setStroke(shapeSpec.getStroke());shapeSpec2.setTexturePaint(shapeSpec.getTexturePaint());shapeSpec2.setShape(gp);shapeSpecs2.add(shapeSpec2);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"buildShapeSpecFromPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside buildShapeSpecFromPoints",exc));}else{throw exc;}} +return shapeSpecs2;},postClipShapes:function(tg,shapeSpecsArray,clipArea){var shapeSpecs2=null;var tempShapes=null;try{if(shapeSpecsArray===null||shapeSpecsArray.size()===0) +return null;shapeSpecs2=new java.util.ArrayList();var j=0;var shapeSpecs=new java.util.ArrayList();for(j=0;jmaxDist){maxDist=dist;}} +if(interval>maxDist) +interval=maxDist;for(j=0;j=interval/2) +resultPts.add(pt);} +resultPts.add(pt1);} +latLongs=resultPts;tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(latLongs,converter);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"postSegmentFSA",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside postSegmentFSA",exc));}else{throw exc;}}},SegmentGeoPoints:function(tg,converter,zoomFactor){try{if(tg.get_Client().equals("2D")) +return;var resultPts=new java.util.ArrayList();var lineType=tg.get_LineType();var interval=250000;var bolSegmentAC=false,bolIsAC=false,acWidth=0;bolSegmentAC=true;switch(lineType){case 22222001:case 22224001:case 22225000:case 22223000:case 22221000:if(!bolSegmentAC) +return;bolIsAC=true;break;case 22528000:case 24222000:case 231111000:case 22350000:case 231117300:case 231117200:case 231117100:case 23131100:case 23131200:case 23132000:case 23134000:case 23112000:case 23111000:case 23111001:case 22522100:case 23350000:case 22624000:case 22122000:case 23113000:case 23115000:case 23114000:case 22134000:case 23330000:break;case 231116000:case 231115000:case 231114000:case 231113000:case 231112000:interval=500000;break;case 22123000:interval=2000000;break;default:if(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF.segmentAnticipatedLine(tg)) +{break;} +return;} +var j=0;var k=0;var n=0;var pt0=null;var pt1=null;var pt=null;var dist=0;var az=0;var maxDist=0;var useVincenty=false;var fraction=0;var start=null,end=null;var lon=0,lat=0;var cartographic=new Cartographic(0,0,0);var colorStrs=null;var H="";var color="";var segPlusColor=null;var seg="";var hmap=armyc2.c2sd.JavaTacticalRenderer.clsUtility.getMSRSegmentColorStrings(tg);if(hmap!==null) +tg.set_H("");useVincenty=true;for(j=0;jmaxDist){maxDist=dist;}} +if(interval>maxDist) +interval=maxDist;if(zoomFactor>0&&zoomFactor<0.01) +zoomFactor=0.01;if(zoomFactor>0&&zoomFactor<1) +interval*=zoomFactor;for(j=0;j100) +n=100;if(j===0) +{resultPts.add(pt0);if(hmap!==null&&hmap.containsKey(j)) +{if(!H.isEmpty()) +H+=",";color=hmap.get(j);H+=(resultPts.size()-1).toString()+":"+color;}} +for(k=1;k<=n;k++) +{if(!useVincenty) +{pt=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(pt0,interval*k,az);pt.style=-2;dist=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(pt,pt1,null,null);if(dist>=interval/2) +{resultPts.add(pt);if(hmap!==null&&hmap.containsKey(j)) +{color=hmap.get(j);if(!H.isEmpty()) +H+=",";H+=(resultPts.size()-1).toString()+":"+color;}}} +else +{fraction=k/n;if(fraction>=1) +break;vincenty.EllipsoidGeodesic.interpolateUsingFraction(fraction,cartographic);pt=new armyc2.c2sd.JavaLineArray.POINT2(cartographic.longitude*180.0/Math.PI,cartographic.latitude*180.0/Math.PI);if(bolIsAC) +pt.style=-acWidth;resultPts.add(pt);if(hmap!==null&&hmap.containsKey(j)) +{color=hmap.get(j);if(!H.isEmpty()) +H+=",";H+=(resultPts.size()-1).toString()+":"+color;}}} +resultPts.add(pt1);if(hmap!==null&&hmap.containsKey(j+1)) +{if(!H.isEmpty()) +H+=",";color=hmap.get(j+1);H+=(resultPts.size()-1).toString()+":"+color;}} +if(!H.isEmpty()) +tg.set_H(H);tg.LatLongs=resultPts;tg.Pixels=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.LatLongToPixels(tg.LatLongs,converter);}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityCPOF._className,"SegmentGeoPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside SegmentGeoPoints",exc));}else{throw exc;}} +return;},_className:"clsUtilityCPOF"};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.JavaRendererServer=armyc2.c2sd.JavaRendererServer||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints=armyc2.c2sd.JavaRendererServer.RenderMultipoints||{};armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE={setSplineLinetype:function(tg){switch(tg.get_LineType()){case 22623000:tg.set_LineType(22623001);break;case 22612000:tg.set_LineType(22612001);break;case 32164000:tg.set_LineType(32164001);break;case 32163000:tg.set_LineType(32163001);break;case 32156000:tg.set_LineType(32156001);break;case 32162000:tg.set_LineType(32162001);break;case 32610000:tg.set_LineType(32610001);break;case 31430000:tg.set_LineType(31430001);break;case 31440000:tg.set_LineType(31440001);break;case 32273000:tg.set_LineType(32273001);break;case 32272000:tg.set_LineType(32272001);break;case 32234300:tg.set_LineType(32234301);break;case 32234200:tg.set_LineType(32234201);break;case 32234100:tg.set_LineType(32234101);break;case 32233700:tg.set_LineType(32233701);break;case 32233600:tg.set_LineType(32233601);break;case 32231700:tg.set_LineType(32231701);break;case 32221000:tg.set_LineType(32221001);break;case 32213000:tg.set_LineType(32213001);break;case 32212000:tg.set_LineType(32212001);break;case 32161000:tg.set_LineType(32161001);break;case 32155000:tg.set_LineType(32155001);break;case 32154000:tg.set_LineType(32154001);break;case 31830000:tg.set_LineType(31830001);break;case 31820000:tg.set_LineType(31820001);break;case 31810000:tg.set_LineType(31810001);break;case 31850000:tg.set_LineType(31850001);break;case 31840000:tg.set_LineType(31840001);break;case 31860000:tg.set_LineType(31860001);break;default:break;} +return;},createDashedPolylines:function(tg,polylines,shape){try{if(tg.get_UseDashArray()===true) +return polylines;if(shape.getLineColor()===null) +return polylines;var dashedPolylines=new java.util.ArrayList();var s=shape.getStroke();var dash=s.getDashArray();var lineThickness=tg.get_LineThickness();if(dash===null||dash.length<2) +return polylines;if(dash.length===8){dash=Clazz.newArray(2,0);dash[0]=2;dash[1]=2;s=new armyc2.c2sd.graphics2d.BasicStroke(2,1,0,2,dash,0);shape.setStroke(s);} +if(dash.length===4){if(dash[0]===lineThickness*2&&dash[1]===lineThickness*2&&dash[2]===lineThickness*2&&dash[3]===lineThickness*2){dash=Clazz.newArray(2,0);dash[0]=lineThickness;dash[1]=lineThickness;}} +var j=0;var k=0;var i=0;var l=0;var n=0;var polyline=null;var dashedPolyline=null;var pt2d0=null;var pt2d1=null;var pt2d2=null;var pt2d3=null;var pt0=null;var pt1=null;var pt2=null;var pt3=null;var dist=0;var patternLength=0;var numSegments=0;var dashMultiplier=armyc2.c2sd.renderer.utilities.RendererSettings.getInstance().getDeviceDPI()/96.0;for(j=0;j0) +{dashedPolyline=new java.util.ArrayList();pt2=armyc2.c2sd.JavaLineArray.lineutility.ExtendAlongLineDouble2(pt0,pt1,numSegments*patternLength+remainder/2);pt2d2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(pt2.x,pt2.y);dashedPolyline.add(pt2d2);dashedPolyline.add(pt2d1);dashedPolylines.add(dashedPolyline);}}} +return dashedPolylines;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"createDashedPolylines",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createDashedPolylines",exc));}else{throw exc;}}},createSimpleFillShape:function(tg,shape,polylines){try{var s=shape.getStroke();var dash=s.getDashArray();if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType())===false) +if(armyc2.c2sd.JavaTacticalRenderer.clsUtility.IsChange1Area(tg.get_LineType(),null)===false) +{return null;} +if(dash===null||dash.length<2) +return null;if(shape.getFillColor()===null) +return null;var j=0;var k=0;var shape2=new armyc2.c2sd.renderer.utilities.ShapeInfo(shape.getShape());shape2.setShapeType(armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL);var polylines2=new java.util.ArrayList();var polyline=null;var polyline2=null;var pt2d=null;s=new armyc2.c2sd.graphics2d.BasicStroke(0);shape2.setStroke(s);shape2.setFillColor(shape.getFillColor());for(j=0;j=0) +return true;switch(linetype){case 15000001:case 15000003:case 21700000:case 21700000:case 21710000:case 22320000:case 22521100:case 22521200:case 22521300:case 22521410:case 22521420:case 22139000:case 243112000:case 243111000:case 23172000:case 23173000:case 23174000:case 23200001:case 23211000:case 23131200:case 23132000:case 23223000:case 23212000:case 23213000:case 32214000:return true;default:return false;}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"allowFillForThese",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside allowFillForThese",exc));}else{throw exc;}} +return false;},SetShapeInfosPolylines:function(tg,shapeInfos,clipBounds){try{var j=0;var shape=null;var shapeInfo=null;var polylines=null;var type=-1;var simpleFillShape=null;var isClosed=new Boolean(armyc2.c2sd.JavaTacticalRenderer.clsUtility.isClosedPolygon(tg.get_LineType()));var linetype=tg.get_LineType();var fillColor=null;for(j=0;j0) +{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL) +{if(ptsPoly[ptsPoly.length-1].getX()!==ptsPoly[0].getX()||ptsPoly[ptsPoly.length-1].getY()!==ptsPoly[0].getY()) +{pt2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ptsPoly[0].getX(),ptsPoly[0].getY());ptsPoly.add(pt2d)}} +if(ptsPoly.size()>1) +polylines2.add(ptsPoly);} +ptsPoly=new java.util.ArrayList();ptPoly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(coords[0],coords[1]);ptsPoly.add(ptPoly);break;case 1:ptPoly=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(coords[0],coords[1]);ptsPoly.add(ptPoly);break;case 2:break;case 3:break;case 4:break;}} +if(ptsPoly.size()>1) +{if(shapeType===armyc2.c2sd.renderer.utilities.ShapeInfo.SHAPE_TYPE_FILL) +{if(ptsPoly.get(ptsPoly.size()-1).getX()!==ptsPoly.get(0).getX()||ptsPoly.get(ptsPoly.size()-1).getY()!==ptsPoly.get(0).getY()) +{pt2d=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setPoint2D(ptsPoly.get(0).getX(),ptsPoly.get(0).getY());ptsPoly.add(pt2d);}} +polylines2.add(ptsPoly);} +else +if(ptsPoly.size()===1&&polylines2.isEmpty()) +{ptsPoly.add(ptsPoly.get(0));polylines2.add(ptsPoly);}}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"createRenderableFromShape",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside createRenderableFromShape",exc));}else{throw exc;}} +return polylines2;},expandPolygon:function(pts,expand){var lgPoly=null;try{var j=0;var destPts=null;var isClosed=false;if(pts.get(pts.size()-1).getX()===pts.get(0).getX()&&pts.get(pts.size()-1).getY()===pts.get(0).getY()){pts.remove(pts.size()-1);isClosed=true;} +var pts2=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtility.Points2DToPOINT2(pts);var pt0=null;var pt1=null;var pt2=null;var pt3=null;var m=0;var m1=0;var b=0;var b1=0;var lineSegments=new java.util.ArrayList();for(j=0;j0;j--){pt0=tg.Pixels.get(j);pt1=tg.Pixels.get(j-1);line=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.setLine2D(pt0.x,pt0.y,pt1.x,pt1.y);intersects=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.lineIntersectsClipArea(line,clipPoints);if(intersects===true){backIndex=j;break;}else if(area.containsPt2(Math.floor(pt0.x),Math.floor(pt0.y))||area.containsPt2(Math.floor(pt1.x),Math.floor(pt1.y))){backIndex=j;break;}} +var pts=new java.util.ArrayList();for(j=frontIndex;j<=backIndex;j++){pt0=armyc2.c2sd.JavaLineArray.lineutility.setPOINT2(tg.Pixels.get(j));pts.add(pt0);} +tg.Pixels=pts;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("clsRenderer","removeTrailingPoints",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside removeTrailingPoints",exc));}else{throw exc;}}},lineIntersectsClipArea:function(line,clipPts){var result=false;try{var j=0;var poly=new armyc2.c2sd.graphics2d.Polygon();for(j=0;jheight) +height=width;else +width=height;if(tg.get_UseHatchFill()===true) +{hatchLineShape.set_Fillstyle(hatch);hatchLineShape.setShape(armyc2.c2sd.JavaLineArray.lineutility.createStrokedShape(shape.getShape()));return hatchLineShape;} +width*=2;height*=2;var horizLimit=0;var vertLimit=0;var j=0;var vertPts=new java.util.ArrayList();var horizPts=new java.util.ArrayList();var vertPt=null;var horizPt=null;if(hatch===armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE.Hatch_BackwardDiagonal){horizLimit=Math.floor((width/20.0));vertLimit=Math.floor((height/20.0));for(j=0;j1) +return true;}catch(exc){if(Clazz.instanceOf(exc)){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"segmentColorsSet",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside segmentColorsSet",exc));}else{throw exc;}} +return false;},setPoint2D:function(){var pt2d=new armyc2.c2sd.graphics2d.Point2D();if(arguments.length===1) +{pt2d.x=arguments[0].x;pt2d.y=arguments[0].y;} +else if(arguments.length===2) +{pt2d.x=arguments[0];pt2d.y=arguments[1];} +return pt2d;},setLine2D:function() +{var line=new armyc2.c2sd.graphics2d.Line2D();if(arguments.length===1) +{var line1=arguments[0];line.x1=line1.x1;line.y1=line1.y1;line.x2=line1.x2;line.y2=line1.y2;} +else if(arguments.length===2) +{var pt1=arguments[0];var pt2=arguments[1];line.x1=pt1.x;line.y1=pt1.y;line.x2=pt2.x;line.y2=pt2.y;} +else if(arguments.length===4) +{var x1=arguments[0];var y1=arguments[1];var x2=arguments[2];var y2=arguments[3];line.x1=x1;line.y1=y1;line.x2=x2;line.y2=y2;} +return line;},getZoomFactor:function(rect,clipPoints,pixels) +{var factor=-1;try +{if(pixels===null||pixels.size()<2) +return factor;if(clipPoints===null&&rect===null) +return factor;var maxLengthPixels=0,maxLengthClipArea=0,temp=0;var j=0;var pt2d0=null,pt2d1=null,pt0=null,pt1=null;for(j=0;jmaxLengthPixels) +maxLengthPixels=temp;} +temp=0;if(clipPoints!==null) +{for(j=0;jmaxLengthClipArea) +maxLengthClipArea=temp;if(maxLengthPixels>0&&maxLengthClipArea>0) +factor=maxLengthClipArea/maxLengthPixels;} +catch(exc) +{if(Clazz.instanceOf(exc)) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException(armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsUtilityGE._className,"segmentColorsSet",new armyc2.c2sd.renderer.utilities.RendererException("Failed inside segmentColorsSet",exc));} +else +{throw exc;}} +return factor;},_className:"clsUtilityGE",Hatch_ForwardDiagonal:2,Hatch_BackwardDiagonal:3,Hatch_Vertical:4,Hatch_Horizontal:5,Hatch_Cross:8};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.TacticalGraphicIconRenderer=(function(){var fontSizeForTGIcons=60;return{getIcon:function(symbolID,size,color,alpha,symStd){var id=symbolID;if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isWeather(symbolID)===true) +{color=armyc2.c2sd.renderer.utilities.SymbolUtilities.getFillColorOfWeather(symbolID);if(color) +color=color.toHexString(false);if(color===null) +color=armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfWeather(symbolID).toHexString(false);} +else if(color===null) +{color=armyc2.c2sd.renderer.utilities.SymbolUtilities.getLineColorOfAffiliation(symbolID).toHexString(false);} +if(color.toHexString) +color=color.toHexString(false);var charSymbolIndex=armyc2.c2sd.renderer.utilities.TacticalGraphicLookup.getCharCodeFromSymbol(id,symStd);if(charSymbolIndex>=0) +{var fontSize=fontSizeForTGIcons;var ratio=size/40.0;var strSymbol=String.fromCharCode(charSymbolIndex);var pixel=new armyc2.c2sd.renderer.so.Point(0,0);if(ratio>0) +{fontSize=fontSize*ratio;} +fontSize=(fontSize/96*72);var buffer=this.createBuffer(size,size),ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=5;ctx.fillStyle=color;ctx.font=fontSize+"pt TacticalGraphics";if(alpha<1.0) +ctx.globalAlpha=alpha;var x=Math.round(size/2),y=Math.round(size/2);ctx.fillText(strSymbol,x,y);var centerPoint=new armyc2.c2sd.renderer.so.Point(x,y),symbolBounds=new armyc2.c2sd.renderer.so.Rectangle(0,0,size,size),imageBounds=symbolBounds.clone();var ii=new armyc2.c2sd.renderer.utilities.ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);return ii;}},createBuffer:function(width,height) +{var buffer=document.createElement('canvas');buffer.width=width;buffer.height=height;return buffer;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.SinglePointRenderer=(function(){var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,UnitFontLookup=armyc2.c2sd.renderer.utilities.UnitFontLookup,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,SO=armyc2.c2sd.renderer.so,RendererUtilities=armyc2.c2sd.renderer.utilities.RendererUtilities,TextInfo=armyc2.c2sd.renderer.utilities.TextInfo,ImageInfo=armyc2.c2sd.renderer.utilities.ImageInfo,MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes,SymbolDimensions=armyc2.c2sd.renderer.utilities.SymbolDimensions,ModifiersUnits=armyc2.c2sd.renderer.utilities.ModifiersUnits,ModifiersTG=armyc2.c2sd.renderer.utilities.ModifiersTG,SinglePointLookup=armyc2.c2sd.renderer.utilities.SinglePointLookup,SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable;var textInfoBuffer=null,textInfoContext=null,textInfoContextFont=null,_bufferUnit=null,_bufferUnitSize=150,_bufferSymbol=null,_bufferSymbolSize=150,_bufferDisplayModifiers=null,_document=document;var _statusColorMap={"C":"#00FF00","D":"#FFFF00","X":"#FF0000","F":"#0000FF"},_unitTextModifierKeys=["B","C","F","G","H","H1","H2","J","K","L","M","N","P","R2","T","T1","V","W","W1","X","Y","Z","AC","AD","AE","AF","CN"],_tgTextModifierKeys=["B","C","F","G","H","H1","H2","N","T","T1","V","W","W1","X","Y","AM","AN","Length","Width","Radius","Angle"];return{checkModifierFont:function() +{if(textInfoBuffer===null) +textInfoBuffer=this.createBuffer(1,1);if(textInfoContext===null&&textInfoBuffer.getContext!==undefined) +{textInfoContext=textInfoBuffer.getContext('2d');textInfoContext.lineCap="butt";textInfoContext.lineJoin="miter";textInfoContext.miterLimit=3;} +else if(!(textInfoContext)) +{textInfoContext={};} +if(textInfoContextFont!==RendererSettings.getModifierFont()) +{textInfoContextFont=RendererSettings.getModifierFont();textInfoContext.font=textInfoContextFont;}},renderUnit:function(symbolID,modifiers) +{var render=true;if(modifiers["RENDER"]!==undefined) +render=modifiers["RENDER"];var buffer=null,ctx=null;if(render&&_bufferUnit===null) +{_bufferUnit=this.createBuffer(_bufferUnitSize,_bufferUnitSize);ctx=_bufferUnit.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;ctx=null;} +if(modifiers===undefined||modifiers===null) +modifiers={};var pixel=null,basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID),symStd=modifiers[MilStdAttributes.SymbologyStandard],ufli=UnitFontLookup.getUnitLookup(basicID,symStd),strUnitFont="";var intFill=UnitFontLookup.getFillCode(symbolID,symStd),intFrame=UnitFontLookup.getFrameCode(symbolID,intFill,symStd),fillColor=SymbolUtilities.getFillColorOfAffiliation(symbolID).toHexString(false),lineColor=SymbolUtilities.getLineColorOfAffiliation(symbolID).toHexString(false),fill=(intFill>0)?String.fromCharCode(intFill):null,frame=(intFrame>0)?String.fromCharCode(intFrame):null,mapping1=ufli.getMapping1(symbolID),mapping2=ufli.getMapping2(),symbol1=(mapping1!==null)?String.fromCharCode(mapping1):null,symbol2=(mapping2!==null)?String.fromCharCode(mapping2):null,color1=ufli.getColor1(),color2=ufli.getColor2(),alpha=1.0,lineAlpha=1.0,fillAlpha=1.0;var hasDisplayModifiers=false;var hasTextModifiers=false;var intFrameAssume=-1,frameAssume=null;if(render===false) +ctx={};if(symStd>RendererSettings.Symbology_2525B) +{var affiliation=symbolID.charAt(1);switch(affiliation) +{case'P':case'A':case'S':case'G':case'M':if(symbolID.charAt(2)==='U'&&(symbolID.substring(4,6)==="WM"||symbolID.substring(4,7)==="WDM")) +{if(symbolID.charAt(3)!=='A') +{intFill++;fill=String.fromCharCode(intFill);} +intFrameAssume=intFill-1;intFrame=-1;frame=null;} +else +{intFrame=intFill+2;intFrameAssume=intFill+1;frame=String.fromCharCode(intFrame);} +break;} +if(intFrameAssume>0) +frameAssume=String.fromCharCode(intFrameAssume);} +this.checkModifierFont();if(modifiers===undefined||modifiers===null) +modifiers={};var pixelSize=-1;if(modifiers[MilStdAttributes.PixelSize]) +{pixelSize=modifiers[MilStdAttributes.PixelSize];} +else +{pixelSize=RendererSettings.getDefaultPixelSize();} +var keepUnitRatio=true;if(modifiers[MilStdAttributes.KeepUnitRatio]!==undefined) +{keepUnitRatio=modifiers[MilStdAttributes.KeepUnitRatio];} +var icon=false;if(modifiers[MilStdAttributes.Icon]!==undefined) +{icon=modifiers[MilStdAttributes.Icon];} +if(icon) +{keepUnitRatio=false;hasDisplayModifiers=false;hasTextModifiers=false;symbolID=symbolID.substring(0,10)+"-----";} +else +{hasDisplayModifiers=this.hasDisplayModifiers(symbolID,modifiers);hasTextModifiers=this.hasTextModifiers(symbolID,modifiers);} +if(modifiers[MilStdAttributes.LineColor]!==undefined) +{lineColor=modifiers[MilStdAttributes.LineColor];lineColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString(lineColor);lineAlpha=lineColor.getAlpha()/255.0;lineColor=lineColor.toHexString(false);} +if(modifiers[MilStdAttributes.FillColor]!==undefined) +{fillColor=modifiers[MilStdAttributes.FillColor];fillColor=armyc2.c2sd.renderer.utilities.Color.getColorFromHexString(fillColor);fillAlpha=fillColor.getAlpha()/255.0;fillColor=fillColor.toHexString(false);} +if(modifiers[MilStdAttributes.Alpha]!==undefined) +{alpha=modifiers[MilStdAttributes.Alpha]/255.0;if(alpha!==1) +{lineAlpha=alpha;fillAlpha=alpha;}} +if(modifiers[MilStdAttributes.IconColor]!==undefined) +{color1=modifiers[MilStdAttributes.IconColor];} +if(symbolID.charAt(2)==='U'&&symbolID.substring(4,6)==="WM") +{if(symStd===RendererSettings.Symbology_2525B) +{if(modifiers[MilStdAttributes.LineColor]!==undefined) +{color1=lineColor;}} +else if(symStd===RendererSettings.Symbology_2525C) +{if(modifiers[MilStdAttributes.LineColor]!==undefined) +{fillColor=lineColor;}}} +else if(symbolID.charAt(2)==='S'&&symbolID.charAt(4)==='O') +{if(modifiers[MilStdAttributes.LineColor]!==undefined) +{fillColor=modifiers[MilStdAttributes.LineColor];}} +var symbolBounds=SymbolDimensions.getUnitBounds(intFill,50);var rect=SymbolDimensions.getUnitBounds(intFill,50);if(pixelSize>0&&keepUnitRatio===true) +{var heightRatio=UnitFontLookup.getUnitRatioHeight(intFill),widthRatio=UnitFontLookup.getUnitRatioWidth(intFill);var ratio=-1;if(heightRatio>widthRatio) +{pixelSize=(pixelSize/1.5)*heightRatio;} +else +{pixelSize=(pixelSize/1.5)*widthRatio;}} +if(pixelSize>0) +{ratio=Math.min((pixelSize/rect.getHeight()),(pixelSize/rect.getWidth()));var fontsize=50;fontsize=(((fontsize*ratio)/96)*72);strUnitFont=fontsize+"pt UnitFont";symbolBounds=SymbolDimensions.getUnitBounds(intFill,(50*ratio));} +else +{strUnitFont=150+"pt UnitFont";} +var symbolWidth=Math.round(symbolBounds.getWidth()),symbolHeight=Math.round(symbolBounds.getHeight());if(render===true) +{if((hasDisplayModifiers===true||hasTextModifiers===true)&&symbolWidth<_bufferUnitSize&&symbolHeight<_bufferUnitSize) +{buffer=_bufferUnit;ctx=buffer.getContext('2d');ctx.clearRect(0,0,_bufferUnitSize,_bufferUnitSize);if(ctx.globalAlpha<1.0) +ctx.globalAlpha=1.0;} +else +{buffer=this.createBuffer(symbolWidth,symbolHeight);ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;} +ctx.font=strUnitFont;} +var x=Math.round(symbolBounds.getWidth()/2),y=Math.round((symbolBounds.getHeight()/2)+symbolBounds.getY());if(render===true) +{if(color1==="") +{color1="#000000";} +var currentAlpha=1;if(frameAssume!==null&&frameAssume!==""&&intFrame===-1) +{if(lineAlpha!==1) +{ctx.globalAlpha=lineAlpha;currentAlpha=lineAlpha;} +ctx.fillStyle="#ffffff";ctx.fillText(frameAssume,x,y);frameAssume=null;} +if(fill!==null&&fill!=="") +{if(currentAlpha!==fillAlpha) +{ctx.globalAlpha=fillAlpha;currentAlpha=fillAlpha;} +ctx.fillStyle=fillColor;ctx.fillText(fill,x,y);} +if(currentAlpha!==lineAlpha) +{ctx.globalAlpha=lineAlpha;currentAlpha=lineAlpha;} +if(frameAssume!==null&&frameAssume!=="") +{if(lineAlpha!==fillAlpha) +ctx.globalAlpha=lineAlpha;ctx.fillStyle="#ffffff";ctx.fillText(frameAssume,x,y);} +if(frame!==null&&frame!=="") +{ctx.fillStyle=lineColor;ctx.fillText(frame,x,y);} +if(alpha!==1&¤tAlpha!==alpha) +{ctx.globalAlpha=alpha;currentAlpha=alpha;} +else if(alpha===1&¤tAlpha!==1) +{ctx.globalAlpha=1;currentAlpha=1;} +if(symbol2!==null&&symbol2!=="") +{ctx.fillStyle=color2;ctx.fillText(symbol2,x,y);} +if(symbol1!==null&&symbol1!=="") +{ctx.fillStyle=color1;ctx.fillText(symbol1,x,y);}} +symbolBounds.setLocation(0,0);var imageBounds=new SO.Rectangle(0,0,symbolWidth,symbolHeight);var centerPoint=new SO.Point(x,y);var ii=new ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);var iinew=null;if(hasDisplayModifiers===true) +iinew=this.processUnitDisplayModifiers(ii,symbolID,modifiers,hasTextModifiers);if(iinew!==null) +ii=iinew;iinew=null;if(hasTextModifiers===true) +iinew=this.processUnitModifiers(ii,symbolID,modifiers);if(iinew!==null) +ii=iinew;ctx=null;buffer=null;if(icon) +return ii.getSquareImageInfo();else +return ii;},processUnitDisplayModifiers:function(ii,symbolID,modifiers){var render=true;if(modifiers["RENDER"]!==undefined) +render=modifiers["RENDER"];var newii=null,symbolBounds=ii.getSymbolBounds(),imageBounds=ii.getImageBounds(),centerPoint=ii.getCenterPoint(),tiEchelon=null,echelonBounds=null,amBounds=null,buffer=null,ctx=null,offsetX=0,offsetY=0,hasOCMSlash=false,symStd=modifiers[MilStdAttributes.SymbologyStandard],lineColor=SymbolUtilities.getLineColorOfAffiliation(symbolID).toHexString(false);if(modifiers[MilStdAttributes.LineColor]!==undefined) +lineColor=modifiers[MilStdAttributes.LineColor];var mobilityBounds=null;var shapes=new Array();if(symbolID.charAt(10)===("M")||symbolID.charAt(10)===("N")) +{var x=0,y=0,centerX=0,bottomY=0,height=0,width=0,middleY=0,wheelOffset=1,wheelSize=5,rrHeight=5,rrArcWidth=8;var mobility=symbolID.substring(10,12);x=symbolBounds.getX()+1;y=symbolBounds.getY();height=Math.round(symbolBounds.getHeight());width=Math.round(symbolBounds.getWidth())-1;bottomY=y+height+2;if(symbolID.charAt(10)===("M")&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.R_MOBILITY_INDICATOR)){wheelSize=width/7;rrHeight=width/7;switch(mobility) +{case"MO":shapes.push(new SO.Line(x,bottomY,x+width,bottomY));shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));break;case"MP":var line=new SO.Line(x,bottomY,x+width,bottomY);shapes.push(line);shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+(width/2)-(wheelSize/2),bottomY+wheelOffset,wheelSize,wheelSize));break;case"MQ":shapes.push(new SO.RoundedRectangle(x,bottomY,width,rrHeight,rrArcWidth));break;case"MR":shapes.push(new SO.RoundedRectangle(x,bottomY,width,rrHeight,rrArcWidth));shapes.push(new SO.Ellipse(x-wheelSize-wheelSize,bottomY,wheelSize,wheelSize));break;case"MS":var line=new SO.Line(x+wheelSize,bottomY+(wheelSize/2),x+width-wheelSize,bottomY+(wheelSize/2));shapes.push(line);shapes.push(new SO.Ellipse(x,bottomY,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY,wheelSize,wheelSize));break;case"MT":var line=new SO.Line(x,bottomY,x+width,bottomY);shapes.push(line);shapes.push(new SO.Ellipse(x+wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));shapes.push(new SO.Ellipse(x+width-wheelSize-wheelSize,bottomY+wheelOffset,wheelSize,wheelSize));break;case"MU":var muPath=new SO.Path();muPath.moveTo(x,bottomY);muPath.lineTo(x+5,bottomY+5);muPath.lineTo(x+width,bottomY+5);shapes.push(muPath);break;case"MV":var path=new SO.Path();path.moveTo(x,bottomY);path.bezierCurveTo(x,bottomY,x-rrArcWidth,bottomY+3,x,bottomY+rrHeight);path.lineTo(x+width,bottomY+rrHeight);shapes.push(path);break;case"MW":centerX=Math.round(symbolBounds.getCenterX());var mwPath=new SO.Path();mwPath.moveTo(centerX,bottomY+rrHeight+2);mwPath.lineTo(centerX-3,bottomY);mwPath.lineTo(centerX-6,bottomY+rrHeight+2);mwPath.moveTo(centerX,bottomY+rrHeight+2);mwPath.lineTo(centerX+3,bottomY);mwPath.lineTo(centerX+6,bottomY+rrHeight+2);shapes.push(mwPath);break;case"MX":centerX=Math.round(symbolBounds.getCenterX());var line=new SO.Line(x+width,bottomY,x,bottomY);shapes.push(line);var quarterX=(centerX-x)/2;shapes.push(new SO.BCurve(x,bottomY,x+quarterX,bottomY+rrHeight,centerX+quarterX,bottomY+rrHeight,x+width,bottomY));break;case"MY":var incrementX=width/7,middleY=(bottomY+(rrHeight/2));var x=Math.round(x+(incrementX/2));var r=Math.round(incrementX/2);var path=new SO.Path();path.arc(x,middleY,r,180,0);path.arc(x+incrementX,middleY,r,180,0,true);path.arc(x+incrementX*2,middleY,r,180,0);path.arc(x+incrementX*3,middleY,r,180,0,true);path.arc(x+incrementX*4,middleY,r,180,0);path.arc(x+incrementX*5,middleY,r,180,0,true);path.arc(x+incrementX*6,middleY,r,180,0);shapes.push(path);break;default:break;}} +else if(symbolID.charAt(10)===("N")&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AG_AUX_EQUIP_INDICATOR)){var offsetY=1;centerX=symbolBounds.getCenterX();var squareOffset=Math.round(wheelSize/2);middleY=((rrHeight/2)+bottomY)+offsetY;if(symbolID.substring(10,12)===("NS")) +{shapes.push(new SO.Line(centerX-1,bottomY-1,centerX-1,bottomY+rrHeight+3));shapes.push(new SO.Line(x,middleY,x+width,middleY));shapes.push(new SO.Rectangle(x-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(Math.round(centerX-squareOffset),bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(x+width-squareOffset,bottomY+offsetY,5,5));} +else if(symbolID.substring(10,12)===("NL")) +{var leftX=x+(centerX-x)/2,rightX=centerX+(x+width-centerX)/2;shapes.push(new SO.Line(leftX,bottomY-1,leftX,bottomY+rrHeight+3));shapes.push(new SO.Line(rightX,bottomY-1,rightX,bottomY+rrHeight+3));shapes.push(new SO.Line(x,middleY,x+width,middleY));shapes.push(new SO.Rectangle(x-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(centerX-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(x+width-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(leftX-squareOffset,bottomY+offsetY,5,5));shapes.push(new SO.Rectangle(rightX-squareOffset,bottomY+offsetY,5,5));}} +if(shapes!==null&&shapes.length>0) +{mobilityBounds=shapes[0].getBounds();var size=shapes.length;var tempShape=null;for(var i=1;isymbolBounds.getX()+symbolBounds.getWidth()))) +{y=Math.round(symbolBounds.getY()-amOffset),x=echelonBounds.getX()+echelonBounds.getWidth();} +else +{y=Math.round(symbolBounds.getY()-amOffset),x=Math.round(symbolBounds.getX()+symbolBounds.getWidth());} +tiAM.setLocation(x,y);amBounds=tiAM.getTextOutlineBounds();amBounds.shift(0,-outlineOffset);tiAM.setLocation(x,y-outlineOffset);imageBounds.union(amBounds);} +var tfBounds=null,tfRectangle=null;if(SymbolUtilities.isTaskForce(symbolID)&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.D_TASK_FORCE_INDICATOR)) +{if(echelonBounds!==null) +{tfRectangle=new SO.Rectangle(echelonBounds.getX()-1,echelonBounds.getY()-1,echelonBounds.getWidth()+3,symbolBounds.getY()-(echelonBounds.getY()-1));tfBounds=new SO.Rectangle(echelonBounds.getX()-2,echelonBounds.getY()-2,echelonBounds.getWidth()+5,echelonBounds.getHeight()+4);} +else +{var height=Math.round(symbolBounds.getHeight()/4),width=Math.round(symbolBounds.getWidth()/3);tfRectangle=new SO.Rectangle(symbolBounds.getX()+width,symbolBounds.getY()-height,width,height);tfBounds=new SO.Rectangle(tfRectangle.getX()+-1,tfRectangle.getY()-1,tfRectangle.getWidth()+2,tfRectangle.getHeight()+2);} +imageBounds.union(tfBounds);} +var fdiBounds=null,fdiTop=null,fdiLeft=null,fdiRight=null;if((SymbolUtilities.isFeintDummy(symbolID)||SymbolUtilities.isFeintDummyInstallation(symbolID))&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AB_FEINT_DUMMY_INDICATOR)) +{fdiLeft=new SO.Point(symbolBounds.getX(),symbolBounds.getY());fdiRight=new SO.Point(symbolBounds.getX()+symbolBounds.getWidth(),symbolBounds.getY());var affiliation=symbolID.charAt(1);if(affiliation===("F")||affiliation===("A")||affiliation===("D")||affiliation===("M")||affiliation===("J")||affiliation===("K")) +{fdiTop=new SO.Point(Math.round(symbolBounds.getCenterX()),Math.round(symbolBounds.getY()-(symbolBounds.getHeight()*.75)));} +else +{fdiTop=new SO.Point(Math.round(symbolBounds.getCenterX()),Math.round(symbolBounds.getY()-(symbolBounds.getHeight()*.54)));} +fdiBounds=new SO.Rectangle(fdiLeft.getX(),fdiLeft.getY(),1,1);fdiBounds.unionPoint(fdiTop);fdiBounds.unionPoint(fdiRight);if(echelonBounds!==null) +{var shiftY=(symbolBounds.getY()-echelonBounds.getHeight()-2);fdiLeft.shift(0,shiftY);fdiTop.shift(0,shiftY);fdiRight.shift(0,shiftY);fdiBounds.shift(0,shiftY);} +imageBounds.union(fdiBounds);} +var instRectangle=null,instBounds=null;if(SymbolUtilities.hasInstallationModifier(symbolID)&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AC_INSTALLATION)) +{var affiliation=SymbolUtilities.getAffiliation(symbolID);if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K') +{height=Math.round(symbolBounds.getHeight()/4);width=Math.round(symbolBounds.getWidth()/3);} +else if(affiliation==='H'||affiliation==='S') +{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3*0.9);} +else if(affiliation==='N'||affiliation==='L') +{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} +else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') +{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} +else +{height=Math.round(symbolBounds.getHeight()/6);width=Math.round(symbolBounds.getWidth()/3);} +if(affiliation==='F'||affiliation==='A'||affiliation==='D'||affiliation==='M'||affiliation==='J'||affiliation==='K'||affiliation==='N'||affiliation==='L') +{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,symbolBounds.getY()-height,width,height);} +else if(affiliation==='H'||affiliation==='S') +{instRectangle=new SO.Rectangle(symbolBounds.getCenterX()-width/2,Math.round(symbolBounds.getY()-(height*0.15)),width,height);} +else if(affiliation==='P'||affiliation==='U'||affiliation==='G'||affiliation==='W') +{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,Math.round(symbolBounds.getY()-(height*0.3)),width,height);} +else +{instRectangle=new SO.Rectangle(symbolBounds.getX()+width,Math.round(symbolBounds.getY()-(height*0.3)),width,height);} +instBounds=new SO.Rectangle(instRectangle.getX()+-1,instRectangle.getY()-1,instRectangle.getWidth()+2,instRectangle.getWidth()+2);imageBounds.union(instBounds);} +var domPoints=null,domBounds=null;if(modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT]&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.Q_DIRECTION_OF_MOVEMENT)) +{var q=modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT];var isY=(modifiers[ModifiersUnits.Y_LOCATION]!==undefined);domPoints=this.createDOMArrowPoints(symbolID,symbolBounds,centerPoint,q,isY);domBounds=new SO.Rectangle(domPoints[0].getX(),domPoints[0].getY(),1,1);var temp=null;for(var i=1;i<6;i++) +{temp=domPoints[i];if(temp!==null) +domBounds.unionPoint(temp);} +imageBounds.union(domBounds);} +var hqBounds=null;if(SymbolUtilities.isHQ(symbolID)&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.S_HQ_STAFF_OR_OFFSET_INDICATOR)) +{var pt1HQ=null,pt2HQ=null,affiliation=symbolID.charAt(1);if(affiliation===("F")||affiliation===("A")||affiliation===("D")||affiliation===("M")||affiliation===("J")||affiliation===("K")||affiliation===("N")||affiliation===("L")) +{pt1HQ=new SO.Point(symbolBounds.getX()+1,symbolBounds.getY()+symbolBounds.getHeight());pt2HQ=new SO.Point(pt1HQ.getX(),pt1HQ.getY()+symbolBounds.getHeight());} +else +{pt1HQ=new SO.Point(symbolBounds.getX()+1,symbolBounds.getY()+(symbolBounds.getHeight()/2));pt2HQ=new SO.Point(pt1HQ.getX(),pt1HQ.getY()+symbolBounds.getHeight());} +hqBounds=new SO.Rectangle(pt1HQ.getX(),pt1HQ.getY(),2,pt2HQ.getY()-pt1HQ.getY());imageBounds.union(hqBounds);centerPoint.setLocation(pt2HQ.getX(),pt2HQ.getY());} +var ociBounds=null;var ociOffset=2;if(mobilityBounds!==null) +{ociOffset=Math.round(mobilityBounds.bottom-symbolBounds.bottom)+2;} +var ociShape=this.processOperationalConditionIndicator(symbolID,symbolBounds,ociOffset);if(ociShape!==null) +{ociBounds=ociShape.getBounds();} +imageBounds.union(ociBounds);if(imageBounds.getX()<0||imageBounds.getY()<0) +{var shiftX=Math.abs(imageBounds.getX()),shiftY=Math.abs(imageBounds.getY());if(hqBounds!==null) +{pt1HQ.shift(shiftX,shiftY);pt2HQ.shift(shiftX,shiftY);} +if(echelonBounds!==null) +{tiEchelon.setLocation(tiEchelon.getLocation().getX()+shiftX,tiEchelon.getLocation().getY()+shiftY);} +if(amBounds) +{tiAM.setLocation(tiAM.getLocation().getX()+shiftX,tiAM.getLocation().getY()+shiftY);} +if(tfBounds!==null) +{tfRectangle.shift(shiftX,shiftY);tfBounds.shift(shiftX,shiftY);} +if(instBounds!==null) +{instRectangle.shift(shiftX,shiftY);instBounds.shift(shiftX,shiftY);} +if(fdiBounds!==null) +{fdiBounds.shift(shiftX,shiftY);fdiLeft.shift(shiftX,shiftY);fdiTop.shift(shiftX,shiftY);fdiRight.shift(shiftX,shiftY);} +if(ociBounds!==null) +{ociBounds.shift(shiftX,shiftY);ociShape.shift(shiftX,shiftY);} +if(domBounds!==null) +{for(var i=0;i<6;i++) +{temp=domPoints[i];if(temp!==null) +temp.shift(shiftX,shiftY);} +domBounds.shift(shiftX,shiftY);} +if(mobilityBounds!==null) +{var size=shapes.length;var tempShape=null;for(var i=0;i19) +{ctx.setLineDash([6,4]);} +else +{ctx.setLineDash([5,3]);} +ctx.lineCap="butt";ctx.lineJoin="miter";ctx.strokeStyle=lineColor;ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(fdiLeft.getX(),fdiLeft.getY());ctx.lineTo(fdiTop.getX(),fdiTop.getY());ctx.lineTo(fdiRight.getX(),fdiRight.getY());ctx.stroke();ctx.setLineDash(oldDash);fdiBounds=null;} +if(mobilityBounds!==null) +{if(symbolID.charAt(10)===("M")) +{ctx.lineWidth=2;ctx.strokeStyle=lineColor;ctx.fillStyle=lineColor;} +else +{ctx.lineWidth=1;ctx.strokeStyle=lineColor;ctx.fillStyle=lineColor;} +var size=shapes.length;var tempShape=null;for(var i=0;i0) +barSize=Math.round(pixelSize/5);if(barSize<2) +barSize=2;offsetY+=Math.round(symbolBounds.getY()+symbolBounds.getHeight());bar=new SO.Rectangle(symbolBounds.getX()+1,offsetY,Math.round(symbolBounds.getWidth())-2,barSize);} +return bar;} +else if(status==='D'||status==='X') +{var fillCode=UnitFontLookup.getFillCode(symbolID,RendererSettings.Symbology_2525C) +var widthRatio=UnitFontLookup.getUnitRatioWidth(fillCode);var heightRatio=UnitFontLookup.getUnitRatioHeight(fillCode);var slashHeight=symbolBounds.getHeight()/heightRatio*1.47;var slashWidth=symbolBounds.getWidth()/widthRatio*0.85;var centerX=symbolBounds.getCenterX();var centerY=symbolBounds.getCenterY();var path=new SO.Path();if(status==='D') +{path.moveTo(centerX-(slashWidth/2),centerY+(slashHeight/2));path.lineTo(centerX+(slashWidth/2),centerY-(slashHeight/2));} +else if(status==='X') +{path.moveTo(centerX-(slashWidth/2),centerY+(slashHeight/2));path.lineTo(centerX+(slashWidth/2),centerY-(slashHeight/2));path.moveTo(centerX-(slashWidth/2),centerY-(slashHeight/2));path.lineTo(centerX+(slashWidth/2),centerY+(slashHeight/2));} +return path;} +return null;},processUnitModifiers:function(ii,symbolID,modifiers){var render=true;if(modifiers["RENDER"]!==undefined) +render=modifiers["RENDER"];var bufferXL=5,bufferXR=5,bufferY=2,bufferText=2,x=0,y=0,cpofNameX=0,newii=null;var tiArray=new Array(),descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj"),bounds=null,labelBounds=null,labelWidth,labelHeight;var bounds=ii.getSymbolBounds().clone(),symbolBounds=ii.getSymbolBounds().clone(),centerPoint=ii.getCenterPoint(),imageBounds=ii.getImageBounds().clone(),imageBoundsOld=ii.getImageBounds().clone();var echelon=SymbolUtilities.getEchelon(symbolID),echelonText=SymbolUtilities.getEchelonText(echelon),amText=SymbolUtilities.getUnitAffiliationModifier(symbolID,symStd);var textColor=null,textBackgroundColor=null;if(modifiers[ModifiersUnits.Q_DIRECTION_OF_MOVEMENT]&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.Q_DIRECTION_OF_MOVEMENT)) +{bounds=new SO.Rectangle(imageBounds.getX(),symbolBounds.getY(),imageBounds.getWidth(),symbolBounds.getHeight());} +else +{if(echelonText!==null||amText!==null) +{bounds=new SO.Rectangle(imageBounds.getX(),bounds.getY(),imageBounds.getWidth(),bounds.getHeight());} +else if(symbolID.substring(10,12)==="MR") +{x=-(Math.round((symbolBounds.getWidth()-1)/7)*2);if(xmaxHeight) +byLabelHeight=true;var symStd=modifiers[MilStdAttributes.SymbologyStandard];var affiliationModifier=null;if(RendererSettings.getDrawAffiliationModifierAsLabel()) +{affiliationModifier=SymbolUtilities.getUnitAffiliationModifier(symbolID,symStd);} +if(affiliationModifier!==null) +{modifiers[ModifiersUnits.E_FRAME_SHAPE_MODIFIER]=affiliationModifier;} +if(RendererSettings.getDrawCountryCode()&&SymbolUtilities.hasValidCountryCode(symbolID)) +{modifiers[ModifiersUnits.CC_COUNTRY_CODE]=symbolID.substring(12,14);} +var modifierValue=null;var tiTemp=null;if(modifiers.C&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.C_QUANTITY)) +{var text=modifiers[ModifiersUnits.C_QUANTITY];tiTemp=new TextInfo(text,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=Math.round((symbolBounds.x+(symbolBounds.width*0.5))-(labelWidth*0.5));y=Math.round(symbolBounds.y-bufferY-descent);tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.X||modifiers.Y) +{modifierValue=null;var xm=null,ym=null;if(modifiers.X&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.X_ALTITUDE_DEPTH)) +xm=modifiers.X;else +xm=null;if(modifiers.Y) +ym=modifiers.Y;if(xm===null&&ym!==null) +modifierValue=ym;else if(xm!==null&&ym===null) +modifierValue=xm;else if(xm!==null&&ym!==null) +modifierValue=xm+" "+ym;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) +{x=bounds.x-labelBounds.width-bufferXL;y=bounds.y+labelHeight-descent;} +else +{x=bounds.x-labelBounds.width-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText));y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.G&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.G_STAFF_COMMENTS)) +{modifierValue=modifiers.G;tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) +{x=bounds.x+bounds.width+bufferXR;y=bounds.y+labelHeight-descent;} +else +{x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText));y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) +cpofNameX=x+labelWidth+3;} +if(modifiers.V||modifiers.AD||modifiers.AE) +{var vm="";var adm="";var aem="";if(modifiers.V&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.V_EQUIP_TYPE)) +vm=modifiers.V;if(modifiers.AD&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AD_PLATFORM_TYPE)) +adm=modifiers.AD;if(modifiers.AE&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AE_EQUIPMENT_TEARDOWN_TIME)) +aem=modifiers.AE;modifierValue=vm+" "+adm+" "+aem;modifierValue=modifierValue.trim();tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x-labelBounds.width-bufferXL;y=(bounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.H||modifiers.AF) +{var hm="";var afm="";if(modifiers.H) +hm=modifiers.H;if(modifiers.AF&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AF_COMMON_IDENTIFIER)) +afm=modifiers.AF;modifierValue=hm+" "+afm;modifierValue=modifierValue.trim();tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) +cpofNameX=x+labelWidth+3;} +if(modifiers.T) +{modifierValue=modifiers[ModifiersUnits.T_UNIQUE_DESIGNATION_1];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) +{x=bounds.x-labelWidth-bufferXL;y=bounds.y+bounds.height;} +else +{x=bounds.x-labelWidth-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText));y=bounds.y+y;} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.M||modifiers.CC) +{modifierValue="";if(modifiers[ModifiersUnits.M_HIGHER_FORMATION]&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.M_HIGHER_FORMATION)) +modifierValue+=modifiers[ModifiersUnits.M_HIGHER_FORMATION];if(modifiers[ModifiersUnits.CC_COUNTRY_CODE]) +{if(modifiers[ModifiersUnits.M_HIGHER_FORMATION]) +modifierValue+=" ";modifierValue+=modifiers[ModifiersUnits.CC_COUNTRY_CODE];} +tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) +y=bounds.y+bounds.height;else +{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText));y=bounds.y+y;} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) +cpofNameX=x+labelWidth+3;} +if(modifiers.Z&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.Z_SPEED)) +{modifierValue=modifiers[ModifiersUnits.Z_SPEED];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) +y=Math.round(bounds.y+bounds.height+labelHeight+bufferText);else +{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.J||modifiers.K||modifiers.L||modifiers.N||modifiers.P) +{modifierValue=null;var jm=null,km=null,lm=null,nm=null,pm=null;if(modifiers.J) +jm=modifiers[ModifiersUnits.J_EVALUATION_RATING];if(modifiers.K&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.K_COMBAT_EFFECTIVENESS)) +km=modifiers[ModifiersUnits.K_COMBAT_EFFECTIVENESS];if(modifiers.L&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.L_SIGNATURE_EQUIP)) +lm=modifiers[ModifiersUnits.L_SIGNATURE_EQUIP];if(modifiers.N&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.N_HOSTILE)) +nm=modifiers[ModifiersUnits.N_HOSTILE];if(modifiers.P&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.P_IFF_SIF)) +pm=modifiers[ModifiersUnits.P_IFF_SIF];modifierValue="";if(jm!==null&&jm!==("")) +modifierValue=modifierValue+jm;if(km!==null&&km!==("")) +modifierValue=modifierValue+" "+km;if(lm!==null&&lm!==("")) +modifierValue=modifierValue+" "+lm;if(nm!==null&&nm!==("")) +modifierValue=modifierValue+" "+nm;if(pm!==null&&pm!==("")) +modifierValue=modifierValue+" "+pm;if(modifierValue.charAt(0)===" ") +modifierValue=modifierValue.substring(1);tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) +y=Math.round(bounds.y+bounds.height+labelHeight+bufferText);else +{y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y+((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) +cpofNameX=x+labelWidth+3;} +if(modifiers.W) +{modifierValue=modifiers[ModifiersUnits.W_DTG_1];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) +{x=bounds.x-labelWidth-bufferXL;y=bounds.y-bufferY-descent;} +else +{x=bounds.x-labelWidth-bufferXL;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if((modifiers.F&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.F_REINFORCED_REDUCED))||modifiers.E) +{modifierValue=null;var E=null,F=null;if(modifiers.E) +E=modifiers[ModifiersUnits.E_FRAME_SHAPE_MODIFIER];if(modifiers.F&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.F_REINFORCED_REDUCED)) +F=modifiers[ModifiersUnits.F_REINFORCED_REDUCED];if(E!==null&&E!==("")) +modifierValue=E;if(F!==null&&F!==("")) +{if(F.toUpperCase()===("R")) +F="(+)";else if(F.toUpperCase()===("D")) +F="(-)";else if(F.toUpperCase()===("RD")) +F="("+String.fromCharCode(177)+")";} +if(F!==null&&F!==("")) +{if(modifierValue!==null&&modifierValue!==("")) +modifierValue=modifierValue+" "+F;else +modifierValue=F;} +tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();if(!byLabelHeight) +{x=bounds.x+bounds.width+bufferXR;y=bounds.y-bufferY-descent;} +else +{x=bounds.x+bounds.width+bufferXR;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=y-((labelHeight+bufferText)*2);y=Math.round(bounds.y+y);} +tiTemp.setLocation(x,y);tiArray.push(tiTemp);if((x+labelWidth+3)>cpofNameX) +cpofNameX=x+labelWidth+3;} +if(modifiers.AA&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.AA_SPECIAL_C2_HQ)) +{modifierValue=modifiers[ModifiersUnits.AA_SPECIAL_C2_HQ];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=(symbolBounds.x+(symbolBounds.width*0.5))-(labelWidth*0.5);y=(symbolBounds.height);y=((y*0.5)+((labelHeight-descent)*0.5));y=symbolBounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.CN) +{modifierValue=modifiers[ModifiersUnits.CN_CPOF_NAME_LABEL];tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=cpofNameX;y=(bounds.height);y=((y*0.5)+(labelHeight*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);} +if(modifiers.SCC&&SymbolUtilities.canUnitHaveModifier(symbolID,ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE)) +{modifierValue=modifiers[ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE];var scc=0;if(SymbolUtilities.isNumber(modifierValue)&&SymbolUtilities.hasModifier(symbolID,ModifiersUnits.SCC_SONAR_CLASSIFICATION_CONFIDENCE)) +{scc=parseInt(modifierValue);if(scc>0&&scc<6) +{var yPosition=this.getYPositionForSCC(symbolID);tiTemp=new TextInfo(modifierValue,0,0,textInfoContext,textInfoContextFont);labelBounds=tiTemp.getTextBounds();labelWidth=labelBounds.getWidth();x=(bounds.x+(bounds.width*0.5))-(labelWidth*0.5);y=(bounds.height);y=((y*yPosition)+((labelHeight-descent)*0.5));y=bounds.y+y;tiTemp.setLocation(x,y);tiArray.push(tiTemp);}}} +var modifierBounds=null;if(tiArray!==null&&tiArray.length>0) +{modifierBounds=tiArray[0].getTextOutlineBounds();var size=tiArray.length;var tempShape=null;for(var i=1;i2) +outlineOffset=(outlineOffset-1)/2;else +outlineOffset=0;var spli=SinglePointLookup.getSPLookupInfo(symbolID,symStd);if(spli===null) +{if(modifiers===null) +modifiers={};if(modifiers.H!==undefined) +modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2]=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];modifiers[ModifiersTG.H_ADDITIONAL_INFO_1]=symbolID.substring(0,10);symbolID="G"+SymbolUtilities.getAffiliation(symbolID)+"G"+SymbolUtilities.getStatus(symbolID)+"GPP---****X";spli=SinglePointLookup.getSPLookupInfo(symbolID,symStd);} +var symbolBounds=null,rect=null;var ratio=1;if(pixelSize>0) +{symbolBounds=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);rect=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);if(keepUnitRatio===true) +{if(fontSize===80) +{scale=pixelSize/35.0;} +else if(fontSize===60) +{scale=pixelSize/35.0;} +else if(fontSize===100) +{scale=pixelSize/35.0;} +else if(fontSize===120) +{scale=pixelSize/35.0;} +else +{scale=pixelSize/35.0;}} +ratio=Math.min((pixelSize/rect.getHeight()),(pixelSize/rect.getWidth()));} +if(scale!==-999) +{ratio=scale;} +if(ratio>0) +{fontSize=fontSize*ratio;} +symbolBounds=SymbolDimensions.getSymbolBounds(symbolID,symStd,fontSize);fontSize=(((fontSize)/96)*72);strSPFont=fontSize+"pt SinglePoint";this.checkModifierFont();intFrame=SinglePointLookup.getCharCodeFromSymbol(symbolID,symStd);var fillID=null;if(SymbolUtilities.hasDefaultFill(symbolID)&&fillColor===null) +{fillColor=SymbolUtilities.getFillColorOfAffiliation(symbolID).toHexString(false);} +if(SymbolUtilities.isTGSPWithFill(symbolID)) +{fillID=SymbolUtilities.getTGFillSymbolCode(symbolID);if(fillID!==null) +intFill=SinglePointLookup.getCharCodeFromSymbol(fillID,symStd);} +else if(SymbolUtilities.isWeatherSPWithFill(symbolID)) +{intFill=intFrame+1;fillColor=SymbolUtilities.getFillColorOfWeather(symbolID).toHexString(false);} +if(intFill>0) +fill=String.fromCharCode(intFill);frame=String.fromCharCode(intFrame);var symbolWidth=Math.round(symbolBounds.getWidth())+(outlineOffset*2),symbolHeight=Math.round(symbolBounds.getHeight())+(outlineOffset*2);var imageBounds=new SO.Rectangle(0,0,symbolWidth,symbolHeight);if(render===true) +{if((hasDisplayModifiers===true||hasTextModifiers===true)&&symbolWidth<_bufferSymbolSize&&symbolHeight<_bufferSymbolSize) +{buffer=_bufferSymbol;ctx=buffer.getContext('2d');ctx.clearRect(0,0,_bufferSymbolSize,_bufferSymbolSize);if(ctx.globalAlpha<1.0) +ctx.globalAlpha=1.0;} +else +{buffer=this.createBuffer(symbolWidth,symbolHeight);ctx=buffer.getContext('2d');ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;} +ctx.font=strSPFont;} +var x=Math.round(symbolBounds.getWidth()/2),y=Math.round(symbolBounds.getHeight()/2);var centerPoint=SymbolDimensions.getSymbolCenter(symbolID,symbolBounds);x=centerPoint.getX();y=centerPoint.getY();if(outlineOffset>0) +{centerPoint.shift(outlineOffset,outlineOffset);x+=outlineOffset;y+=outlineOffset;symbolBounds.shift(outlineOffset,outlineOffset);symbolBounds.grow(outlineOffset);} +if(render===true) +{var currentAlpha=1;if(fill!==null&&fill!==""&&fillColor!==null) +{if(fillAlpha!==currentAlpha) +{ctx.globalAlpha=fillAlpha;currentAlpha=fillAlpha;} +ctx.fillStyle=fillColor;ctx.fillText(fill,x,y);} +if(frame!==null&&frame!=="") +{if(outlineOffset>0) +{if(lineAlpha!==currentAlpha) +{ctx.globalAlpha=lineAlpha;currentAlpha=lineAlpha;} +ctx.lineWidth=symbolOutlineWidth;ctx.strokeStyle=RendererUtilities.getIdealOutlineColor(lineColor,true);ctx.strokeText(frame,x,y);}} +if(frame!==null&&frame!=="") +{if(lineAlpha!==currentAlpha) +{ctx.globalAlpha=lineAlpha;currentAlpha=lineAlpha;} +ctx.fillStyle=lineColor;ctx.fillText(frame,x,y);}} +var ii=new ImageInfo(buffer,centerPoint,symbolBounds,imageBounds);var iiNew=null;if(icon===false&&(hasTextModifiers||hasDisplayModifiers||SymbolUtilities.isTGSPWithIntegralText(symbolID))) +{if(SymbolUtilities.isTGSPWithSpecialModifierLayout(symbolID)||SymbolUtilities.isTGSPWithIntegralText(symbolID)) +{iiNew=this.ProcessTGSPWithSpecialModifierLayout(ii,symbolID,modifiers,lineColor);} +else +{iiNew=this.ProcessTGSPModifiers(ii,symbolID,modifiers,lineColor);}} +if(iiNew) +ii=iiNew;ctx=null;buffer=null;if(icon) +return ii.getSquareImageInfo();else +return ii;},ProcessTGSPWithSpecialModifierLayout:function(ii,symbolID,modifiers,overrideColor){var render=true;if(modifiers["RENDER"]!==undefined) +render=modifiers["RENDER"];var bufferXL=6,bufferXR=4,bufferY=2,bufferText=2,centerOffset=1,x=0,y=0,x2=0,y2=0,symStd=modifiers[MilStdAttributes.SymbologyStandard],outlineOffset=RendererSettings.getTextOutlineWidth(),labelHeight=0,labelWidth=0,newii=null;var arrMods=new Array();var duplicate=false;var symbolBounds=ii.getSymbolBounds().clone(),bounds=ii.getSymbolBounds().clone(),imageBounds=ii.getImageBounds().clone(),centerPoint=ii.getCenterPoint().clone();var textColor=overrideColor,textBackgroundColor=null;centerPoint=new SO.Point(Math.round(ii.getCenterPoint().getX()),Math.round(ii.getCenterPoint().getY()));var byLabelHeight=false;labelHeight=RendererUtilities.measureTextHeight(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle()).fullHeight;labelHeight=Math.round(labelHeight);var maxHeight=(symbolBounds.getHeight());if((labelHeight*3)>maxHeight) +byLabelHeight=true;var descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj");var yForY=-1;var labelBounds1=null,labelBounds2=null,strText="",strText1="",strText2="",text1=null,text2=null;var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);if(outlineOffset>2) +outlineOffset=((outlineOffset-1)/2);else +outlineOffset=0;if(basicID===("G*G*GPRD--****X")) +{strText1="D";text1=new TextInfo(strText1,0,0,textInfoContext);labelBounds1=text1.getTextBounds();if(symStd===RendererSettings.Symbology_2525B) +{y=symbolBounds.getY()+symbolBounds.getHeight();x=symbolBounds.getX()-labelBounds1.getWidth()-bufferXL;text1.setLocation(Math.round(x),Math.round(y));} +else +{text1=null;}} +else if(basicID===("G*G*APU---****X")) +{strText1="PUP";text1=new TextInfo(strText1,0,0,textInfoContext);labelBounds1=text1.getTextBounds();y=symbolBounds.getCenterY()+((labelBounds1.getHeight()-descent)/2);x=symbolBounds.getX()+symbolBounds.getWidth()+bufferXR;text1.setLocation(Math.round(x),Math.round(y));} +else if(basicID===("G*M*NZ----****X")) +{} +else if(basicID===("G*M*NF----****X")) +{} +else if(basicID===("G*M*NEB---****X")) +{var offset=1;strText2="BIO";text2=new TextInfo(strText2,0,0,textInfoContext);labelBounds2=text2.getTextBounds();y2=symbolBounds.getCenterY()+((labelBounds2.getHeight()-descent)*0.5);x2=symbolBounds.getX()-labelBounds2.getWidth()-bufferXL;text2.setLocation(Math.round(x2),Math.round(y2-offset));} +else if(basicID===("G*M*NEC---****X")) +{var offset=1;strText2="CML";text2=new TextInfo(strText2,0,0,textInfoContext);labelBounds2=text2.getTextBounds();y2=symbolBounds.getCenterY()+((labelBounds2.getHeight()-descent)/2);x2=symbolBounds.getX()-labelBounds2.getWidth()-bufferXL;text2.setLocation(Math.round(x2),Math.round(y2-offset));} +if(text1!==null) +{arrMods.push(text1);} +if(text2!==null) +{arrMods.push(text2);} +var ti=null;if(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")) +{if((labelHeight*3)>bounds.getHeight()) +byLabelHeight=true;} +if(basicID===("G*G*GPPC--****X")||basicID===("G*G*GPPD--****X")) +{if(modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1]!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.4);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID==="G*G*GPH---****X") +{if(modifiers[ModifiersTG.H_ADDITIONAL_INFO_1]!==undefined) +{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*G*GPRI--****X")) +{if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.25);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*G*GPPW--****X")||basicID===("G*F*PCF---****X")) +{if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+(bounds.width*0.75);y=bounds.y+(bounds.height*0.5);y=y+((labelHeight-descent)*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*G*APP---****X")||basicID===("G*G*APC---****X")) +{if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);var labelWidth=ti.getTextBounds().getWidth();x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y+(((bounds.height*0.5)-labelHeight)/2)+labelHeight-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*G*DPT---****X")||basicID===("G*F*PTS---****X")||basicID===("G*F*PTN---****X")) +{if(modifiers.H!==undefined&&basicID===("G*F*PTS---****X")) +{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.getCenterX()+(bounds.width*0.15);y=bounds.y+(bounds.height*0.75);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.H1!==undefined&&basicID===("G*F*PTS---****X")) +{strText=modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.getCenterX()-(bounds.width*0.15);x=x-(labelWidth);y=bounds.y+(bounds.height*0.75);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.getCenterX()+(bounds.width*0.15);y=bounds.y+(bounds.height*0.25);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X")) +{if(modifiers.N!==undefined) +{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) +{y=bounds.y+bounds.height;} +else +{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+(labelHeight-descent+bufferText));} +ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.H!==undefined) +{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) +{y=bounds.y+labelHeight-descent;} +else +{y=bounds.y+((bounds.height*0.5)-((labelHeight-descent)*0.5)+(-descent-bufferText));} +ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.W!==undefined) +{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) +{y=bounds.y+labelHeight-descent;} +else +{y=bounds.y+((bounds.height*0.5)-((labelHeight-descent)*0.5)+(-descent-bufferText));} +ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.V!==undefined&&basicID===("G*M*NZ----****X")) +{strText=modifiers[ModifiersTG.V_EQUIP_TYPE];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5));ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;if(!byLabelHeight) +{y=bounds.y+bounds.height;} +else +{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+(labelHeight-descent+bufferText));} +ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.Y!==undefined) +{strText=modifiers[ModifiersTG.Y_LOCATION];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);if(!byLabelHeight) +{y=bounds.y+bounds.height+labelHeight-descent+bufferY;} +else +{y=bounds.y+((bounds.height*0.5)+((labelHeight-descent)*0.5)+((labelHeight+bufferText)*2)-descent);} +yForY=y+descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.C!==undefined) +{strText=modifiers[ModifiersTG.C_QUANTITY];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +else if(basicID===("G*M*OFS---****X")) +{if(modifiers.H!==undefined) +{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.W!==undefined) +{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height);y=y+(labelHeight);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +if(modifiers.N!==undefined) +{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);var ti2=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width)+bufferXR;duplicate=true;x2=bounds.x;x2=x2-labelWidth-bufferXL;y=bounds.y+(bounds.height*0.5);y=y+((labelHeight-descent)*0.5);y2=y;ti.setLocation(Math.round(x),Math.round(y));ti2.setLocation(Math.round(x2),Math.round(y2));arrMods.push(ti);arrMods.push(ti2);}} +else if(basicID.charAt(0)==='W') +{if(basicID===("WAS-WSF-LVP----")) +{strText="0"+String.fromCharCode(176)+":";if(modifiers.X!==undefined) +strText+=modifiers[ModifiersTG.X_ALTITUDE_DEPTH];else +strText+="X?";ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.4);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +else if(basicID===("WAS-WST-LVP----")) +{strText="X?";if(modifiers.X!==undefined) +strText=modifiers[ModifiersTG.X_ALTITUDE_DEPTH];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.4);y=y+(labelHeight*0.5);ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +else if(basicID===("WAS-PLT---P----")) +{strText="X?";if(modifiers.X) +strText=modifiers[ModifiersTG.X_ALTITUDE_DEPTH];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);} +else if(basicID===("WAS-PHT---P----")) +{strText="X?";if(modifiers.X) +strText=modifiers[ModifiersTG.X_ALTITUDE_DEPTH];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+(bounds.height*0.5);y=y+(((bounds.height*0.5)-labelHeight)/2)+labelHeight-descent;ti.setLocation(Math.round(x),Math.round(y));arrMods.push(ti);}} +var domPoints=null,domBounds=null;if(modifiers[ModifiersTG.Q_DIRECTION_OF_MOVEMENT]&&(basicID===("G*M*NZ----****X")||basicID===("G*M*NEB---****X")||basicID===("G*M*NEC---****X"))) +{var q=modifiers[ModifiersTG.Q_DIRECTION_OF_MOVEMENT];var tempBounds=bounds.clone();tempBounds.unionPoint(new SO.Point(bounds.getCenterX(),yForY));domPoints=this.createDOMArrowPoints(symbolID,tempBounds,ii.getCenterPoint(),q,false);domBounds=new SO.Rectangle(domPoints[0].getX(),domPoints[0].getY(),1,1);var temp=null;for(var i=1;i<6;i++) +{temp=domPoints[i];if(temp!==null) +domBounds.unionPoint(temp);} +imageBounds.union(domBounds);} +var modifierBounds=null;if(arrMods!==null&&arrMods.length>0) +{modifierBounds=arrMods[0].getTextOutlineBounds();var size=arrMods.length;var tempShape=null;for(var i=1;imaxHeight) +byLabelHeight=true;var descent=RendererUtilities.getFontDescent(RendererSettings.getModifierFontName(),RendererSettings.getModifierFontSize(),RendererSettings.getModifierFontStyle(),"TQgj");var yForY=-1;var labelBounds1=null,labelBounds2=null,strText="",strText1="",strText2="",text1=null,text2=null;var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);if(outlineOffset>2) +outlineOffset=((outlineOffset-1)/2);else +outlineOffset=0;var ti=null;{if(modifiers.N) +{strText=modifiers[ModifiersTG.N_HOSTILE];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;if(!byLabelHeight) +{y=((bounds.height/3)*2);y=bounds.y+y;} +else +{y=bounds.y+bounds.height;} +ti.setLocation(x,y);arrMods.push(ti);} +if(modifiers.H!==undefined) +{strText=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y-descent;ti.setLocation(x,y);arrMods.push(ti);} +if(modifiers.H1!==undefined) +{strText=modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=bounds.y+labelHeight+(bounds.height*0.2);ti.setLocation(x,y);arrMods.push(ti);} +if(modifiers.W!==undefined) +{strText=modifiers[ModifiersTG.W_DTG_1];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=bounds.y+labelHeight-descent;ti.setLocation(x,y);arrMods.push(ti);} +if(modifiers.W1!==undefined) +{strText=modifiers[ModifiersTG.W1_DTG_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x-labelWidth-bufferXL;y=((labelHeight-descent+bufferText)*2);y=bounds.y+y;ti.setLocation(x,y);arrMods.push(ti);} +if(modifiers.T!==undefined) +{strText=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];ti=new TextInfo(strText,0,0,textInfoContext);x=bounds.x+bounds.width+bufferXR;y=bounds.y+labelHeight-descent;ti.setLocation(x,y);arrMods.push(ti);} +if((modifiers.T1!==undefined)&&(basicID===("G*O*ES----****X")||basicID===("G*S*PP----****X")||basicID===("G*S*PX----****X"))) +{strText=modifiers[ModifiersTG.T1_UNIQUE_DESIGNATION_2];ti=new TextInfo(strText,0,0,textInfoContext);labelWidth=Math.round(ti.getTextBounds().getWidth());x=bounds.x+(bounds.width*0.5);x=x-(labelWidth*0.5);y=((bounds.height*0.60));y=bounds.y+y;ti.setLocation(x,y);arrMods.push(ti);}} +var modifierBounds=null;if(arrMods!==null&&arrMods.length>0) +{modifierBounds=arrMods[0].getTextOutlineBounds();var size=arrMods.length;var tempShape=null;for(var i=1;i0) +{ctx.lineWidth=RendererSettings.getTextOutlineWidth();ctx.fillStyle=outlineStyle;ctx.strokeStyle=outlineStyle;for(var i=0;i0) +{ctx.fillStyle=outlineStyle;for(var i=0;i0) +ctx.lineWidth=(outlineWidth*2)+1;ctx.fillStyle=fillStyle;ctx.strokeStyle=outlineStyle;for(var i=0;i0) +{tempShape.strokeText(ctx);} +tempShape.fillText(ctx);}}},renderImage:function(ii,symbolID,modifiers) +{var iinew=null;var hasTextModifiers=true;iinew=this.processUnitDisplayModifiers(ii,symbolID,modifiers,hasTextModifiers);if(iinew!==null) +ii=iinew;iinew=null;iinew=this.processUnitModifiers(ii,symbolID,modifiers);if(iinew!==null) +ii=iinew;return ii;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.MilStdIconRenderer=(function(){var MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes,SO=armyc2.c2sd.renderer.so,ImageInfo=armyc2.c2sd.renderer.utilities.ImageInfo,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,UnitDefTable=armyc2.c2sd.renderer.utilities.UnitDefTable,UnitFontLookup=armyc2.c2sd.renderer.utilities.UnitFontLookup,SymbolDefTable=armyc2.c2sd.renderer.utilities.SymbolDefTable,RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings,RendererUtilities=armyc2.c2sd.renderer.utilities.RendererUtilities,SinglePointRenderer=armyc2.c2sd.renderer.SinglePointRenderer,TacticalGraphicIconRenderer=armyc2.c2sd.renderer.TacticalGraphicIconRenderer,initialized=false;try +{if(initialized===false) +{UnitDefTable.init();SymbolDefTable.init();armyc2.c2sd.renderer.utilities.SinglePointLookup.init();armyc2.c2sd.renderer.utilities.UnitFontLookup.init();armyc2.c2sd.renderer.utilities.TacticalGraphicLookup.init();if(UnitDefTable.hasSymbolMap(RendererSettings.Symbology_2525B)===false) +{RendererSettings.setSymbologyStandard(RendererSettings.Symbology_2525C);} +initialized=true;}} +catch(err) +{err.message+=" - MilStdIconRenderer failed to initialize";armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MilStdIconRenderer","Init",err);} +function renderTacticalMultipointIcon(symbolID,modifiers) +{var lineColor=SymbolUtilities.getLineColorOfAffiliation(symbolID);if(modifiers[MilStdAttributes.LineColor]!==undefined) +{lineColor=modifiers[MilStdAttributes.LineColor];} +var size=RendererSettings.getDefaultPixelSize();if(modifiers[MilStdAttributes.PixelSize]!==undefined) +{size=modifiers[MilStdAttributes.PixelSize];} +var alpha=1.0;if(modifiers[MilStdAttributes.Alpha]!==undefined) +{alpha=modifiers[MilStdAttributes.Alpha]/255.0;} +var symStd=RendererSettings.getSymbologyStandard();if(modifiers[MilStdAttributes.SymbologyStandard]!==undefined) +{symStd=modifiers[MilStdAttributes.SymbologyStandard];} +var ii=TacticalGraphicIconRenderer.getIcon(symbolID,size,lineColor,alpha,symStd);return ii;} +return{CanRender:function(){},Render:function(symbolID,modifiers){if(!(modifiers)) +{modifiers={};} +var symStd=0;if(modifiers[MilStdAttributes.SymbologyStandard]!==null&&modifiers[MilStdAttributes.SymbologyStandard]!==undefined) +{symStd=modifiers[MilStdAttributes.SymbologyStandard];} +else +{symStd=RendererSettings.getSymbologyStandard();modifiers[MilStdAttributes.SymbologyStandard]=symStd;} +var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);if(SymbolUtilities.isTacticalGraphic(symbolID)) +{var sd=SymbolDefTable.getSymbolDef(basicID,symStd);if(sd===null) +{symbolID=SymbolUtilities.reconcileSymbolID(symbolID);basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);sd=SymbolDefTable.getSymbolDef(basicID);} +if(sd!==null&&sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_POINT) +{return armyc2.c2sd.renderer.SinglePointRenderer.renderSPTG(symbolID,modifiers);} +else +{return renderTacticalMultipointIcon(symbolID,modifiers);}} +else if(UnitFontLookup.hasUnitLookup(basicID,symStd)) +{return SinglePointRenderer.renderUnit(symbolID,modifiers);} +else if(SymbolUtilities.is3dAirspace(symbolID)) +{return renderTacticalMultipointIcon(symbolID,modifiers);} +else +{symbolID=SymbolUtilities.reconcileSymbolID(symbolID,false);return SinglePointRenderer.renderUnit(symbolID,modifiers);}},RenderImageInfoWithLabels:function(imageInfo,symbolID,modifiers) +{var ii=SinglePointRenderer.renderImage(imageInfo,symbolID,modifiers);return ii;},RenderCanvasWithLabels:function(canvas,symbolID,modifiers,centerPoint,symbolBounds) +{var ib=null,cp=null,sb=null;var width=canvas.width;var height=canvas.height;ib=new SO.Rectangle(0,0,width,height);if(centerPoint) +cp=centerPoint;else +cp=cp=new SO.Point(width/2,height/2);if(symbolBounds) +sb=symbolBounds;else +sb=new SO.Rectangle(0,0,width,height);var ii=new ImageInfo(canvas,cp,sb,ib);ii=SinglePointRenderer.renderImage(ii,symbolID,modifiers);return ii;},RenderImageUrlWithLabels:function(url,symbolID,modifiers,callback) +{var buffer=null;var ctx=null;var image=new Image();var rcwl=this.RenderCanvasWithLabels;image.onload=function() +{buffer=document.createElement('canvas');ctx=buffer.getContext('2d');buffer.width=image.width;buffer.height=image.height;ctx.drawImage(image,0,0);var ii=rcwl(buffer,symbolID,modifiers);callback(ii);};image.src=url;}};}());var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.ShapeTypes={};armyc2.c2sd.renderer.so.ShapeTypes.RECTANGLE="RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.POINT="POINT";armyc2.c2sd.renderer.so.ShapeTypes.ELLIPSE="ELLIPSE";armyc2.c2sd.renderer.so.ShapeTypes.ROUNDED_RECTANGLE="ROUNDED_RECTANGLE";armyc2.c2sd.renderer.so.ShapeTypes.LINE="LINE";armyc2.c2sd.renderer.so.ShapeTypes.BCURVE="BCURVE";armyc2.c2sd.renderer.so.ShapeTypes.ARC="ARC";armyc2.c2sd.renderer.so.ShapeTypes.PATH="PATH";armyc2.c2sd.renderer.so.ActionTypes={};armyc2.c2sd.renderer.so.ActionTypes.ACTION_MOVE_TO=0;armyc2.c2sd.renderer.so.ActionTypes.ACTION_LINE_TO=1;armyc2.c2sd.renderer.so.ActionTypes.ACTION_CURVE_TO=2;armyc2.c2sd.renderer.so.ActionTypes.ACTION_QUAD_TO=3;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC_TO=4;armyc2.c2sd.renderer.so.ActionTypes.ACTION_ARC=5;armyc2.c2sd.renderer.so.ActionTypes.ACTION_DASHED_LINE_TO=6;var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.utilities=armyc2.c2sd.renderer.so.utilities||{};armyc2.c2sd.renderer.so.utilities.relativeCCW=function(x1,y1,x2,y2,px,py) +{x2-=x1;y2-=y1;px-=x1;py-=y1;var ccw=px*y2-py*x2;if(ccw===0.0){ccw=px*x2+py*y2;if(ccw>0.0){px-=x2;py-=y2;ccw=px*x2+py*y2;if(ccw<0.0){ccw=0.0;}}} +return(ccw<0.0)?-1:((ccw>0.0)?1:0);};armyc2.c2sd.renderer.so.utilities.linesIntersect=function(x1,y1,x2,y2,x3,y3,x4,y4) +{var rCCW1=this.relativeCCW(x1,y1,x2,y2,x3,y3),rCCW2=this.relativeCCW(x1,y1,x2,y2,x4,y4),rCCW3=this.relativeCCW(x3,y3,x4,y4,x1,y1),rCCW4=this.relativeCCW(x3,y3,x4,y4,x2,y2);return(((rCCW1*rCCW2)<=0)&&((rCCW3*rCCW4)<=0));};armyc2.c2sd.renderer.so.utilities.intersectRects=function(src1,src2) +{var x1=Math.max(src1.getMinX(),src2.getMinX()),y1=Math.max(src1.getMinY(),src2.getMinY()),x2=Math.min(src1.getMaxX(),src2.getMaxX()),y2=Math.min(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2-x1,y2-y1);};armyc2.c2sd.renderer.so.utilities.unionRects=function(src1,src2) +{var x1=Math.min(src1.getMinX(),src2.getMinX()),y1=Math.min(src1.getMinY(),src2.getMinY()),x2=Math.max(src1.getMaxX(),src2.getMaxX()),y2=Math.max(src1.getMaxY(),src2.getMaxY());return new armyc2.c2sd.renderer.so.Rectangle(x1,y1,x2,y2);};if(typeof CanvasRenderingContext2D!=='undefined'&&CanvasRenderingContext2D.prototype.dashedLineTo!=='undefined') +{CanvasRenderingContext2D.prototype.dashedLineTo=function(fromX,fromY,toX,toY,pattern) +{var lt=function(a,b){return a<=b;};var gt=function(a,b){return a>=b;};var capmin=function(a,b){return Math.min(a,b);};var capmax=function(a,b){return Math.max(a,b);};var checkX={thereYet:gt,cap:capmin};var checkY={thereYet:gt,cap:capmin};if(fromY-toY>0){checkY.thereYet=lt;checkY.cap=capmax;} +if(fromX-toX>0) +{checkX.thereYet=lt;checkX.cap=capmax;} +this.moveTo(fromX,fromY);var offsetX=fromX;var offsetY=fromY;var idx=0,dash=true;while(!(checkX.thereYet(offsetX,toX)&&checkY.thereYet(offsetY,toY))) +{var ang=Math.atan2(toY-fromY,toX-fromX);var len=pattern[idx];offsetX=checkX.cap(toX,offsetX+(Math.cos(ang)*len));offsetY=checkY.cap(toY,offsetY+(Math.sin(ang)*len));if(dash)this.lineTo(offsetX,offsetY);else this.moveTo(offsetX,offsetY);idx=(idx+1)%pattern.length;dash=!dash;}};}var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Point=function(x,y){this.x=x,this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.getShapeType=function(){return"POINT";};armyc2.c2sd.renderer.so.Point.prototype.getX=function(){return this.x;};armyc2.c2sd.renderer.so.Point.prototype.getY=function(){return this.y;};armyc2.c2sd.renderer.so.Point.prototype.setLocation=function(x,y){this.x=x;this.y=y;};armyc2.c2sd.renderer.so.Point.prototype.shift=function(x,y){this.x+=x;this.y+=y;};armyc2.c2sd.renderer.so.Point.prototype.toStringFormatted=function(){return"{x:"+this.x+", y:"+this.y+"}";};armyc2.c2sd.renderer.so.Point.prototype.clone=function(){return new armyc2.c2sd.renderer.so.Point(this.x,this.y);};armyc2.c2sd.renderer.so.Point.prototype.setPath=function(context){var x=this.x,y=this.y;context.moveTo(x,y);context.lineTo(x+1,y);context.lineTo(x+1,y+1);context.lineTo(x,y+1);context.closePath();};armyc2.c2sd.renderer.so.Point.prototype.stroke=function(context){context.beginPath();this.setPath(context);context.stroke();};armyc2.c2sd.renderer.so.Point.prototype.fill=function(context){context.beginPath();this.setPath(context);context.fill();};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.so=armyc2.c2sd.renderer.so||{};armyc2.c2sd.renderer.so.Path=function(){this._actions=[],this._dashArray=null,this._startPoint=null,this._endPoint=null,this._lastMoveTo=null,this._rectangle=null,this._method=null;};armyc2.c2sd.renderer.so.Path.prototype.getShapeType=function(){return armyc2.c2sd.renderer.so.ShapeTypes.PATH;};armyc2.c2sd.renderer.so.Path.prototype.setLineDash=function(dashArray) +{this._dashArray=dashArray;} +armyc2.c2sd.renderer.so.Path.prototype.getBounds=function(){if(this._rectangle) +{return new armyc2.c2sd.renderer.so.Rectangle(this._rectangle.getX(),this._rectangle.getY(),this._rectangle.getWidth(),this._rectangle.getHeight());} +else +{return null;}};armyc2.c2sd.renderer.so.Path.prototype.shift=function(x,y){var size=this._actions.length;var temp=null;this._rectangle.shift(x,y);for(var i=0;i/g,"%3E");uri=uri.replace(/\//g,"%2F");uri=uri.replace(/\\/g,"%5C");uri=uri.replace(/\[/g,"%5B");uri=uri.replace(/\]/g,"%5D");uri=uri.replace(/\^/g,"%5E");uri=uri.replace(/\`/g,"%60");uri=uri.replace(/\~/g,"%7E");uri=uri.replace(/\?/g,"%3F");uri=uri.replace(/:/g,"%3A");uri=uri.replace(/;/g,"%3B");uri=uri.replace(/\@/g,"%40");uri=uri.replace(/\&/g,"%26");uri=uri.replace(/\{/g,"%7B");uri=uri.replace(/\|/g,"%7C");uri=uri.replace(/\}/g,"%7D");uri="data:image/svg+xml,"+uri;} +if(save) +this._svgDataURI=uri;return uri;}};armyc2.c2sd.renderer.utilities.SVGInfo.prototype.getAnchorPoint=function(){return this._center;};armyc2.c2sd.renderer.utilities.SVGInfo.prototype.getSymbolBounds=function(){return this._symbolBounds;};armyc2.c2sd.renderer.utilities.SVGInfo.prototype.getSVGBounds=function(){return this._bounds;};var armyc2=armyc2||{};armyc2.c2sd=armyc2.c2sd||{};armyc2.c2sd.renderer=armyc2.c2sd.renderer||{};armyc2.c2sd.renderer.utilities=armyc2.c2sd.renderer.utilities||{};armyc2.c2sd.renderer.utilities.SVGTextInfo=function(text,anchorPoint,fontInfo,justification,angle){this._text=text;this._fontName=fontInfo.name;this._fontSize=fontInfo.size;this._fontStyle=fontInfo.style;if(anchorPoint) +this._anchor=anchorPoint;else +this._anchor=new armyc2.c2sd.renderer.so.Point(0,0);if(justification) +this._justification=justification;else +this._justification="start";if(angle) +this._angle=angle;else +this._angle=null;this._bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.measureStringNoDOM(text,fontInfo.measurements);this._bounds.setLocation(this._anchor.getX(),this._anchor.getY());if(this._justification==="start") +{this._bounds.shift(0,this._anchor.getX()-fontInfo.measurements.height);} +else if(this._justification==="middle") +{this._bounds.shift(-(this._bounds.getWidth()/2),-fontInfo.measurements.height);} +else if(this._justification==="end") +{this._bounds.shift(-this._bounds.getWidth(),-fontInfo.measurements.height);}};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.getAnchorPoint=function(){return this._anchor;};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.getBounds=function(){return this._bounds;};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.getOutlineBounds=function() +{var RS=armyc2.c2sd.renderer.utilities.RendererSettings;var outlineOffset=RS.getTextOutlineWidth();var tbm=RS.getTextBackgroundMethod();if(tbm===RS.TextBackgroundMethod_OUTLINE) +outlineOffset+=2;if(outlineOffset>0) +{var bounds=new armyc2.c2sd.renderer.so.Rectangle(this._bounds.x-outlineOffset,this._bounds.y-outlineOffset,this._bounds.width+outlineOffset*2,this._bounds.height+outlineOffset*2);return bounds;} +else +{return this._bounds;}};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.shift=function(x,y){this._bounds.shift(x,y);this._anchor.shift(x,y);};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.setLocation=function(x,y){var diffX=this._anchor.getX()-x;var diffY=this._anchor.getY()-y;var shiftX=0;var shiftY=0;shiftX=-diffX;shiftY=-diffY;this._bounds.shift(shiftX,shiftY);this._anchor.setLocation(x,y);};armyc2.c2sd.renderer.utilities.SVGTextInfo.prototype.toSVGElement=function(stroke,strokeWidth,fill,svgFormat) +{var format=1;if(svgFormat) +{format=svgFormat;} +var se='';} +if(fill) +{if(format===2) +seFill=se+' fill="'+fill.replace(/#/g,"%23")+'"';else +seFill=se+' fill="'+fill+'"';seFill+='>';seFill+=text;seFill+='';} +if(stroke&&fill) +se=seStroke+seFill;else if(fill) +se=seFill;else +se="";return se;};var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.MultiPointHandlerSVG=(function(){var ErrorLogger=armyc2.c2sd.renderer.utilities.ErrorLogger;var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;var RendererUtilities=armyc2.c2sd.renderer.utilities.RendererUtilities;var MilStdAttributes=armyc2.c2sd.renderer.utilities.MilStdAttributes;var hasSetLineDash=false;var fillTextures={};var _decimalAccuracy=7;var _decimalAccMult=10000000;function toFixedPrecision(n) +{return Math.round(n*_decimalAccMult)/_decimalAccMult;} +return{GeoSVGize:function(symbolID,shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,wasClipped,pixelWidth,pixelHeight,fillTexture,fontInfo,SVGFormat,converter) +{var height=10;var tempBounds=null;var paths=[];var pathBounds=null;var labels=[];var labelBounds=null;var unionBounds=null;var rotatedBounds=null;var lineWidth=4;var svgFormat=1;if(SVGFormat) +svgFormat=SVGFormat;try +{if(!fontInfo) +fontInfo=RendererSettings.getMPFontInfo();height=fontInfo.measurements.height;var len=shapes.size();for(var i=0;i0&&pixelHeight>0) +bbox=new armyc2.c2sd.renderer.so.Rectangle(0,0,pixelWidth,pixelHeight);var tempModifier,len2=modifiers.size();var tiTemp=null;for(var j=0;j0&&unionBounds) +{var group='';if(format===6) +{for(var i=0;i';if(fillTexture) +geoSVG+=fillTexture;geoSVG+=group;geoSVG+='';if(svgFormat===1) +{return{svg:"data:image/svg+xml;base64,"+btoa(geoSVG),geoTL:geoCoordTL,geoBR:geoCoordBR,geoTR:geoCoordTR,geoBL:geoCoordBL,north:north,south:south,east:east,west:west,wasClipped:wasClipped,bounds:unionBounds};} +else if(svgFormat===2) +{geoSVG=geoSVG.replace(/\/g,"%3E");geoSVG=geoSVG.replace(/\"/g,"%22");geoSVG=geoSVG.replace(/\#/g,"%23");return{svg:"data:image/svg+xml,"+geoSVG,geoTL:geoCoordTL,geoBR:geoCoordBR,geoTR:geoCoordTR,geoBL:geoCoordBL,north:north,south:south,east:east,west:west,wasClipped:wasClipped,bounds:unionBounds};} +else +{return{svg:"data:image/svg+xml,"+geoSVG,geoTL:geoCoordTL,geoBR:geoCoordBR,geoTR:geoCoordTR,geoBL:geoCoordBL,north:north,south:south,east:east,west:west,wasClipped:wasClipped,bounds:unionBounds};}} +else +{return{svg:'data:image/svg+xml,',geoTL:geoCoordTL,geoBR:geoCoordBR,geoTR:geoCoordTR,geoBL:geoCoordBL,north:north,south:south,east:east,west:west,wasClipped:wasClipped};}},renderTextElement:function(tiArray,color,backgroundColor,svgFormat) +{var svgElements=[] +var size=tiArray.length,tempShape=null,fillStyle="#000000",outlineStyle=null,tbm=RendererSettings.getTextBackgroundMethod(),outlineWidth=RendererSettings.getTextOutlineWidth();if(color) +{fillStyle=color;} +else if(RendererSettings.getLabelForegroundColor()!==null) +{fillStyle=RendererSettings.getLabelForegroundColor().toHexString(false);} +if(backgroundColor) +{outlineStyle=backgroundColor;} +else +{outlineStyle=RendererUtilities.getIdealOutlineColor(fillStyle,true);} +if(tbm===RendererSettings.TextBackgroundMethod_OUTLINE) +{for(var i=0;i1) +{fillPattern=armyc2.c2sd.renderer.utilities.FillPatterns.getSVGFillStylePattern(shapeInfo.getFillStyle(),lineColor) +fillTexture="url(#fillPattern)";fillColor=null;} +var stroke=null;stroke=shapeInfo.getStroke();lineWidth=4;if(stroke!==null){lineWidth=Math.round(stroke.getLineWidth());dashArray=stroke.getDashArray();} +var shapesArray=shapeInfo.getPolylines();path=new armyc2.c2sd.renderer.so.Path();path.setLineDash(dashArray);for(var i=0;iwidth) +width=rect.getWidth();if(rect.getHeight()>height) +height=rect.getHeight();} +spacerW=width/3;spacerH=10;svgWidth=(width*symbols.length)+(spacerW*symbols.length);svgHeight=height+spacerH;var x=spacerW;var y=spacerH;var pattern="";for(var j=0;j';var paths=sym.getSVG();paths=paths.substr(paths.indexOf("","");pattern+=paths;pattern+='';x+=spacerW+width;} +texture='';texture+='';texture+=pattern;texture+='';texture+='';return texture;},GetRotatedRectangleBounds:function(rectangle,pointOfRotation,angle) +{try{var degrees=angle;var location=pointOfRotation;var bounds=rectangle;var radius=bounds.width+bounds.height;bounds=new armyc2.c2sd.renderer.so.Rectangle(location.x-radius,location.y-radius,radius*2,radius*2);return bounds;}catch(err){ErrorLogger.LogException("MultiPointHandler","AdjustModifierPointToCenter",err);return null;}}};}());var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.utilities=sec.web.renderer.utilities||{};sec.web.renderer.utilities.JavaRendererUtilities={};sec.web.renderer.utilities.JavaRendererUtilities.getBrowserEngine=function() +{var ua=navigator.userAgent;if(ua.indexOf("Trident")>0) +return"Trident";else if(ua.indexOf("AppleWebKit")>0) +return"AppleWebKit";else if(ua.indexOf("Gecko")>0&&ua.indexOf("Firefox")>0) +return"Gecko";else +return"Other";};sec.web.renderer.utilities.JavaRendererUtilities.ARGBtoABGR=function(rgbString) +{if(rgbString.length===6) +{var s="FF";rgbString=s.concat(rgbString);} +var c=rgbString.split('');var temp1=c[2];var temp2=c[3];c[2]=c[6];c[3]=c[7];c[6]=temp1;c[7]=temp2;var returnVal=c.join("");return returnVal;};sec.web.renderer.utilities.JavaRendererUtilities.normalizeSymbolCode=function(symbolCode) +{var newSymbolCode=symbolCode;if(symbolCode.charAt(0)==="G"||symbolCode.charAt(0)==="S"){newSymbolCode=newSymbolCode.substring(0,1)+'*'+newSymbolCode.substring(2);newSymbolCode=newSymbolCode.substring(0,3)+'*'+newSymbolCode.substring(4);newSymbolCode=newSymbolCode.substring(0,10)+"****"+newSymbolCode.substring(14);} +if(symbolCode.charAt(0)===("S")){newSymbolCode=newSymbolCode.substring(0,14)+'*';} +return newSymbolCode;};sec.web.renderer.utilities.JavaRendererUtilities.ReconcileSymbolID=function(symbolID) +{var SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities;var sb="";var codingScheme=symbolID.charAt(0);if(symbolID!==null&&symbolID.length===15) +{if(codingScheme==='S'||codingScheme==='I'||codingScheme==='O'||codingScheme==='E') +{sb+=(codingScheme);if(SymbolUtilities.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));if(SymbolUtilities.hasValidBattleDimension(symbolID)===false) +{sb+=('Z');sb="S"+sb.substring(1);} +else +sb+=(symbolID.charAt(2));if(SymbolUtilities.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));} +else if(codingScheme==='G') +{sb+=(codingScheme);if(SymbolUtilities.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));sb+=('G');if(SymbolUtilities.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));sb+=("GPP---");sb+=(symbolID.substring(10,15));} +else if(codingScheme==='W') +{return"SUZP-----------";} +else +{sb+=('S');if(SymbolUtilities.hasValidAffiliation(symbolID)===false) +sb+=('U');else +sb+=(symbolID.charAt(1));if(SymbolUtilities.hasValidBattleDimension(symbolID)===false) +{sb+=('Z');sb="S"+sb.substring(1);} +else +sb+=(symbolID.charAt(2));if(SymbolUtilities.hasValidStatus(symbolID)===false) +sb+=('P');else +sb+=(symbolID.charAt(3));sb+=("------");sb+=(symbolID.substring(10,15));}} +else +{return"SUZP-----------";} +return sb;};sec.web.renderer.utilities.JavaRendererUtilities.addAltModeToModifiersString=function(modifiers,altMode) +{if(altMode) +{if(altMode==="relativeToGround") +modifiers["ALTMODE"]="AGL";else if(altMode==="absolute") +modifiers["ALTMODE"]="MSL";else +modifiers["ALTMODE"]="";}} +sec.web.renderer.utilities.JavaRendererUtilities.is3dSymbol=function(symbolCode,modifiers) +{var returnValue=false;try +{var symbolId=symbolCode.substring(4,10);if(symbolId==="ACAI--"||symbolId==="ACAR--"||symbolId==="ACAC--"||symbolId==="AKPC--"||symbolId==="AKPR--"||symbolId==="AKPI--"||symbolId==="ALC---"||symbolId==="ALM---"||symbolId==="ALS---"||symbolId==="ALU---"||symbolId==="ALL---"||symbolId==="AAR---"||symbolId==="AAF---"||symbolId==="AAH---"||symbolId==="AAM---"||symbolId==="AAML--"||symbolId==="AAMH--") +{try +{if(modifiers) +{if(modifiers.modifiers) +{modifiers=modifiers.modifiers;} +var jsonAltitudeArray=null;if(modifiers.X) +{jsonAltitudeArray=modifiers.X;} +else if(modifiers.altitudeDepth) +{jsonAltitudeArray=modifiers.altitudeDepth;} +if(jsonAltitudeArray&&jsonAltitudeArray.length>=2) +{returnValue=true;} +else if((jsonAltitudeArray)&&(jsonAltitudeArray.length===1)&&(symbolId==="AKPC--"||symbolId==="AKPR--"||symbolId==="AKPI--")) +{returnValue=true;} +else +{returnValue=false;}}} +catch(je) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("JavaRendererUtilities","is3DSymbol()",je);}}} +catch(err) +{returnValue=false;} +return returnValue;};sec.web.renderer.utilities.JavaRendererUtilities.isNumber=function(text){return armyc2.c2sd.renderer.utilities.SymbolUtilities.isNumber(text);};sec.web.renderer.utilities.JavaRendererUtilities.createParameterMapFromURL=function(SymbolInfo) +{var modifiers={},symbolID=null,parameters=null,key=null,value=null,arrParameters=null,arrKeyValue=null,temp=null,questionIndex=SymbolInfo.indexOf('?');if(questionIndex===-1) +symbolID=SymbolInfo;else +symbolID=SymbolInfo.substring(0,questionIndex);if(questionIndex>0&&(questionIndex+10) +{distance=(modsAM[modsAM.length-1]*2);} +else +{distance=this.measureDistance(controlPointBounds.getY(),controlPointBounds.getX(),controlPointBounds.getBottom(),controlPointBounds.getRight(),"meters");} +distance=distance*1.1;var long=controlPointBounds.getCenterX();var lat=controlPointBounds.getCenterY();LookAtTag+=""+long+"";LookAtTag+=""+lat+"";LookAtTag+=""+0+"";LookAtTag+=""+0+"";LookAtTag+=""+distance+"";LookAtTag+=""+"absolute"+"";LookAtTag+="";} +return LookAtTag;};sec.web.renderer.utilities.JavaRendererUtilities.HOSTILE_FILL_COLOR="FFFF8080";sec.web.renderer.utilities.JavaRendererUtilities.FRIENDLY_FILL_COLOR="FF80E0FF";sec.web.renderer.utilities.JavaRendererUtilities.NEUTRAL_FILL_COLOR="FFAAFFAA";sec.web.renderer.utilities.JavaRendererUtilities.UNKNOWN_FILL_COLOR="FFFFFF80";var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.PointConverter=function(controlLong,controlLat,scale){this._controlLat=0,this._controlLong=0,this._scale=0,this._metersPerPixel=0,this._normalize=true,this._GeoPixelConversion=sec.web.renderer.GeoPixelConversion;this._controlLat=Number(controlLat);this._controlLong=Number(controlLong);this._scale=Number(scale);this._metersPerPixel=sec.web.renderer.GeoPixelConversion.metersPerPixel(scale);};sec.web.renderer.PointConverter.prototype.set_normalize=function(value) +{this._normalize=value;};sec.web.renderer.PointConverter.prototype.GeoToPixels=function(coord) +{var y=this._GeoPixelConversion.lat2y(coord.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=this._GeoPixelConversion.long2x(coord.getX(),this._scale,this._controlLong,coord.getY(),this._metersPerPixel,this._normalize);var ptPixels=new armyc2.c2sd.graphics2d.Point2D(x,y);return ptPixels;};sec.web.renderer.PointConverter.prototype.PixelsToGeo=function(pixel) +{var y=this._GeoPixelConversion.y2lat(pixel.getY(),this._scale,this._controlLat,this._metersPerPixel);var x=this._GeoPixelConversion.x2long(pixel.getX(),this._scale,this._controlLong,y,this._metersPerPixel);var pt2dGeo=new armyc2.c2sd.graphics2d.Point2D(x,y);return pt2dGeo;};var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.SymbolModifiers=sec.web.renderer.SymbolModifiers||{};sec.web.renderer.SymbolModifiers.A_SYMBOL_ICON="";sec.web.renderer.SymbolModifiers.B_ECHELON="";sec.web.renderer.SymbolModifiers.C_QUANTITY="";sec.web.renderer.SymbolModifiers.H_ADDITIONAL_INFO_1="";sec.web.renderer.SymbolModifiers.H1_ADDITIONAL_INFO_2="";sec.web.renderer.SymbolModifiers.H2_ADDITIONAL_INFO_3="";sec.web.renderer.SymbolModifiers.N_HOSTILE="";sec.web.renderer.SymbolModifiers.Q_DIRECTION_OF_MOVEMENT="";sec.web.renderer.SymbolModifiers.S_OFFSET_INDICATOR="";sec.web.renderer.SymbolModifiers.T_UNIQUE_DESIGNATION_1="";sec.web.renderer.SymbolModifiers.T1_UNIQUE_DESIGNATION_2="";sec.web.renderer.SymbolModifiers.V_EQUIP_TYPE="";sec.web.renderer.SymbolModifiers.W_DTG_1="";sec.web.renderer.SymbolModifiers.W1_DTG_2="";sec.web.renderer.SymbolModifiers.X_ALTITUDE_DEPTH=null;sec.web.renderer.SymbolModifiers.Y_LOCATION="";sec.web.renderer.SymbolModifiers.AM_DISTANCE=null;sec.web.renderer.SymbolModifiers.AN_AZIMUTH=null;sec.web.renderer.SymbolModifiers.FillColor="";sec.web.renderer.SymbolModifiers.LineColor="";sec.web.renderer.SymbolModifiers.X_ALTITUDE_DEPTH=[];sec.web.renderer.SymbolModifiers.AM_DISTANCE=[];sec.web.renderer.SymbolModifiers.AN_AZIMUTH=[];var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.GeoPixelConversion=(function(){var inchPerMeter=39.3700787,pixelsPerInch=96,METERS_PER_DEG=111319.49079327357264771338267056;return{metersPerPixel:function(scale) +{var step1=scale/pixelsPerInch;return step1/inchPerMeter;},lat2y:function(latitude,scale,latOrigin,metPerPix) +{var latRem=latOrigin-latitude;var pixDis=(latRem*METERS_PER_DEG)/metPerPix;return pixDis;},y2lat:function(yPosition,scale,latOrigin,metPerPix){var latitude=latOrigin-((yPosition*metPerPix)/METERS_PER_DEG);return latitude;},long2x:function(longitude,scale,longOrigin,latitude,metPerPix,normalize){var longRem=longitude-longOrigin;if(normalize===true) +{if(longRem>180){longRem-=360;} +if(longRem<-180){longRem+=360;}} +var metersPerDeg=this.GetMetersPerDegAtLat(latitude);var pixDis=(longRem*metersPerDeg)/metPerPix;return pixDis;},x2long:function(xPosition,scale,longOrigin,latitude,metPerPix){var metersPerDeg=this.GetMetersPerDegAtLat(latitude);var longitude=longOrigin+((xPosition*metPerPix)/metersPerDeg);if(longitude<-180){longitude+=360;}else if(longitude>180){longitude-=360;} +return longitude;},Deg2Rad:function(deg){var conv_factor=(2.0*Math.PI)/360.0;return(deg*conv_factor);},GetMetersPerDegAtLat:function(lat){lat=this.Deg2Rad(lat);var p1=111412.84;var p2=-93.5;var p3=0.118;var longlen=(p1*Math.cos(lat))+(p2*Math.cos(3*lat))+(p3*Math.cos(5*lat));return longlen;}};}());var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.MultiPointHandlerCanvas=(function(){var ErrorLogger=armyc2.c2sd.renderer.utilities.ErrorLogger;var RendererSettings=armyc2.c2sd.renderer.utilities.RendererSettings;var RendererUtilities=armyc2.c2sd.renderer.utilities.RendererUtilities;var _buffer=null;var _blankCanvas=null;var _blankCanvasContext=null;var _document=document;var textInfoBuffer=null,textInfoContext=null,textInfoContextFont=null,tempMPBuffer=null,tempMPContext=null;var hasSetLineDash=false;var _decimalAccuracy=7;if(document) +{_blankCanvas=document.createElement('canvas');_blankCanvas.width=2;_blankCanvas.height=2;_blankCanvasContext=_blankCanvas.getContext('2d');if(_blankCanvasContext.setLineDash) +{hasSetLineDash=true;}} +return{GeoCanvasize:function(symbolID,shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,wasClipped,pixelWidth,pixelHeight,fillTexture,converter) +{if(textInfoBuffer===null) +{textInfoBuffer=document.createElement('canvas');textInfoBuffer.width=1;textInfoBuffer.height=1;} +if(textInfoContext===null&&textInfoBuffer.getContext!==undefined) +{textInfoContext=textInfoBuffer.getContext('2d');textInfoContext.lineCap="butt";textInfoContext.lineJoin="miter";textInfoContext.miterLimit=3;textInfoContextFont=RendererSettings.getMPModifierFont();textInfoContext.font=textInfoContextFont;} +var height=RendererUtilities.measureTextWithFontString(textInfoContext.font,"Tj",textInfoContext).height;var tempBounds=null;var paths=[];var pathBounds=null;var labels=[];var labelBounds=null;var unionBounds=null;var rotatedBounds=null;try +{var len=shapes.size();for(var i=0;i0&&pixelHeight>0) +bbox=new armyc2.c2sd.renderer.so.Rectangle(0,0,pixelWidth,pixelHeight);var tempModifier,len2=modifiers.size();var tiTemp=null;for(var j=0;j0&&unionBounds) +{paths.smooth=shapes.smooth;var geoCanvas=this.RenderShapeInfoToCanvas(symbolID,paths,labels,unionBounds,geoCoordTL,geoCoordBR,geoCoordTR,geoCoordBL,north,south,east,west,format,hexTextColor,hexTextBackgroundColor,wasClipped);return geoCanvas;} +else +{return{image:_blankCanvas,geoTL:geoCoordTL,geoBR:geoCoordBR,wasClipped:wasClipped};}},RenderShapeInfoToCanvas:function(symbolID,paths,textInfos,bounds,geoTL,geoBR,geoTR,geoBL,north,south,east,west,format,hexTextColor,hexTextBackgroundColor,wasClipped,fillTexture) +{var buffer=null;if(format===4) +{if(tempMPBuffer===null) +{tempMPBuffer=document.createElement('canvas');} +if(tempMPContext===null) +{tempMPContext=tempMPBuffer.getContext('2d');} +buffer=tempMPBuffer;ctx=tempMPContext;} +else +{buffer=document.createElement('canvas');} +var pathSize=paths.length;var textSize=textInfos.length;var pathInfo=paths;var pi=null;var bounds=bounds;buffer.width=bounds.getWidth();buffer.height=bounds.getHeight();if(format===4) +{ctx.clearRect(0,0,bounds.getWidth(),bounds.getHeight());} +var lineColor="#000000";var ctx=buffer.getContext('2d');ctx.globalAlpha=1;ctx.lineCap="round";if(paths.smooth===true) +{ctx.lineJoin="round";} +else +{ctx.lineJoin="miter";} +ctx.translate(bounds.getX()*-1,bounds.getY()*-1);if(format!==5) +{for(var i=0;i0) +{ctx.globalAlpha=1;var tis=textInfos;var ti=null;var angle=0;var tbm=RendererSettings.getTextBackgroundMethod();var outlineWidth=RendererSettings.getTextOutlineWidth();var mpFont=RendererSettings.getMPModifierFont();var htbc=hexTextBackgroundColor||RendererUtilities.getIdealOutlineColor((hexTextColor||lineColor),true);var htc=hexTextColor||lineColor;ctx.fillStyle=htc;var outlineStyle=htbc;ctx.font=mpFont;if(outlineWidth>0) +ctx.lineWidth=(outlineWidth*2)+1;ctx.strokeStyle=outlineStyle;var offsetX=bounds.getX();var offsetY=bounds.getY();var tX=0;var tY=0;var height=RendererUtilities.measureTextWithFontString(mpFont,"Tj",ctx).height;ctx.lineCap="butt";ctx.lineJoin="miter";ctx.miterLimit=3;for(var j=0;j0) +{ctx.strokeText(ti.text,0,0);ctx.fillText(ti.text,0,0);} +break;case RendererSettings.TextBackgroundMethod_COLORFILL:ctx.fillStyle=htbc;var rectFill=ti.getTextOutlineBounds();rectFill.setLocation(0-outlineWidth,0-Math.round(rectFill.getHeight()/2));rectFill.fill(ctx);ctx.fillStyle=htc;ctx.fillText(ti.text,0,0);break;default:ctx.fillText(ti.text,0,0);break;} +ctx.setTransform(1,0,0,1,0,0);}} +if(format===3||format===5) +{return{image:buffer,geoTL:geoTL,geoBR:geoBR,geoTR:geoTR,geoBL:geoBL,north:north,south:south,east:east,west:west,width:buffer.width,height:buffer.height,wasClipped:wasClipped};} +else if(format===4) +{return{dataURL:buffer.toDataURL(),geoTL:geoTL,geoBR:geoBR,geoTR:geoTR,geoBL:geoBL,north:north,south:south,east:east,west:west,width:buffer.width,height:buffer.height,wasClipped:wasClipped};} +else +{buffer.geoTL=geoTL;buffer.geoBR=geoBR;return buffer;}},ShapesToGeoCanvas:function(symbolID,shapeInfo,ipc,normalize,fillTexture,converter) +{var pathInfo=null;var path=null;var fillColor=null;var lineColor=null;var lineWidth=null;var alpha=null;var dashArray=null;var fillPattern=null;var feature={};feature.type="Feature";feature.properties={};feature.properties.label="";var geometry={};if(shapeInfo.getLineColor()){lineColor=shapeInfo.getLineColor();alpha=lineColor.getAlpha()/255;lineColor=lineColor.toHexString(false);} +if(shapeInfo.getFillColor()){fillColor=shapeInfo.getFillColor();if(fillColor.getAlpha()===0&&fillTexture) +{fillPattern=fillTexture;fillColor=null;} +else +{alpha=fillColor.getAlpha()/255;fillColor=fillColor.toHexString(false);}} +else if(fillTexture&&symbolID.charAt(0)==='W') +{fillPattern=fillTexture;} +if(shapeInfo.getFillStyle()>1) +{fillPattern=armyc2.c2sd.renderer.utilities.FillPatterns.getCanvasFillStylePattern(shapeInfo.getFillStyle(),lineColor)} +var stroke=null;stroke=shapeInfo.getStroke();lineWidth=4;if(stroke!==null){lineWidth=Math.round(stroke.getLineWidth());dashArray=stroke.getDashArray();} +var shapesArray=shapeInfo.getPolylines();path=new armyc2.c2sd.renderer.so.Path();path.setLineDash(dashArray);for(var i=0;iwidth) +width=rect.getWidth();if(rect.getHeight()>height) +height=rect.getHeight();} +spacerW=width/3;spacerH=10;texture=_document.createElement('canvas');texture.width=(width*symbols.length)+(spacerW*symbols.length);texture.height=height+spacerH;var x=spacerW;var y=spacerH;var ctx=texture.getContext('2d');for(var j=0;j=16&&dc<=20)) +{if(dc===SymbolDefTable.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE) +{if(AM!==null&&AM.length>0) +return{hasRequiredModifiers:true,message:true};else +{message+=symbolID+" requires a modifiers object that has 1 distance/AM value.";return{hasRequiredModifiers:false,message:message};}} +else if(dc===SymbolDefTable.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE) +{if(AM!==null&&AM.length>=2&&AN!==null&&AN.length>=1) +return{hasRequiredModifiers:true,message:true};else +{message+=symbolID+" requires a modifiers object that has 2 distance/AM values and 1 azimuth/AN value.";return{hasRequiredModifiers:false,message:message};}} +else if(dc===SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE) +{if(AM!==null&&AM.length>=2&&AN!==null&&AN.length>=2) +return{hasRequiredModifiers:true,message:true};else +{message+=symbolID+" requires a modifiers object that has 2 distance/AM values and 2 azimuth/AN values per sector. The first sector can have just one AM value although it is recommended to always use 2 values for each sector.";return{hasRequiredModifiers:false,message:message};}} +else if(dc===SymbolDefTable.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE) +{if(AM!==null&&AM.length>0) +return{hasRequiredModifiers:true,message:true};else +{message+=symbolID+" requires a modifiers object that has at least 1 distance/AM value";return{hasRequiredModifiers:false,message:message};}} +else if(dc===SymbolDefTable.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE) +{if(AM!==null&&AM.length>0) +return{hasRequiredModifiers:true,message:true};else +{message+=symbolID+" requires a modifiers object that has 1 distance/AM value.";return{hasRequiredModifiers:false,message:message};}} +else +{return{hasRequiredModifiers:true,message:true};}} +else +{return{hasRequiredModifiers:true,message:true};}};return{MODIFIER_HEADER:"modifiers",QUANTITY:"quantity",REINFORCE_OR_REDUCED:"reinforcedOrReduced",STAFF_COMMENTS:"staffComments",ADDITIONAL_INFO_1:"additionalInfo1",ADDITIONAL_INFO_2:"additionalInfo2",ADDITIONAL_INFO_3:"additionalInfo3",EVALUATION_RATION:"evaluationRating",COMBAT_EFFECTIVENESS:"combatEffectiveness",SIGNATURE_EQUIPMENT:"signatureEquipment",HIGHER_FORMATION:"higherFormation",HOSTILE:"hostile",IFFSIFF:"iffSif",DIRECTION_OF_MOVEMENT:"directionOfMovement",UNIQUE_DESIGNATION_1:"uniqueDesignation1",UNIQUE_DESIGNATION_2:"uniqueDesignation2",EQUIPMENT_TYPE:"equipmentType",DATE_TIME_GROUP_1:"dateTimeGroup1",DATE_TIME_GROUP_2:"dateTimeGroup2",DATE_TIME_GROUP_3:"dateTimeGroup3",ALTITUDE_DEPTH:"altitudeDepth",LOCATION:"location",SPEED:"speed",SPECIAL_C2_HQ:"specialC2Headquarters",DISTANCE:"distance",AZIMUTH:"azimuth",FILL_COLOR:"fillColor",LINE_COLOR:"lineColor",TEXT_COLOR:"textColor",TEXT_BACKGROUND_COLOR:"textBackgroundColor",LINE_THICKNESS:"lineThickness",SYMBOL_FILL_ICON_SIZE:"symbolFillIconSize",SYMBOL_FILL_IDS:"symbolFillIds",SYMBOL_LINE_IDS:"symbolLineIds",Symbology_2525Bch2_USAS_13_14:0,Symbology_2525C:1,NormalizeGECoordsToGEExtents:function(leftLongitude,rightLongitude,pts2d) +{try +{var j=0;var x=0,y=0;var pt2d=null;for(j=0;jrightLongitude) +x-=360;pt2d=new armyc2.c2sd.graphics2d.Point2D(x,y);pts2d[j]=pt2d;}} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","NormalizeGECoordsToGEExtents",err);}},NormalizeCoordToGECoord:function(pt2d) +{var ptGeo=null;try +{var x=pt2d.getX(),y=pt2d.getY();while(x<-180) +x+=360;while(x>180) +x-=360;ptGeo=new armyc2.c2sd.graphics2d.Point2D(x,y);} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","NormalizeCoordToGECoord",err);} +return ptGeo;},getBoundingRectangle:function(controlPoints,bbox) +{var bbox2="";try +{var left=0,right=0,top=0,bottom=0;var coordinates=controlPoints.split(" ");var len=coordinates.length;var i=0;left=Number.MAX_VALUE;right=Number.MIN_VALUE;top=Number.MIN_VALUE;bottom=Number.MAX_VALUE;for(i=0;iright) +right=longitude;if(latitude>top) +top=latitude;if(latituderight) +right=ptTemp.getX();if(ptTemp.getY()>top) +top=ptTemp.getY();if(ptTemp.getY()right) +right=pt.getX();if(pt.getY()>top) +top=pt.getY();if(pt.getY()180) +{left=180;for(j=0;j0&&pt.getX()right) +right=pt.getX();if(pt.getY()>top) +top=pt.getY();if(pt.getY()180) +{left=180;right=-180;for(j=0;j0&&pt.getX()right) +right=pt.getX();}} +bbox=Double.toString(left)+","+Double.toString(bottom)+","+Double.toString(right)+","+Double.toString(top);} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","getBboxFromCoords",err);} +return bbox;},getGeoUL2:function(geoCoords) +{var ptGeo=null;try +{var j=0;var pt=null;var left=geoCoords.get(0).x;var top=geoCoords.get(0).y;var right=geoCoords.get(0).x;var bottom=geoCoords.get(0).y;for(j=1;jright) +right=pt.getX();if(pt.getY()>top) +top=pt.getY();if(pt.getY()180) +{left=180;for(j=0;j0&&pt.getX()180) +return true;} +return result;},ShouldClipSymbol:function(symbolID) +{var status=armyc2.c2sd.renderer.utilities.SymbolUtilities.getStatus(symbolID);if(symbolID.charAt(0)===("G")&&status===("A")){return true;} +if(armyc2.c2sd.renderer.utilities.SymbolUtilities.isWeather(symbolID)) +return true;var id=armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolIDStrict(symbolID);if(id===("G*T*F-----****X")||id===("G*F*LCC---****X")||id===("G*G*GLB---****X")||id===("G*G*GLF---****X")||id===("G*G*GLC---****X")||id===("G*G*GAF---****X")||id===("G*G*AAW---****X")||id===("G*G*DABP--****X")||id===("G*G*OLP---****X")||id===("G*G*PY----****X")||id===("G*G*PM----****X")||id===("G*G*ALL---****X")||id===("G*G*ALU---****X")||id===("G*G*ALM---****X")||id===("G*G*ALC---****X")||id===("G*G*SLB---****X")||id===("G*G*SLH---****X")||id===("G*G*GAY---****X")||id===("G*G*ALS---****X")||id===("G*M*OFA---****X")||id===("G*M*OGB---****X")||id===("G*M*OGL---****X")||id===("G*M*OGZ---****X")||id===("G*M*OGF---****X")||id===("G*M*OGR---****X")||id===("G*M*OADU--****X")||id===("G*M*OADC--****X")||id===("G*M*OAR---****X")||id===("G*M*OAW---****X")||id===("G*M*OEF---****X")||id===("G*M*OMC---****X")||id===("G*M*OWU---****X")||id===("G*M*OWS---****X")||id===("G*M*OWD---****X")||id===("G*M*OWA---****X")||id===("G*M*OWL---****X")||id===("G*M*OWH---****X")||id===("G*M*OWCS--****X")||id===("G*M*OWCD--****X")||id===("G*M*OWCT--****X")||id===("G*M*OHO---****X")||id===("G*M*BDD---****X")||id===("G*M*BCD---****X")||id===("G*M*BCE---****X")||id===("G*M*SL----****X")||id===("G*M*SP----****X")||id===("G*M*NR----****X")||id===("G*M*NB----****X")||id===("G*M*NC----****X")||id===("G*F*ACNI--****X")||id===("G*F*ACNR--****X")||id===("G*F*ACNC--****X")||id===("G*F*AKBC--****X")||id===("G*F*AKBI--****X")||id===("G*F*AKBR--****X")||id===("G*F*AKPC--****X")||id===("G*F*AKPI--****X")||id===("G*F*AKPR--****X")||id===("G*F*LT----****X")||id===("G*F*LTS---****X")||id===("G*G*SAE---****X")||id===("G*S*LRA---****X")||id===("G*S*LRM---****X")||id===("G*S*LRO---****X")||id===("G*S*LRT---****X")||id===("G*S*LRW---****X")||id===("G*T*Q-----****X")||id===("G*T*E-----****X")||id===("G*T*F-----****X")||id===("G*T*K-----****X")||id===("G*T*KF----****X")||id===("G*T*A-----****X")||id===("G*G*PA----****X")||id===("G*M*ORP---****X")||id===("G*M*ORS---****X")) +{return true;} +else +return false;},getReasonableScale:function(bbox,origScale) +{var scale=origScale;try +{var bounds=bbox.split(",");var left=bounds[0];var right=bounds[2];var top=bounds[3];var bottom=bounds[1];if(left.equalsIgnoreCase("-180")&&right.equalsIgnoreCase("180")) +return 7.573e7;else if(left.equalsIgnoreCase("180")&&right.equalsIgnoreCase("-180")) +return 7.573e7;var ul=new armyc2.c2sd.JavaLineArray.POINT2(left,top);var ur=new armyc2.c2sd.JavaLineArray.POINT2(right,top);var ml=new armyc2.c2sd.JavaLineArray.POINT2(left,(parseFloat(top)+parseFloat(bottom))/2);var mr=new armyc2.c2sd.JavaLineArray.POINT2(right,(parseFloat(top)+parseFloat(bottom))/2);var lr=new armyc2.c2sd.JavaLineArray.POINT2(right,bottom);var widthInMeters=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_distance(ml,mr,null,null);var maxWidthInPixels=_maxWidthInPixels;var minScale=(maxWidthInPixels/widthInMeters)*(1.0/96.0)*(1.0/39.37);minScale=1.0/minScale;if(origScale===null||origScale===undefined){return minScale;} +if(origScalemaxScale){return maxScale;}} +catch(err){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","getGeoUL",err);} +return scale;},RenderSymbol:function(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd,converter,fontInfo) +{if(!symStd) +{symStd=armyc2.c2sd.renderer.utilities.RendererSettings.getSymbologyStandard();} +var normalize=true,jsonOutput="",jsonContent="",rect=null,tgPoints=null,coordinates=null,tgl=new armyc2.c2sd.JavaTacticalRenderer.TGLight(),shapes=[],modifiers=[],geoCoords=[],ipc=null,left=0,right=0,top=0,bottom=0,temp=null,ptGeoUL=null,width=0,height=0,leftX=0,topY=0,bottomY=0,rightX=0,j=0,bboxCoords=null;var setRectNull=false;var tempPt=null;coordinates=controlPoints.trim();coordinates=coordinates.split(" ");var len=coordinates.length;var convRect=null;for(var i=0;i180) +right-=360;else +if(right<-180) +right+=360;} +if(top===bottom) +{dist=1000.0*(1.0/96.0)*(1.0/39.37)*scale;var ptTop=new armyc2.c2sd.JavaLineArray.POINT2(left,top);var ptBottom=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate(ptTop,dist,180.0);bottom=ptBottom.y;} +if(converter) +{var ptUL={};ptUL.x=left;ptUL.y=top;ptUL=converter.GeoToPixels(ptUL);leftX=ptUL.x;topY=ptUL.y;var ptBR={};ptBR.x=right;ptBR.y=bottom;ptBR=converter.GeoToPixels(ptBR);rightX=ptBR.x;bottomY=ptBR.y;width=Math.abs(rightX-leftX);height=Math.abs(bottomY-topY);convRect=new armyc2.c2sd.graphics2d.Rectangle(leftX,topY,width,height);} +var pt2d=null;if(bboxCoords===undefined||bboxCoords===null) +{pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(left,top);temp=ipc.GeoToPixels(pt2d);leftX=Math.round(temp.getX());topY=Math.round(temp.getY());pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(right,bottom);temp=ipc.GeoToPixels(pt2d);bottomY=Math.round(temp.getY());rightX=Math.round(temp.getX());width=Math.abs(rightX-leftX);height=Math.abs(bottomY-topY);rect=new armyc2.c2sd.graphics2d.Rectangle(leftX,topY,width,height);if(format>=3&&format<=6&&scale>1e6) +{var midlat=(Number(top)+Number(bottom))/2;pt2d.setLocation(left,midlat);temp=ipc.GeoToPixels(pt2d);leftX=Math.round(temp.getX());pt2d.setLocation(right,midlat);temp=ipc.GeoToPixels(pt2d);rightX=Math.round(temp.getX());if(rightX180) +{var dLeft=180-Number(left);var dRight=180+Number(right);var dIDL=(dLeft+dRight)/2;midlon=Number(left)+dIDL;if(midlon>180) +midlon-=360;} +pt2d.setLocation(midlon,top);temp=ipc.GeoToPixels(pt2d);topY=Math.round(temp.getY());pt2d.setLocation(midlon,bottom);temp=ipc.GeoToPixels(pt2d);bottomY=Math.round(temp.getX());if(bottomY=3&&format<=7) +{symbolModifiers[MilStdAttributes.UseDashArray]=true;} +if(format>=3&&format<=7) +{symbolModifiers[MilStdAttributes.UsePatternFill]=true;} +if(symbolModifiers!==null&&symbolModifiers!==("")) +{sec.web.renderer.MultiPointHandler.populateModifiers(symbolModifiers,mSymbol);} +else +mSymbol.setFillColor(null);var symbolIsValid=this.canRenderMultiPoint(mSymbol);if(symbolIsValid.canRender===false) +{jsonOutput="";jsonOutput+=("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol "+symbolCode+": "+"- ");jsonOutput+=(symbolIsValid.message+" - ");jsonOutput+=("\"}");ErrorLogger.LogWarning("MultiPointHandler","RenderSymbol",symbolIsValid.message);return jsonOutput;} +mSymbol=sec.web.renderer.utilities.JavaRendererUtilities.MilStdSymbolArraysToArrayLists(mSymbol);if(mSymbol.getModifierMap()["symbolFillIds"]!==undefined||mSymbol.getModifierMap()["symbolLineIds"]!==undefined) +{tgl=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(mSymbol,ipc);if(rect!==null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tgl,rect);var tgPoints=tgl.get_Pixels();} +if(bboxCoords===null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.renderWithPolylines(mSymbol,ipc,rect);else +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.renderWithPolylines(mSymbol,ipc,bboxCoords);shapes=mSymbol.getSymbolShapes();modifiers=mSymbol.getModifierShapes();var textColor=mSymbol.getTextColor();var textBackgroundColor=mSymbol.getTextBackgroundColor();var hexTextColor=null;var hexTextBackgroundColor=null;if(format===0) +{if(textColor!==null) +{hexTextColor=textColor.toKMLHexString();} +else +{hexTextColor="#FF000000";} +jsonContent=sec.web.renderer.MultiPointHandler.KMLize(id,name,description,symbolCode,shapes,modifiers,ipc,normalize,hexTextColor,symStd);if(mSymbol.getModifierMap()["symbolFillIds"]!==undefined||mSymbol.getModifierMap()["symbolLineIds"]!==undefined) +{var fillKML=this.AddImageFillToKML(tgPoints,jsonContent,mSymbol,ipc,normalize);if(fillKML!==null&&fillKML!=="") +{jsonContent=fillKML;}} +var doLookAt=false;var LookAtTag=null;if(symbolModifiers[MilStdAttributes.LookAtTag]===true) +{LookAtTag=sec.web.renderer.utilities.JavaRendererUtilities.generateLookAtTag(geoCoords,symbolModifiers["AM"]);if(LookAtTag) +{var idx=jsonContent.indexOf("");jsonContent=jsonContent.substring(0,idx)+LookAtTag+jsonContent.substring(idx);}} +jsonOutput=jsonContent;} +else if(format===2) +{if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);jsonContent=sec.web.renderer.MultiPointHandler.GeoJSONize(shapes,modifiers,ipc,normalize,hexTextColor,hexTextBackgroundColor);jsonContent.properties.id=id;jsonContent.properties.name=name;jsonContent.properties.description=description;jsonContent.properties.symbolID=symbolCode;jsonContent.properties.wasClipped=mSymbol.getWasClipped();var gjFormat=0;if(symbolModifiers[MilStdAttributes.GeoJSONFormat]) +{gjFormat=symbolModifiers[MilStdAttributes.GeoJSONFormat];} +if(gjFormat===0) +{jsonOutput=JSON.stringify(jsonContent);} +else +{jsonOutput=jsonContent;}} +else if(format===3||format===4||format===5) +{if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolCode);var sd=SymbolDefTable.getSymbolDef(basicID,symStd);if(sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_AUTOSHAPE) +{shapes.smooth=true;} +var map=mSymbol.getModifierMap();var fillTexture=null;var fillTextureSymbolSize=15;if(map["symbolFillIds"]) +{var strIDs=map["symbolFillIds"];if(map["symbolFillSize"]) +fillTextureSymbolSize=map["symbolFillSize"];if(strIDs&&strIDs!=="") +{fillTexture=MPHC.MakeFillTexture(strIDs,fillTextureSymbolSize);}} +if(symbolCode.charAt(0)==='W') +{fillTexture=armyc2.c2sd.renderer.utilities.FillPatterns.getCanvasFillStylePattern(symbolCode);} +if(convRect!==null) +jsonOutput=MPHC.GeoCanvasize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),convRect.getWidth(),convRect.getHeight(),fillTexture,converter);else +jsonOutput=MPHC.GeoCanvasize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),-1,-1,fillTexture,converter);} +else if(format===6||format===7) +{var svgFormat=1;if(symbolModifiers[MilStdAttributes.SVGFormat]) +svgFormat=symbolModifiers[MilStdAttributes.SVGFormat];if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);var map=mSymbol.getModifierMap();var fillTexture=null;var fillTextureSymbolSize=15;if(map["symbolFillIds"]) +{var strIDs=map["symbolFillIds"];if(map["symbolFillSize"]) +fillTextureSymbolSize=map["symbolFillSize"];if(strIDs&&strIDs!=="") +{fillTexture=MPHS.MakeFillTextureSVG(strIDs,fillTextureSymbolSize);}} +if(symbolCode.charAt(0)==='W') +{fillTexture=armyc2.c2sd.renderer.utilities.FillPatterns.getSVGFillStylePattern(symbolCode);} +if(convRect!=null) +jsonOutput=MPHS.GeoSVGize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),convRect.getWidth(),convRect.getHeight(),fillTexture,fontInfo,svgFormat,converter);else +jsonOutput=MPHS.GeoSVGize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),-1,-1,fillTexture,fontInfo,svgFormat,converter);} +else if(format===1) +{jsonOutput="{\"type\":\"symbol\",";jsonContent=sec.web.renderer.MultiPointHandler.JSONize(shapes,modifiers,ipc,normalize);jsonOutput+=jsonContent;jsonOutput+="}";}} +catch(exc) +{jsonOutput="";jsonOutput+=("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol "+symbolCode+": "+"- ");jsonOutput+=(exc.message+" - ");jsonOutput+=("\"}");ErrorLogger.LogException("MultiPointHandler","RenderSymbol",exc);} +var debug=false;if(debug===true){console.info("Symbol Code: "+symbolCode);console.info("Scale: "+scale);console.info("BBOX: "+bbox);if(controlPoints!==null){console.info("Geo Points: "+controlPoints);} +if(tgl!==null&&tgl.get_Pixels()!==null){console.info("Pixel: "+tgl.get_Pixels().toString());} +if(bbox!==null){console.info("geo bounds: "+bbox);} +if(rect!==null){console.info("pixel bounds: "+rect.toString());} +if(jsonOutput!==null){console.info(jsonOutput);}} +return jsonOutput;},ConvertPolylinePixelsToCoords:function(polylines,ipc,normalize) +{var newPolylines=[];var latitude=0;var longitude=0;var newLine=null;var tempPt=null;var pt=null;var geoCoord=null;try +{for(var i=0;i90) +pixelHeight*=3;if(top!==bottom&&left!=right) +{ipc=new armyc2.c2sd.renderer.utilities.PointConversion(pixelWidth,pixelHeight,(top),(left),(bottom),(right));} +else +{var rbb=this.GetBboxFromCoordinates(symbolCode,geoCoords,symbolModifiers,symStd);ipc=new armyc2.c2sd.renderer.utilities.PointConversion(pixelWidth,pixelHeight,(rbb.top),(rbb.left),(rbb.bottom),(rbb.right));left=rbb.left;top=rbb.top;right=rbb.right;bottom=rbb.bottom;}} +else +{var rbb=this.GetBboxFromCoordinates(symbolCode,geoCoords,symbolModifiers,symStd);ipc=new armyc2.c2sd.renderer.utilities.PointConversion(pixelWidth,pixelHeight,(rbb.top),(rbb.left),(rbb.bottom),(rbb.right));left=rbb.left;top=rbb.top;right=rbb.right;bottom=rbb.bottom;} +if(converter) +ipc=converter;if(armyc2.c2sd.renderer.utilities.SymbolDefTable.hasSymbolDef(SymbolUtilities.getBasicSymbolIDStrict(symbolCode),symStd)===false) +symbolCode=SymbolUtilities.reconcileSymbolID(symbolCode,true);try +{var mSymbol=new armyc2.c2sd.renderer.utilities.MilStdSymbol(symbolCode,null,geoCoords,null);mSymbol.setSymbologyStandard(symStd);if(format>=3&&format<=7) +{symbolModifiers[MilStdAttributes.UseDashArray]=true;} +if(format>=3&&format<=7) +{symbolModifiers[MilStdAttributes.UsePatternFill]=true;} +if(symbolModifiers!==null&&symbolModifiers!==("")) +{sec.web.renderer.MultiPointHandler.populateModifiers(symbolModifiers,mSymbol);} +else +mSymbol.setFillColor(null);var temp=null;var leftX;var topY;var bottomY;var rightX;var width;var height;var pt2d=null;var normalize=true;if(format>2||(sec.web.renderer.MultiPointHandler.ShouldClipSymbol(symbolCode))===true||sec.web.renderer.MultiPointHandler.crossesIDL(geoCoords)===true) +{pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(left,top);temp=ipc.GeoToPixels(pt2d);leftX=Math.round(temp.getX());topY=Math.round(temp.getY());pt2d=new armyc2.c2sd.graphics2d.Point2D();pt2d.setLocation(right,bottom);temp=ipc.GeoToPixels(pt2d);bottomY=Math.round(temp.getY());rightX=Math.round(temp.getX());width=Math.abs(rightX-leftX);height=Math.abs(bottomY-topY);rect=new armyc2.c2sd.graphics2d.Rectangle(leftX,topY,width,height);} +var symbolIsValid=this.canRenderMultiPoint(mSymbol);if(symbolIsValid.canRender===false) +{jsonOutput="";jsonOutput+=("{\"type\":\"error\",\"error\":\"There was an error creating the MilStdSymbol "+symbolCode+": "+"- ");jsonOutput+=(symbolIsValid.message+" - ");jsonOutput+=("\"}");ErrorLogger.LogWarning("MultiPointHandler","RenderSymbol",symbolIsValid.message);return jsonOutput;} +mSymbol=sec.web.renderer.utilities.JavaRendererUtilities.MilStdSymbolArraysToArrayLists(mSymbol);if(mSymbol.getModifierMap()["symbolFillIds"]||mSymbol.getModifierMap["symbolLineIds"]) +{mSymbol.setFillColor(new armyc2.c2sd.renderer.utilities.Color(0,0,0,0));tgl=armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.createTGLightFromMilStdSymbol(mSymbol,ipc);if(rect!==null) +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsClipPolygon2.ClipPolygon(tgl,rect);tgPoints=tgl.get_Pixels();} +armyc2.c2sd.JavaRendererServer.RenderMultipoints.clsRenderer.renderWithPolylines(mSymbol,ipc,rect);shapes=mSymbol.getSymbolShapes();modifiers=mSymbol.getModifierShapes();var textColor=mSymbol.getTextColor();var textBackgroundColor=mSymbol.getTextBackgroundColor();var hexTextColor=null;var hexTextBackgroundColor=null;if(format===0) +{if(textColor!==null) +{hexTextColor=textColor.toKMLHexString();} +else +{hexTextColor="#FF000000";} +jsonContent=sec.web.renderer.MultiPointHandler.KMLize(id,name,description,symbolCode,shapes,modifiers,ipc,normalize,hexTextColor,symStd);if(mSymbol.getModifierMap()["symbolFillIds"]||mSymbol.getModifierMap["symbolLineIds"]) +{var fillKML=this.AddImageFillToKML(tgPoints,jsonContent,mSymbol,ipc,normalize);if(fillKML!==null&&fillKML!=="") +{jsonContent=fillKML;}} +jsonOutput=jsonContent;} +else if(format===2) +{if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);jsonContent=sec.web.renderer.MultiPointHandler.GeoJSONize(shapes,modifiers,ipc,normalize,hexTextColor,hexTextBackgroundColor);jsonContent.properties.id=id;jsonContent.properties.name=name;jsonContent.properties.description=description;jsonContent.properties.symbolID=symbolCode;jsonContent.properties.wasClipped=mSymbol.getWasClipped();var gjFormat=0;if(symbolModifiers[MilStdAttributes.GeoJSONFormat]) +{gjFormat=symbolModifiers[MilStdAttributes.GeoJSONFormat];} +if(gjFormat===0) +{jsonOutput=JSON.stringify(jsonContent);} +else +{jsonOutput=jsonContent;}} +else if(format===3||format===4||format===5) +{if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolCode);var sd=SymbolDefTable.getSymbolDef(basicID,symStd);if(sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_AUTOSHAPE) +{shapes.smooth=true;} +var map=mSymbol.getModifierMap();var fillTexture=null;var fillTextureSymbolSize=15;if(map["symbolFillIds"]) +{var strIDs=map["symbolFillIds"];if(map["symbolFillIconSize"]) +fillTextureSymbolSize=map["symbolFillIconSize"];if(strIDs&&strIDs!=="") +{fillTexture=MPHC.MakeFillTexture(strIDs,fillTextureSymbolSize);}} +if(symbolCode.charAt(0)==='W') +{fillTexture=armyc2.c2sd.renderer.utilities.FillPatterns.getCanvasFillStylePattern(symbolCode);} +jsonOutput=MPHC.GeoCanvasize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),pixelWidth,pixelHeight,fillTexture);} +else if(format===6||format===7) +{var svgFormat=1;if(symbolModifiers[MilStdAttributes.SVGFormat]) +svgFormat=symbolModifiers[MilStdAttributes.SVGFormat];if(textColor) +hexTextColor=textColor.toHexString(false);if(textBackgroundColor) +hexTextBackgroundColor=textBackgroundColor.toHexString(false);var map=mSymbol.getModifierMap();var fillTexture=null;var fillTextureSymbolSize=15;if(map["symbolFillIds"]) +{var strIDs=map["symbolFillIds"];if(map["symbolFillIconSize"]) +fillTextureSymbolSize=map["symbolFillIconSize"];if(strIDs&&strIDs!=="") +{fillTexture=MPHS.MakeFillTextureSVG(strIDs,fillTextureSymbolSize);}} +if(symbolCode.charAt(0)==='W') +{fillTexture=armyc2.c2sd.renderer.utilities.FillPatterns.getSVGFillStylePattern(symbolCode);} +jsonOutput=MPHS.GeoSVGize(mSymbol.getSymbolID(),shapes,modifiers,ipc,normalize,format,hexTextColor,hexTextBackgroundColor,mSymbol.getWasClipped(),pixelWidth,pixelHeight,fillTexture,fontInfo,svgFormat);} +else if(format===1) +{jsonOutput=("{\"type\":\"symbol\",");jsonContent=sec.web.renderer.MultiPointHandler.JSONize(shapes,modifiers,ipc,normalize);jsonOutput+=(jsonContent);jsonOutput+=("}");}}catch(err){jsonOutput="";jsonOutput+=("{\"type\":\"MultiPointHandler\",\"RenderSymbol2D\":\"There was an error creating the MilStdSymbol "+symbolCode+": "+"- ");jsonOutput+=(err.message+" - ");jsonOutput+=("\"}");ErrorLogger.LogException("MultiPointHandler","RenderSymbol2D",err);} +var debug=false;if(debug===true) +{console.info("Symbol Code: "+symbolCode);console.info("BBOX: "+bbox);if(controlPoints!==null){console.info("Geo Points: "+controlPoints);} +if(tgl!==null&&tgl.get_Pixels()!==null){console.info("Pixel: "+tgl.get_Pixels().toString());} +if(bbox!==null){console.info("geo bounds: "+bbox);} +if(rect!==null){console.info("pixel bounds: "+rect.toString());} +if(jsonOutput!==null){console.info(jsonOutput);}} +return jsonOutput;},canRenderMultiPoint:function(symbol) +{var symStd=symbol.getSymbologyStandard();var symbolID=symbol.getSymbolID();var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);var sd=null;var dc=99;var coordCount=symbol.getCoordinates().length;if(SymbolDefTable.hasSymbolDef(basicID,symStd)) +{sd=SymbolDefTable.getSymbolDef(basicID,symStd);} +if(sd!==null) +{dc=sd.drawCategory;if(coordCount0) +{return{canRender:true,message:""};} +else +{return{canRender:false,message:"Buffered Basic Shapes require a width (AM)"};}} +else if(symbolID.indexOf("PBS_")===0) +{var AM=symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE);if(symbolID==="PBS_CIRCLE-----"||symbolID==="PBS_SQUARE-----") +{if(AM&&AM.length>0&&coordCount>0) +{return{canRender:true,message:""};} +else +{return{canRender:false,message:(symbolID+", requires a width (AM) and 1 control point")};}} +else if(symbolID==="PBS_ELLIPSE----"||symbolID==="PBS_RECTANGLE--") +{if(AM&&AM.length>1&&coordCount>0) +{return{canRender:true,message:""};} +else +{return{canRender:false,message:(symbolID+", requires 2 AM values, length and width (AM) and 1 control point")};}} +else +{return{canRender:false,message:"Parametered Basic Shapes code: "+symbolID+", not recognized."};}} +else +{return{canRender:false,message:"symbolID: \""+symbolID+"\" not recognized."};}},populateModifiers:function(modifiers,symbol) +{var modifierMap={},altitudes=null,azimuths=null,distances=null,fillColor=null,lineColor=null,lineWidth=0,textColor=null,textBackgroundColor=null,symbolFillIDs=null,symbolFillIconSize=null,altMode=null;var useDashArray=symbol.getUseDashArray();var usePatternFill=symbol.getUseFillPattern();var patternFillType=0;var hideOptionalLabels=false;try{if(typeof(modifiers)==='string') +{modifiers=JSON.parse(modifiers);if(modifiers.modifiers) +modifiers=modifiers.modifiers;} +if(modifiers[ModifiersTG.C_QUANTITY]) +modifierMap[ModifiersTG.C_QUANTITY]=modifiers[ModifiersTG.C_QUANTITY];else if(modifiers.quantity) +modifierMap[ModifiersTG.C_QUANTITY]=modifiers.quantity;if(modifiers[ModifiersTG.H_ADDITIONAL_INFO_1]) +modifierMap[ModifiersTG.H_ADDITIONAL_INFO_1]=modifiers[ModifiersTG.H_ADDITIONAL_INFO_1];else if(modifiers.additionalInfo1) +modifierMap[ModifiersTG.H_ADDITIONAL_INFO_1]=modifiers.additionalInfo1;if(modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2]) +modifierMap[ModifiersTG.H1_ADDITIONAL_INFO_2]=modifiers[ModifiersTG.H1_ADDITIONAL_INFO_2];else if(modifiers.additionalInfo2) +modifierMap[ModifiersTG.H1_ADDITIONAL_INFO_2]=modifiers.additionalInfo2;if(modifiers[ModifiersTG.H2_ADDITIONAL_INFO_3]) +modifierMap[ModifiersTG.H2_ADDITIONAL_INFO_3]=modifiers[ModifiersTG.H2_ADDITIONAL_INFO_3];else if(modifiers.additionalInfo3) +modifierMap[ModifiersTG.H2_ADDITIONAL_INFO_3]=modifiers.additionalInfo3;if(modifiers[ModifiersTG.N_HOSTILE]) +modifierMap[ModifiersTG.N_HOSTILE]=modifiers[ModifiersTG.N_HOSTILE];else if(modifiers.hostile) +modifierMap[ModifiersTG.N_HOSTILE]=modifiers.hostile;if(modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1]) +modifierMap[ModifiersTG.T_UNIQUE_DESIGNATION_1]=modifiers[ModifiersTG.T_UNIQUE_DESIGNATION_1];else if(modifiers.uniqueDesignation1) +modifierMap[ModifiersTG.T_UNIQUE_DESIGNATION_1]=modifiers.uniqueDesignation1;if(modifiers[ModifiersTG.T1_UNIQUE_DESIGNATION_2]) +modifierMap[ModifiersTG.T1_UNIQUE_DESIGNATION_2]=modifiers[ModifiersTG.T1_UNIQUE_DESIGNATION_2];else if(modifiers.uniqueDesignation2) +modifierMap[ModifiersTG.T1_UNIQUE_DESIGNATION_2]=modifiers.uniqueDesignation2;if(modifiers[ModifiersTG.W_DTG_1]) +modifierMap[ModifiersTG.W_DTG_1]=modifiers[ModifiersTG.W_DTG_1];else if(modifiers.dateTimeGroup1) +modifierMap[ModifiersTG.W_DTG_1]=modifiers.dateTimeGroup1;if(modifiers[ModifiersTG.W1_DTG_2]) +modifierMap[ModifiersTG.W1_DTG_2]=modifiers[ModifiersTG.W1_DTG_2];else if(modifiers.dateTimeGroup2) +modifierMap[ModifiersTG.W1_DTG_2]=modifiers.dateTimeGroup2;var i=0;if(modifiers[ModifiersTG.X_ALTITUDE_DEPTH]&&modifiers[ModifiersTG.X_ALTITUDE_DEPTH]instanceof Array) +{var XN=modifiers[ModifiersTG.X_ALTITUDE_DEPTH];altitudes=[];for(i=0;i0){symbol.setLineWidth(lineWidth);} +if(altMode!==null){symbol.setAltitudeMode(altMode);} +if(altitudes!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.X_ALTITUDE_DEPTH,altitudes);} +if(distances!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE,distances);} +if(azimuths!==null){symbol.setModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH,azimuths);} +if(armyc2.c2sd.renderer.utilities.SymbolUtilities.getBasicSymbolIDStrict(symbol.getSymbolID())===("G*F*AXS---****X")){if(symbol.getModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH)!==null&&symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE)!==null){var anCount=symbol.getModifiers_AM_AN_X(ModifiersTG.AN_AZIMUTH).length;var amCount=symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE).length;var am=null;if(amCount<((Math.floor(anCount/2))+1)){am=symbol.getModifiers_AM_AN_X(ModifiersTG.AM_DISTANCE);if(am[0]!==0) +{am.splice(0,0,0);}}}}} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","populateModifiers",err);} +return true;},KMLize:function(id,name,description,symbolCode,shapes,modifiers,ipc,normalize,textColor,symStd) +{var kml="";var tempModifier=null;var cdataStart="";kml+=("");kml+=(""+cdataStart+name+cdataEnd+"");kml+=("1");try +{var len=shapes.size();for(var i=0;i0) +{jstr+=",";} +var shapesToAdd=sec.web.renderer.MultiPointHandler.ShapeToJSONString(shapes.get(i),ipc,normalize);if(shapesToAdd.length>0){if(shapesToAdd.substring(2,6)==="line") +{if(lines.length>0) +{lines+=",";} +lines+=shapesToAdd;} +else if(shapesToAdd.substring(2,6)==="poly") +{if(polygons.length>0) +{polygons+=",";} +polygons+=shapesToAdd;}}} +jstr+="\"polygons\": ["+polygons+"],"+"\"lines\": ["+lines+"],";var len2=modifiers.size();labels="";for(var j=0;j0){if(labels.length>0){labels+=",";} +labels+=labelsToAdd;}} +jstr+="\"labels\": ["+labels+"]";} +catch(err) +{armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","JSONize",err);} +return jstr;},GeoJSONize:function(shapes,modifiers,ipc,normalize,textColor,textBackgroundColor) +{var featureCollection={"type":"FeatureCollection","features":[],"properties":{}};try +{var len=shapes.size();for(var i=0;i");if(description) +{kml+=(""+cdataStart+description+cdataEnd+"");} +kml+=("");var shapesArray=shapeInfo.getPolylines();var len=shapesArray.size();var len2=0;kml+=("");for(var i=0;i");kml+=("1");kml+=("clampToGround");kml+=("");len2=shape.size();for(var j=0;j");kml+=("");} +if(fillColor!==null){if(i===0) +kml+=("");if(i===1&&len>1) +kml+=("");else +kml+=("");kml+=("");kml+=("clampToGround");kml+=("1");kml+=("");var lastLongitude=null;if(normalize===false&&this.IsOnePointSymbolCode(symbolCode,symStd)) +{for(var j=0;j180) +{normalize=true;break;}} +lastLongitude=longitude;}} +for(var j=0;j0) +{longitude-=360;}} +kml+=(longitude);kml+=(",");kml+=(latitude);if(j");kml+=("");if(i===1&&len>1) +kml+=("");else +kml+=("");if(i===len-1) +kml+=("");}} +kml+=("");kml+=("");return kml;},AdjustModifierPointToCenter:function(modifier) +{try{var degrees=parseFloat(modifier.getModifierStringAngle());var text=modifier.getModifierString();var location=modifier.getGlyphPosition();var font=RendererSettings.getMPModifierFont();var bounds=armyc2.c2sd.renderer.utilities.RendererUtilities.getTextBounds(null,text,location,font);var offsetX=0;var offsetY=0;if(degrees!==0) +{var theta=degrees*(Math.PI/180);var tl={x:(0),y:(bounds.height)};var bl={x:0,y:0};var tr={x:bounds.width,y:bounds.height};var br={x:bounds.width,y:0};var bb={};var offsetX=0;var offsetY=0;var x0=0;var y0=0;tl.x=(x0+(tl.x-x0)*Math.cos(theta)-(tl.y-y0)*Math.sin(theta));tl.y=(y0+(tl.x-x0)*Math.sin(theta)+(tl.y-y0)*Math.cos(theta));tr.x=(x0+(tr.x-x0)*Math.cos(theta)-(tr.y-y0)*Math.sin(theta));tr.y=(y0+(tr.x-x0)*Math.sin(theta)+(tr.y-y0)*Math.cos(theta));br.x=(x0+(br.x-x0)*Math.cos(theta)-(br.y-y0)*Math.sin(theta));br.y=(y0+(br.x-x0)*Math.sin(theta)+(br.y-y0)*Math.cos(theta));bb.x=Math.min(0,tl.x,tr.x,br.x);bb.y=Math.max(0,tl.y,tr.y,br.y);bb.width=Math.max(0,tl.x,tr.x,br.x)-bb.x;bb.height=bb.y-Math.min(0,tl.y,tr.y,br.y);offsetX+=bb.width/2;offsetY+=bb.height/2;} +else +{offsetX+=bounds.width/2;offsetY+=bounds.height/2;} +var point=modifier.getGlyphPosition();point.x+=offsetX;point.y+=offsetY;modifier.setGlyphPosition(point);}catch(err){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("MultiPointHandler","AdjustModifierPointToCenter",err);}},ShapeToJSONString:function(shapeInfo,ipc,normalize) +{var JSONed="";var fillColor=null;var lineColor=null;if(shapeInfo.getLineColor()!==null){lineColor=shapeInfo.getLineColor().toHexString();} +if(shapeInfo.getFillColor()!==null){fillColor=shapeInfo.getFillColor().toHexString();} +var stroke=null;stroke=shapeInfo.getStroke();var lineWidth=4;if(stroke!==null){lineWidth=Math.round(stroke.getLineWidth());} +var shapesArray=shapeInfo.getPolylines();for(var i=0;i0) +{longitude-=360;}} +coord.setLocation(longitude,latitude);shape[j]=coord;JSONed+=("[");JSONed+=(longitude);JSONed+=(",");JSONed+=(latitude);JSONed+=("]");if(j<(shape.size()-1)){JSONed+=(",");}} +JSONed+=("]");if(lineColor!==null){JSONed+=(",\"lineColor\":\"");JSONed+=(lineColor);JSONed+=("\"");} +if(fillColor!==null){JSONed+=(",\"fillColor\":\"");JSONed+=(fillColor);JSONed+=("\"");} +JSONed+=(",\"lineWidth\":\"");JSONed+=(lineWidth);JSONed+=("\"");JSONed+=("}");if(i<(shapesArray.size()-1)){JSONed+=(",");}} +return JSONed;},ShapeToGeoJSONString:function(shapeInfo,ipc,normalize) +{var JSONed="";var fillColor=null;var lineColor=null;var alpha=255;var feature={};feature.type="Feature";feature.properties={};feature.properties.label="";var geometry={};if(shapeInfo.getLineColor()){lineColor=shapeInfo.getLineColor();feature.properties.strokeColor=lineColor.toHexString(false);alpha=lineColor.getAlpha();feature.properties.lineOpacity=alpha/255;geometry["type"]="MultiLineString";} +if(shapeInfo.getFillColor()){fillColor=shapeInfo.getFillColor();feature.properties.fillColor=fillColor.toHexString(false);alpha=fillColor.getAlpha();feature.properties.fillOpacity=alpha/255;geometry["type"]="Polygon";} +var stroke=null;stroke=shapeInfo.getStroke();var lineWidth=4;if(stroke!==null){lineWidth=Math.round(stroke.getLineWidth());} +feature.properties.strokeWidth=lineWidth;feature.properties.strokeWeight=lineWidth;var coords=[];var line;var shapesArray=shapeInfo.getPolylines();for(var i=0;i0) +{longitude-=360;}} +line.push([longitude,latitude]);} +coords.push(line);} +geometry["coordinates"]=coords;feature["geometry"]=geometry;return feature;},LabelToKMLString:function(shapeInfo,ipc,normalize,textColor) +{var cdataStart="";var kml="";var coord=new armyc2.c2sd.graphics2d.Point2D();coord.setLocation(shapeInfo.getModifierStringPosition().getX(),shapeInfo.getModifierStringPosition().getY());var geoCoord=ipc.PixelsToGeo(coord);if(normalize) +geoCoord=this.NormalizeCoordToGECoord(geoCoord);var latitude=toFixedPrecision(geoCoord.getY());var longitude=toFixedPrecision(geoCoord.getX());var angle=Math.round(shapeInfo.getModifierStringAngle());var text=shapeInfo.getModifierString();var kmlScale=RendererSettings.getKMLLabelScale();if(kmlScale>0&&text!==null&&text!==("")){kml+=("");kml+=(""+cdataStart+text+cdataEnd+"");kml+=("");kml+=("");kml+=("1");kml+=("relativeToGround");kml+=("");kml+=(longitude);kml+=(",");kml+=(latitude);kml+=("");kml+=("");kml+=("");}else{return"";} +return kml;},LabelToJSONString:function(shapeInfo,ipc,normalize) +{var JSONed=("{\"label\":");var coord=new armyc2.c2sd.graphics2d.Point2D();coord.setLocation(shapeInfo.getGlyphPosition().getX(),shapeInfo.getGlyphPosition().getY());var geoCoord=ipc.PixelsToGeo(coord);if(normalize) +geoCoord=this.NormalizeCoordToGECoord(geoCoord);var latitude=toFixedPrecision(geoCoord.getY());var longitude=toFixedPrecision(geoCoord.getX());var angle=shapeInfo.getModifierStringAngle();coord.setLocation(longitude,latitude);shapeInfo.setGlyphPosition(coord);var text=shapeInfo.getModifierString();if(text!==null&&text!==("")){JSONed+=("[");JSONed+=(longitude);JSONed+=(",");JSONed+=(latitude);JSONed+=("]");JSONed+=(",\"text\":\"");JSONed+=(text);JSONed+=("\"");JSONed+=(",\"angle\":\"");JSONed+=(angle);JSONed+=("\"}");}else{return"";} +return JSONed;},LabelToGeoJSONString:function(shapeInfo,ipc,normalize,textColor,textBackgroundColor) +{var JSONed="";var fillColor=null;var lineColor=null;var alpha=255;var feature={};feature.type="Feature";feature.properties={};var geometry={};var RS=armyc2.c2sd.renderer.utilities.RendererSettings;var RU=armyc2.c2sd.renderer.utilities.RendererUtilities;var coord=new armyc2.c2sd.graphics2d.Point2D();coord.setLocation(shapeInfo.getModifierStringPosition().getX(),shapeInfo.getModifierStringPosition().getY());var geoCoord=ipc.PixelsToGeo(coord);if(normalize) +geoCoord=this.NormalizeCoordToGECoord(geoCoord);var latitude=toFixedPrecision(geoCoord.getY());var longitude=toFixedPrecision(geoCoord.getX());latitude=parseFloat(latitude);longitude=parseFloat(longitude);var angle=shapeInfo.getModifierStringAngle();coord.setLocation(longitude,latitude);shapeInfo.setGlyphPosition(coord);var justify=shapeInfo.getTextJustify();var strJustify="left";if(justify===0) +strJustify="left";else if(justify===1) +strJustify="center";else if(justify===2) +strJustify="right";var text=shapeInfo.getModifierString();if(text!==null&&text!==("")){feature={};feature.type="Feature";feature.properties={};geometry={};feature.properties.label=text;feature.properties.pointRadius=0;feature.properties.fontSize=RS.getMPModifierFontSize()+"pt";feature.properties.fontFamily=RS.getMPModifierFontName();feature.properties.fontWeight=RS.getMPModifierFontStyle();feature.properties.fontColor=textColor||shapeInfo.getFillColor().toHexString(false);feature.properties.labelOutlineColor=textBackgroundColor||RU.getIdealOutlineColor(feature.properties.fontColor);feature.properties.labelOutlineWidth=RS.getTextOutlineWidth()*2+1;feature.properties.labelAlign=strJustify;feature.properties.labelBaseline="alphabetic";feature.properties.labelXOffset=0;feature.properties.labelYOffset=0;feature.properties.rotation=angle;feature.properties.angle=angle;geometry["type"]="Point";geometry["coordinates"]=[longitude,latitude];feature["geometry"]=geometry;}else{return null;} +return feature;},getModifierKML:function(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd) +{var output="";var placemarks=[];try +{var maxAlt=0;var minAlt=0;output=this.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,symbolModifiers,format,symStd);var pmiStart=output.indexOf("max) +max=XN[i];}} +else if(symbolModifiers.altitudeDepth&&symbolModifiers.altitudeDepth instanceof Array) +{altitudes=[];for(i=0;imax) +max=symbolModifiers.altitudeDepth[i];}} +while(pmiStart>0) +{if(count>0) +{pmiEnd=output.indexOf("",pmiStart)+12;tempPlacemark=output.substring(pmiStart,pmiEnd);if(tempPlacemark.contains("")) +{var outputSubstring=output.substring(pmiStart,pmiEnd);outputSubstring=outputSubstring.replace(/<\/coordinates>/gi,","+max+"<\/coordinates>");outputSubstring=outputSubstring.replace(/1<\/extrude>/gi,"0<\/extrude>");placemarks.push(outputSubstring);} +pmiStart=output.indexOf("0) +{path.lineTo(temp.getX(),temp.getY());} +else if(i===0) +{path.moveTo(temp.getX(),temp.getY());}} +bounds=path.getBounds();height=bounds.getHeight();width=bounds.getWidth();if(bounds.getX()<0) +{offsetX=Math.round(bounds.getX()*-1);} +else if((bounds.getX()+bounds.getWidth())>width) +{offsetX=Math.round((bounds.getX()+bounds.getWidth())-width)*-1;} +if(bounds.getY()<0) +{offsetY=Math.round(bounds.getY()*-1);} +else if((bounds.getY()+bounds.getHeight())>height) +{offsetY=Math.round((bounds.getY()+bounds.getHeight())-height)*-1;} +if(clip!==null) +{var sbClip="";sbClip+=("&clip=");sbClip+=(clip.getX());sbClip+=(",");sbClip+=(clip.getY());sbClip+=(",");sbClip+=(clip.getWidth());sbClip+=(",");sbClip+=(clip.getHeight());strClip=sbClip;} +var sbCoords="";var sbUrl="";sbCoords+=("coords=");if(modifiers["symbolFillIds"]!==undefined) +{symbolFillIDs=modifiers["symbolFillIds"];} +if(modifiers["symbolLineIds"]!==undefined) +{symbolLineIDs=modifiers["symbolLineIds"];} +if(modifiers["symbolFillIconSize"]!==undefined) +{symbolSize=["symbolFillIconSize"];} +if(modifiers["clip"]) +{strClip=["clip"];} +for(var i=0;i0) +{sbCoords+=(",");} +point=pixels.get(i);x=Math.round(point.getX()+offsetX);y=Math.round(point.getY()+offsetY);sbCoords+=(x);sbCoords+=(",");sbCoords+=(y);} +sbUrl=this.GetImageServerURL();sbUrl+=("AREASYMBOLFILL?");sbUrl+=("renderer=AreaSymbolFillRenderer&");sbUrl+=sbCoords;if(symbolFillIDs!==null) +{sbUrl+=("&symbolFillIds=");sbUrl+=(symbolFillIDs);} +if(symbolLineIDs!==null) +{sbUrl+=("&symbolLineIds=");sbUrl+=(symbolLineIDs);} +if(symbolSize>0) +{sbUrl+=("&symbolFillIconSize=");sbUrl+=(symbolSize);} +if(strClip!==null) +{sbUrl+=(strClip);} +sbUrl+=("&height=");sbUrl+=parseInt(height);sbUrl+=("&width=");sbUrl+=parseInt(width);url=sbUrl;if(height0) +{path.lineTo(tpTemp.x,tpTemp.y);} +else +{path.moveTo(tpTemp.x,tpTemp.y);}} +var rect=path.getBounds();var goImageUrl=this.GenerateSymbolLineFillUrl(mSymbol.getModifierMap(),pixelPoints,rect);var goKML="";if(goImageUrl!==null) +{goKML=this.GenerateGroundOverlayKML(goImageUrl,ipc,rect,normalize);} +goKML+="";jsonContent=jsonContent.replace("",goKML);return jsonContent;},GenerateGroundOverlayKML:function(urlImage,ipc,symbolBounds,normalize) +{var x=0;var y=0;var height=0;var width=0;var sb="";var lineFill=false;var params={};var symbolSize=0;var imageOffset=0;try +{var index=-1;index=urlImage.indexOf(this.SYMBOL_LINE_IDS);if(index>0) +{lineFill=true;if(params[this.SYMBOL_FILL_ICON_SIZE]!==undefined) +{var size=params[this.SYMBOL_FILL_ICON_SIZE];symbolSize=parseInt(size);} +else +{symbolSize=25;} +imageOffset=(symbolSize/2)+3;} +var bounds=null;bounds=symbolBounds;height=bounds.getHeight()+(imageOffset*2);width=bounds.getWidth()+(imageOffset*2);x=bounds.getX()-imageOffset;y=bounds.getY()-imageOffset;var coord=new armyc2.c2sd.graphics2d.Point2D(x,y);var topLeft=ipc.PixelsToGeo(coord);coord=new armyc2.c2sd.graphics2d.Point2D(x+width,y+height);var bottomRight=ipc.PixelsToGeo(coord);if(normalize) +{topLeft=this.NormalizeCoordToGECoord(topLeft);bottomRight=this.NormalizeCoordToGECoord(bottomRight);if(topLeft.getX()>0) +{topLeft.x-=360;}} +var cdataStart="";sb+=("");sb+=("symbol fill");sb+=("symbol fill");sb+=("");sb+=("");sb+=(cdataStart);sb+=(urlImage);sb+=(cdataEnd);sb+=("");sb+=("");sb+=("");sb+=("");sb+=topLeft.getY();sb+=("");sb+=("");sb+=bottomRight.getY();sb+=("");sb+=("");sb+=bottomRight.getX();sb+=("");sb+=("");sb+=topLeft.getX();sb+=("");sb+=("");sb+=("0");sb+=("");sb+=("");sb+=("");} +catch(exc) +{ErrorLogger.LogException("MultiPointHandler","GenerateGroundOverlayKML",exc);} +var kml=sb;return kml;},GetImageServerURL:function() +{if(_appletUrl===null) +{_appletUrl=baseURL;_appletUrl+="mil-sym-service/renderer/image/";} +return _appletUrl;},SetImageServerURL:function(hostURL) +{_appletUrl=hostURL;_appletUrl+="mil-sym-service/renderer/image/";},GetBboxFromCoordinates:function(symbolID,geoCoords,modifiers,symStd) +{var bbox=null;var basicID=SymbolUtilities.getBasicSymbolIDStrict(symbolID);var len=geoCoords.length;if(len>=2) +{rbb=new armyc2.c2sd.renderer.so.Rectangle(geoCoords[0].getX(),geoCoords[0].getY(),0,0);for(var i=1;idAM1) +dAMmax=dAM2/2;pTL=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate({x:geoCoords[0].getX(),y:geoCoords[0].getY()},dAMmax,aTL);pBR=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate({x:geoCoords[0].getX(),y:geoCoords[0].getY()},dAMmax,aBR);bbox={top:pTL.y,left:pTL.x,bottom:pBR.y,right:pBR.x};} +else if(sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_CIRCULAR_RANGEFAN_AUTOSHAPE||sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_SECTOR_PARAMETERED_AUTOSHAPE) +{arrAM=modifiers[ModifiersTG.AM_DISTANCE];var dAM=parseFloat(arrAM[len-1]);var pTL=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate({x:geoCoords[0].getX(),y:geoCoords[0].getY()},dAM,aTL);var pBR=armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic.geodesic_coordinate({x:geoCoords[0].getX(),y:geoCoords[0].getY()},dAM,aBR);bbox={top:pTL.y,left:pTL.x,bottom:pBR.y,right:pBR.x};} +else if(sd.drawCategory===SymbolDefTable.DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE) +{rbb=new armyc2.c2sd.renderer.so.Rect(geoCoords[0].getX(),geoCoords[0].getY(),0,0);for(var i=1;iundefined\n")>0) +result=result.replace("undefined\n","");else if(result.indexOf("null\n")>0) +result=result.replace("null\n","");} +return result;};sec.web.renderer.Shape3DHandler.buildPolygon=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";try{var latlons=controlPoints.split(" ");if(latlons.length>=2){pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getPolygonKml(latlons,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){armyc2.c2sd.renderer.utilities.ErrorLogger.LogException("Shape3DHandler","buildPolygon()",e);} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildCylinder=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.split(" ");if(latlons.length>0){var pivot=latlons[0].split(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} +pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getCircleKml(pivotx,pivoty,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildKml=function(coords,id,name,lineColor,fillColor){var kml=new sec.geo.utilities.StringBuilder();kml.append("");kml.append("");kml.append(name);kml.append("");kml.append("");kml.append(id);kml.append("");kml.append("");kml.append("");for(var s,$s=0,$$s=coords;$s<$$s.length&&((s=$$s[$s])||true);$s++){kml.append("");kml.append("0");kml.append("relativeToGround");kml.append("");kml.append("");kml.append("");kml.append(s);kml.append("");kml.append("");kml.append("");kml.append("");} +kml.append("");kml.append("");return kml.toString();};sec.web.renderer.Shape3DHandler.buildOrbit=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var point1x=0.0;var point1y=0.0;var point2x=0.0;var point2y=0.0;try{var latlons=controlPoints.split(" ");if(latlons.length>1){var point1=latlons[0].split(",");if(point1.length>=2){point1x=Double.parseDouble(point1[0]);point1y=Double.parseDouble(point1[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} +var point2=latlons[1].split(",");if(point2.length>=2){point2x=Double.parseDouble(point2[0]);point2y=Double.parseDouble(point2[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} +pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getOrbitKml(point1x,point1y,point2x,point2y,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildRadarc=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.split(" ");if(latlons.length>0){var pivot=latlons[0].split(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};}}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};} +pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getRadarcKml(pivotx,pivoty,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.AM_DISTANCE.get(1)).doubleValue(),(attributes.AN_AZIMUTH.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(1)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildPolyArc=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var pivotx=0.0;var pivoty=0.0;try{var latlons=controlPoints.split(" ");if(latlons.length>=3){var pivot=latlons[0].split(",");if(pivot.length>=2){pivotx=Double.parseDouble(pivot[0]);pivoty=Double.parseDouble(pivot[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} +var length=latlons.length-1;var points=new Array(length);System.arraycopy(latlons,1,points,0,length);pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getPolyarcKml(points,pivotx,pivoty,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],(attributes.AM_DISTANCE.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(0)).doubleValue(),(attributes.AN_AZIMUTH.get(1)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildRoute=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var width;var leftWidth;var rightWidth;try{var latlons=controlPoints.split(" ");if(latlons.length>=2){width=(attributes.AM_DISTANCE.get(0)).doubleValue();leftWidth=width/2;rightWidth=width/2;pointArrayStringList=sec.geo.kml.XsltCoordinateWrapper.getRouteKml(latlons,id,name,description,lineColor,fillColor,attributes.ALT_MODE[0],leftWidth,rightWidth,(attributes.X_ALTITUDE_DEPTH.get(0)).doubleValue(),(attributes.X_ALTITUDE_DEPTH.get(1)).doubleValue());}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.buildCake=function(controlPoints,id,name,description,lineColor,fillColor,attributes){var pointArrayStringList="";var letThemEat=new sec.geo.shape.Cake();var pivotx=0.0;var pivoty=0.0;var kmlRender=new sec.geo.kml.KmlRenderer();try{var latlons=controlPoints.split(" ");var numberOfPoints=latlons.length;if(numberOfPoints>0){var pivotString=latlons[0].split(",");if(pivotString.length>=2){pivotx=Double.parseDouble(pivotString[0]);pivoty=Double.parseDouble(pivotString[1]);letThemEat.setPivot(new sec.geo.GeoPoint(pivotx,pivoty));}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} +var attributesArrayLength=attributes.X_ALTITUDE_DEPTH.size();for(var i=0;i0) +for(var j=0;j=2){var track=new sec.geo.shape.Track();for(var i=0;i=2){point1lon=Double.parseDouble(point1String[0]);point1lat=Double.parseDouble(point1String[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} +if(point2String.length>=2){point2lon=Double.parseDouble(point2String[0]);point2lat=Double.parseDouble(point2String[1]);}else{throw{message:"Number Format Exception",name:"Format Exception",stack:null};} +route.addPoint(new sec.geo.GeoPoint(point1lon,point1lat));route.addPoint(new sec.geo.GeoPoint(point2lon,point2lat));route.setLeftWidth((attributes.AM_DISTANCE.get(2*i)).doubleValue());route.setRightWidth((attributes.AM_DISTANCE.get(2*i+1)).doubleValue());route.setMinAltitude((attributes.X_ALTITUDE_DEPTH.get(2*i)).doubleValue());route.setMaxAltitude((attributes.X_ALTITUDE_DEPTH.get(2*i+1)).doubleValue());track.addRoute(route);} +pointArrayStringList=kmlRender.getKml(track,id,name,description,lineColor,fillColor);}else{throw{message:"Invalid Number of Points",name:"Point Exception",stack:null};}}catch(e){throw e;} +return pointArrayStringList;};sec.web.renderer.Shape3DHandler.CYLINDER="CYLINDER-------";sec.web.renderer.Shape3DHandler.ORBIT="ORBIT----------";sec.web.renderer.Shape3DHandler.ROUTE="ROUTE----------";sec.web.renderer.Shape3DHandler.POLYGON="POLYGON--------";sec.web.renderer.Shape3DHandler.RADARC="RADARC---------";sec.web.renderer.Shape3DHandler.POLYARC="POLYARC--------";sec.web.renderer.Shape3DHandler.CAKE="CAKE-----------";sec.web.renderer.Shape3DHandler.TRACK="TRACK----------";sec.web.renderer.Shape3DHandler.ATTRIBUTES="attributes";sec.web.renderer.Shape3DHandler.MIN_ALT="minalt";sec.web.renderer.Shape3DHandler.MAX_ALT="maxalt";sec.web.renderer.Shape3DHandler.RADIUS1="radius1";sec.web.renderer.Shape3DHandler.RADIUS2="radius2";sec.web.renderer.Shape3DHandler.LEFT_AZIMUTH="leftazimuth";sec.web.renderer.Shape3DHandler.RIGHT_AZIMUTH="rightazimuth";sec.web.renderer.Shape3DHandler.MIN_ALT_DEFAULT=0.0;sec.web.renderer.Shape3DHandler.MAX_ALT_DEFAULT=100.0;sec.web.renderer.Shape3DHandler.RADIUS1_DEFAULT=50.0;sec.web.renderer.Shape3DHandler.RADIUS2_DEFAULT=100.0;sec.web.renderer.Shape3DHandler.LEFT_AZIMUTH_DEFAULT=0.0;sec.web.renderer.Shape3DHandler.RIGHT_AZIMUTH_DEFAULT=90.0;sec.web.renderer.Shape3DHandler.DEFAULT_ATTRIBUTES="[{radius1:50.0,radius2:100.0,minalt:0.0,maxalt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}]";sec.web.renderer.Shape3DHandler.ERR_ATRIBUTES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"The attribute paramaters are not formatted correctly";sec.web.renderer.Shape3DHandler.ERR_COORDINATES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"There was an error creating the Symbol - the coordinates were not formatted correctly";sec.web.renderer.Shape3DHandler.ERR_GENERAL_ERROR="{\"type\":\"error\",\"error\":\"There was an error creating the Symbol - An unknown error occurred. Please refer to the stack trace";sec.web.renderer.Shape3DHandler.ERR_INVALID_NUMBER_POINTS_ERROR="{\"type\":\"error\",\"error\":\"Not enough points were passed in to create a graphic.";var sec=sec||{};sec.web=sec.web||{};sec.web.renderer=sec.web.renderer||{};sec.web.renderer.SECWebRenderer=(function(){var CYLINDER="CYLINDER-------",ORBIT="ORBIT----------",ROUTE="ROUTE----------",POLYGON="POLYGON--------",RADARC="RADARC---------",POLYARC="POLYARC--------",CAKE="CAKE-----------",TRACK="TRACK----------",CURTAIN="CURTAIN--------",ATTRIBUTES="attributes",MIN_ALT="minalt",MAX_ALT="maxalt",RADIUS1="radius1",RADIUS2="radius2",LEFT_AZIMUTH="leftAzimuth",RIGHT_AZIMUTH="rightAzimuth",MIN_ALT_DEFAULT=0.0,MAX_ALT_DEFAULT=100.0,RADIUS1_DEFAULT=50.0,RADIUS2_DEFAULT=100.0,LEFT_AZIMUTH_DEFAULT=0.0,RIGHT_AZIMUTH_DEFAULT=90.0,ERR_ATTRIBUTES_NOT_FORMATTED="{\"type\":\"error\",\"error\":\"The attribute paramaters are not formatted correctly",DEFAULT_ATTRIBUTES="[{radius1:50.0,radius2:100.0,minalt:0.0,maxalt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}]",spsPortNumber=-1,ErrorLogger=armyc2.c2sd.renderer.utilities.ErrorLogger,SymbolUtilities=armyc2.c2sd.renderer.utilities.SymbolUtilities,JavaRendererUtilities=sec.web.renderer.utilities.JavaRendererUtilities,Shape3DHandler=sec.web.renderer.Shape3DHandler,MilStdIconRenderer=null;if(armyc2.c2sd.renderer.MilStdIconRenderer) +{MilStdIconRenderer=armyc2.c2sd.renderer.MilStdIconRenderer;} +else +{armyc2.c2sd.renderer.utilities.SymbolDefTable.init();} +return{setLoggingLevel:function(level) +{ErrorLogger.setLevel(level);},RenderSymbol:function(id,name,description,symbolCode,controlPoints,altitudeMode,scale,bbox,modifiers,format,symStd,converter,fontInfo) +{var output="";try +{sec.web.renderer.utilities.JavaRendererUtilities.addAltModeToModifiersString(modifiers,altitudeMode);if(altitudeMode!=="clampToGround"&&format===0&&JavaRendererUtilities.is3dSymbol(symbolCode,modifiers)) +{if(!(altitudeMode)) +altitudeMode="absolute";output=this.RenderMilStd3dSymbol(name,id,symbolCode,description,altitudeMode,controlPoints,modifiers);var modifierKML=sec.web.renderer.MultiPointHandler.getModifierKML(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd);modifierKML+="";output=output.replace("",modifierKML);if(output===""){output=sec.web.renderer.MultiPointHandler.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd,converter,fontInfo);}} +else +{output=sec.web.renderer.MultiPointHandler.RenderSymbol(id,name,description,symbolCode,controlPoints,scale,bbox,modifiers,format,symStd,converter,fontInfo);} +return output;} +catch(err) +{output="{\"type\":'error',error:'There was an error creating the MilStdSymbol - "+err.name+":"+err.message+"'}";ErrorLogger.LogException("SECWebRenderer","RenderSymbol",err,ErrorLogger.WARNING);} +return output;},RenderSymbol2D:function(id,name,description,symbolCode,controlPoints,pixelWidth,pixelHeight,bbox,modifiers,format,symStd,fontInfo,converter) +{var output="";try +{output=sec.web.renderer.MultiPointHandler.RenderSymbol2D(id,name,description,symbolCode,controlPoints,pixelWidth,pixelHeight,bbox,modifiers,format,symStd,fontInfo,converter);} +catch(exc) +{output="{\"type\":'error',error:'There was an error creating the MilStdSymbol: "+symbolCode+" - "+exc.toString()+"'}";ErrorLogger.LogException("SECWebRenderer","RenderSymbol2D",exc,ErrorLogger.WARNING);} +return output;},Render3dSymbol:function(name,id,shapeType,description,lineColor,fillColor,controlPoints,AttributesArray) +{var returnValue="";try{var attributes={};attributes.AM_DISTANCE=new java.util.ArrayList();attributes.X_ALTITUDE_DEPTH=new java.util.ArrayList();attributes.AN_AZIMUTH=new java.util.ArrayList();attributes.ALT_MODE=[];if(AttributesArray===null||attributes===""){AttributesArray=[{innerRadius:50.0,radius:100.0,minAlt:0.0,maxAlt:100.0,rightAzimuth:90.0,leftAzimuth:0.0}];} +var attributesArrayLength=AttributesArray.length;if(attributesArrayLength>0){for(var i=0;i0) +{sb+=(",");} +info=jsa[i];var modifiers=JavaRendererUtilities.createParameterMapFromURL(info);var symbolID=modifiers["SYMBOLID"];modifiers["RENDER"]=false;var ii=MilStdIconRenderer.Render(symbolID,modifiers);var anchor=ii.getCenterPoint();var symbolBounds=ii.getSymbolBounds();var iconSize=ii.getImageBounds();var item="";item+=("{\"x\":");item+=(anchor.getX());item+=(",\"y\":");item+=(anchor.getY());item+=(",\"boundsx\":");item+=(symbolBounds.getX());item+=(",\"boundsy\":");item+=(symbolBounds.getY());item+=(",\"boundswidth\":");item+=(symbolBounds.getWidth());item+=(",\"boundsheight\":");item+=(symbolBounds.getHeight());item+=(",\"iconwidth\":");item+=(iconSize.getWidth());item+=(",\"iconheight\":");item+=(iconSize.getHeight());item+=("}");sb+=(item);} +sb+=("]}");}} +catch(exc) +{ErrorLogger.LogException("SECWebRenderer","getSinglePointInfoBatch",exc);} +return sb;},setDefaultSymbologyStandard:function(symStd) +{armyc2.c2sd.renderer.utilities.RendererSettings.setSymbologyStandard(symStd);}};}());function Matrix3(column0Row0,column1Row0,column2Row0,column0Row1,column1Row1,column2Row1,column0Row2,column1Row2,column2Row2){this[0]=defaultValue(column0Row0,0.0);this[1]=defaultValue(column0Row1,0.0);this[2]=defaultValue(column0Row2,0.0);this[3]=defaultValue(column1Row0,0.0);this[4]=defaultValue(column1Row1,0.0);this[5]=defaultValue(column1Row2,0.0);this[6]=defaultValue(column2Row0,0.0);this[7]=defaultValue(column2Row1,0.0);this[8]=defaultValue(column2Row2,0.0);} +Matrix3.packedLength=9;Matrix3.pack=function(value,array,startingIndex){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);array[startingIndex++]=value[0];array[startingIndex++]=value[1];array[startingIndex++]=value[2];array[startingIndex++]=value[3];array[startingIndex++]=value[4];array[startingIndex++]=value[5];array[startingIndex++]=value[6];array[startingIndex++]=value[7];array[startingIndex++]=value[8];return array;};Matrix3.unpack=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);if(!defined(result)){result=new Matrix3();} +result[0]=array[startingIndex++];result[1]=array[startingIndex++];result[2]=array[startingIndex++];result[3]=array[startingIndex++];result[4]=array[startingIndex++];result[5]=array[startingIndex++];result[6]=array[startingIndex++];result[7]=array[startingIndex++];result[8]=array[startingIndex++];return result;};Matrix3.clone=function(values,result){if(!defined(values)){return undefined;} +if(!defined(result)){return new Matrix3(values[0],values[3],values[6],values[1],values[4],values[7],values[2],values[5],values[8]);} +result[0]=values[0];result[1]=values[1];result[2]=values[2];result[3]=values[3];result[4]=values[4];result[5]=values[5];result[6]=values[6];result[7]=values[7];result[8]=values[8];return result;};Matrix3.fromArray=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);if(!defined(result)){result=new Matrix3();} +result[0]=array[startingIndex];result[1]=array[startingIndex+1];result[2]=array[startingIndex+2];result[3]=array[startingIndex+3];result[4]=array[startingIndex+4];result[5]=array[startingIndex+5];result[6]=array[startingIndex+6];result[7]=array[startingIndex+7];result[8]=array[startingIndex+8];return result;};Matrix3.fromColumnMajorArray=function(values,result){if(!defined(values)){throw new DeveloperError('values parameter is required');} +return Matrix3.clone(values,result);};Matrix3.fromRowMajorArray=function(values,result){if(!defined(values)){throw new DeveloperError('values is required.');} +if(!defined(result)){return new Matrix3(values[0],values[1],values[2],values[3],values[4],values[5],values[6],values[7],values[8]);} +result[0]=values[0];result[1]=values[3];result[2]=values[6];result[3]=values[1];result[4]=values[4];result[5]=values[7];result[6]=values[2];result[7]=values[5];result[8]=values[8];return result;};Matrix3.fromQuaternion=function(quaternion,result){if(!defined(quaternion)){throw new DeveloperError('quaternion is required');} +var x2=quaternion.x*quaternion.x;var xy=quaternion.x*quaternion.y;var xz=quaternion.x*quaternion.z;var xw=quaternion.x*quaternion.w;var y2=quaternion.y*quaternion.y;var yz=quaternion.y*quaternion.z;var yw=quaternion.y*quaternion.w;var z2=quaternion.z*quaternion.z;var zw=quaternion.z*quaternion.w;var w2=quaternion.w*quaternion.w;var m00=x2-y2-z2+w2;var m01=2.0*(xy-zw);var m02=2.0*(xz+yw);var m10=2.0*(xy+zw);var m11=-x2+y2-z2+w2;var m12=2.0*(yz-xw);var m20=2.0*(xz-yw);var m21=2.0*(yz+xw);var m22=-x2-y2+z2+w2;if(!defined(result)){return new Matrix3(m00,m01,m02,m10,m11,m12,m20,m21,m22);} +result[0]=m00;result[1]=m10;result[2]=m20;result[3]=m01;result[4]=m11;result[5]=m21;result[6]=m02;result[7]=m12;result[8]=m22;return result;};Matrix3.fromHeadingPitchRoll=function(headingPitchRoll,result){if(!defined(headingPitchRoll)){throw new DeveloperError('headingPitchRoll is required');} +var cosTheta=Math.cos(-headingPitchRoll.pitch);var cosPsi=Math.cos(-headingPitchRoll.heading);var cosPhi=Math.cos(headingPitchRoll.roll);var sinTheta=Math.sin(-headingPitchRoll.pitch);var sinPsi=Math.sin(-headingPitchRoll.heading);var sinPhi=Math.sin(headingPitchRoll.roll);var m00=cosTheta*cosPsi;var m01=-cosPhi*sinPsi+sinPhi*sinTheta*cosPsi;var m02=sinPhi*sinPsi+cosPhi*sinTheta*cosPsi;var m10=cosTheta*sinPsi;var m11=cosPhi*cosPsi+sinPhi*sinTheta*sinPsi;var m12=-sinTheta*cosPhi+cosPhi*sinTheta*sinPsi;var m20=-sinTheta;var m21=sinPhi*cosTheta;var m22=cosPhi*cosTheta;if(!defined(result)){return new Matrix3(m00,m01,m02,m10,m11,m12,m20,m21,m22);} +result[0]=m00;result[1]=m10;result[2]=m20;result[3]=m01;result[4]=m11;result[5]=m21;result[6]=m02;result[7]=m12;result[8]=m22;return result;};Matrix3.fromScale=function(scale,result){if(!defined(scale)){throw new DeveloperError('scale is required.');} +if(!defined(result)){return new Matrix3(scale.x,0.0,0.0,0.0,scale.y,0.0,0.0,0.0,scale.z);} +result[0]=scale.x;result[1]=0.0;result[2]=0.0;result[3]=0.0;result[4]=scale.y;result[5]=0.0;result[6]=0.0;result[7]=0.0;result[8]=scale.z;return result;};Matrix3.fromUniformScale=function(scale,result){if(typeof scale!=='number'){throw new DeveloperError('scale is required.');} +if(!defined(result)){return new Matrix3(scale,0.0,0.0,0.0,scale,0.0,0.0,0.0,scale);} +result[0]=scale;result[1]=0.0;result[2]=0.0;result[3]=0.0;result[4]=scale;result[5]=0.0;result[6]=0.0;result[7]=0.0;result[8]=scale;return result;};Matrix3.fromCrossProduct=function(vector,result){if(!defined(vector)){throw new DeveloperError('vector is required.');} +if(!defined(result)){return new Matrix3(0.0,-vector.z,vector.y,vector.z,0.0,-vector.x,-vector.y,vector.x,0.0);} +result[0]=0.0;result[1]=vector.z;result[2]=-vector.y;result[3]=-vector.z;result[4]=0.0;result[5]=vector.x;result[6]=vector.y;result[7]=-vector.x;result[8]=0.0;return result;};Matrix3.fromRotationX=function(angle,result){if(!defined(angle)){throw new DeveloperError('angle is required.');} +var cosAngle=Math.cos(angle);var sinAngle=Math.sin(angle);if(!defined(result)){return new Matrix3(1.0,0.0,0.0,0.0,cosAngle,-sinAngle,0.0,sinAngle,cosAngle);} +result[0]=1.0;result[1]=0.0;result[2]=0.0;result[3]=0.0;result[4]=cosAngle;result[5]=sinAngle;result[6]=0.0;result[7]=-sinAngle;result[8]=cosAngle;return result;};Matrix3.fromRotationY=function(angle,result){if(!defined(angle)){throw new DeveloperError('angle is required.');} +var cosAngle=Math.cos(angle);var sinAngle=Math.sin(angle);if(!defined(result)){return new Matrix3(cosAngle,0.0,sinAngle,0.0,1.0,0.0,-sinAngle,0.0,cosAngle);} +result[0]=cosAngle;result[1]=0.0;result[2]=-sinAngle;result[3]=0.0;result[4]=1.0;result[5]=0.0;result[6]=sinAngle;result[7]=0.0;result[8]=cosAngle;return result;};Matrix3.fromRotationZ=function(angle,result){if(!defined(angle)){throw new DeveloperError('angle is required.');} +var cosAngle=Math.cos(angle);var sinAngle=Math.sin(angle);if(!defined(result)){return new Matrix3(cosAngle,-sinAngle,0.0,sinAngle,cosAngle,0.0,0.0,0.0,1.0);} +result[0]=cosAngle;result[1]=sinAngle;result[2]=0.0;result[3]=-sinAngle;result[4]=cosAngle;result[5]=0.0;result[6]=0.0;result[7]=0.0;result[8]=1.0;return result;};Matrix3.toArray=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(result)){return[matrix[0],matrix[1],matrix[2],matrix[3],matrix[4],matrix[5],matrix[6],matrix[7],matrix[8]];} +result[0]=matrix[0];result[1]=matrix[1];result[2]=matrix[2];result[3]=matrix[3];result[4]=matrix[4];result[5]=matrix[5];result[6]=matrix[6];result[7]=matrix[7];result[8]=matrix[8];return result;};Matrix3.getElementIndex=function(column,row){if(typeof row!=='number'||row<0||row>2){throw new DeveloperError('row must be 0, 1, or 2.');} +if(typeof column!=='number'||column<0||column>2){throw new DeveloperError('column must be 0, 1, or 2.');} +return column*3+row;};Matrix3.getColumn=function(matrix,index,result){if(!defined(matrix)){throw new DeveloperError('matrix is required.');} +if(typeof index!=='number'||index<0||index>2){throw new DeveloperError('index must be 0, 1, or 2.');} +if(!defined(result)){throw new DeveloperError('result is required');} +var startIndex=index*3;var x=matrix[startIndex];var y=matrix[startIndex+1];var z=matrix[startIndex+2];result.x=x;result.y=y;result.z=z;return result;};Matrix3.setColumn=function(matrix,index,cartesian,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(typeof index!=='number'||index<0||index>2){throw new DeveloperError('index must be 0, 1, or 2.');} +if(!defined(result)){throw new DeveloperError('result is required');} +result=Matrix3.clone(matrix,result);var startIndex=index*3;result[startIndex]=cartesian.x;result[startIndex+1]=cartesian.y;result[startIndex+2]=cartesian.z;return result;};Matrix3.getRow=function(matrix,index,result){if(!defined(matrix)){throw new DeveloperError('matrix is required.');} +if(typeof index!=='number'||index<0||index>2){throw new DeveloperError('index must be 0, 1, or 2.');} +if(!defined(result)){throw new DeveloperError('result is required');} +var x=matrix[index];var y=matrix[index+3];var z=matrix[index+6];result.x=x;result.y=y;result.z=z;return result;};Matrix3.setRow=function(matrix,index,cartesian,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(typeof index!=='number'||index<0||index>2){throw new DeveloperError('index must be 0, 1, or 2.');} +if(!defined(result)){throw new DeveloperError('result is required');} +result=Matrix3.clone(matrix,result);result[index]=cartesian.x;result[index+3]=cartesian.y;result[index+6]=cartesian.z;return result;};var scratchColumn=new Cartesian3();Matrix3.getScale=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required.');} +if(!defined(result)){throw new DeveloperError('result is required');} +result.x=Cartesian3.magnitude(Cartesian3.fromElements(matrix[0],matrix[1],matrix[2],scratchColumn));result.y=Cartesian3.magnitude(Cartesian3.fromElements(matrix[3],matrix[4],matrix[5],scratchColumn));result.z=Cartesian3.magnitude(Cartesian3.fromElements(matrix[6],matrix[7],matrix[8],scratchColumn));return result;};var scratchScale=new Cartesian3();Matrix3.getMaximumScale=function(matrix){Matrix3.getScale(matrix,scratchScale);return Cartesian3.maximumComponent(scratchScale);};Matrix3.multiply=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var column0Row0=left[0]*right[0]+left[3]*right[1]+left[6]*right[2];var column0Row1=left[1]*right[0]+left[4]*right[1]+left[7]*right[2];var column0Row2=left[2]*right[0]+left[5]*right[1]+left[8]*right[2];var column1Row0=left[0]*right[3]+left[3]*right[4]+left[6]*right[5];var column1Row1=left[1]*right[3]+left[4]*right[4]+left[7]*right[5];var column1Row2=left[2]*right[3]+left[5]*right[4]+left[8]*right[5];var column2Row0=left[0]*right[6]+left[3]*right[7]+left[6]*right[8];var column2Row1=left[1]*right[6]+left[4]*right[7]+left[7]*right[8];var column2Row2=left[2]*right[6]+left[5]*right[7]+left[8]*right[8];result[0]=column0Row0;result[1]=column0Row1;result[2]=column0Row2;result[3]=column1Row0;result[4]=column1Row1;result[5]=column1Row2;result[6]=column2Row0;result[7]=column2Row1;result[8]=column2Row2;return result;};Matrix3.add=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=left[0]+right[0];result[1]=left[1]+right[1];result[2]=left[2]+right[2];result[3]=left[3]+right[3];result[4]=left[4]+right[4];result[5]=left[5]+right[5];result[6]=left[6]+right[6];result[7]=left[7]+right[7];result[8]=left[8]+right[8];return result;};Matrix3.subtract=function(left,right,result){if(!defined(left)){throw new DeveloperError('left is required');} +if(!defined(right)){throw new DeveloperError('right is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=left[0]-right[0];result[1]=left[1]-right[1];result[2]=left[2]-right[2];result[3]=left[3]-right[3];result[4]=left[4]-right[4];result[5]=left[5]-right[5];result[6]=left[6]-right[6];result[7]=left[7]-right[7];result[8]=left[8]-right[8];return result;};Matrix3.multiplyByVector=function(matrix,cartesian,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(cartesian)){throw new DeveloperError('cartesian is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var vX=cartesian.x;var vY=cartesian.y;var vZ=cartesian.z;var x=matrix[0]*vX+matrix[3]*vY+matrix[6]*vZ;var y=matrix[1]*vX+matrix[4]*vY+matrix[7]*vZ;var z=matrix[2]*vX+matrix[5]*vY+matrix[8]*vZ;result.x=x;result.y=y;result.z=z;return result;};Matrix3.multiplyByScalar=function(matrix,scalar,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(typeof scalar!=='number'){throw new DeveloperError('scalar must be a number');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=matrix[0]*scalar;result[1]=matrix[1]*scalar;result[2]=matrix[2]*scalar;result[3]=matrix[3]*scalar;result[4]=matrix[4]*scalar;result[5]=matrix[5]*scalar;result[6]=matrix[6]*scalar;result[7]=matrix[7]*scalar;result[8]=matrix[8]*scalar;return result;};Matrix3.multiplyByScale=function(matrix,scale,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(scale)){throw new DeveloperError('scale is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=matrix[0]*scale.x;result[1]=matrix[1]*scale.x;result[2]=matrix[2]*scale.x;result[3]=matrix[3]*scale.y;result[4]=matrix[4]*scale.y;result[5]=matrix[5]*scale.y;result[6]=matrix[6]*scale.z;result[7]=matrix[7]*scale.z;result[8]=matrix[8]*scale.z;return result;};Matrix3.negate=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=-matrix[0];result[1]=-matrix[1];result[2]=-matrix[2];result[3]=-matrix[3];result[4]=-matrix[4];result[5]=-matrix[5];result[6]=-matrix[6];result[7]=-matrix[7];result[8]=-matrix[8];return result;};Matrix3.transpose=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var column0Row0=matrix[0];var column0Row1=matrix[3];var column0Row2=matrix[6];var column1Row0=matrix[1];var column1Row1=matrix[4];var column1Row2=matrix[7];var column2Row0=matrix[2];var column2Row1=matrix[5];var column2Row2=matrix[8];result[0]=column0Row0;result[1]=column0Row1;result[2]=column0Row2;result[3]=column1Row0;result[4]=column1Row1;result[5]=column1Row2;result[6]=column2Row0;result[7]=column2Row1;result[8]=column2Row2;return result;};function computeFrobeniusNorm(matrix){var norm=0.0;for(var i=0;i<9;++i){var temp=matrix[i];norm+=temp*temp;} +return Math.sqrt(norm);} +var rowVal=[1,0,0];var colVal=[2,2,1];function offDiagonalFrobeniusNorm(matrix){var norm=0.0;for(var i=0;i<3;++i){var temp=matrix[Matrix3.getElementIndex(colVal[i],rowVal[i])];norm+=2.0*temp*temp;} +return Math.sqrt(norm);} +function shurDecomposition(matrix,result){var tolerance=CesiumMath.EPSILON15;var maxDiagonal=0.0;var rotAxis=1;for(var i=0;i<3;++i){var temp=Math.abs(matrix[Matrix3.getElementIndex(colVal[i],rowVal[i])]);if(temp>maxDiagonal){rotAxis=i;maxDiagonal=temp;}} +var c=1.0;var s=0.0;var p=rowVal[rotAxis];var q=colVal[rotAxis];if(Math.abs(matrix[Matrix3.getElementIndex(q,p)])>tolerance){var qq=matrix[Matrix3.getElementIndex(q,q)];var pp=matrix[Matrix3.getElementIndex(p,p)];var qp=matrix[Matrix3.getElementIndex(q,p)];var tau=(qq-pp)/2.0/qp;var t;if(tau<0.0){t=-1.0/(-tau+Math.sqrt(1.0+tau*tau));}else{t=1.0/(tau+Math.sqrt(1.0+tau*tau));} +c=1.0/Math.sqrt(1.0+t*t);s=t*c;} +result=Matrix3.clone(Matrix3.IDENTITY,result);result[Matrix3.getElementIndex(p,p)]=result[Matrix3.getElementIndex(q,q)]=c;result[Matrix3.getElementIndex(q,p)]=s;result[Matrix3.getElementIndex(p,q)]=-s;return result;} +var jMatrix=new Matrix3();var jMatrixTranspose=new Matrix3();Matrix3.computeEigenDecomposition=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required.');} +var tolerance=CesiumMath.EPSILON20;var maxSweeps=10;var count=0;var sweep=0;if(!defined(result)){result={};} +var unitaryMatrix=result.unitary=Matrix3.clone(Matrix3.IDENTITY,result.unitary);var diagMatrix=result.diagonal=Matrix3.clone(matrix,result.diagonal);var epsilon=tolerance*computeFrobeniusNorm(diagMatrix);while(sweepepsilon){shurDecomposition(diagMatrix,jMatrix);Matrix3.transpose(jMatrix,jMatrixTranspose);Matrix3.multiply(diagMatrix,jMatrix,diagMatrix);Matrix3.multiply(jMatrixTranspose,diagMatrix,diagMatrix);Matrix3.multiply(unitaryMatrix,jMatrix,unitaryMatrix);if(++count>2){++sweep;count=0;}} +return result;};Matrix3.abs=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +result[0]=Math.abs(matrix[0]);result[1]=Math.abs(matrix[1]);result[2]=Math.abs(matrix[2]);result[3]=Math.abs(matrix[3]);result[4]=Math.abs(matrix[4]);result[5]=Math.abs(matrix[5]);result[6]=Math.abs(matrix[6]);result[7]=Math.abs(matrix[7]);result[8]=Math.abs(matrix[8]);return result;};Matrix3.determinant=function(matrix){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +var m11=matrix[0];var m21=matrix[3];var m31=matrix[6];var m12=matrix[1];var m22=matrix[4];var m32=matrix[7];var m13=matrix[2];var m23=matrix[5];var m33=matrix[8];return m11*(m22*m33-m23*m32)+m12*(m23*m31-m21*m33)+m13*(m21*m32-m22*m31);};Matrix3.inverse=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required');} +if(!defined(result)){throw new DeveloperError('result is required');} +var m11=matrix[0];var m21=matrix[1];var m31=matrix[2];var m12=matrix[3];var m22=matrix[4];var m32=matrix[5];var m13=matrix[6];var m23=matrix[7];var m33=matrix[8];var determinant=Matrix3.determinant(matrix);if(Math.abs(determinant)<=CesiumMath.EPSILON15){throw new DeveloperError('matrix is not invertible');} +result[0]=m22*m33-m23*m32;result[1]=m23*m31-m21*m33;result[2]=m21*m32-m22*m31;result[3]=m13*m32-m12*m33;result[4]=m11*m33-m13*m31;result[5]=m12*m31-m11*m32;result[6]=m12*m23-m13*m22;result[7]=m13*m21-m11*m23;result[8]=m11*m22-m12*m21;var scale=1.0/determinant;return Matrix3.multiplyByScalar(result,scale,result);};Matrix3.equals=function(left,right){return(left===right)||(defined(left)&&defined(right)&&left[0]===right[0]&&left[1]===right[1]&&left[2]===right[2]&&left[3]===right[3]&&left[4]===right[4]&&left[5]===right[5]&&left[6]===right[6]&&left[7]===right[7]&&left[8]===right[8]);};Matrix3.equalsEpsilon=function(left,right,epsilon){if(typeof epsilon!=='number'){throw new DeveloperError('epsilon must be a number');} +return(left===right)||(defined(left)&&defined(right)&&Math.abs(left[0]-right[0])<=epsilon&&Math.abs(left[1]-right[1])<=epsilon&&Math.abs(left[2]-right[2])<=epsilon&&Math.abs(left[3]-right[3])<=epsilon&&Math.abs(left[4]-right[4])<=epsilon&&Math.abs(left[5]-right[5])<=epsilon&&Math.abs(left[6]-right[6])<=epsilon&&Math.abs(left[7]-right[7])<=epsilon&&Math.abs(left[8]-right[8])<=epsilon);};Matrix3.IDENTITY=freezeObject(new Matrix3(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0));Matrix3.ZERO=freezeObject(new Matrix3(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0));Matrix3.COLUMN0ROW0=0;Matrix3.COLUMN0ROW1=1;Matrix3.COLUMN0ROW2=2;Matrix3.COLUMN1ROW0=3;Matrix3.COLUMN1ROW1=4;Matrix3.COLUMN1ROW2=5;Matrix3.COLUMN2ROW0=6;Matrix3.COLUMN2ROW1=7;Matrix3.COLUMN2ROW2=8;defineProperties(Matrix3.prototype,{length:{get:function(){return Matrix3.packedLength;}}});Matrix3.prototype.clone=function(result){return Matrix3.clone(this,result);};Matrix3.prototype.equals=function(right){return Matrix3.equals(this,right);};Matrix3.equalsArray=function(matrix,array,offset){return matrix[0]===array[offset]&&matrix[1]===array[offset+1]&&matrix[2]===array[offset+2]&&matrix[3]===array[offset+3]&&matrix[4]===array[offset+4]&&matrix[5]===array[offset+5]&&matrix[6]===array[offset+6]&&matrix[7]===array[offset+7]&&matrix[8]===array[offset+8];};Matrix3.prototype.equalsEpsilon=function(right,epsilon){return Matrix3.equalsEpsilon(this,right,epsilon);};Matrix3.prototype.toString=function(){return'('+this[0]+', '+this[3]+', '+this[6]+')\n'+'('+this[1]+', '+this[4]+', '+this[7]+')\n'+'('+this[2]+', '+this[5]+', '+this[8]+')';};function VertexFormat(options){options=defaultValue(options,defaultValue.EMPTY_OBJECT);this.position=defaultValue(options.position,false);this.normal=defaultValue(options.normal,false);this.st=defaultValue(options.st,false);this.binormal=defaultValue(options.binormal,false);this.tangent=defaultValue(options.tangent,false);this.color=defaultValue(options.color,false);} +VertexFormat.POSITION_ONLY=freezeObject(new VertexFormat({position:true}));VertexFormat.POSITION_AND_NORMAL=freezeObject(new VertexFormat({position:true,normal:true}));VertexFormat.POSITION_NORMAL_AND_ST=freezeObject(new VertexFormat({position:true,normal:true,st:true}));VertexFormat.POSITION_AND_ST=freezeObject(new VertexFormat({position:true,st:true}));VertexFormat.POSITION_AND_COLOR=freezeObject(new VertexFormat({position:true,color:true}));VertexFormat.ALL=freezeObject(new VertexFormat({position:true,normal:true,st:true,binormal:true,tangent:true}));VertexFormat.DEFAULT=VertexFormat.POSITION_NORMAL_AND_ST;VertexFormat.packedLength=6;VertexFormat.pack=function(value,array,startingIndex){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);array[startingIndex++]=value.position?1.0:0.0;array[startingIndex++]=value.normal?1.0:0.0;array[startingIndex++]=value.st?1.0:0.0;array[startingIndex++]=value.binormal?1.0:0.0;array[startingIndex++]=value.tangent?1.0:0.0;array[startingIndex++]=value.color?1.0:0.0;return array;};VertexFormat.unpack=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);if(!defined(result)){result=new VertexFormat();} +result.position=array[startingIndex++]===1.0;result.normal=array[startingIndex++]===1.0;result.st=array[startingIndex++]===1.0;result.binormal=array[startingIndex++]===1.0;result.tangent=array[startingIndex++]===1.0;result.color=array[startingIndex++]===1.0;return result;};VertexFormat.clone=function(vertexFormat,result){if(!defined(vertexFormat)){return undefined;} +if(!defined(result)){result=new VertexFormat();} +result.position=vertexFormat.position;result.normal=vertexFormat.normal;result.st=vertexFormat.st;result.binormal=vertexFormat.binormal;result.tangent=vertexFormat.tangent;result.color=vertexFormat.color;return result;};function Quaternion(x,y,z,w){this.x=defaultValue(x,0.0);this.y=defaultValue(y,0.0);this.z=defaultValue(z,0.0);this.w=defaultValue(w,0.0);} +var fromAxisAngleScratch=new Cartesian3();Quaternion.fromAxisAngle=function(axis,angle,result){if(!defined(axis)){throw new DeveloperError('axis is required.');} +if(typeof angle!=='number'){throw new DeveloperError('angle is required and must be a number.');} +var halfAngle=angle/2.0;var s=Math.sin(halfAngle);fromAxisAngleScratch=Cartesian3.normalize(axis,fromAxisAngleScratch);var x=fromAxisAngleScratch.x*s;var y=fromAxisAngleScratch.y*s;var z=fromAxisAngleScratch.z*s;var w=Math.cos(halfAngle);if(!defined(result)){return new Quaternion(x,y,z,w);} +result.x=x;result.y=y;result.z=z;result.w=w;return result;};var fromRotationMatrixNext=[1,2,0];var fromRotationMatrixQuat=new Array(3);Quaternion.fromRotationMatrix=function(matrix,result){if(!defined(matrix)){throw new DeveloperError('matrix is required.');} +var root;var x;var y;var z;var w;var m00=matrix[Matrix3.COLUMN0ROW0];var m11=matrix[Matrix3.COLUMN1ROW1];var m22=matrix[Matrix3.COLUMN2ROW2];var trace=m00+m11+m22;if(trace>0.0){root=Math.sqrt(trace+1.0);w=0.5*root;root=0.5/root;x=(matrix[Matrix3.COLUMN1ROW2]-matrix[Matrix3.COLUMN2ROW1])*root;y=(matrix[Matrix3.COLUMN2ROW0]-matrix[Matrix3.COLUMN0ROW2])*root;z=(matrix[Matrix3.COLUMN0ROW1]-matrix[Matrix3.COLUMN1ROW0])*root;}else{var next=fromRotationMatrixNext;var i=0;if(m11>m00){i=1;} +if(m22>m00&&m22>m11){i=2;} +var j=next[i];var k=next[j];root=Math.sqrt(matrix[Matrix3.getElementIndex(i,i)]-matrix[Matrix3.getElementIndex(j,j)]-matrix[Matrix3.getElementIndex(k,k)]+1.0);var quat=fromRotationMatrixQuat;quat[i]=0.5*root;root=0.5/root;w=(matrix[Matrix3.getElementIndex(k,j)]-matrix[Matrix3.getElementIndex(j,k)])*root;quat[j]=(matrix[Matrix3.getElementIndex(j,i)]+matrix[Matrix3.getElementIndex(i,j)])*root;quat[k]=(matrix[Matrix3.getElementIndex(k,i)]+matrix[Matrix3.getElementIndex(i,k)])*root;x=-quat[0];y=-quat[1];z=-quat[2];} +if(!defined(result)){return new Quaternion(x,y,z,w);} +result.x=x;result.y=y;result.z=z;result.w=w;return result;};var scratchHPRQuaternion=new Quaternion();Quaternion.fromHeadingPitchRoll=function(heading,pitch,roll,result){if(!defined(heading)){throw new DeveloperError('heading is required.');} +if(!defined(pitch)){throw new DeveloperError('pitch is required.');} +if(!defined(roll)){throw new DeveloperError('roll is required.');} +var rollQuaternion=Quaternion.fromAxisAngle(Cartesian3.UNIT_X,roll,scratchHPRQuaternion);var pitchQuaternion=Quaternion.fromAxisAngle(Cartesian3.UNIT_Y,-pitch,result);result=Quaternion.multiply(pitchQuaternion,rollQuaternion,pitchQuaternion);var headingQuaternion=Quaternion.fromAxisAngle(Cartesian3.UNIT_Z,-heading,scratchHPRQuaternion);return Quaternion.multiply(headingQuaternion,result,result);};var sampledQuaternionAxis=new Cartesian3();var sampledQuaternionRotation=new Cartesian3();var sampledQuaternionTempQuaternion=new Quaternion();var sampledQuaternionQuaternion0=new Quaternion();var sampledQuaternionQuaternion0Conjugate=new Quaternion();Quaternion.packedLength=4;Quaternion.pack=function(value,array,startingIndex){if(!defined(value)){throw new DeveloperError('value is required');} +if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);array[startingIndex++]=value.x;array[startingIndex++]=value.y;array[startingIndex++]=value.z;array[startingIndex]=value.w;return array;};Quaternion.unpack=function(array,startingIndex,result){if(!defined(array)){throw new DeveloperError('array is required');} +startingIndex=defaultValue(startingIndex,0);if(!defined(result)){result=new Quaternion();} +result.x=array[startingIndex];result.y=array[startingIndex+1];result.z=array[startingIndex+2];result.w=array[startingIndex+3];return result;};Quaternion.packedInterpolationLength=3;Quaternion.convertPackedArrayForInterpolation=function(packedArray,startingIndex,lastIndex,result){Quaternion.unpack(packedArray,lastIndex*4,sampledQuaternionQuaternion0Conjugate);Quaternion.conjugate(sampledQuaternionQuaternion0Conjugate,sampledQuaternionQuaternion0Conjugate);for(var i=0,len=lastIndex-startingIndex+1;i=CesiumMath.SIXTY_FOUR_KILOBYTES){return new Uint32Array(indicesLengthOrArray);} +return new Uint16Array(indicesLengthOrArray);};var EllipseGeometryLibrary={};var rotAxis=new Cartesian3();var tempVec=new Cartesian3();var unitQuat=new Quaternion();var rotMtx=new Matrix3();EllipseGeometryLibrary.pointOnEllipsoid=function(theta,rotation,northVec,eastVec,aSqr,ab,bSqr,mag,unitPos,result){var azimuth=theta+rotation;Cartesian3.multiplyByScalar(eastVec,Math.cos(azimuth),rotAxis);Cartesian3.multiplyByScalar(northVec,Math.sin(azimuth),tempVec);Cartesian3.add(rotAxis,tempVec,rotAxis);var cosThetaSquared=Math.cos(theta);cosThetaSquared=cosThetaSquared*cosThetaSquared;var sinThetaSquared=Math.sin(theta);sinThetaSquared=sinThetaSquared*sinThetaSquared;var radius=ab/Math.sqrt(bSqr*cosThetaSquared+aSqr*sinThetaSquared);var angle=radius/mag;Quaternion.fromAxisAngle(rotAxis,angle,unitQuat);Matrix3.fromQuaternion(unitQuat,rotMtx);Matrix3.multiplyByVector(rotMtx,unitPos,result);Cartesian3.normalize(result,result);Cartesian3.multiplyByScalar(result,mag,result);return result;} +var scratchCartesian1=new Cartesian3();var scratchCartesian2=new Cartesian3();var scratchCartesian3=new Cartesian3();var scratchNormal=new Cartesian3();EllipseGeometryLibrary.raisePositionsToHeight=function(positions,options,extrude){var ellipsoid=options.ellipsoid;var height=options.height;var extrudedHeight=options.extrudedHeight;var size=(extrude)?positions.length/3*2:positions.length/3;var finalPositions=new Float64Array(size*3);var length=positions.length;var bottomOffset=(extrude)?length:0;for(var i=0;i1;--i){theta=CesiumMath.PI_OVER_TWO-(i-1)*deltaTheta;position=this.pointOnEllipsoid(-theta,rotation,northVec,eastVec,aSqr,ab,bSqr,mag,unitPos,position);reflectedPosition=this.pointOnEllipsoid(theta+Math.PI,rotation,northVec,eastVec,aSqr,ab,bSqr,mag,unitPos,reflectedPosition);if(addFillPositions){positions[positionIndex++]=position.x;positions[positionIndex++]=position.y;positions[positionIndex++]=position.z;numInterior=2*(i-1)+2;for(j=1;j1.0);var vertexFormat=defaultValue(options.vertexFormat,VertexFormat.DEFAULT);if(!defined(center)){throw new DeveloperError('center is required.');} +if(!defined(semiMajorAxis)){throw new DeveloperError('semiMajorAxis is required.');} +if(!defined(semiMinorAxis)){throw new DeveloperError('semiMinorAxis is required.');} +if(semiMajorAxis1;--i){indices[indicesIndex++]=prevIndex++;indices[indicesIndex++]=prevIndex;indices[indicesIndex++]=positionIndex;numInterior=2*i;for(j=0;j with the reference URI: . @@ -300,7 +303,29 @@ define( [ "module", var a = doc.createElement( "a" ); a.href = uri; - return a.href; + result = a.href; + + // Interpret the result with respect to the reference uri. + + if ( relative ) { + + var aref = doc.createElement( "a" ); + aref.href = typeof relative === "string" ? relative : document.location.href; + aref.pathname = aref.pathname.replace( /[^/]*$/, "" ); + + var aref_ph = aref.protocol + "//" + aref.host; + + if ( result.substring( 0, aref.href.length ) === aref.href ) { + result = result.substring( aref.href.length ); + } else if ( result.substring( 0, aref_ph.length ) === aref_ph ) { + result = result.substring( aref_ph.length ); + } + + } + + // Return the result. + + return result; }, // -- merge -------------------------------------------------------------------------------- diff --git a/support/client/lib/vwf/utility/vertexSimplify/LICENSE b/support/client/lib/vwf/utility/vertexSimplify/LICENSE new file mode 100644 index 000000000..d4e133577 --- /dev/null +++ b/support/client/lib/vwf/utility/vertexSimplify/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012, Vladimir Agafonkin +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/support/client/lib/vwf/utility/vertexSimplify/README.md b/support/client/lib/vwf/utility/vertexSimplify/README.md new file mode 100644 index 000000000..f0f54bf04 --- /dev/null +++ b/support/client/lib/vwf/utility/vertexSimplify/README.md @@ -0,0 +1,13 @@ +Simplify.js is a high-performance JavaScript polyline simplification library by Vladimir Agafonkin, extracted from [Leaflet](http://leafletjs.com). + +Checkout the demo with docs: http://mourner.github.io/simplify-js/ + +#### Ports + + * Python: [omarestrella / simplify.py](https://github.com/omarestrella/simplify.py) (by Omar Estrella) + * PHP: [AKeN / simplify-php](https://github.com/AKeN/simplify-php) (by Rotari Gheorghe) + * Java: [ekeneijeoma / simplify-java](https://github.com/ekeneijeoma/simplify-java) (by Ekene Ijeoma) + * Java: [hgoebl / simplify-java](https://github.com/hgoebl/simplify-java) (by Heinrich Göbl) + * Processing: [ekeneijeoma / simplify-processing](https://github.com/ekeneijeoma/simplify-processing) (by Ekene Ijeoma) + * AS3: [fnicollet / simplify-as3](https://github.com/fnicollet/simplify-as3) (by Fabien Nicollet) + * Rust: [calvinmetcalf / simplify-rs](https://github.com/calvinmetcalf/simplify-rs) (by Calvin Metcalf) diff --git a/support/client/lib/vwf/utility/vertexSimplify/simplify.js b/support/client/lib/vwf/utility/vertexSimplify/simplify.js new file mode 100644 index 000000000..1dc62fef3 --- /dev/null +++ b/support/client/lib/vwf/utility/vertexSimplify/simplify.js @@ -0,0 +1,132 @@ +/* + (c) 2013, Vladimir Agafonkin + Simplify.js, a high-performance JS polyline simplification library + mourner.github.io/simplify-js +*/ +define ( function() { + 'use strict'; + // Modified from original Simplify.js npm module to correct script errors thrown on define + + var Simplify = { + // to suit your point format, run search/replace for '.x' and '.y'; + // for 3D version, see 3d branch (configurability would draw significant performance overhead) + + // square distance between 2 points + getSqDist: function(p1, p2) { + + var dx = p1.x - p2.x, + dy = p1.y - p2.y; + + return dx * dx + dy * dy; + }, + + // square distance from a point to a segment + getSqSegDist: function(p, p1, p2) { + + var x = p1.x, + y = p1.y, + dx = p2.x - x, + dy = p2.y - y; + + if (dx !== 0 || dy !== 0) { + + var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy); + + if (t > 1) { + x = p2.x; + y = p2.y; + + } else if (t > 0) { + x += dx * t; + y += dy * t; + } + } + + dx = p.x - x; + dy = p.y - y; + + return dx * dx + dy * dy; + }, + // rest of the code doesn't care about point format + + // basic distance-based simplification + simplifyRadialDist: function(points, sqTolerance) { + + var prevPoint = points[0], + newPoints = [prevPoint], + point; + + for (var i = 1, len = points.length; i < len; i++) { + point = points[i]; + + if (this.getSqDist(point, prevPoint) > sqTolerance) { + newPoints.push(point); + prevPoint = point; + } + } + + if (prevPoint !== point) newPoints.push(point); + + return newPoints; + }, + + // simplification using optimized Douglas-Peucker algorithm with recursion elimination + simplifyDouglasPeucker: function(points, sqTolerance) { + + var len = points.length, + MarkerArray = typeof Uint8Array !== 'undefined' ? Uint8Array : Array, + markers = new MarkerArray(len), + first = 0, + last = len - 1, + stack = [], + newPoints = [], + i, maxSqDist, sqDist, index; + + markers[first] = markers[last] = 1; + + while (last) { + + maxSqDist = 0; + + for (i = first + 1; i < last; i++) { + sqDist = this.getSqSegDist(points[i], points[first], points[last]); + + if (sqDist > maxSqDist) { + index = i; + maxSqDist = sqDist; + } + } + + if (maxSqDist > sqTolerance) { + markers[index] = 1; + stack.push(first, index, index, last); + } + + last = stack.pop(); + first = stack.pop(); + } + + for (i = 0; i < len; i++) { + if (markers[i]) newPoints.push(points[i]); + } + + return newPoints; + }, + + // both algorithms combined for awesome performance + simplify: function(points, tolerance, highestQuality) { + + var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; + + points = highestQuality ? points : this.simplifyRadialDist(points, sqTolerance); + points = this.simplifyDouglasPeucker(points, sqTolerance); + + return points; + } + + }; + + return Simplify; +}); + +//module.exports = simplify; diff --git a/support/client/lib/vwf/utility/xpath.js b/support/client/lib/vwf/utility/xpath.js index c4638d078..6aa1b487e 100644 --- a/support/client/lib/vwf/utility/xpath.js +++ b/support/client/lib/vwf/utility/xpath.js @@ -375,10 +375,10 @@ define( [ "module" ], function( module ) { regex: ( function() { - var name = "[A-Za-z_][A-Za-z_0-9.-]*", // XPath QName: http://www.w3.org/TR/xpath20/#prod-xpath-QName - singleQuotedName = "'(?:[^'\\\\]|\\'|\\\\)+'", // Single-quoted QName (VWF extension) - doubleQuotedName = '"(?:[^"\\\\]|\\"|\\\\)+"', // Double-quoted QName (VWF extension) - wildcard = "\\*"; // XPath Wildcard: http://www.w3.org/TR/xpath20/#prod-xpath-Wildcard + var name = "[A-Za-z_][A-Za-z_0-9.-]*", // XPath QName: http://www.w3.org/TR/xpath20/#prod-xpath-QName + singleQuotedName = "'(?:[^'\\\\]|\\\\'|\\\\\\\\)+'", // Single-quoted QName (VWF extension) + doubleQuotedName = '"(?:[^"\\\\]|\\\\"|\\\\\\\\)+"', // Double-quoted QName (VWF extension) + wildcard = "\\*"; // XPath Wildcard: http://www.w3.org/TR/xpath20/#prod-xpath-Wildcard /// @field diff --git a/support/client/lib/vwf/view/chai/.npmignore b/support/client/lib/vwf/view/chai/.npmignore new file mode 100644 index 000000000..59f495632 --- /dev/null +++ b/support/client/lib/vwf/view/chai/.npmignore @@ -0,0 +1,14 @@ +.git* +docs/ +test/ +support/ +component.json +components/ +build/ +lib-cov/ +coverage/ +.travis.yml +.mailmap +Makefile +*.swp +.DS_Store diff --git a/support/client/lib/vwf/view/chai/CODE_OF_CONDUCT.md b/support/client/lib/vwf/view/chai/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..5194527f2 --- /dev/null +++ b/support/client/lib/vwf/view/chai/CODE_OF_CONDUCT.md @@ -0,0 +1,58 @@ +# Contributor Code of Conduct + +> Read in: [Español](http://contributor-covenant.org/version/1/3/0/es/) | +[Français](http://contributor-covenant.org/version/1/3/0/fr/) | +[Italiano](http://contributor-covenant.org/version/1/3/0/it/) | +[Magyar](http://contributor-covenant.org/version/1/3/0/hu/) | +[Polskie](http://contributor-covenant.org/version/1/3/0/pl/) | +[Português](http://contributor-covenant.org/version/1/3/0/pt/) | +[Português do Brasil](http://contributor-covenant.org/version/1/3/0/pt_br/) + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer at [INSERT EMAIL ADDRESS]. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[http://contributor-covenant.org/version/1/3/0/][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/3/0/ diff --git a/support/client/lib/vwf/view/chai/CONTRIBUTING.md b/support/client/lib/vwf/view/chai/CONTRIBUTING.md new file mode 100644 index 000000000..8de9ba8ee --- /dev/null +++ b/support/client/lib/vwf/view/chai/CONTRIBUTING.md @@ -0,0 +1,214 @@ +# Chai Contribution Guidelines + +We like to encourage you to contribute to the Chai.js repository. This should be as easy as possible for you but there are a few things to consider when contributing. The following guidelines for contribution should be followed if you want to submit a pull request or open an issue. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. + +#### Table of Contents + +- [TLDR;](#tldr) +- [Contributing](#contributing) + - [Bug Reports](#bugs) + - [Feature Requests](#features) + - [Pull Requests](#pull-requests) +- [Releasing](#releasing) +- [Support](#support) + - [Resources](#resources) + - [Core Contributors](#contributors) + + +## TLDR; + +- Creating an Issue or Pull Request requires a [GitHub](http://github.com) account. +- Issue reports should be **clear**, **concise** and **reproducible**. Check to see if your issue has already been resolved in the [master]() branch or already reported in Chai's [GitHub Issue Tracker](https://github.com/chaijs/chai/issues). +- Pull Requests must adhere to strict [coding style guidelines](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). +- In general, avoid submitting PRs for new Assertions without asking core contributors first. More than likely it would be better implemented as a plugin. +- Additional support is available via the [Google Group](http://groups.google.com/group/chaijs) or on irc.freenode.net#chaijs. +- **IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + + + +## Contributing + +The issue tracker is the preferred channel for [bug reports](#bugs), +[feature requests](#features) and [submitting pull +requests](#pull-requests), but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests (use + [Google Group](https://groups.google.com/forum/#!forum/chaijs) or IRC). +* Please **do not** derail or troll issues. Keep the discussion on topic and + respect the opinions of others + + +### Bug Reports + +A bug is a **demonstrable problem** that is caused by the code in the repository. + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been reported. +2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. +3. **Isolate the problem** — create a test case to demonstrate your issue. Provide either a repo, gist, or code sample to demonstrate you problem. + +A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s) and/or Node.js versions experience the problem? What would you expect to be the outcome? All these details will help people to fix any potential bugs. + +Example: + +> Short and descriptive example bug report title +> +> A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the steps required to reproduce the bug. +> +> 1. This is the first step +> 2. This is the second step +> 3. Further steps, etc. +> +> `` - a link to the reduced test case OR +> ```js +> expect(a).to.equal('a'); +> // code sample +> ``` +> +> Any other information you want to share that is relevant to the issue being reported. This might include the lines of code that you have identified as causing the bug, and potential solutions (and your opinions on their merits). + + +### Feature Requests + +Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible. + +Furthermore, since Chai.js has a [robust plugin API](http://chaijs.com/guide/plugins/), we encourage you to publish **new Assertions** as plugins. If your feature is an enhancement to an **existing Assertion**, please propose your changes as an issue prior to opening a pull request. If the core Chai.js contributors feel your plugin would be better suited as a core assertion, they will invite you to open a PR in [chaijs/chai](https://github.com/chaijs/chai). + + +### Pull Requests + +- PRs for new core-assertions are advised against. +- PRs for core-assertion bug fixes are always welcome. +- PRs for enhancing the interfaces are always welcome. +- PRs that increase test coverage are always welcome. +- PRs are scrutinized for coding-style. + +Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. + +**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. + +Please adhere to the coding conventions used throughout a project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). Please review the [Chai.js Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide). + +Follow this process if you'd like your work considered for inclusion in the project: + +1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes: + +```bash +# Clone your fork of the repo into the current directory +git clone https://github.com// +# Navigate to the newly cloned directory +cd +# Assign the original repo to a remote called "upstream" +git remote add upstream https://github.com// +``` + +2. If you cloned a while ago, get the latest changes from upstream: + +```bash +git checkout +git pull upstream +``` + +3. Create a new topic branch (off the main project development branch) to contain your feature, change, or fix: + +```bash +git checkout -b +``` + +4. Commit your changes in logical chunks. Use Git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public. + +5. Run you code to make sure it works. If you're still having problems please try to run `make clean` and then test your code again. + +```bash +npm test +# when finished running tests... +git checkout chai.js +``` + +6. Locally merge (or rebase) the upstream development branch into your topic branch: + +```bash +git pull [--rebase] upstream +``` + +7. Push your topic branch up to your fork: + +```bash +git push origin +``` + +8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description. + +**IMPORTANT**: By submitting a patch, you agree to allow the project owner to license your work under the same license as that used by the project. + + +## Releasing + +Releases can be **prepared** by anyone with access to the code. + +Simply run `make release-major`, `make release-minor`, or `make-release-patch` +and it will automatically do the following: + + - Build chai.js + - Bump the version numbers accross the project + - Make a commit within git + +All you need to do is push the commit up and make a pull request, one of the core contributors will merge it and publish a release. + +### Publishing a Release + +Anyone who is a core contributor (see the [Core Contributors Heading in the Readme](https://github.com/chaijs/chai#core-contributors)) can publish a release: + +1. Go to te [Releases page on Github](https://github.com/chaijs/chai/releases) +2. Hit "Draft a new release" (if you can't see this, you're not a core contributor!) +3. Write human-friendly Release Notes based on changelog. + - The release title is "x.x.x / YYYY-MM-DD" (where x.x.x is the version number) + - If breaking changes, write migration tutorial(s) and reasoning. + - Callouts for community contributions (PRs) with links to PR and contributing user. + - Callouts for other fixes made by core contributors with links to issue. +4. Hit "Save Draft" and get other core contributors to check your work, or alternatively hit "Publish release" +5. That's it! + + +## Support + + +### Resources + +For most of the documentation you are going to want to visit [ChaiJS.com](http://chaijs.com). + +- [Getting Started Guide](http://chaijs.com/guide/) +- [API Reference](http://chaijs.com/api/) +- [Plugins](http://chaijs.com/plugins/) + +Alternatively, the [wiki](https://github.com/chaijs/chai/wiki) might be what you are looking for. + +- [Chai Coding Style Guide](https://github.com/chaijs/chai/wiki/Chai-Coding-Style-Guide) +- [Third-party Resources](https://github.com/chaijs/chai/wiki/Third-Party-Resources) + +Or finally, you may find a core-contributor or like-minded developer in any of our support channels. + +- IRC: irc.freenode.org #chaijs +- [Mailing List / Google Group](https://groups.google.com/forum/#!forum/chaijs) + + +### Core Contributors + +Feel free to reach out to any of the core-contributors with you questions or concerns. We will do our best to respond in a timely manner. + +- Jake Luer + - GH: [@logicalparadox](https://github.com/logicalparadox) + - TW: [@jakeluer](http://twitter.com/jakeluer) + - IRC: logicalparadox +- Veselin Todorov + - GH: [@vesln](https://github.com/vesln/) + - TW: [@vesln](http://twitter.com/vesln) + - IRC: vesln +- Keith Cirkel + - GH: [@keithamus](https://github.com/keithamus) + - TW: [@keithamus](http://twitter.com/keithamus) + - IRC: keithamus diff --git a/support/client/lib/vwf/view/chai/History.md b/support/client/lib/vwf/view/chai/History.md new file mode 100644 index 000000000..ae4d323e7 --- /dev/null +++ b/support/client/lib/vwf/view/chai/History.md @@ -0,0 +1,1059 @@ +### Note + +As of 3.0.0, the History.md file has been deprecated. [Please refer to the full +commit logs available on GitHub](https://github.com/chaijs/chai/commits/master). + +--- + +2.3.0 / 2015-04-26 +================== + + * Merge pull request #423 from ehntoo/patch-1 + * Merge pull request #422 from ljharb/fix_descriptor_tests + * Fix a small bug in the .null assertion docs + * Use a regex to account for property ordering issues across engines. + * Add `make test-firefox` + * Merge pull request #417 from astorije/astorije/minimalist-typo + * Remove trailing whitespaces + * Fix super minor typo in an example + * Merge pull request #408 from ljharb/enumerableProperty + * Add `ownPropertyDescriptor` assertion. + +2.2.0 / 2015-03-26 +================== + + * Merge pull request #405 from chaijs/deep-escape-doc-tweaks + * Tweak documentation on `.deep` flag. + * Merge pull request #402 from umireon/escaping-dot-should-be-taken + * Documentation of escaping in `.deep` flag. + * take regular expression apart + * Feature: backslash-escaping in `.deep.property` + * Escaping dot should be taken in deep property + +2.1.2 / 2015-03-15 +================== + + * Merge pull request #396 from chaijs/add-keith-cirkel-contributing-md + * Add Keith Cirkel to CONTRIBUTING.md + * Merge pull request #395 from cjqed/386-assert-operator-no-eval + * No longer using eval on assert operator #386 + * Merge pull request #389 from chaijs/update-git-summary + * Update `git summary` in README + +2.1.1 / 2015-03-04 +================== + + * Merge pull request #385 from eldritch-fossicker/master + * updates to reflect code style preference from @keithamus + * fix indexing into array with deep propery + * Merge pull request #382 from astorije/patch-2 + * Merge pull request #383 from gurdiga/config-doc-wording-improvement + * config.truncateThreshold docs: simpler wording + * Add missing docstring for showDiff argument of assert + * Merge pull request #381 from astorije/patch-1 + * Add a minor precision that empty asserts on strings too. + * Merge pull request #379 from dcneiner/should-primitive-fix + * Primitives now use valueOf in shouldGetter + +2.1.0 / 2015-02-23 +================== + + * Merge pull request #374 from jmm/v2.0.1 + * Increment version to 2.0.1. + * Merge pull request #365 from chaijs/fix-travis + * Fix travis.yml deploy + * Merge pull request #356 from Soviut/master + * documented fail methods for expect and should interfaces + * fail method added directly to expect + +2.0.0 / 2015-02-09 +================== + + * Merge pull request #361 from gregglind/b265-keys-object + * fix #359. Add `.keys(object)` + * Merge pull request #359 from gregglind/b359-unexpected-keys-sort + * Fix #359 keys() sorts input unexpectedly + * contrib: publish release strategy and travis npm creds #337 + * Merge pull request #357 from danilovaz/master + * Update copyright date + * Merge pull request #349 from toastynerd/add-which-chain-method + * add the which chain method as per issue #347 + * Merge pull request #333 from cmpolis/change-assertions + * more `by` cleanup + * cleaned out `.by` for #333 + * Merge pull request #335 from DingoEatingFuzz/expose-util + * Expose chai util through the chai object + * cleanup (per notes on pr #333) + * updated `change` to work w/ non-number values + tests + * Merge pull request #334 from hurrymaplelad/patch-1 + * Typo, the flag is called 'contains' with an 's' + * updated assertion interface with `change` (#330) + * added `change`,`increase`,`decrease` assertions (#330) + * assert tests for `change`,`increase`,`decrease` + * expect/should tests for `change`,`increase`,`decrease` + * Merge pull request #328 from lo1tuma/issue-327 + * Add includes and contains alias (fixes #327) + * Merge pull request #325 from chasenlehara/overwriteChainableMethodDocs + * Fix docs for overwriteChainableMethod parameters + * Merge pull request #317 from jasonkarns/patch-2 + * Merge pull request #318 from jasonkarns/patch-3 + * Merge pull request #316 from jasonkarns/patch-1 + * typos in docs + * minor docs typo + * update docs: getAllFlags -> transferFlags + * Merge pull request #313 from cjqed/254-expect-any-all + * Added the all and any flags for keys assertion, with all being the default behavior + * Merge pull request #312 from cjqed/291-assert-same-deep-members + * Changed public comment of sameDeepMemebers to be more clear + * Fixes issue #291, adds assert.sameDeepMembers + * Merge pull request #311 from cjqed/305-above-below-on-assert + * Merge pull request #308 from prodatakey/hasproperty + * Issue #305 fixed, added assert.isAbove and assert.isBelow + * Fix typo + * More unit tests for new utility functions + * Refactor common functionality, document, test + * Refactor if statement out + * Small unit test fix + * Handle array indexing terminating paths + * Merge pull request #309 from ericdouglas/iterableEqual-couting-once + * couting variables just once + * Fix properties with `undefined` value pass property assertion + * Merge pull request #306 from chaijs/revert-297-noopchainfunc + * Revert "Allows writing lint-friendly tests" + +1.10.0 / 2014-11-10 +================== + + * Merge pull request #297 from prodatakey/noopchainfunc + * Merge pull request #300 from julienw/299-fix-getMessage-test + * Fix #299: the test is defining global variables + * Add a couple more unit tests + * Add unit tests for chained terminating property asserts + * Revise documentation wording + * Add docs for function style NOOP asserts + * Make the NOOP function a shared constant + * Merge pull request #298 from dasilvacontin/negativeZeroLogging + * why not more assertions + * added test for inspecting `-0` + * a more readable/simple condition statement, as pointed out by @keithamus + * added check for logging negative zero + * Change test to not trigger argument bug + * Allows writing lint-friendly tests + * readme: update contributors for 1.9.2 + +1.9.2 / 2014-09-29 +================== + + * Merge pull request #268 from charlierudolph/cr-lazyMessages + * Merge pull request #269 from charlierudolph/cr-codeCleanup + * Merge pull request #277 from charlierudolph/fix-doc + * Merge pull request #279 from mohayonao/fix-closeTo + * Merge pull request #292 from boneskull/mocha + * resolves #255: upgrade mocha + * Merge pull request #289 from charlierudolph/cr-dryUpCode + * Dry up code + * Merge pull request #275 from DrRataplan/master + * assert: .closeTo() verify value's type before assertion + * Rewrite pretty-printing HTML elements to prevent throwing internal errors Fixes errors occuring when using a non-native DOM implementation + * Fix assert documentation + * Remove unused argument + * Allow messages to be functions + * Merge pull request #267 from shinnn/master + * Use SVG badge + * Merge pull request #264 from cjthompson/keys_diff + * Show diff for keys assertion + +1.9.1 / 2014-03-19 +================== + + * deps update + * util: [getActual] select actual logic now allows undefined for actual. Closes #183 + * docs: [config] make public, express param type + * Merge pull request #251 from romario333/threshold3 + * Fix issue #166 - configurable threshold in objDisplay. + * Move configuration options to config.js. + * Merge pull request #233 from Empeeric/master + * Merge pull request #244 from leider/fix_for_contains + * Merge pull request #247 from didoarellano/typo-fixes + * Fix typos + * Merge pull request #245 from lfac-pt/patch-1 + * Update `exports.version` to 1.9.0 + * aborting loop on finding + * declaring variable only once + * additional test finds incomplete implementation + * simplified code + * fixing #239 (without changing chai.js) + * ssfi as it should be + * Merge pull request #228 from duncanbeevers/deep_members + * Deep equality check for collection membership + +1.9.0 / 2014-01-29 +================== + + * docs: add contributing.md #238 + * assert: .throws() returns thrown error. Closes #185 + * Merge pull request #232 from laconbass/assert-throws + * assert: .fail() parameter mismatch. Closes #206 + * Merge branch 'karma-fixes' + * Add karma phantomjs launcher + * Use latest karma and sauce launcher + * Karma tweaks + * Merge pull request #230 from jkroso/include + * Merge pull request #237 from chaijs/coverage + * Add coverage to npmignore + * Remove lib-cov from test-travisci dependents + * Remove the not longer needed lcov reporter + * Test coverage with istanbul + * Remove jscoverage + * Remove coveralls + * Merge pull request #226 from duncanbeevers/add_has + * Avoid error instantiation if possible on assert.throws + * Merge pull request #231 from duncanbeevers/update_copyright_year + * Update Copyright notices to 2014 + * handle negation correctly + * add failing test case + * support `{a:1,b:2}.should.include({a:1})` + * Merge pull request #224 from vbardales/master + * Add `has` to language chains + * Merge pull request #219 from demands/overwrite_chainable + * return error on throw method to chain on error properties, possibly different from message + * util: store chainable behavior in a __methods object on ctx + * util: code style fix + * util: add overwriteChainableMethod utility (for #215) + * Merge pull request #217 from demands/test_cleanup + * test: make it possible to run utilities tests with --watch + * makefile: change location of karma-runner bin script + * Merge pull request #202 from andreineculau/patch-2 + * test: add tests for throwing custom errors + * Merge pull request #201 from andreineculau/patch-1 + * test: updated for the new assertion errors + * core: improve message for assertion errors (throw assertion) + +1.8.1 / 2013-10-10 +================== + + * pkg: update deep-eql version + +1.8.0 / 2013-09-18 +================== + + * test: [sauce] add a few more browsers + * Merge branch 'refactor/deep-equal' + * util: remove embedded deep equal utility + * util: replace embedded deep equal with external module + * Merge branch 'feature/karma' + * docs: add sauce badge to readme [ci skip] + * test: [sauce] use karma@canary to prevent timeouts + * travis: only run on node 0.10 + * test: [karma] use karma phantomjs runner + * Merge pull request #181 from tricknotes/fix-highlight + * Fix highlight for example code + +1.7.2 / 2013-06-27 +================== + + * coverage: add coveralls badge + * test: [coveralls] add coveralls api integration. testing travis-ci integration + * Merge branch 'master' of github.com:chaijs/chai + * Merge branch 'feature/bower' + * Merge pull request #180 from tricknotes/modify-method-title + * Merge pull request #179 from tricknotes/highlight-code-example + * Modify method title to include argument name + * Fix to highlight code example + * bower: granular ignores + +1.7.1 / 2013-06-24 +================== + + * Merge branch 'feature/bower'. #175 + * bower: add json file + * build: browser + +1.7.0 / 2013-06-17 +================== + + * error: remove internal assertion error constructor + * core: [assertion-error] replace internal assertion error with dep + * deps: add chaijs/assertion-error@1.0.0 + * docs: fix typo in source file. #174 + * Merge pull request #174 from piecioshka/master + * typo + * Merge branch 'master' of github.com:chaijs/chai + * pkg: lock mocha/mocha-phantomjs versions (for now) + * Merge pull request #173 from chaijs/inspect-fix + * Fix `utils.inspect` with custom object-returning inspect()s. + * Merge pull request #171 from Bartvds/master + * replaced tabs with 2 spaces + * added assert.notOk() + * Merge pull request #169 from katsgeorgeek/topics/master + * Fix comparison objects. + +1.6.1 / 2013-06-05 +================== + + * Merge pull request #168 from katsgeorgeek/topics/master + * Add test for different RegExp flags. + * Add test for regexp comparison. + * Downgrade mocha version for fix running Phantom tests. + * Fix comparison equality of two regexps. + * Merge pull request #161 from brandonpayton/master + * Fix documented name for assert interfaces isDefined method + +1.6.0 / 2013-04-29 +================== + + * build: browser + * assert: [(not)include] throw on incompatible haystack. Closes #142 + * assert: [notInclude] add assert.notInclude. Closes #158 + * browser build + * makefile: force browser build on browser-test + * makefile: use component for browser build + * core: [assertions] remove extraneous comments + * Merge branch 'master' of github.com:chaijs/chai + * test: [assert] deep equal ordering + * Merge pull request #153 from NickHeiner/array-assertions + * giving members a no-flag assertion + * Code review comments - changing syntax + * Code review comments + * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148. + * Merge pull request #140 from RubenVerborgh/function-prototype + * Restore the `call` and `apply` methods of Function when adding a chainable method. + * readme: 2013 + * notes: migration notes for deep equal changes + * test: for ever err() there must be a passing version + +1.5.0 / 2013-02-03 +================== + + * docs: add Release Notes for non-gitlog summary of changes. + * lib: update copyright to 2013 + * Merge branch 'refactor/travis' + * makefile: remove test-component for full test run + * pkg: script test now runs make test so travis will test browser + * browser: build + * tests: refactor some tests to support new objDisplay output + * test: [bootstrap] normalize boostrap across all test scenarios + * assertions: refactor some assertions to use objDisplay instead of inspect + * util: [objDisplay] normalize output of functions + * makefile: refactor for full build scenarios + * component: fix build bug where missing util:type file + * assertions: [throw] code cleanup + * Merge branch 'refactor/typeDetection' + * browser: build + * makefile: chai.js is .PHONY so it builds every time + * test: [expect] add arguments type detection test + * core/assertions: [type] (a/an) refactor to use type detection utility + * util: add cross-browser type detection utility + * Merge branch 'feature/component' + * browser: build + * component: add component.json file + * makefile: refactor for fine grain control of testing scenarios + * test: add mochaPhantomJS support and component test file + * deps: add component and mocha-phantomjs for browser testing + * ignore: update ignore files for component support + * travis: run for all branches + * Merge branch 'feature/showDiff' + * test: [Assertion] configruable showDiff flag. Closes #132 + * lib: [Assertion] add configurable showDiff flag. #132 + * Merge branch 'feature/saucelabs' + * Merge branch 'master' into feature/saucelabs + * browser: build + * support: add mocha cloud runner, client, and html test page + * test: [saucelabs] add auth placeholder + * deps: add mocha-cloud + * Merge pull request #136 from whatthejeff/message_fix + * Merge pull request #138 from timnew/master + * Fix issue #137, test message existence by using message!=null rather than using message + * Fixed backwards negation messages. + * Merge pull request #133 from RubenVerborgh/throw + * Functions throwing strings can reliably be tested. + * Merge pull request #131 from RubenVerborgh/proto + * Cache whether __proto__ is supported. + * Use __proto__ if available. + * Determine the property names to exclude beforehand. + * Merge pull request #126 from RubenVerborgh/eqls + * Add alias eqls for eql. + * Use inherited enumerable properties in deep equality comparison. + * Show inherited properties when inspecting an object. + * Add new getProperties and getEnumerableProperties utils. + * showDiff: force true for equal and eql + +1.4.2 / 2012-12-21 +================== + + * browser build: (object diff support when used with mocha) #106 + * test: [display] array test for mocha object diff + * browser: no longer need different AssertionError constructor + +1.4.1 / 2012-12-21 +================== + + * showDiff: force diff for equal and eql. #106 + * test: [expect] type null. #122 + * Merge pull request #115 from eshao/fix-assert-Throw + * FIX: assert.Throw checks error type/message + * TST: assert.Throw should check error type/message + +1.4.0 / 2012-11-29 +================== + + * pre-release browser build + * clean up index.js to not check for cov, revert package.json to use index.js + * convert tests to use new bootstrap + * refactor testing bootstrap + * use spaces (not tabs). Clean up #114 + * Merge pull request #114 from trantorLiu/master + * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of". + * Change `main` to ./lib/chai. Fixes #28. + * Merge pull request #104 from connec/deep_equals_circular_references_ + * Merge pull request #109 from nnarhinen/patch-1 + * Check for 'actual' type + * Added support for circular references when checking deep (in)equality. + +1.3.0 / 2012-10-01 +================== + + * browser build w/ folio >= 0.3.4. Closes #99 + * add back buffer test for deep equal + * do not write flags to assertion.prototype + * remove buffer test from expect + * browser build + * improve documentation of custom error messages + * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master + * browser build + * improved buffer deep equal checking + * mocha is npm test command + * Cleaning up the js style… + * expect tests now include message pass-through + * packaging up browser-side changes… + * Increasing Throws error message verbosity + * Should syntax: piping message through + * Make globalShould test work in browser too. + * Add a setter for `Object.prototype.should`. Closes #86. + +1.2.0 / 2012-08-07 +================== + + * Merge branch 'feature/errmsg' + * browser build + * comment updates for utilities + * tweak objDislay to only kick in if object inspection is too long + * Merge branch 'master' into feature/errmsg + * add display sample for error message refactor + * first draft of error message refactor. #93 + * add `closeTo` assertion to `assert` interface. Closes #89. + * update folio build for better require.js handling. Closes #85 + * Merge pull request #92 from paulmillr/topics/add-dom-checks + * Add check for DOM objects. + * browser build + * Merge branch 'master' of github.com:chaijs/chai + * bug - getActual not defaulting to assertion subject + * Merge pull request #88 from pwnall/master + * Don't inspect() assertion arguments if the assertion passes. + +1.1.1 / 2012-07-09 +================== + + * improve commonjs support on browser build + * Merge pull request #83 from tkazec/equals + * Document .equals + * Add .equals as an alias of .equal + * remove unused browser prefix/suffix + * Merge branch 'feature/folio-build' + * browser build + * using folio to compile + * clean up makefile + * early folio 0.3.x support + +1.1.0 / 2012-06-26 +================== + + * browser build + * Disable "Assertion.includeStack is false" test in IE. + * Use `utils.getName` for all function inspections. + * Merge pull request #80 from kilianc/closeTo + * fixes #79 + * browser build + * expand docs to indicate change of subject for chaining. Closes #78 + * add `that` chain noop + * Merge branch 'bug/74' + * comments on how to property use `length` as chain. Closes #74 + * tests for length as chainable property. #74 + * add support for `length` as chainable prop/method. + * Merge branch 'bug/77' + * tests for getPathValue when working with nested arrays. Closes #77 + * add getPathValue support for nested arrays + * browser build + * fix bug for missing browser utils + * compile tool aware of new folder layout + * Merge branch 'refactor/1dot1' + * move core assertions to own file and refactor all using utils + * rearrange folder structure + +1.0.4 / 2012-06-03 +================== + + * Merge pull request #68 from fizker/itself + * Added itself chain. + * simplify error inspections for cross browser compatibility + * fix safari `addChainableMethod` errors. Closes #69 + +1.0.3 / 2012-05-27 +================== + + * Point Travis badge to the right place. + * Make error message for eql/deep.equal more clear. + * Fix .not.deep.equal. + * contributors list + +1.0.2 / 2012-05-26 +================== + + * Merge pull request #67 from chaijs/chaining-and-flags + * Browser build. + * Use `addChainableMethod` to get away from `__proto__` manipulation. + * New `addChainableMethod` utility. + * Replace `getAllFlags` with `transferFlags` utility. + * browser build + * test - get all flags + * utility - get all flags + * Add .mailmap to .npmignore. + * Add a .mailmap file to fix my name in shortlogs. + +1.0.1 / 2012-05-18 +================== + + * browser build + * Fixing "an" vs. "a" grammar in type assertions. + * Uniformize `assert` interface inline docs. + * Don't use `instanceof` for `assert.isArray`. + * Add `deep` flag for equality and property value. + * Merge pull request #64 from chaijs/assertion-docs + * Uniformize assertion inline docs. + * Add npm-debug.log to .gitignore. + * no reserved words as actuals. #62 + +1.0.0 / 2012-05-15 +================== + + * readme cleanup + * browser build + * utility comments + * removed docs + * update to package.json + * docs build + * comments / docs updates + * plugins app cleanup + * Merge pull request #61 from joliss/doc + * Fix and improve documentation of assert.equal and friends + * browser build + * doc checkpoint - texture + * Update chai-jquery link + * Use defined return value of Assertion extension functions + * Update utility docs + +1.0.0-rc3 / 2012-05-09 +================== + + * Merge branch 'feature/rc3' + * docs update + * browser build + * assert test conformity for minor refactor api + * assert minor refactor + * update util tests for new add/overwrite prop/method format + * added chai.Assertion.add/overwrite prop/method for plugin toolbox + * add/overwrite prop/method don't make assumptions about context + * doc test suite + * docs don't need coverage + * refactor all simple chains into one forEach loop, for clean documentation + * updated npm ignore + * remove old docs + * docs checkpoint - guide styled + * Merge pull request #59 from joliss/doc + * Document how to run the test suite + * don't need to rebuild docs to view + * dep update + * docs checkpoint - api section + * comment updates for docs + * new doc site checkpoint - plugin directory! + * Merge pull request #57 from kossnocorp/patch-1 + * Fix typo: devDependancies → devDependencies + * Using message flag in `getMessage` util instead of old `msg` property. + * Adding self to package.json contributors. + * `getMessage` shouldn't choke on null/omitted messages. + * `return this` not necessary in example. + * `return this` not necessary in example. + * Sinon–Chai has a dash + * updated plugins list for docs + +1.0.0-rc2 / 2012-05-06 +================== + + * Merge branch 'feature/test-cov' + * browser build + * missing assert tests for ownProperty + * appropriate assert equivalent for expect.to.have.property(key, val) + * reset AssertionError to include full stack + * test for plugin utilities + * overwrite Property and Method now ensure chain + * version notes in readme + +1.0.0-rc1 / 2012-05-04 +================== + + * browser build (rc1) + * assert match/notMatch tests + * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal + * cleaner should interface export. + * added chai.Assertion.prototype._obj (getter) for quick access to object flag + * moved almostEqual / almostDeepEqual to stats plugin + * added mocha.opts + * Add test for `utils.addMethod` + * Fix a typo + * Add test for `utils.overwriteMethod` + * Fix a typo + * Browser build + * Add undefined assertion + * Add null assertion + * Fix an issue with `mocha --watch` + * travis no longer tests on node 0.4.x + * removing unnecissary carbon dep + * Merge branch 'feature/plugins-app' + * docs build + * templates for docs express app for plugin directory + * express app for plugin and static serving + * added web server deps + * Merge pull request #54 from josher19/master + * Remove old test.assert code + * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual + * browser build + * Added almostEqual and deepAlmostEqual to assert test suite. + * bug - context determinants for utils + * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true + * wrong travis link + * readme updates for version information + * travis tests 0.5.x branch as well + * [bug] util `addProperty` not correctly exporting + * read me version notes + * browser build 1.0.0alpha1 + * not using reserved words in internal assertions. #52 + * version tick + * clean up redundant tests + * Merge branch 'refs/heads/0.6.x' + * update version tag in package 1.0.0alpha1 + * browser build + * added utility tests to browser specs + * beginning utility testing + * updated utility comments + * utility - overwriteMethod + * utility - overwriteProperty + * utility - addMethod + * utility - addProperty + * missing ; + * contributors list update + * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x + * Added guide link to docs. WIP + * Include/contain are now both properties and methods + * Add an alias annotation + * Remove usless function wrapper + * Fix a typo + * A/an are now both properties and methods + * [docs] new site homepage layout / color checkpoint + * Ignore IE-specific error properties. + * Fixing order of error message test. + * New cross-browser `getName` util. + * Fixing up `AssertionError` inheritance. + * backup docs + * Add doctypes + * [bug] was still using `constructor.name` in `throw` assertion + * [bug] flag Object.create(null) instead of new Object + * [test] browser build + * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags + * [refactor] remove Assertion.prototype.inspect for testable object inspection + * [refactor] object to test is now stored in flag, with ssfi and custom message + * [bug] flag util - don't return on `set` + * [docs] comments for getMessage utility + * [feature] getMessage + * [feature] testing utilities + * [refactor] flag doesn't require `call` + * Make order of source files well-defined + * Added support for throw(errorInstance). + * Use a foolproof method of grabbing an error's name. + * Removed constructor.name check from throw. + * disabled stackTrack configuration tests until api is stable again + * first version of line displayed error for node js (unstable) + * refactor core Assertion to use flag utility for negation + * added flag utility + * tests for assert interface negatives. Closed #42 + * added assertion negatives that were missing. #42 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + * Added assert.fail. Closes #40 + * better error message for assert.operator. Closes #39 + * [refactor] Assertion#property to use getPathValue property + * added getPathValue utility helper + * removed todo about browser build + * version notes + * version bumb 0.6.0 + * browser build + * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')' + * [feature] browser uses different error.js + * [refactor] error without chai.fail + * Assertion & interfaces use new utils helper export + * [refactor] primary export for new plugin util usage + * added util index.js helper + * added 2012 to copyright headers + * Added DeepEqual assertions + +0.5.3 / 2012-04-21 +================== + + * Merge branch 'refs/heads/jgonera-oldbrowsers' + * browser build + * fixed reserved names for old browsers in interface/assert + * fixed reserved names for old browsers in interface/should + * fixed: chai.js no longer contains fail() + * fixed reserved names for old browsers in Assertion + * Merge pull request #49 from joliss/build-order + * Make order of source files well-defined + * Merge pull request #43 from zzen/patch-1 + * Support for expected and actual parameters in assert-style error object + * chai as promised - readme + +0.5.2 / 2012-03-21 +================== + + * browser build + * Merge branch 'feature/assert-fail' + * Added assert.fail. Closes #40 + * Merge branch 'bug/operator-msg' + * better error message for assert.operator. Closes #39 + * version notes + +0.5.1 / 2012-03-14 +================== + + * chai.fail no longer exists + * Merge branch 'feature/assertdefined' + * Added asset#isDefined. Closes #37. + * dev docs update for Assertion#assert + +0.5.0 / 2012-03-07 +================== + + * [bug] on inspect of reg on n 0.4.12 + * Merge branch 'bug/33-throws' + * Merge pull request #35 from logicalparadox/empty-object + * browser build + * updated #throw docs + * Assertion#throw `should` tests updated + * Assertion#throw `expect` tests + * Should interface supports multiple throw parameters + * Update Assertion#throw to support strings and type checks. + * Add more tests for `empty` in `should`. + * Add more tests for `empty` in `expect`. + * Merge branch 'master' into empty-object + * don't switch act/exp + * Merge pull request #34 from logicalparadox/assert-operator + * Update the compiled verison. + * Add `assert.operator`. + * Notes on messages. #22 + * browser build + * have been test + * below tests + * Merge branch 'feature/actexp' + * browser build + * remove unnecessary fail export + * full support for actual/expected where relevant + * Assertion.assert support expected value + * clean up error + * Update the compiled version. + * Add object & sane arguments support to `Assertion#empty`. + +0.4.2 / 2012-02-28 +================== + + * fix for `process` not available in browser when used via browserify. Closes #28 + * Merge pull request #31 from joliss/doc + * Document that "should" works in browsers other than IE + * Merge pull request #30 from logicalparadox/assert-tests + * Update the browser version of chai. + * Update `assert.doesNotThrow` test in order to check the use case when type is a string. + * Add test for `assert.ifError`. + * Falsey -> falsy. + * Full coverage for `assert.throws` and `assert.doesNotThrow`. + * Add test for `assert.doesNotThrow`. + * Add test for `assert.throws`. + * Add test for `assert.length`. + * Add test for `assert.include`. + * Add test for `assert.isBoolean`. + * Fix the implementation of `assert.isNumber`. + * Add test for `assert.isNumber`. + * Add test for `assert.isString`. + * Add test for `assert.isArray`. + * Add test for `assert.isUndefined`. + * Add test for `assert.isNotNull`. + * Fix `assert.isNotNull` implementation. + * Fix `assert.isNull` implementation. + * Add test for `assert.isNull`. + * Add test for `assert.notDeepEqual`. + * Add test for `assert.deepEqual`. + * Add test for `assert.notStrictEqual`. + * Add test for `assert.strictEqual`. + * Add test for `assert.notEqual`. + +0.4.1 / 2012-02-26 +================== + + * Merge pull request #27 from logicalparadox/type-fix + * Update the browser version. + * Add should tests for type checks. + * Add function type check test. + * Add more type checks tests. + * Add test for `new Number` type check. + * Fix type of actual checks. + +0.4.0 / 2012-02-25 +================== + + * docs and readme for upcoming 0.4.0 + * docs generated + * putting coverage and tests for docs in docs/out/support + * make docs + * makefile copy necessary resources for tests in docs + * rename configuration test + * Merge pull request #21 from logicalparadox/close-to + * Update the browser version. + * Update `closeTo()` docs. + * Add `Assertion.closeTo()` method. + * Add `.closeTo()` should test. + * Add `.closeTo()` expect test. + * Merge pull request #20 from logicalparadox/satisfy + * Update the browser version. + * `..` -> `()` in `.satisfy()` should test. + * Update example for `.satisfy()`. + * Update the compiled browser version. + * Add `Assertion.satisfy()` method. + * Add `.satisfy()` should test. + * Add `.satisfy()` expect test. + * Merge pull request #19 from logicalparadox/respond-to + * Update the compiled browser version. + * Add `respondTo` Assertion. + * Add `respondTo` should test. + * Add `respondTo` expect test. + * Merge branch 'feature/coverage' + * mocha coverage support + * doc contributors + * README contributors + +0.3.4 / 2012-02-23 +================== + + * inline comment typos for #15 + * Merge branch 'refs/heads/jeffbski-configErrorStackCompat' + * includeStack documentation for all interfaces + * suite name more generic + * Update test to be compatible with browsers that do not support err.stack + * udpated compiled chai.js and added to browser tests + * Allow inclusion of stack trace for Assert error messages to be configurable + * docs sharing buttons + * sinon-chai link + * doc updates + * read me updates include plugins + +0.3.3 / 2012-02-12 +================== + + * Merge pull request #14 from jfirebaugh/configurable_properties + * Make Assertion.prototype properties configurable + +0.3.2 / 2012-02-10 +================== + + * codex version + * docs + * docs cleanup + +0.3.1 / 2012-02-07 +================== + + * node 0.4.x compat + +0.3.0 / 2012-02-07 +================== + + * Merge branch 'feature/03x' + * browser build + * remove html/json/headers testign + * regex error.message testing + * tests for using plugins + * Merge pull request #11 from domenic/master + * Make `chai.use` a no-op if the function has already been used. + +0.2.4 / 2012-02-02 +================== + + * added in past tense switch for `been` + +0.2.3 / 2012-02-01 +================== + + * try that again + +0.2.2 / 2012-02-01 +================== + + * added `been` (past of `be`) alias + +0.2.1 / 2012-01-29 +================== + + * added Throw, with a capital T, as an alias to `throw` (#7) + +0.2.0 / 2012-01-26 +================== + + * update gitignore for vim *.swp + * Merge branch 'feature/plugins' + * browser build + * interfaces now work with use + * simple .use function. See #9. + * readme notice on browser compat + +0.1.7 / 2012-01-25 +================== + + * added assert tests to browser test runner + * browser update + * `should` interface patch for primitives support in FF + * fix isObject() Thanks @milewise + * travis only on branch `master` + * add instanceof alias `instanceOf`. #6 + * some tests for assert module + +0.1.6 / 2012-01-02 +================== + + * commenting for assert interface + * updated codex dep + +0.1.5 / 2012-01-02 +================== + + * browser tests pass + * type in should.not.equal + * test for should (not) exist + * added should.exist and should.not.exist + * browser uses tdd + * convert tests to tdd + +0.1.4 / 2011-12-26 +================== + + * browser lib update for new assert interface compatiblitiy + * inspect typos + * added strict equal + negatives and ifError + * interface assert had doesNotThrow + * added should tests to browser + * new expect empty tests + * should test browser compat + * Fix typo for instanceof docs. Closes #3 [ci skip] + +0.1.3 / 2011-12-18 +================== + + * much cleaner reporting string on error. + +0.1.2 / 2011-12-18 +================== + + * [docs] for upcoming 0.1.2 + * browser version built with pre/suffix … all tests passing + * make / compile now use prefix/suffix correctly + * code clean + * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods. + * Merge branch 'feature/should4xcompatibility' + * compile for browser tests.. all pass + * added header/status/html/json + * throw tests + * should.throw & should.not.throw shortcuts + * improved `throw` type detection and messaging + * contain is now `include` … keys modifier is now `contain` + * removed object() test + * removed #respondTo + * Merge branch 'bug/2' + * replaced __defineGetter__ with defineProperty for all uses + * [docs] change mp tracking code + * docs site updated with assert (TDD) interface + * updated doc comments for assert interface + +0.1.1 / 2011-12-16 +================== + + * docs ready for upcoming 0.1.1 + * readme image fixed [ci skip] + * more readme tweaks [ci skip] + * réadmet image fixed [ci skip] + * documentation + * codex locked in version 0.0.5 + * more comments to assertions for docs + * assertions fully commented, browser library updated + * adding codex as doc dependancy + * prepping for docs + * assertion component completely commented for documentation + * added exist test + * var expect outside of browser if check + * added keywords to package.json + +0.1.0 / 2011-12-15 +================== + + * failing on purpose successful .. back to normal + * testing travis failure + * assert#arguments getter + * readme typo + * updated README + * added travis and npmignore + * copyright notices … think i got them all + * moved expect interface to own file for consistency + * assert ui deepEqual + * browser tests expect (all working) + * browser version built + * chai.fail (should ui) + * expect tests browser compatible + * tests for should and expect (all pass) + * moved fail to primary export + * should compatibility testing + * within, greaterThan, object, keys, + * Aliases + * Assertion#property now correctly works with negate and undefined values + * error message language matches should + * Assertion#respondTo + * Assertion now uses inspect util + * git ignore node modules + * should is exported + * AssertionError __proto__ from Error.prototype + * add should interface for should.js compatibility + * moved eql to until folder and added inspect from (joyent/node) + * added mocha for testing + * browser build for current api + * multiple .property assertions + * added deep equal from node + +0.0.2 / 2011-12-07 +================== + + * cleaner output on error + * improved exists detection + * package remnant artifact + * empty deep equal + * test browser build + * assertion cleanup + * client compile script + * makefile + * most of the basic assertions + * allow no parameters to assertion error + * name change + * assertion error instance + * main exports: assert() & expect() + * initialize diff --git a/support/client/lib/vwf/view/chai/README.md b/support/client/lib/vwf/view/chai/README.md new file mode 100644 index 000000000..c61bfa8b7 --- /dev/null +++ b/support/client/lib/vwf/view/chai/README.md @@ -0,0 +1,83 @@ +[![Chai Documentation](http://chaijs.com/public/img/chai-logo.png)](http://chaijs.com) + +[![license:mit](https://img.shields.io/badge/license-mit-green.svg?style=flat-square)](#license)
+[![tag:?](https://img.shields.io/github/tag/chaijs/chai.svg?style=flat-square)](https://github.com/chaijs/chai/releases) +[![build:?](https://img.shields.io/travis/chaijs/chai/master.svg?style=flat-square)](https://travis-ci.org/chaijs/chai) +[![coverage:?](https://img.shields.io/coveralls/chaijs/chai/master.svg?style=flat-square)](https://coveralls.io/r/chaijs/chai)
+[![npm:](https://img.shields.io/npm/v/chai.svg?style=flat-square)](https://www.npmjs.com/packages/chai) +[![dependencies:?](https://img.shields.io/npm/dm/chai.svg?style=flat-square)](https://www.npmjs.com/packages/chai) +[![devDependencies:?](https://img.shields.io/david/chaijs/chai.svg?style=flat-square)](https://david-dm.org/chaijs/chai) + +[![Selenium Test Status](https://saucelabs.com/browser-matrix/chaijs.svg)](https://saucelabs.com/u/chaijs) + +[![Slack Status](https://chai-slack.herokuapp.com/badge.svg)]( https://chai-slack.herokuapp.com/) +[![Join the chat at https://gitter.im/chaijs/chai](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/chaijs/chai) + +Chai is a BDD / TDD assertion library for [node](http://nodejs.org) and the browser that +can be delightfully paired with any javascript testing framework. + +For more information or to download plugins, view the [documentation](http://chaijs.com). + +### Plugins + +Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces. + +- Need a plugin? View the [official plugin list](http://chaijs.com/plugins). +- Have a plugin and want it listed? Open a Pull Request at [chaijs/chai-docs:plugin.js](https://github.com/chaijs/chai-docs/blob/master/plugins.js#L1-L12). +- Want to build a plugin? Read the [plugin api documentation](http://chaijs.com/guide/plugins/). + +### Related Projects + +- [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. +- [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. +- [chaijs / type-detect](https://github.com/chaijs/type-detect): Improved typeof detection for node.js and the browser. + +### Contributing + +Thank you very much for considering to contribute! + +Here are a few issues other contributors frequently ran into when opening pull requests: + +- Please do not commit changes to the `chai.js` build. We do it once per release. +- Before pushing your commits, please make sure you [rebase](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md#pull-requests) them. + +We also strongly encourage you to read our detailed [contribution guidelines](https://github.com/chaijs/chai/blob/master/CONTRIBUTING.md). + +### Contributors + +Please see the full +[Contributors Graph](https://github.com/chaijs/chai/graphs/contributors) for our +list of contributors. + +### Core Contributors + +Feel free to reach out to any of the core contributors with your questions or +concerns. We will do our best to respond in a timely manner. + +[![Jake Luer](https://avatars3.githubusercontent.com/u/58988?v=3&s=50)](https://github.com/logicalparadox) +[![Veselin Todorov](https://avatars3.githubusercontent.com/u/330048?v=3&s=50)](https://github.com/vesln) +[![Keith Cirkel](https://avatars3.githubusercontent.com/u/118266?v=3&s=50)](https://github.com/keithamus) + +## License + +(The MIT License) + +Copyright (c) 2011-2015 Jake Luer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/support/client/lib/vwf/view/chai/ReleaseNotes.md b/support/client/lib/vwf/view/chai/ReleaseNotes.md new file mode 100644 index 000000000..2a80d5cec --- /dev/null +++ b/support/client/lib/vwf/view/chai/ReleaseNotes.md @@ -0,0 +1,737 @@ +# Release Notes + +## Note + +As of 3.0.0, the ReleaseNotes.md file has been deprecated. [Please refer to the release notes available on Github](https://github.com/chaijs/chai/releases). Or +[the release notes on the chaijs.com website](https://chaijs.com/releases). + +--- + +## 2.3.0 / 2015-04-26 + +Added `ownPropertyDescriptor` assertion: + +```js +expect('test').to.have.ownPropertyDescriptor('length'); +expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); +expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); +expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); +expect('test').ownPropertyDescriptor('length').to.have.keys('value'); +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#408](https://github.com/chaijs/chai/pull/408) Add `ownPropertyDescriptor` + assertion. + By [@ljharb](https://github.com/ljharb) + * [#422](https://github.com/chaijs/chai/pull/422) Improve ownPropertyDescriptor + tests. + By [@ljharb](https://github.com/ljharb) + +#### Documentation fixes + + * [#417](https://github.com/chaijs/chai/pull/417) Fix documentation typo + By [@astorije](https://github.com/astorije) + * [#423](https://github.com/chaijs/chai/pull/423) Fix inconsistency in docs. + By [@ehntoo](https://github.com/ehntoo) + + +## 2.2.0 / 2015-03-26 + +Deep property strings can now be escaped using `\\` - for example: + +```js +var deepCss = { '.link': { '[target]': 42 }}; +expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42) +``` + +### Community Contributions + +#### Code Features & Fixes + + * [#402](https://github.com/chaijs/chai/pull/402) Allow escaping of deep + property keys. + By [@umireon](https://github.com/umireon) + +#### Documentation fixes + + * [#405](https://github.com/chaijs/chai/pull/405) Tweak documentation around + deep property escaping. + By [@keithamus](https://github.com/keithamus) + + +## 2.1.2 / 2015-03-15 + +A minor bug fix. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#395](https://github.com/chaijs/chai/pull/395) Fix eval-related bugs with + assert.operator ([#386](https://github.com/chaijs/chai/pull/386)). + By [@cjqed](https://github.com/cjqed) + +## 2.1.1 / 2015-03-04 + +Two minor bugfixes. No new features. + +### Community Contributions + +#### Code Features & Fixes + + * [#385](https://github.com/chaijs/chai/pull/385) Fix a bug (also described in + [#387](https://github.com/chaijs/chai/pull/385)) where `deep.property` would not work with single + key names. By [@eldritch-fossicker](https://github.com/eldritch-fossicker) + * [#379](https://github.com/chaijs/chai/pull/379) Fix bug where tools which overwrite + primitive prototypes, such as Babel or core-js would fail. + By [@dcneiner](https://github.com/dcneiner) + +#### Documentation fixes + + * [#382](https://github.com/chaijs/chai/pull/382) Add doc for showDiff argument in assert. + By [@astorije](https://github.com/astorije) + * [#383](https://github.com/chaijs/chai/pull/383) Improve wording for truncateTreshold docs + By [@gurdiga](https://github.com/gurdiga) + * [#381](https://github.com/chaijs/chai/pull/381) Improve wording for assert.empty docs + By [@astorije](https://github.com/astorije) + +## 2.1.0 / 2015-02-23 + +Small release; fixes an issue where the Chai lib was incorrectly reporting the +version number. + +Adds new `should.fail()` and `expect.fail()` methods, which are convinience +methods to throw Assertion Errors. + +### Community Contributions + +#### Code Features & Fixes + + * [#356](https://github.com/chaijs/chai/pull/356) Add should.fail(), expect.fail(). By [@Soviut](https://github.com/Soviut) + * [#374](https://github.com/chaijs/chai/pull/374) Increment version. By [@jmm](https://github.com/jmm) + +## 2.0.0 / 2015-02-09 + +Unfortunately with 1.10.0 - compatibility broke with older versions because of +the `addChainableNoop`. This change has been reverted. + +Any plugins using `addChainableNoop` should cease to do so. + +Any developers wishing for this behaviour can use [dirty-chai](https://www.npmjs.com/package/dirty-chai) +by [@joshperry](https://github.com/joshperry) + +### Community Contributions + +#### Code Features & Fixes + + * [#361](https://github.com/chaijs/chai/pull/361) `.keys()` now accepts Objects, extracting keys from them. By [@gregglind](https://github.com/gregglind) + * [#359](https://github.com/chaijs/chai/pull/359) `.keys()` no longer mutates passed arrays. By [@gregglind](https://github.com/gregglind) + * [#349](https://github.com/chaijs/chai/pull/349) Add a new chainable keyword - `.which`. By [@toastynerd](https://github.com/toastynerd) + * [#333](https://github.com/chaijs/chai/pull/333) Add `.change`, `.increase` and `.decrease` assertions. By [@cmpolis](https://github.com/cmpolis) + * [#335](https://github.com/chaijs/chai/pull/335) `chai.util` is now exposed [@DingoEatingFuzz](https://github.com/DingoEatingFuzz) + * [#328](https://github.com/chaijs/chai/pull/328) Add `.includes` and `.contains` aliases (for `.include` and `.contain`). By [@lo1tuma](https://github.com/lo1tuma) + * [#313](https://github.com/chaijs/chai/pull/313) Add `.any.keys()` and `.all.keys()` qualifiers. By [@cjqed](https://github.com/cjqed) + * [#312](https://github.com/chaijs/chai/pull/312) Add `assert.sameDeepMembers()`. By [@cjqed](https://github.com/cjqed) + * [#311](https://github.com/chaijs/chai/pull/311) Add `assert.isAbove()` and `assert.isBelow()`. By [@cjqed](https://github.com/cjqed) + * [#308](https://github.com/chaijs/chai/pull/308) `property` and `deep.property` now pass if a value is set to `undefined`. By [@prodatakey](https://github.com/prodatakey) + * [#309](https://github.com/chaijs/chai/pull/309) optimize deep equal in Arrays. By [@ericdouglas](https://github.com/ericdouglas) + * [#306](https://github.com/chaijs/chai/pull/306) revert #297 - allowing lint-friendly tests. By [@keithamus](https://github.com/keithamus) + +#### Documentation fixes + + * [#357](https://github.com/chaijs/chai/pull/357) Copyright year updated in docs. By [@danilovaz](https://github.com/danilovaz) + * [#325](https://github.com/chaijs/chai/pull/325) Fix documentation for overwriteChainableMethod. By [@chasenlehara](https://github.com/chasenlehara) + * [#334](https://github.com/chaijs/chai/pull/334) Typo fix. By [@hurrymaplelad](https://github.com/hurrymaplelad) + * [#317](https://github.com/chaijs/chai/pull/317) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#318](https://github.com/chaijs/chai/pull/318) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + * [#316](https://github.com/chaijs/chai/pull/316) Typo fix. By [@jasonkarns](https://github.com/jasonkarns) + + +## 1.10.0 / 2014-11-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review `addChainableNoop` notes below. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Noop Function for Terminating Assertion Properties + +The following assertions can now also be used in the function-call form: + +* ok +* true +* false +* null +* undefined +* exist +* empty +* arguments +* Arguments + +The above list of assertions are property getters that assert immediately on +access. Because of that, they were written to be used by terminating the assertion +chain with a property access. + +```js +expect(true).to.be.true; +foo.should.be.ok; +``` + +This syntax is definitely aesthetically pleasing but, if you are linting your +test code, your linter will complain with an error something like "Expected an +assignment or function call and instead saw an expression." Since the linter +doesn't know about the property getter it assumes this line has no side-effects, +and throws a warning in case you made a mistake. + +Squelching these errors is not a good solution as test code is getting to be +just as important as, if not more than, production code. Catching syntactical +errors in tests using static analysis is a great tool to help make sure that your +tests are well-defined and free of typos. + +A better option was to provide a function-call form for these assertions so that +the code's intent is more clear and the linters stop complaining about something +looking off. This form is added in addition to the existing property access form +and does not impact existing test code. + +```js +expect(true).to.be.true(); +foo.should.be.ok(); +``` + +These forms can also be mixed in any way, these are all functionally identical: + +```js +expect(true).to.be.true.and.not.false(); +expect(true).to.be.true().and.not.false; +expect(true).to.be.true.and.not.false; +``` + +#### Plugin Authors + +If you would like to provide this function-call form for your terminating assertion +properties, there is a new function to register these types of asserts. Instead +of using `addProperty` to register terminating assertions, simply use `addChainableNoop` +instead; the arguments to both are identical. The latter will make the assertion +available in both the attribute and function-call forms and should have no impact +on existing users of your plugin. + +### Community Contributions + +- [#297](https://github.com/chaijs/chai/pull/297) Allow writing lint-friendly tests. [@joshperry](https://github.com/joshperry) +- [#298](https://github.com/chaijs/chai/pull/298) Add check for logging `-0`. [@dasilvacontin](https://github.com/dasilvacontin) +- [#300](https://github.com/chaijs/chai/pull/300) Fix #299: the test is defining global variables [@julienw](https://github.com/julienw) + +Thank you to all who took time to contribute! + +## 1.9.2 / 2014-09-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#264](https://github.com/chaijs/chai/pull/264) Show diff for keys assertions [@cjthompson](https://github.com/cjthompson) +- [#267](https://github.com/chaijs/chai/pull/267) Use SVG badges [@shinnn](https://github.com/shinnn) +- [#268](https://github.com/chaijs/chai/pull/268) Allow messages to be functions (sinon-compat) [@charlierudolph](https://github.com/charlierudolph) +- [#269](https://github.com/chaijs/chai/pull/269) Remove unused argument for #lengthOf [@charlierudolph](https://github.com/charlierudolph) +- [#275](https://github.com/chaijs/chai/pull/275) Rewrite pretty-printing HTML elements to prevent throwing internal errors [@DrRataplan](https://github.com/DrRataplan) +- [#277](https://github.com/chaijs/chai/pull/277) Fix assert documentation for #sameMembers [@charlierudolph](https://github.com/charlierudolph) +- [#279](https://github.com/chaijs/chai/pull/279) closeTo should check value's type before assertion [@mohayonao](https://github.com/mohayonao) +- [#289](https://github.com/chaijs/chai/pull/289) satisfy is called twice [@charlierudolph](https://github.com/charlierudolph) +- [#292](https://github.com/chaijs/chai/pull/292) resolve conflicts with node-webkit and global usage [@boneskull](https://github.com/boneskull) + +Thank you to all who took time to contribute! + +## 1.9.1 / 2014-03-19 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Migrate configuration options to new interface. (see notes) +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Configuration + +There have been requests for changes and additions to the configuration mechanisms +and their impact in the Chai architecture. As such, we have decoupled the +configuration from the `Assertion` constructor. This not only allows for centralized +configuration, but will allow us to shift the responsibility from the `Assertion` +constructor to the `assert` interface in future releases. + +These changes have been implemented in a non-breaking way, but a depretiation +warning will be presented to users until they migrate. The old config method will +be removed in either `v1.11.0` or `v2.0.0`, whichever comes first. + +#### Quick Migration + +```js +// change this: +chai.Assertion.includeStack = true; +chai.Assertion.showDiff = false; + +// ... to this: +chai.config.includeStack = true; +chai.config.showDiff = false; +``` + +#### All Config Options + +##### config.includeStack + +- **@param** _{Boolean}_ +- **@default** `false` + +User configurable property, influences whether stack trace is included in +Assertion error message. Default of `false` suppresses stack trace in the error +message. + +##### config.showDiff + +- **@param** _{Boolean}_ +- **@default** `true` + +User configurable property, influences whether or not the `showDiff` flag +should be included in the thrown AssertionErrors. `false` will always be `false`; +`true` will be true when the assertion has requested a diff be shown. + +##### config.truncateThreshold **(NEW)** + +- **@param** _{Number}_ +- **@default** `40` + +User configurable property, sets length threshold for actual and expected values +in assertion errors. If this threshold is exceeded, the value is truncated. + +Set it to zero if you want to disable truncating altogether. + +```js +chai.config.truncateThreshold = 0; // disable truncating +``` + +### Community Contributions + +- [#228](https://github.com/chaijs/chai/pull/228) Deep equality check for memebers. [@duncanbeevers](https://github.com/duncanbeevers) +- [#247](https://github.com/chaijs/chai/pull/247) Proofreading. [@didorellano](https://github.com/didoarellano) +- [#244](https://github.com/chaijs/chai/pull/244) Fix `contain`/`include` 1.9.0 regression. [@leider](https://github.com/leider) +- [#233](https://github.com/chaijs/chai/pull/233) Improvements to `ssfi` for `assert` interface. [@refack](https://github.com/refack) +- [#251](https://github.com/chaijs/chai/pull/251) New config option: object display threshold. [@romario333](https://github.com/romario333) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#183](https://github.com/chaijs/chai/issues/183) Allow `undefined` for actual. (internal api) +- Update Karam(+plugins)/Istanbul to most recent versions. + +## 1.9.0 / 2014-01-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required +- **Plugin Developers:** + - Review [#219](https://github.com/chaijs/chai/pull/219). +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Community Contributions + +- [#202](https://github.com/chaijs/chai/pull/201) Improve error message for .throw(). [@andreineculau](https://github.com/andreineculau) +- [#217](https://github.com/chaijs/chai/pull/217) Chai tests can be run with `--watch`. [@demands](https://github.com/demands) +- [#219](https://github.com/chaijs/chai/pull/219) Add overwriteChainableMethod utility. [@demands](https://github.com/demands) +- [#224](https://github.com/chaijs/chai/pull/224) Return error on throw method to chain on error properties. [@vbardales](https://github.com/vbardales) +- [#226](https://github.com/chaijs/chai/pull/226) Add `has` to language chains. [@duncanbeevers](https://github.com/duncanbeevers) +- [#230](https://github.com/chaijs/chai/pull/230) Support `{a:1,b:2}.should.include({a:1})` [@jkroso](https://github.com/jkroso) +- [#231](https://github.com/chaijs/chai/pull/231) Update Copyright notices to 2014 [@duncanbeevers](https://github.com/duncanbeevers) +- [#232](https://github.com/chaijs/chai/pull/232) Avoid error instantiation if possible on assert.throws. [@laconbass](https://github.com/laconbass) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#225](https://github.com/chaijs/chai/pull/225) Improved AMD wrapper provided by upstream `component(1)`. +- [#185](https://github.com/chaijs/chai/issues/185) `assert.throws()` returns thrown error for further assertions. +- [#237](https://github.com/chaijs/chai/pull/237) Remove coveralls/jscoverage, include istanbul coverage report in travis test. +- Update Karma and Sauce runner versions for consistent CI results. No more karma@canary. + +## 1.8.1 / 2013-10-10 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - Refresh `node_modules` folder for updated dependencies. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Browserify + +This is a small patch that updates the dependency tree so browserify users can install +chai. (Remove conditional requires) + +## 1.8.0 / 2013-09-18 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - See `deep.equal` notes. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Deep Equals + +This version of Chai focused on a overhaul to the deep equal utility. The code for this +tool has been removed from the core lib and can now be found at: +[chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases, +this is part of a larger initiative to provide transparency, independent testing, and coverage for +some of the more complicated internal tools. + +For the most part `.deep.equal` will behave the same as it has. However, in order to provide a +consistent ruleset across all types being tested, the following changes have been made and _might_ +require changes to your tests. + +**1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + +_Previously:_ Non-traversable equal via `===`. + +```js +expect(NaN).to.deep.equal(NaN); +expect(-0).to.not.deep.equal(+0); +``` + +**2.** Arguments are not Arrays (and all types must be equal): + +_Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates. + +```js +expect(arguments).to.not.deep.equal([]); +expect(Array.prototype.slice.call(arguments)).to.deep.equal([]); +``` + +- [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array +- [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object +- [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility + +### CI and Browser Testing + +Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at +[SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands... +and we get a cool badge: + +[![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox) + +Look for the list of browsers/versions to expand over the coming releases. + +- [#195](https://github.com/chaijs/chai/issues/195) karma test framework + +## 1.7.2 / 2013-06-27 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Coverage Reporting + +Coverage reporting has always been available for core-developers but the data has never been published +for our end users. In our ongoing effort to improve accountability this data will now be published via +the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report +can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs +will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI. + +### Other Fixes + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all) + +## 1.7.1 / 2013-06-24 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### Official Bower Support + +Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though +Chai could be installed via Bower in the past, this update adds official support via the `bower.json` +specification file. + +- [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. + +## 1.7.0 / 2013-06-17 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - Review AssertionError update notice. +- **Core Contributors:** + - Refresh `node_modules` folder for updated dependencies. + +### AssertionError Update Notice + +Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal +constructor. This will allow for further iteration/experimentation of the AssertionError constructor +independant of Chai. Future plans include stack parsing for callsite support. + +This update constructor has a different constructor param signature that conforms more with the standard +`Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin +with the new signature. + +```js +var AssertionError = require('chai').AssertionError; + +/** + * previous + * + * @param {Object} options + */ + +throw new AssertionError({ + message: 'An assertion error occurred' + , actual: actual + , expect: expect + , startStackFunction: arguments.callee + , showStack: true +}); + +/** + * new + * + * @param {String} message + * @param {Object} options + * @param {Function} start stack function + */ + +throw new AssertionError('An assertion error occurred', { + actual: actual + , expect: expect + , showStack: true +}, arguments.callee); + +// other signatures +throw new AssertionError('An assertion error occurred'); +throw new AssertionError('An assertion error occurred', null, arguments.callee); +``` + +#### External Dependencies + +This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding +more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing +there is an higher need for accountability and documentation. External dependencies will allow us to iterate and +test on features independent from our interfaces. + +Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai. + +### Community Contributions + +- [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek) +- [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds) +- [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic) + +Thank you to all who took the time to contribute! + +## 1.6.1 / 2013-06-05 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Deep Equality + +Regular Expressions are now tested as part of all deep equality assertions. In previous versions +they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution. + +### Community Contributions + +- [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton) +- [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek) + +Thank you to all who took the time to contribute! + +### Additional Notes + +- Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility. + +## 1.6.0 / 2013-04-29 + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - No changes required. +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### New Assertions + +#### Array Members Inclusion + +Asserts that the target is a superset of `set`, or that the target and `set` have the same members. +Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution. + +```js +// (expect/should) full set +expect([4, 2]).to.have.members([2, 4]); +expect([5, 2]).to.not.have.members([5, 2, 1]); + +// (expect/should) inclusion +expect([1, 2, 3]).to.include.members([3, 2]); +expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + +// (assert) full set +assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + +// (assert) inclusion +assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + +``` + +#### Non-inclusion for Assert Interface + +Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`. +However `include()` did not have a corresponding `notInclude()`. This has been added. + +```js +assert.notInclude([ 1, 2, 3 ], 8); +assert.notInclude('foobar', 'baz'); +``` + +### Community Contributions + +- [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack. +- [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added. +- Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before. + +## 1.5.0 / 2013-02-03 + +### Migration Requirements + +The following changes are required if you are upgrading from the previous version: + +- **Users:** + - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of + [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions + to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139). +- **Plugin Developers:** + - No changes required. +- **Core Contributors:** + - Refresh `node_modules` folder for updated developement dependencies. + +### Community Contributions + +- [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh) +- [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew) +- [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff) + +Thank you to all who took time to contribute! + +### Other Bug Fixes + +- Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios. +- [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers. +- [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers. + + +### Usage Updates + +#### For Users + +**1. Component Support:** Chai now included the proper configuration to be installed as a +[component](https://github.com/component/component). Component users are encouraged to consult +[chaijs.com](http://chaijs.com) for the latest version number as using the master branch +does not gaurantee stability. + +```js +// relevant component.json + devDependencies: { + "chaijs/chai": "1.5.0" + } +``` + +Alternatively, bleeding-edge is available: + + $ component install chaijs/chai + +**2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/)) +include support for showing the diff of strings and objects when an equality error occurs. Chai has +already included support for this, however some users may not prefer this display behavior. To revert to +no diff display, the following configuration is available: + +```js +chai.Assertion.showDiff = false; // diff output disabled +chai.Assertion.showDiff = true; // default, diff output enabled +``` + +#### For Plugin Developers + +**1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof` +that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection. + +- **@param** _{Mixed}_ object to detect type of +- **@return** _{String}_ object type + +```js +chai.use(function (c, utils) { + // some examples + utils.type({}); // 'object' + utils.type(null); // `null' + utils.type(undefined); // `undefined` + utils.type([]); // `array` +}); +``` + +#### For Core Contributors + +**1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line +via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all +pull requests will now be browser tested in this way. + +_Note: Contributors opening pull requests should still NOT include the browser build._ + +**2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`. +Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account +and include their credentials in `./test/auth/sauce.json`. diff --git a/support/client/lib/vwf/view/chai/bower.json b/support/client/lib/vwf/view/chai/bower.json new file mode 100644 index 000000000..af2ee029b --- /dev/null +++ b/support/client/lib/vwf/view/chai/bower.json @@ -0,0 +1,26 @@ +{ + "name": "chai", + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "license": "MIT", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "main": "chai.js", + "ignore": [ + "build", + "components", + "lib", + "node_modules", + "support", + "test", + "index.js", + "Makefile", + ".*" + ], + "dependencies": {}, + "devDependencies": {} +} diff --git a/support/client/lib/vwf/view/chai/chai.js b/support/client/lib/vwf/view/chai/chai.js new file mode 100644 index 000000000..8c5ae1f81 --- /dev/null +++ b/support/client/lib/vwf/view/chai/chai.js @@ -0,0 +1,6146 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o + * MIT Licensed + */ + +var used = [] + , exports = module.exports = {}; + +/*! + * Chai version + */ + +exports.version = '3.5.0'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(this, util); + used.push(fn); + } + + return this; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +},{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":30}],3:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * @api private + */ + + function Assertion (obj, msg, stack) { + flag(this, 'ssfi', stack || arguments.callee); + flag(this, 'object', obj); + flag(this, 'message', msg); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (true !== showDiff) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + var msg = util.getMessage(this, arguments) + , actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; + +},{"./config":4}],4:[function(require,module,exports){ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40 + +}; + +},{}],5:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , toString = Object.prototype.toString + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to + * improve the readability of your assertions. They + * do not provide testing capabilities unless they + * have been overwritten by a plugin. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'has', 'have' + , 'with', 'that', 'which', 'at' + , 'of', 'same' ].forEach(function (chain) { + Assertion.addProperty(chain, function () { + return this; + }); + }); + + /** + * ### .not + * + * Negates any of assertions following in the chain. + * + * expect(foo).to.not.equal('bar'); + * expect(goodFn).to.not.throw(Error); + * expect({ foo: 'baz' }).to.have.property('foo') + * .and.not.equal('bar'); + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Sets the `deep` flag, later used by the `equal` and + * `property` assertions. + * + * expect(foo).to.deep.equal({ bar: 'baz' }); + * expect({ foo: { bar: { baz: 'quux' } } }) + * .to.have.deep.property('foo.bar.baz', 'quux'); + * + * `.deep.property` special characters can be escaped + * by adding two slashes before the `.` or `[]`. + * + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .any + * + * Sets the `any` flag, (opposite of the `all` flag) + * later used in the `keys` assertion. + * + * expect(foo).to.have.any.keys('bar', 'baz'); + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false) + }); + + + /** + * ### .all + * + * Sets the `all` flag (opposite of the `any` flag) + * later used by the `keys` assertion. + * + * expect(foo).to.have.all.keys('bar', 'baz'); + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type) + * + * The `a` and `an` assertions are aliases that can be + * used either as language chains or to assert a value's + * type. + * + * // typeof + * expect('test').to.be.a('string'); + * expect({ foo: 'bar' }).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(new Promise).to.be.a('promise'); + * expect(new Float32Array()).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * // es6 overrides + * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); + * + * // language chain + * expect(foo).to.be.an.instanceof(Foo); + * + * @name a + * @alias an + * @param {String} type + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj) + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(value) + * + * The `include` and `contain` assertions can be used as either property + * based language chains or as methods to assert the inclusion of an object + * in an array or a substring in a string. When used as language chains, + * they toggle the `contains` flag for the `keys` assertion. + * + * expect([1,2,3]).to.include(2); + * expect('foobar').to.contain('foo'); + * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Object|String|Number} obj + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + _.expectTypes(this, ['array', 'object', 'string']); + + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var expected = false; + + if (_.type(obj) === 'array' && _.type(val) === 'object') { + for (var i in obj) { + if (_.eql(obj[i], val)) { + expected = true; + break; + } + } + } else if (_.type(val) === 'object') { + if (!flag(this, 'negate')) { + for (var k in val) new Assertion(obj).property(k, val[k]); + return; + } + var subset = {}; + for (var k in val) subset[k] = obj[k]; + expected = _.eql(subset, val); + } else { + expected = (obj != undefined) && ~obj.indexOf(val); + } + this.assert( + expected + , 'expected #{this} to include ' + _.inspect(val) + , 'expected #{this} to not include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is truthy. + * + * expect('everything').to.be.ok; + * expect(1).to.be.ok; + * expect(false).to.not.be.ok; + * expect(undefined).to.not.be.ok; + * expect(null).to.not.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is `true`. + * + * expect(true).to.be.true; + * expect(1).to.not.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , this.negate ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is `false`. + * + * expect(false).to.be.false; + * expect(0).to.not.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , this.negate ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is `null`. + * + * expect(null).to.be.null; + * expect(undefined).to.not.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is `undefined`. + * + * expect(undefined).to.be.undefined; + * expect(null).to.not.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * Asserts that the target is `NaN`. + * + * expect('foo').to.be.NaN; + * expect(4).not.to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi' + * , bar = null + * , baz; + * + * expect(foo).to.exist; + * expect(bar).to.not.exist; + * expect(baz).to.not.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + this.assert( + null != flag(this, 'object') + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + + /** + * ### .empty + * + * Asserts that the target's length is `0`. For arrays and strings, it checks + * the `length` property. For objects, it gets the count of + * enumerable keys. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * expect({}).to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var obj = flag(this, 'object') + , expected = obj; + + if (Array.isArray(obj) || 'string' === typeof object) { + expected = obj.length; + } else if (typeof obj === 'object') { + expected = Object.keys(obj).length; + } + + this.assert( + !expected + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an arguments object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = Object.prototype.toString.call(obj); + this.assert( + '[object Arguments]' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(value) + * + * Asserts that the target is strictly equal (`===`) to `value`. + * Alternately, if the `deep` flag is set, asserts that + * the target is deeply equal to `value`. + * + * expect('hello').to.equal('hello'); + * expect(42).to.equal(42); + * expect(1).to.not.equal(true); + * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); + * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); + * + * @name equal + * @alias equals + * @alias eq + * @alias deep.equal + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(value) + * + * Asserts that the target is deeply equal to `value`. + * + * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); + * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); + * + * @name eql + * @alias eqls + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(value) + * + * Asserts that the target is greater than `value`. + * + * expect(10).to.be.above(5); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above ' + n + , 'expected #{this} to be at most ' + n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(value) + * + * Asserts that the target is greater than or equal to `value`. + * + * expect(10).to.be.at.least(10); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.least(2); + * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3); + * + * @name least + * @alias gte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= n + , 'expected #{this} to have a length at least #{exp} but got #{act}' + , 'expected #{this} to have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least ' + n + , 'expected #{this} to be below ' + n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(value) + * + * Asserts that the target is less than `value`. + * + * expect(5).to.be.below(10); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below ' + n + , 'expected #{this} to be at least ' + n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(value) + * + * Asserts that the target is less than or equal to `value`. + * + * expect(5).to.be.at.most(5); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.most(4); + * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3); + * + * @name most + * @alias lte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len <= n + , 'expected #{this} to have a length at most #{exp} but got #{act}' + , 'expected #{this} to have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most ' + n + , 'expected #{this} to be above ' + n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish) + * + * Asserts that the target is within a range. + * + * expect(7).to.be.within(5,10); + * + * Can also be used in conjunction with `length` to + * assert a length range. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * @name within + * @param {Number} start lowerbound inclusive + * @param {Number} finish upperbound inclusive + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , range = start + '..' + finish; + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor) + * + * Asserts that the target is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , Chai = new Tea('chai'); + * + * expect(Chai).to.be.an.instanceof(Tea); + * expect([ 1, 2, 3 ]).to.be.instanceof(Array); + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} message _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + var name = _.getName(constructor); + this.assert( + flag(this, 'object') instanceof constructor + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name, [value]) + * + * Asserts that the target has a property `name`, optionally asserting that + * the value of that property is strictly equal to `value`. + * If the `deep` flag is set, you can use dot- and bracket-notation for deep + * references into objects and arrays. + * + * // simple referencing + * var obj = { foo: 'bar' }; + * expect(obj).to.have.property('foo'); + * expect(obj).to.have.property('foo', 'bar'); + * + * // deep referencing + * var deepObj = { + * green: { tea: 'matcha' } + * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] + * }; + * + * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); + * + * You can also use an array as the starting point of a `deep.property` + * assertion, or traverse nested arrays. + * + * var arr = [ + * [ 'chai', 'matcha', 'konacha' ] + * , [ { tea: 'chai' } + * , { tea: 'matcha' } + * , { tea: 'konacha' } ] + * ]; + * + * expect(arr).to.have.deep.property('[0][1]', 'matcha'); + * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); + * + * Furthermore, `property` changes the subject of the assertion + * to be the value of that property from the original object. This + * permits for further chainable assertions on that property. + * + * expect(obj).to.have.property('foo') + * .that.is.a('string'); + * expect(deepObj).to.have.property('green') + * .that.is.an('object') + * .that.deep.equals({ tea: 'matcha' }); + * expect(deepObj).to.have.property('teas') + * .that.is.an('array') + * .with.deep.property('[2]') + * .that.deep.equals({ tea: 'konacha' }); + * + * Note that dots and bracket in `name` must be backslash-escaped when + * the `deep` flag is set, while they must NOT be escaped when the `deep` + * flag is not set. + * + * // simple referencing + * var css = { '.link[target]': 42 }; + * expect(css).to.have.property('.link[target]', 42); + * + * // deep referencing + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name property + * @alias deep.property + * @param {String} name + * @param {Mixed} value (optional) + * @param {String} message _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + Assertion.addMethod('property', function (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isDeep = !!flag(this, 'deep') + , descriptor = isDeep ? 'deep property ' : 'property ' + , negate = flag(this, 'negate') + , obj = flag(this, 'object') + , pathInfo = isDeep ? _.getPathInfo(name, obj) : null + , hasProperty = isDeep + ? pathInfo.exists + : _.hasProperty(name, obj) + , value = isDeep + ? pathInfo.value + : obj[name]; + + if (negate && arguments.length > 1) { + if (undefined === value) { + msg = (msg != null) ? msg + ': ' : ''; + throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name)); + } + } else { + this.assert( + hasProperty + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + val === value + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + }); + + + /** + * ### .ownProperty(name) + * + * Asserts that the target has an own property `name`. + * + * expect('test').to.have.ownProperty('length'); + * + * @name ownProperty + * @alias haveOwnProperty + * @param {String} name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnProperty (name, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + obj.hasOwnProperty(name) + , 'expected #{this} to have own property ' + _.inspect(name) + , 'expected #{this} to not have own property ' + _.inspect(name) + ); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, message]]) + * + * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`. + * + * expect('test').to.have.ownPropertyDescriptor('length'); + * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); + * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); + * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); + * expect('test').ownPropertyDescriptor('length').to.have.keys('value'); + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .length + * + * Sets the `doLength` flag later used as a chain precursor to a value + * comparison for the `length` property. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * *Deprecation notice:* Using `length` as an assertion will be deprecated + * in version 2.4.0 and removed in 3.0.0. Code using the old style of + * asserting for `length` property value using `length(value)` should be + * switched to use `lengthOf(value)` instead. + * + * @name length + * @namespace BDD + * @api public + */ + + /** + * ### .lengthOf(value[, message]) + * + * Asserts that the target's `length` property has + * the expected value. + * + * expect([ 1, 2, 3]).to.have.lengthOf(3); + * expect('foobar').to.have.lengthOf(6); + * + * @name lengthOf + * @param {Number} length + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addMethod('lengthOf', assertLength); + + /** + * ### .match(regexp) + * + * Asserts that the target matches a regular expression. + * + * expect('foobar').to.match(/^foo/); + * + * @name match + * @alias matches + * @param {RegExp} RegularExpression + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(string) + * + * Asserts that the string target contains another string. + * + * expect('foobar').to.have.string('bar'); + * + * @name string + * @param {String} string + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + + /** + * ### .keys(key1, [key2], [...]) + * + * Asserts that the target contains any or all of the passed-in keys. + * Use in combination with `any`, `all`, `contains`, or `have` will affect + * what will pass. + * + * When used in conjunction with `any`, at least one key that is passed + * in must exist in the target object. This is regardless whether or not + * the `have` or `contain` qualifiers are used. Note, either `any` or `all` + * should be used in the assertion. If neither are used, the assertion is + * defaulted to `all`. + * + * When both `all` and `contain` are used, the target object must have at + * least all of the passed-in keys but may have more keys not listed. + * + * When both `all` and `have` are used, the target object must both contain + * all of the passed-in keys AND the number of keys in the target object must + * match the number of keys passed in (in other words, a target object must + * have all and only all of the passed-in keys). + * + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6}); + * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7}); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6}); + * + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , str + , ok = true + , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments'; + + switch (_.type(keys)) { + case "array": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + break; + case "object": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + if (!keys.length) throw new Error('keys required'); + + var actual = Object.keys(obj) + , expected = keys + , len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all'); + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + var intersection = expected.filter(function(key) { + return ~actual.indexOf(key); + }); + ok = intersection.length > 0; + } + + // Has all + if (all) { + ok = keys.every(function(key){ + return ~actual.indexOf(key); + }); + if (!flag(this, 'negate') && !flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key){ + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + str + , 'expected #{this} to not ' + str + , expected.slice(0).sort() + , actual.sort() + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw(constructor) + * + * Asserts that the function target will throw a specific error, or specific type of error + * (as determined using `instanceof`), optionally with a RegExp or string inclusion test + * for the error's message. + * + * var err = new ReferenceError('This is a bad function.'); + * var fn = function () { throw err; } + * expect(fn).to.throw(ReferenceError); + * expect(fn).to.throw(Error); + * expect(fn).to.throw(/bad function/); + * expect(fn).to.not.throw('good function'); + * expect(fn).to.throw(ReferenceError, /bad function/); + * expect(fn).to.throw(err); + * + * Please note that when a throw expectation is negated, it will check each + * parameter independently, starting with error constructor type. The appropriate way + * to check for the existence of a type of error but for a message that does not match + * is to use `and`. + * + * expect(fn).to.throw(ReferenceError) + * .and.not.throw(/good function/); + * + * @name throw + * @alias throws + * @alias Throw + * @param {ErrorConstructor} constructor + * @param {String|RegExp} expected error message + * @param {String} message _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (constructor, errMsg, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('function'); + + var thrown = false + , desiredError = null + , name = null + , thrownError = null; + + if (arguments.length === 0) { + errMsg = null; + constructor = null; + } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { + errMsg = constructor; + constructor = null; + } else if (constructor && constructor instanceof Error) { + desiredError = constructor; + constructor = null; + errMsg = null; + } else if (typeof constructor === 'function') { + name = constructor.prototype.name; + if (!name || (name === 'Error' && constructor !== Error)) { + name = constructor.name || (new constructor()).name; + } + } else { + constructor = null; + } + + try { + obj(); + } catch (err) { + // first, check desired error + if (desiredError) { + this.assert( + err === desiredError + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (err instanceof Error ? err.toString() : err) + ); + + flag(this, 'object', err); + return this; + } + + // next, check constructor + if (constructor) { + this.assert( + err instanceof constructor + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp} but #{act} was thrown' + , name + , (err instanceof Error ? err.toString() : err) + ); + + if (!errMsg) { + flag(this, 'object', err); + return this; + } + } + + // next, check message + var message = 'error' === _.type(err) && "message" in err + ? err.message + : '' + err; + + if ((message != null) && errMsg && errMsg instanceof RegExp) { + this.assert( + errMsg.exec(message) + , 'expected #{this} to throw error matching #{exp} but got #{act}' + , 'expected #{this} to throw error not matching #{exp}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else if ((message != null) && errMsg && 'string' === typeof errMsg) { + this.assert( + ~message.indexOf(errMsg) + , 'expected #{this} to throw error including #{exp} but got #{act}' + , 'expected #{this} to throw error not including #{act}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else { + thrown = true; + thrownError = err; + } + } + + var actuallyGot = '' + , expectedThrown = name !== null + ? name + : desiredError + ? '#{exp}' //_.inspect(desiredError) + : 'an error'; + + if (thrown) { + actuallyGot = ' but #{act} was thrown' + } + + this.assert( + thrown === true + , 'expected #{this} to throw ' + expectedThrown + actuallyGot + , 'expected #{this} to not throw ' + expectedThrown + actuallyGot + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (thrownError instanceof Error ? thrownError.toString() : thrownError) + ); + + flag(this, 'object', thrownError); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method) + * + * Asserts that the object or class target will respond to a method. + * + * Klass.prototype.bar = function(){}; + * expect(Klass).to.respondTo('bar'); + * expect(obj).to.respondTo('bar'); + * + * To check if a constructor will respond to a static function, + * set the `itself` flag. + * + * Klass.baz = function(){}; + * expect(Klass).itself.to.respondTo('baz'); + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === _.type(obj) && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Sets the `itself` flag, later used by the `respondTo` assertion. + * + * function Foo() {} + * Foo.bar = function() {} + * Foo.prototype.baz = function() {} + * + * expect(Foo).itself.to.respondTo('bar'); + * expect(Foo).itself.not.to.respondTo('baz'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(method) + * + * Asserts that the target passes a given truth test. + * + * expect(1).to.satisfy(function(num) { return num > 0; }); + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , this.negate ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * expect(1.5).to.be.closeTo(1, 0.5); + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj, msg).is.a('number'); + if (_.type(expected) !== 'number' || _.type(delta) !== 'number') { + throw new Error('the arguments to closeTo or approximately must be numbers'); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + function isSubsetOf(subset, superset, cmp) { + return subset.every(function(elem) { + if (!cmp) return superset.indexOf(elem) !== -1; + + return superset.some(function(elem2) { + return cmp(elem, elem2); + }); + }) + } + + /** + * ### .members(set) + * + * Asserts that the target is a superset of `set`, + * or that the target and `set` have the same strictly-equal (===) members. + * Alternately, if the `deep` flag is set, set members are compared for deep + * equality. + * + * expect([1, 2, 3]).to.include.members([3, 2]); + * expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + * + * expect([4, 2]).to.have.members([2, 4]); + * expect([5, 2]).to.not.have.members([5, 2, 1]); + * + * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]); + * + * @name members + * @param {Array} set + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj).to.be.an('array'); + new Assertion(subset).to.be.an('array'); + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + if (flag(this, 'contains')) { + return this.assert( + isSubsetOf(subset, obj, cmp) + , 'expected #{this} to be a superset of #{act}' + , 'expected #{this} to not be a superset of #{act}' + , obj + , subset + ); + } + + this.assert( + isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp) + , 'expected #{this} to have the same members as #{act}' + , 'expected #{this} to not have the same members as #{act}' + , obj + , subset + ); + }); + + /** + * ### .oneOf(list) + * + * Assert that a value appears somewhere in the top level of array `list`. + * + * expect('a').to.be.oneOf(['a', 'b', 'c']); + * expect(9).to.not.be.oneOf(['z']); + * expect([3]).to.not.be.oneOf([1, 2, [3]]); + * + * var three = [3]; + * // for object-types, contents are not compared + * expect(three).to.not.be.oneOf([1, 2, [3]]); + * // comparing references works + * expect(three).to.be.oneOf([1, 2, three]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object'); + new Assertion(list).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + + /** + * ### .change(function) + * + * Asserts that a function changes an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 3 }; + * var noChangeFn = function() { return 'foo' + 'bar'; } + * expect(fn).to.change(obj, 'val'); + * expect(noChangeFn).to.not.change(obj, 'val') + * + * @name change + * @alias changes + * @alias Change + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + initial !== object[prop] + , 'expected .' + prop + ' to change' + , 'expected .' + prop + ' to not change' + ); + } + + Assertion.addChainableMethod('change', assertChanges); + Assertion.addChainableMethod('changes', assertChanges); + + /** + * ### .increase(function) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * expect(fn).to.increase(obj, 'val'); + * + * @name increase + * @alias increases + * @alias Increase + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial > 0 + , 'expected .' + prop + ' to increase' + , 'expected .' + prop + ' to not increase' + ); + } + + Assertion.addChainableMethod('increase', assertIncreases); + Assertion.addChainableMethod('increases', assertIncreases); + + /** + * ### .decrease(function) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * expect(fn).to.decrease(obj, 'val'); + * + * @name decrease + * @alias decreases + * @alias Decrease + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial < 0 + , 'expected .' + prop + ' to decrease' + , 'expected .' + prop + ' to not decrease' + ); + } + + Assertion.addChainableMethod('decrease', assertDecreases); + Assertion.addChainableMethod('decreases', assertDecreases); + + /** + * ### .extensible + * + * Asserts that the target is extensible (can have new properties added to + * it). + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect({}).to.be.extensible; + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isExtensible; + + try { + isExtensible = Object.isExtensible(obj); + } catch (err) { + if (err instanceof TypeError) isExtensible = false; + else throw err; + } + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect({}).to.not.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isSealed; + + try { + isSealed = Object.isSealed(obj); + } catch (err) { + if (err instanceof TypeError) isSealed = true; + else throw err; + } + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect({}).to.not.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isFrozen; + + try { + isFrozen = Object.isFrozen(obj); + } catch (err) { + if (err instanceof TypeError) isFrozen = true; + else throw err; + } + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); +}; + +},{}],6:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + + +module.exports = function (chai, util) { + + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove` + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast` + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow` + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost` + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg).to.not.equal(null); + }; + + /** + * ### .isNaN + * Asserts that value is NaN + * + * assert.isNaN('foo', 'foo is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg).to.be.NaN; + }; + + /** + * ### .isNotNaN + * Asserts that value is not NaN + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg).not.to.be.NaN; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg).to.not.be.a('number'); + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Works + * for strings and arrays. + * + * assert.include('foobar', 'bar', 'foobar contains string "bar"'); + * assert.include([ 1, 2, 3 ], 3, 'array contains value'); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Works + * for strings and arrays. + * + * assert.notInclude('foobar', 'baz', 'string not include substring'); + * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value'); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude).not.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a property named by `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.property(prop); + }; + + /** + * ### .deepProperty(object, property, [message]) + * + * Asserts that `object` has a property named by `property`, which can be a + * string using dot- and bracket-notation for deep reference. + * + * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name deepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.deep.property(prop); + }; + + /** + * ### .notDeepProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for deep reference. + * + * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notDeepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.property(prop, val); + }; + + /** + * ### .propertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. + * + * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); + * + * @name propertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for deep + * reference. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.deep.property(prop, val); + }; + + /** + * ### .deepPropertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. `property` can use dot- and + * bracket-notation for deep reference. + * + * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * + * @name deepPropertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop, val); + }; + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` property with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg).to.have.length(len); + }; + + /** + * ### .throws(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * assert.throws(fn, 'function throws a reference error'); + * assert.throws(fn, /function throws a reference error/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, ReferenceError, 'function throws a reference error'); + * assert.throws(fn, ReferenceError, /function throws a reference error/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errt, errs, msg) { + if ('string' === typeof errt || errt instanceof RegExp) { + errs = errt; + errt = null; + } + + var assertErr = new Assertion(fn, msg).to.throw(errt, errs); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * assert.doesNotThrow(fn, Error, 'function does not throw'); + * + * @name doesNotThrow + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, type, msg) { + if ('string' === typeof type) { + msg = type; + type = null; + } + + new Assertion(fn, msg).to.not.Throw(type); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + throw new Error('Invalid operator "' + operator + '"'); + } + var test = new Assertion(ok, msg); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members. + * Order is not taken into account. + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members - using a deep equality checking. + * Order is not taken into account. + * + * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.deep.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset`. + * Order is not taken into account. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` - using deep equality checking. + * Order is not taken into account. + * Duplicates are ignored. + * + * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.deep.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property) + * + * Asserts that a function changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop) { + new Assertion(fn).to.change(obj, prop); + } + + /** + * ### .doesNotChange(function, object, property) + * + * Asserts that a function does not changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop) { + new Assertion(fn).to.not.change(obj, prop); + } + + /** + * ### .increases(function, object, property) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop) { + new Assertion(fn).to.increase(obj, prop); + } + + /** + * ### .doesNotIncrease(function, object, property) + * + * Asserts that a function does not increase object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop) { + new Assertion(fn).to.not.increase(obj, prop); + } + + /** + * ### .decreases(function, object, property) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop) { + new Assertion(fn).to.decrease(obj, prop); + } + + /** + * ### .doesNotDecrease(function, object, property) + * + * Asserts that a function does not decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop) { + new Assertion(fn).to.not.decrease(obj, prop); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freese({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg).to.not.be.frozen; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen'); +}; + +},{}],7:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Expect + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; + +},{}],8:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String || this instanceof Number || this instanceof Boolean ) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Should + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; + +},{}],9:[function(require,module,exports){ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var transferFlags = require('./transferFlags'); +var flag = require('./flag'); +var config = require('../config'); + +/*! + * Module variables + */ + +// Check whether `__proto__` is supported +var hasProtoSupport = '__proto__' in Object; + +// Without `__proto__` support, this module will need to add properties to a function. +// However, some Function.prototype methods cannot be overwritten, +// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69). +var excludeNames = /^(?:length|name|arguments|caller)$/; + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### addChainableMethod (ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function () { + chainableBehavior.chainingBehavior.call(this); + + var assert = function assert() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', assert); + var result = chainableBehavior.method.apply(this, arguments); + return result === undefined ? this : result; + }; + + // Use `__proto__` if available + if (hasProtoSupport) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = assert.__proto__ = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (!excludeNames.test(asserterName)) { + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(assert, asserterName, pd); + } + }); + } + + transferFlags(this, assert); + return assert; + } + , configurable: true + }); +}; + +},{"../config":4,"./flag":13,"./transferFlags":29}],10:[function(require,module,exports){ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); + +/** + * ### .addMethod (ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ +var flag = require('./flag'); + +module.exports = function (ctx, name, method) { + ctx[name] = function () { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', ctx[name]); + var result = method.apply(this, arguments); + return result === undefined ? this : result; + }; +}; + +},{"../config":4,"./flag":13}],11:[function(require,module,exports){ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); +var flag = require('./flag'); + +/** + * ### addProperty (ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + Object.defineProperty(ctx, name, + { get: function addProperty() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', addProperty); + + var result = getter.call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; + +},{"../config":4,"./flag":13}],12:[function(require,module,exports){ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function (obj, types) { + var obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + if (!types.some(function (expected) { return type(obj) === expected; })) { + throw new AssertionError( + 'object tested must be ' + str + ', but ' + type(obj) + ' given' + ); + } +}; + +},{"./flag":13,"assertion-error":30,"type-detect":35}],13:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function (obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; + +},{}],14:[function(require,module,exports){ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function (obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; + +},{}],15:[function(require,module,exports){ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; + +},{}],16:[function(require,module,exports){ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , inspect = require('./inspect') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; + +},{"./flag":13,"./getActual":14,"./inspect":23,"./objDisplay":24}],17:[function(require,module,exports){ +/*! + * Chai - getName utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getName(func) + * + * Gets the name of a function, in a cross-browser way. + * + * @param {Function} a function (usually a constructor) + * @namespace Utils + * @name getName + */ + +module.exports = function (func) { + if (func.name) return func.name; + + var match = /^\s?function ([^(]*)\(/.exec(func); + return match && match[1] ? match[1] : ""; +}; + +},{}],18:[function(require,module,exports){ +/*! + * Chai - getPathInfo utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var hasProperty = require('./hasProperty'); + +/** + * ### .getPathInfo(path, object) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {String} path + * @param {Object} object + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +module.exports = function getPathInfo(path, obj) { + var parsed = parsePath(path), + last = parsed[parsed.length - 1]; + + var info = { + parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj, + name: last.p || last.i, + value: _getPathValue(parsed, obj) + }; + info.exists = hasProperty(info.name, info.parent); + + return info; +}; + + +/*! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `_getPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be as near infinitely deep and nested + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath (path) { + var str = path.replace(/([^\\])\[/g, '$1.[') + , parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function (value) { + var re = /^\[(\d+)\]$/ + , mArr = re.exec(value); + if (mArr) return { i: parseFloat(mArr[1]) }; + else return { p: value.replace(/\\([.\[\]])/g, '$1') }; + }); +} + + +/*! + * ## _getPathValue(parsed, obj) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(parsed, obj); + * + * @param {Object} parsed definition from `parsePath`. + * @param {Object} object to search against + * @param {Number} object to search against + * @returns {Object|Undefined} value + * @api private + */ + +function _getPathValue (parsed, obj, index) { + var tmp = obj + , res; + + index = (index === undefined ? parsed.length : index); + + for (var i = 0, l = index; i < l; i++) { + var part = parsed[i]; + if (tmp) { + if ('undefined' !== typeof part.p) + tmp = tmp[part.p]; + else if ('undefined' !== typeof part.i) + tmp = tmp[part.i]; + if (i == (l - 1)) res = tmp; + } else { + res = undefined; + } + } + return res; +} + +},{"./hasProperty":21}],19:[function(require,module,exports){ +/*! + * Chai - getPathValue utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +var getPathInfo = require('./getPathInfo'); + +/** + * ### .getPathValue(path, object) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue('prop1.str', obj); // Hello + * getPathValue('prop1.att[2]', obj); // b + * getPathValue('prop2.arr[0].nested', obj); // Universe + * + * @param {String} path + * @param {Object} object + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ +module.exports = function(path, obj) { + var info = getPathInfo(path, obj); + return info.value; +}; + +},{"./getPathInfo":18}],20:[function(require,module,exports){ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; + +},{}],21:[function(require,module,exports){ +/*! + * Chai - hasProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has + * named property or numeric array index. + * + * Basically does the same thing as the `in` + * operator but works properly with natives + * and null/undefined values. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty('str', obj); // true + * hasProperty('constructor', obj); // true + * hasProperty('bar', obj); // false + * + * hasProperty('length', obj.str); // true + * hasProperty(1, obj.str); // true + * hasProperty(5, obj.str); // false + * + * hasProperty('length', obj.arr); // true + * hasProperty(2, obj.arr); // true + * hasProperty(3, obj.arr); // false + * + * @param {Objuect} object + * @param {String|Number} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name getPathInfo + * @api public + */ + +var literals = { + 'number': Number + , 'string': String +}; + +module.exports = function hasProperty(name, obj) { + var ot = type(obj); + + // Bad Object, obviously no props at all + if(ot === 'null' || ot === 'undefined') + return false; + + // The `in` operator does not work with certain literals + // box these before the check + if(literals[ot] && typeof obj !== 'object') + obj = new literals[ot](obj); + + return name in obj; +}; + +},{"type-detect":35}],22:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Main exports + */ + +var exports = module.exports = {}; + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path value + */ + +exports.getPathValue = require('./getPathValue'); + +/*! + * Deep path info + */ + +exports.getPathInfo = require('./getPathInfo'); + +/*! + * Check if a property exists + */ + +exports.hasProperty = require('./hasProperty'); + +/*! + * Function name + */ + +exports.getName = require('./getName'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +},{"./addChainableMethod":9,"./addMethod":10,"./addProperty":11,"./expectTypes":12,"./flag":13,"./getActual":14,"./getMessage":16,"./getName":17,"./getPathInfo":18,"./getPathValue":19,"./hasProperty":21,"./inspect":23,"./objDisplay":24,"./overwriteChainableMethod":25,"./overwriteMethod":26,"./overwriteProperty":27,"./test":28,"./transferFlags":29,"deep-eql":31,"type-detect":35}],23:[function(require,module,exports){ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('./getName'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); + +module.exports = inspect; + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + // Some type of object without properties can be shortcutted. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +},{"./getEnumerableProperties":15,"./getName":17,"./getProperties":20}],24:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay (object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function (obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; + +},{"../config":4,"./inspect":23}],25:[function(require,module,exports){ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteChainableMethod (ctx, name, method, chainingBehavior) + * + * Overwites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.length(3); + * expect(myFoo).to.have.length.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function () { + var result = chainingBehavior(_chainingBehavior).call(this); + return result === undefined ? this : result; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function () { + var result = method(_method).apply(this, arguments); + return result === undefined ? this : result; + }; +}; + +},{}],26:[function(require,module,exports){ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteMethod (ctx, name, fn) + * + * Overwites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function (ctx, name, method) { + var _method = ctx[name] + , _super = function () { return this; }; + + if (_method && 'function' === typeof _method) + _super = _method; + + ctx[name] = function () { + var result = method(_super).apply(this, arguments); + return result === undefined ? this : result; + } +}; + +},{}],27:[function(require,module,exports){ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteProperty (ctx, name, fn) + * + * Overwites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function () { + var result = getter(_super).call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; + +},{}],28:[function(require,module,exports){ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag'); + +/** + * # test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; + +},{"./flag":13}],29:[function(require,module,exports){ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, and `message`) + * will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAsseriton = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function (assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; + +},{}],30:[function(require,module,exports){ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || arguments.callee; + if (ssf && Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + this.stack = new Error().stack; + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; + +},{}],31:[function(require,module,exports){ +module.exports = require('./lib/eql'); + +},{"./lib/eql":32}],32:[function(require,module,exports){ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var type = require('type-detect'); + +/*! + * Buffer.isBuffer browser shim + */ + +var Buffer; +try { Buffer = require('buffer').Buffer; } +catch(ex) { + Buffer = {}; + Buffer.isBuffer = function() { return false; } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; + +/** + * Assert super-strict (egal) equality between + * two objects of any type. + * + * @param {Mixed} a + * @param {Mixed} b + * @param {Array} memoised (optional) + * @return {Boolean} equal match + */ + +function deepEqual(a, b, m) { + if (sameValue(a, b)) { + return true; + } else if ('date' === type(a)) { + return dateEqual(a, b); + } else if ('regexp' === type(a)) { + return regexpEqual(a, b); + } else if (Buffer.isBuffer(a)) { + return bufferEqual(a, b); + } else if ('arguments' === type(a)) { + return argumentsEqual(a, b, m); + } else if (!typeEqual(a, b)) { + return false; + } else if (('object' !== type(a) && 'object' !== type(b)) + && ('array' !== type(a) && 'array' !== type(b))) { + return sameValue(a, b); + } else { + return objectEqual(a, b, m); + } +} + +/*! + * Strict (egal) equality test. Ensures that NaN always + * equals NaN and `-0` does not equal `+0`. + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} equal match + */ + +function sameValue(a, b) { + if (a === b) return a !== 0 || 1 / a === 1 / b; + return a !== a && b !== b; +} + +/*! + * Compare the types of two given objects and + * return if they are equal. Note that an Array + * has a type of `array` (not `object`) and arguments + * have a type of `arguments` (not `array`/`object`). + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function typeEqual(a, b) { + return type(a) === type(b); +} + +/*! + * Compare two Date objects by asserting that + * the time values are equal using `saveValue`. + * + * @param {Date} a + * @param {Date} b + * @return {Boolean} result + */ + +function dateEqual(a, b) { + if ('date' !== type(b)) return false; + return sameValue(a.getTime(), b.getTime()); +} + +/*! + * Compare two regular expressions by converting them + * to string and checking for `sameValue`. + * + * @param {RegExp} a + * @param {RegExp} b + * @return {Boolean} result + */ + +function regexpEqual(a, b) { + if ('regexp' !== type(b)) return false; + return sameValue(a.toString(), b.toString()); +} + +/*! + * Assert deep equality of two `arguments` objects. + * Unfortunately, these must be sliced to arrays + * prior to test to ensure no bad behavior. + * + * @param {Arguments} a + * @param {Arguments} b + * @param {Array} memoize (optional) + * @return {Boolean} result + */ + +function argumentsEqual(a, b, m) { + if ('arguments' !== type(b)) return false; + a = [].slice.call(a); + b = [].slice.call(b); + return deepEqual(a, b, m); +} + +/*! + * Get enumerable properties of a given object. + * + * @param {Object} a + * @return {Array} property names + */ + +function enumerable(a) { + var res = []; + for (var key in a) res.push(key); + return res; +} + +/*! + * Simple equality for flat iterable objects + * such as Arrays or Node.js buffers. + * + * @param {Iterable} a + * @param {Iterable} b + * @return {Boolean} result + */ + +function iterableEqual(a, b) { + if (a.length !== b.length) return false; + + var i = 0; + var match = true; + + for (; i < a.length; i++) { + if (a[i] !== b[i]) { + match = false; + break; + } + } + + return match; +} + +/*! + * Extension to `iterableEqual` specifically + * for Node.js Buffers. + * + * @param {Buffer} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function bufferEqual(a, b) { + if (!Buffer.isBuffer(b)) return false; + return iterableEqual(a, b); +} + +/*! + * Block for `objectEqual` ensuring non-existing + * values don't get in. + * + * @param {Mixed} object + * @return {Boolean} result + */ + +function isValue(a) { + return a !== null && a !== undefined; +} + +/*! + * Recursively check the equality of two objects. + * Once basic sameness has been established it will + * defer to `deepEqual` for each enumerable key + * in the object. + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function objectEqual(a, b, m) { + if (!isValue(a) || !isValue(b)) { + return false; + } + + if (a.prototype !== b.prototype) { + return false; + } + + var i; + if (m) { + for (i = 0; i < m.length; i++) { + if ((m[i][0] === a && m[i][1] === b) + || (m[i][0] === b && m[i][1] === a)) { + return true; + } + } + } else { + m = []; + } + + try { + var ka = enumerable(a); + var kb = enumerable(b); + } catch (ex) { + return false; + } + + ka.sort(); + kb.sort(); + + if (!iterableEqual(ka, kb)) { + return false; + } + + m.push([ a, b ]); + + var key; + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!deepEqual(a[key], b[key], m)) { + return false; + } + } + + return true; +} + +},{"buffer":undefined,"type-detect":33}],33:[function(require,module,exports){ +module.exports = require('./lib/type'); + +},{"./lib/type":34}],34:[function(require,module,exports){ +/*! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ + +/*! + * Primary Exports + */ + +var exports = module.exports = getType; + +/*! + * Detectable javascript natives + */ + +var natives = { + '[object Array]': 'array' + , '[object RegExp]': 'regexp' + , '[object Function]': 'function' + , '[object Arguments]': 'arguments' + , '[object Date]': 'date' +}; + +/** + * ### typeOf (obj) + * + * Use several different techniques to determine + * the type of object being tested. + * + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ + +function getType (obj) { + var str = Object.prototype.toString.call(obj); + if (natives[str]) return natives[str]; + if (obj === null) return 'null'; + if (obj === undefined) return 'undefined'; + if (obj === Object(obj)) return 'object'; + return typeof obj; +} + +exports.Library = Library; + +/** + * ### Library + * + * Create a repository for custom type detection. + * + * ```js + * var lib = new type.Library; + * ``` + * + */ + +function Library () { + this.tests = {}; +} + +/** + * #### .of (obj) + * + * Expose replacement `typeof` detection to the library. + * + * ```js + * if ('string' === lib.of('hello world')) { + * // ... + * } + * ``` + * + * @param {Mixed} object to test + * @return {String} type + */ + +Library.prototype.of = getType; + +/** + * #### .define (type, test) + * + * Add a test to for the `.test()` assertion. + * + * Can be defined as a regular expression: + * + * ```js + * lib.define('int', /^[0-9]+$/); + * ``` + * + * ... or as a function: + * + * ```js + * lib.define('bln', function (obj) { + * if ('boolean' === lib.of(obj)) return true; + * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; + * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); + * return !! ~blns.indexOf(obj); + * }); + * ``` + * + * @param {String} type + * @param {RegExp|Function} test + * @api public + */ + +Library.prototype.define = function (type, test) { + if (arguments.length === 1) return this.tests[type]; + this.tests[type] = test; + return this; +}; + +/** + * #### .test (obj, test) + * + * Assert that an object is of type. Will first + * check natives, and if that does not pass it will + * use the user defined custom tests. + * + * ```js + * assert(lib.test('1', 'int')); + * assert(lib.test('yes', 'bln')); + * ``` + * + * @param {Mixed} object + * @param {String} type + * @return {Boolean} result + * @api public + */ + +Library.prototype.test = function (obj, type) { + if (type === getType(obj)) return true; + var test = this.tests[type]; + + if (test && 'regexp' === getType(test)) { + return test.test(obj); + } else if (test && 'function' === getType(test)) { + return test(obj); + } else { + throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); + } +}; + +},{}],35:[function(require,module,exports){ +arguments[4][33][0].apply(exports,arguments) +},{"./lib/type":36,"dup":33}],36:[function(require,module,exports){ +/*! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ + +/*! + * Primary Exports + */ + +var exports = module.exports = getType; + +/** + * ### typeOf (obj) + * + * Use several different techniques to determine + * the type of object being tested. + * + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ +var objectTypeRegexp = /^\[object (.*)\]$/; + +function getType(obj) { + var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase(); + // Let "new String('')" return 'object' + if (typeof Promise === 'function' && obj instanceof Promise) return 'promise'; + // PhantomJS has type "DOMWindow" for null + if (obj === null) return 'null'; + // PhantomJS has type "DOMWindow" for undefined + if (obj === undefined) return 'undefined'; + return type; +} + +exports.Library = Library; + +/** + * ### Library + * + * Create a repository for custom type detection. + * + * ```js + * var lib = new type.Library; + * ``` + * + */ + +function Library() { + if (!(this instanceof Library)) return new Library(); + this.tests = {}; +} + +/** + * #### .of (obj) + * + * Expose replacement `typeof` detection to the library. + * + * ```js + * if ('string' === lib.of('hello world')) { + * // ... + * } + * ``` + * + * @param {Mixed} object to test + * @return {String} type + */ + +Library.prototype.of = getType; + +/** + * #### .define (type, test) + * + * Add a test to for the `.test()` assertion. + * + * Can be defined as a regular expression: + * + * ```js + * lib.define('int', /^[0-9]+$/); + * ``` + * + * ... or as a function: + * + * ```js + * lib.define('bln', function (obj) { + * if ('boolean' === lib.of(obj)) return true; + * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; + * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); + * return !! ~blns.indexOf(obj); + * }); + * ``` + * + * @param {String} type + * @param {RegExp|Function} test + * @api public + */ + +Library.prototype.define = function(type, test) { + if (arguments.length === 1) return this.tests[type]; + this.tests[type] = test; + return this; +}; + +/** + * #### .test (obj, test) + * + * Assert that an object is of type. Will first + * check natives, and if that does not pass it will + * use the user defined custom tests. + * + * ```js + * assert(lib.test('1', 'int')); + * assert(lib.test('yes', 'bln')); + * ``` + * + * @param {Mixed} object + * @param {String} type + * @return {Boolean} result + * @api public + */ + +Library.prototype.test = function(obj, type) { + if (type === getType(obj)) return true; + var test = this.tests[type]; + + if (test && 'regexp' === getType(test)) { + return test.test(obj); + } else if (test && 'function' === getType(test)) { + return test(obj); + } else { + throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); + } +}; + +},{}]},{},[1])(1) +}); + +console.log( "chai loaded" ); + +//# sourceURL=chai.js \ No newline at end of file diff --git a/support/client/lib/vwf/view/chai/index.js b/support/client/lib/vwf/view/chai/index.js new file mode 100644 index 000000000..634483b02 --- /dev/null +++ b/support/client/lib/vwf/view/chai/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/chai'); diff --git a/support/client/lib/vwf/view/chai/karma.conf.js b/support/client/lib/vwf/view/chai/karma.conf.js new file mode 100644 index 000000000..48cf54193 --- /dev/null +++ b/support/client/lib/vwf/view/chai/karma.conf.js @@ -0,0 +1,28 @@ +module.exports = function(config) { + config.set({ + frameworks: [ 'mocha' ] + , files: [ + 'chai.js' + , 'test/bootstrap/karma.js' + , 'test/*.js' + ] + , reporters: [ 'progress' ] + , colors: true + , logLevel: config.LOG_INFO + , autoWatch: false + , browsers: [ 'PhantomJS' ] + , browserDisconnectTimeout: 10000 + , browserDisconnectTolerance: 2 + , browserNoActivityTimeout: 20000 + , singleRun: true + }); + + switch (process.env.CHAI_TEST_ENV) { + case 'sauce': + require('./karma.sauce')(config); + break; + default: + // ... + break; + }; +}; diff --git a/support/client/lib/vwf/view/chai/karma.sauce.js b/support/client/lib/vwf/view/chai/karma.sauce.js new file mode 100644 index 000000000..e57d5e0db --- /dev/null +++ b/support/client/lib/vwf/view/chai/karma.sauce.js @@ -0,0 +1,41 @@ +var version = require('./package.json').version; +var ts = new Date().getTime(); + +module.exports = function(config) { + var auth; + + try { + auth = require('./test/auth/index'); + } catch(ex) { + auth = {}; + auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null; + auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null; + } + + if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return; + if (process.env.SKIP_SAUCE) return; + + var branch = process.env.TRAVIS_BRANCH || 'local' + var browserConfig = require('./sauce.browsers'); + var browsers = Object.keys(browserConfig); + var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ]; + var tunnel = process.env.TRAVIS_JOB_NUMBER || ts; + + if (process.env.TRAVIS_JOB_NUMBER) { + tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER); + } + + config.browsers = config.browsers.concat(browsers); + config.customLaunchers = browserConfig; + config.reporters.push('saucelabs'); + config.transports = [ 'xhr-polling' ]; + + config.sauceLabs = { + username: auth.SAUCE_USERNAME + , accessKey: auth.SAUCE_ACCESS_KEY + , startConnect: true + , tags: tags + , testName: 'ChaiJS' + , tunnelIdentifier: tunnel + }; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai.js b/support/client/lib/vwf/view/chai/lib/chai.js new file mode 100644 index 000000000..888b485a6 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai.js @@ -0,0 +1,93 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var used = [] + , exports = module.exports = {}; + +/*! + * Chai version + */ + +exports.version = '3.5.0'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(this, util); + used.push(fn); + } + + return this; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); diff --git a/support/client/lib/vwf/view/chai/lib/chai/assertion.js b/support/client/lib/vwf/view/chai/lib/chai/assertion.js new file mode 100644 index 000000000..b7a7fb5e6 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/assertion.js @@ -0,0 +1,131 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * @api private + */ + + function Assertion (obj, msg, stack) { + flag(this, 'ssfi', stack || arguments.callee); + flag(this, 'object', obj); + flag(this, 'message', msg); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (true !== showDiff) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + var msg = util.getMessage(this, arguments) + , actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/config.js b/support/client/lib/vwf/view/chai/lib/chai/config.js new file mode 100644 index 000000000..e6f38fff2 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/config.js @@ -0,0 +1,55 @@ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40 + +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/core/assertions.js b/support/client/lib/vwf/view/chai/lib/chai/core/assertions.js new file mode 100644 index 000000000..072718e86 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/core/assertions.js @@ -0,0 +1,1860 @@ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , toString = Object.prototype.toString + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to + * improve the readability of your assertions. They + * do not provide testing capabilities unless they + * have been overwritten by a plugin. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'has', 'have' + , 'with', 'that', 'which', 'at' + , 'of', 'same' ].forEach(function (chain) { + Assertion.addProperty(chain, function () { + return this; + }); + }); + + /** + * ### .not + * + * Negates any of assertions following in the chain. + * + * expect(foo).to.not.equal('bar'); + * expect(goodFn).to.not.throw(Error); + * expect({ foo: 'baz' }).to.have.property('foo') + * .and.not.equal('bar'); + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Sets the `deep` flag, later used by the `equal` and + * `property` assertions. + * + * expect(foo).to.deep.equal({ bar: 'baz' }); + * expect({ foo: { bar: { baz: 'quux' } } }) + * .to.have.deep.property('foo.bar.baz', 'quux'); + * + * `.deep.property` special characters can be escaped + * by adding two slashes before the `.` or `[]`. + * + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .any + * + * Sets the `any` flag, (opposite of the `all` flag) + * later used in the `keys` assertion. + * + * expect(foo).to.have.any.keys('bar', 'baz'); + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false) + }); + + + /** + * ### .all + * + * Sets the `all` flag (opposite of the `any` flag) + * later used by the `keys` assertion. + * + * expect(foo).to.have.all.keys('bar', 'baz'); + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type) + * + * The `a` and `an` assertions are aliases that can be + * used either as language chains or to assert a value's + * type. + * + * // typeof + * expect('test').to.be.a('string'); + * expect({ foo: 'bar' }).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(new Promise).to.be.a('promise'); + * expect(new Float32Array()).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * // es6 overrides + * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); + * + * // language chain + * expect(foo).to.be.an.instanceof(Foo); + * + * @name a + * @alias an + * @param {String} type + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj) + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(value) + * + * The `include` and `contain` assertions can be used as either property + * based language chains or as methods to assert the inclusion of an object + * in an array or a substring in a string. When used as language chains, + * they toggle the `contains` flag for the `keys` assertion. + * + * expect([1,2,3]).to.include(2); + * expect('foobar').to.contain('foo'); + * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Object|String|Number} obj + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + _.expectTypes(this, ['array', 'object', 'string']); + + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var expected = false; + + if (_.type(obj) === 'array' && _.type(val) === 'object') { + for (var i in obj) { + if (_.eql(obj[i], val)) { + expected = true; + break; + } + } + } else if (_.type(val) === 'object') { + if (!flag(this, 'negate')) { + for (var k in val) new Assertion(obj).property(k, val[k]); + return; + } + var subset = {}; + for (var k in val) subset[k] = obj[k]; + expected = _.eql(subset, val); + } else { + expected = (obj != undefined) && ~obj.indexOf(val); + } + this.assert( + expected + , 'expected #{this} to include ' + _.inspect(val) + , 'expected #{this} to not include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is truthy. + * + * expect('everything').to.be.ok; + * expect(1).to.be.ok; + * expect(false).to.not.be.ok; + * expect(undefined).to.not.be.ok; + * expect(null).to.not.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is `true`. + * + * expect(true).to.be.true; + * expect(1).to.not.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , this.negate ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is `false`. + * + * expect(false).to.be.false; + * expect(0).to.not.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , this.negate ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is `null`. + * + * expect(null).to.be.null; + * expect(undefined).to.not.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is `undefined`. + * + * expect(undefined).to.be.undefined; + * expect(null).to.not.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * Asserts that the target is `NaN`. + * + * expect('foo').to.be.NaN; + * expect(4).not.to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi' + * , bar = null + * , baz; + * + * expect(foo).to.exist; + * expect(bar).to.not.exist; + * expect(baz).to.not.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + this.assert( + null != flag(this, 'object') + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + + /** + * ### .empty + * + * Asserts that the target's length is `0`. For arrays and strings, it checks + * the `length` property. For objects, it gets the count of + * enumerable keys. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * expect({}).to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var obj = flag(this, 'object') + , expected = obj; + + if (Array.isArray(obj) || 'string' === typeof object) { + expected = obj.length; + } else if (typeof obj === 'object') { + expected = Object.keys(obj).length; + } + + this.assert( + !expected + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an arguments object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = Object.prototype.toString.call(obj); + this.assert( + '[object Arguments]' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(value) + * + * Asserts that the target is strictly equal (`===`) to `value`. + * Alternately, if the `deep` flag is set, asserts that + * the target is deeply equal to `value`. + * + * expect('hello').to.equal('hello'); + * expect(42).to.equal(42); + * expect(1).to.not.equal(true); + * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); + * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); + * + * @name equal + * @alias equals + * @alias eq + * @alias deep.equal + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(value) + * + * Asserts that the target is deeply equal to `value`. + * + * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); + * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); + * + * @name eql + * @alias eqls + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(value) + * + * Asserts that the target is greater than `value`. + * + * expect(10).to.be.above(5); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above ' + n + , 'expected #{this} to be at most ' + n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(value) + * + * Asserts that the target is greater than or equal to `value`. + * + * expect(10).to.be.at.least(10); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.least(2); + * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3); + * + * @name least + * @alias gte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= n + , 'expected #{this} to have a length at least #{exp} but got #{act}' + , 'expected #{this} to have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least ' + n + , 'expected #{this} to be below ' + n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(value) + * + * Asserts that the target is less than `value`. + * + * expect(5).to.be.below(10); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below ' + n + , 'expected #{this} to be at least ' + n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(value) + * + * Asserts that the target is less than or equal to `value`. + * + * expect(5).to.be.at.most(5); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.most(4); + * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3); + * + * @name most + * @alias lte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len <= n + , 'expected #{this} to have a length at most #{exp} but got #{act}' + , 'expected #{this} to have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most ' + n + , 'expected #{this} to be above ' + n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish) + * + * Asserts that the target is within a range. + * + * expect(7).to.be.within(5,10); + * + * Can also be used in conjunction with `length` to + * assert a length range. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * @name within + * @param {Number} start lowerbound inclusive + * @param {Number} finish upperbound inclusive + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , range = start + '..' + finish; + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor) + * + * Asserts that the target is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , Chai = new Tea('chai'); + * + * expect(Chai).to.be.an.instanceof(Tea); + * expect([ 1, 2, 3 ]).to.be.instanceof(Array); + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} message _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + var name = _.getName(constructor); + this.assert( + flag(this, 'object') instanceof constructor + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name, [value]) + * + * Asserts that the target has a property `name`, optionally asserting that + * the value of that property is strictly equal to `value`. + * If the `deep` flag is set, you can use dot- and bracket-notation for deep + * references into objects and arrays. + * + * // simple referencing + * var obj = { foo: 'bar' }; + * expect(obj).to.have.property('foo'); + * expect(obj).to.have.property('foo', 'bar'); + * + * // deep referencing + * var deepObj = { + * green: { tea: 'matcha' } + * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] + * }; + * + * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); + * + * You can also use an array as the starting point of a `deep.property` + * assertion, or traverse nested arrays. + * + * var arr = [ + * [ 'chai', 'matcha', 'konacha' ] + * , [ { tea: 'chai' } + * , { tea: 'matcha' } + * , { tea: 'konacha' } ] + * ]; + * + * expect(arr).to.have.deep.property('[0][1]', 'matcha'); + * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); + * + * Furthermore, `property` changes the subject of the assertion + * to be the value of that property from the original object. This + * permits for further chainable assertions on that property. + * + * expect(obj).to.have.property('foo') + * .that.is.a('string'); + * expect(deepObj).to.have.property('green') + * .that.is.an('object') + * .that.deep.equals({ tea: 'matcha' }); + * expect(deepObj).to.have.property('teas') + * .that.is.an('array') + * .with.deep.property('[2]') + * .that.deep.equals({ tea: 'konacha' }); + * + * Note that dots and bracket in `name` must be backslash-escaped when + * the `deep` flag is set, while they must NOT be escaped when the `deep` + * flag is not set. + * + * // simple referencing + * var css = { '.link[target]': 42 }; + * expect(css).to.have.property('.link[target]', 42); + * + * // deep referencing + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name property + * @alias deep.property + * @param {String} name + * @param {Mixed} value (optional) + * @param {String} message _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + Assertion.addMethod('property', function (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isDeep = !!flag(this, 'deep') + , descriptor = isDeep ? 'deep property ' : 'property ' + , negate = flag(this, 'negate') + , obj = flag(this, 'object') + , pathInfo = isDeep ? _.getPathInfo(name, obj) : null + , hasProperty = isDeep + ? pathInfo.exists + : _.hasProperty(name, obj) + , value = isDeep + ? pathInfo.value + : obj[name]; + + if (negate && arguments.length > 1) { + if (undefined === value) { + msg = (msg != null) ? msg + ': ' : ''; + throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name)); + } + } else { + this.assert( + hasProperty + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + val === value + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + }); + + + /** + * ### .ownProperty(name) + * + * Asserts that the target has an own property `name`. + * + * expect('test').to.have.ownProperty('length'); + * + * @name ownProperty + * @alias haveOwnProperty + * @param {String} name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnProperty (name, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + obj.hasOwnProperty(name) + , 'expected #{this} to have own property ' + _.inspect(name) + , 'expected #{this} to not have own property ' + _.inspect(name) + ); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, message]]) + * + * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`. + * + * expect('test').to.have.ownPropertyDescriptor('length'); + * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); + * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); + * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); + * expect('test').ownPropertyDescriptor('length').to.have.keys('value'); + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .length + * + * Sets the `doLength` flag later used as a chain precursor to a value + * comparison for the `length` property. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * *Deprecation notice:* Using `length` as an assertion will be deprecated + * in version 2.4.0 and removed in 3.0.0. Code using the old style of + * asserting for `length` property value using `length(value)` should be + * switched to use `lengthOf(value)` instead. + * + * @name length + * @namespace BDD + * @api public + */ + + /** + * ### .lengthOf(value[, message]) + * + * Asserts that the target's `length` property has + * the expected value. + * + * expect([ 1, 2, 3]).to.have.lengthOf(3); + * expect('foobar').to.have.lengthOf(6); + * + * @name lengthOf + * @param {Number} length + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addMethod('lengthOf', assertLength); + + /** + * ### .match(regexp) + * + * Asserts that the target matches a regular expression. + * + * expect('foobar').to.match(/^foo/); + * + * @name match + * @alias matches + * @param {RegExp} RegularExpression + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(string) + * + * Asserts that the string target contains another string. + * + * expect('foobar').to.have.string('bar'); + * + * @name string + * @param {String} string + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + + /** + * ### .keys(key1, [key2], [...]) + * + * Asserts that the target contains any or all of the passed-in keys. + * Use in combination with `any`, `all`, `contains`, or `have` will affect + * what will pass. + * + * When used in conjunction with `any`, at least one key that is passed + * in must exist in the target object. This is regardless whether or not + * the `have` or `contain` qualifiers are used. Note, either `any` or `all` + * should be used in the assertion. If neither are used, the assertion is + * defaulted to `all`. + * + * When both `all` and `contain` are used, the target object must have at + * least all of the passed-in keys but may have more keys not listed. + * + * When both `all` and `have` are used, the target object must both contain + * all of the passed-in keys AND the number of keys in the target object must + * match the number of keys passed in (in other words, a target object must + * have all and only all of the passed-in keys). + * + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6}); + * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7}); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6}); + * + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , str + , ok = true + , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments'; + + switch (_.type(keys)) { + case "array": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + break; + case "object": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + if (!keys.length) throw new Error('keys required'); + + var actual = Object.keys(obj) + , expected = keys + , len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all'); + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + var intersection = expected.filter(function(key) { + return ~actual.indexOf(key); + }); + ok = intersection.length > 0; + } + + // Has all + if (all) { + ok = keys.every(function(key){ + return ~actual.indexOf(key); + }); + if (!flag(this, 'negate') && !flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key){ + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + str + , 'expected #{this} to not ' + str + , expected.slice(0).sort() + , actual.sort() + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw(constructor) + * + * Asserts that the function target will throw a specific error, or specific type of error + * (as determined using `instanceof`), optionally with a RegExp or string inclusion test + * for the error's message. + * + * var err = new ReferenceError('This is a bad function.'); + * var fn = function () { throw err; } + * expect(fn).to.throw(ReferenceError); + * expect(fn).to.throw(Error); + * expect(fn).to.throw(/bad function/); + * expect(fn).to.not.throw('good function'); + * expect(fn).to.throw(ReferenceError, /bad function/); + * expect(fn).to.throw(err); + * + * Please note that when a throw expectation is negated, it will check each + * parameter independently, starting with error constructor type. The appropriate way + * to check for the existence of a type of error but for a message that does not match + * is to use `and`. + * + * expect(fn).to.throw(ReferenceError) + * .and.not.throw(/good function/); + * + * @name throw + * @alias throws + * @alias Throw + * @param {ErrorConstructor} constructor + * @param {String|RegExp} expected error message + * @param {String} message _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (constructor, errMsg, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('function'); + + var thrown = false + , desiredError = null + , name = null + , thrownError = null; + + if (arguments.length === 0) { + errMsg = null; + constructor = null; + } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { + errMsg = constructor; + constructor = null; + } else if (constructor && constructor instanceof Error) { + desiredError = constructor; + constructor = null; + errMsg = null; + } else if (typeof constructor === 'function') { + name = constructor.prototype.name; + if (!name || (name === 'Error' && constructor !== Error)) { + name = constructor.name || (new constructor()).name; + } + } else { + constructor = null; + } + + try { + obj(); + } catch (err) { + // first, check desired error + if (desiredError) { + this.assert( + err === desiredError + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (err instanceof Error ? err.toString() : err) + ); + + flag(this, 'object', err); + return this; + } + + // next, check constructor + if (constructor) { + this.assert( + err instanceof constructor + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp} but #{act} was thrown' + , name + , (err instanceof Error ? err.toString() : err) + ); + + if (!errMsg) { + flag(this, 'object', err); + return this; + } + } + + // next, check message + var message = 'error' === _.type(err) && "message" in err + ? err.message + : '' + err; + + if ((message != null) && errMsg && errMsg instanceof RegExp) { + this.assert( + errMsg.exec(message) + , 'expected #{this} to throw error matching #{exp} but got #{act}' + , 'expected #{this} to throw error not matching #{exp}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else if ((message != null) && errMsg && 'string' === typeof errMsg) { + this.assert( + ~message.indexOf(errMsg) + , 'expected #{this} to throw error including #{exp} but got #{act}' + , 'expected #{this} to throw error not including #{act}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else { + thrown = true; + thrownError = err; + } + } + + var actuallyGot = '' + , expectedThrown = name !== null + ? name + : desiredError + ? '#{exp}' //_.inspect(desiredError) + : 'an error'; + + if (thrown) { + actuallyGot = ' but #{act} was thrown' + } + + this.assert( + thrown === true + , 'expected #{this} to throw ' + expectedThrown + actuallyGot + , 'expected #{this} to not throw ' + expectedThrown + actuallyGot + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (thrownError instanceof Error ? thrownError.toString() : thrownError) + ); + + flag(this, 'object', thrownError); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method) + * + * Asserts that the object or class target will respond to a method. + * + * Klass.prototype.bar = function(){}; + * expect(Klass).to.respondTo('bar'); + * expect(obj).to.respondTo('bar'); + * + * To check if a constructor will respond to a static function, + * set the `itself` flag. + * + * Klass.baz = function(){}; + * expect(Klass).itself.to.respondTo('baz'); + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === _.type(obj) && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Sets the `itself` flag, later used by the `respondTo` assertion. + * + * function Foo() {} + * Foo.bar = function() {} + * Foo.prototype.baz = function() {} + * + * expect(Foo).itself.to.respondTo('bar'); + * expect(Foo).itself.not.to.respondTo('baz'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(method) + * + * Asserts that the target passes a given truth test. + * + * expect(1).to.satisfy(function(num) { return num > 0; }); + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , this.negate ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * expect(1.5).to.be.closeTo(1, 0.5); + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj, msg).is.a('number'); + if (_.type(expected) !== 'number' || _.type(delta) !== 'number') { + throw new Error('the arguments to closeTo or approximately must be numbers'); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + function isSubsetOf(subset, superset, cmp) { + return subset.every(function(elem) { + if (!cmp) return superset.indexOf(elem) !== -1; + + return superset.some(function(elem2) { + return cmp(elem, elem2); + }); + }) + } + + /** + * ### .members(set) + * + * Asserts that the target is a superset of `set`, + * or that the target and `set` have the same strictly-equal (===) members. + * Alternately, if the `deep` flag is set, set members are compared for deep + * equality. + * + * expect([1, 2, 3]).to.include.members([3, 2]); + * expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + * + * expect([4, 2]).to.have.members([2, 4]); + * expect([5, 2]).to.not.have.members([5, 2, 1]); + * + * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]); + * + * @name members + * @param {Array} set + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj).to.be.an('array'); + new Assertion(subset).to.be.an('array'); + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + if (flag(this, 'contains')) { + return this.assert( + isSubsetOf(subset, obj, cmp) + , 'expected #{this} to be a superset of #{act}' + , 'expected #{this} to not be a superset of #{act}' + , obj + , subset + ); + } + + this.assert( + isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp) + , 'expected #{this} to have the same members as #{act}' + , 'expected #{this} to not have the same members as #{act}' + , obj + , subset + ); + }); + + /** + * ### .oneOf(list) + * + * Assert that a value appears somewhere in the top level of array `list`. + * + * expect('a').to.be.oneOf(['a', 'b', 'c']); + * expect(9).to.not.be.oneOf(['z']); + * expect([3]).to.not.be.oneOf([1, 2, [3]]); + * + * var three = [3]; + * // for object-types, contents are not compared + * expect(three).to.not.be.oneOf([1, 2, [3]]); + * // comparing references works + * expect(three).to.be.oneOf([1, 2, three]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object'); + new Assertion(list).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + + /** + * ### .change(function) + * + * Asserts that a function changes an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 3 }; + * var noChangeFn = function() { return 'foo' + 'bar'; } + * expect(fn).to.change(obj, 'val'); + * expect(noChangeFn).to.not.change(obj, 'val') + * + * @name change + * @alias changes + * @alias Change + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + initial !== object[prop] + , 'expected .' + prop + ' to change' + , 'expected .' + prop + ' to not change' + ); + } + + Assertion.addChainableMethod('change', assertChanges); + Assertion.addChainableMethod('changes', assertChanges); + + /** + * ### .increase(function) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * expect(fn).to.increase(obj, 'val'); + * + * @name increase + * @alias increases + * @alias Increase + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial > 0 + , 'expected .' + prop + ' to increase' + , 'expected .' + prop + ' to not increase' + ); + } + + Assertion.addChainableMethod('increase', assertIncreases); + Assertion.addChainableMethod('increases', assertIncreases); + + /** + * ### .decrease(function) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * expect(fn).to.decrease(obj, 'val'); + * + * @name decrease + * @alias decreases + * @alias Decrease + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial < 0 + , 'expected .' + prop + ' to decrease' + , 'expected .' + prop + ' to not decrease' + ); + } + + Assertion.addChainableMethod('decrease', assertDecreases); + Assertion.addChainableMethod('decreases', assertDecreases); + + /** + * ### .extensible + * + * Asserts that the target is extensible (can have new properties added to + * it). + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect({}).to.be.extensible; + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isExtensible; + + try { + isExtensible = Object.isExtensible(obj); + } catch (err) { + if (err instanceof TypeError) isExtensible = false; + else throw err; + } + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect({}).to.not.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isSealed; + + try { + isSealed = Object.isSealed(obj); + } catch (err) { + if (err instanceof TypeError) isSealed = true; + else throw err; + } + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect({}).to.not.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isFrozen; + + try { + isFrozen = Object.isFrozen(obj); + } catch (err) { + if (err instanceof TypeError) isFrozen = true; + else throw err; + } + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/interface/assert.js b/support/client/lib/vwf/view/chai/lib/chai/interface/assert.js new file mode 100644 index 000000000..09729db99 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/interface/assert.js @@ -0,0 +1,1645 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + + +module.exports = function (chai, util) { + + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove` + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast` + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow` + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost` + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg).to.not.equal(null); + }; + + /** + * ### .isNaN + * Asserts that value is NaN + * + * assert.isNaN('foo', 'foo is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg).to.be.NaN; + }; + + /** + * ### .isNotNaN + * Asserts that value is not NaN + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg).not.to.be.NaN; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg).to.not.be.a('number'); + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Works + * for strings and arrays. + * + * assert.include('foobar', 'bar', 'foobar contains string "bar"'); + * assert.include([ 1, 2, 3 ], 3, 'array contains value'); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Works + * for strings and arrays. + * + * assert.notInclude('foobar', 'baz', 'string not include substring'); + * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value'); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude).not.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a property named by `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.property(prop); + }; + + /** + * ### .deepProperty(object, property, [message]) + * + * Asserts that `object` has a property named by `property`, which can be a + * string using dot- and bracket-notation for deep reference. + * + * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name deepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.deep.property(prop); + }; + + /** + * ### .notDeepProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for deep reference. + * + * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notDeepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.property(prop, val); + }; + + /** + * ### .propertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. + * + * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); + * + * @name propertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for deep + * reference. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.deep.property(prop, val); + }; + + /** + * ### .deepPropertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. `property` can use dot- and + * bracket-notation for deep reference. + * + * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * + * @name deepPropertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop, val); + }; + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` property with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg).to.have.length(len); + }; + + /** + * ### .throws(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * assert.throws(fn, 'function throws a reference error'); + * assert.throws(fn, /function throws a reference error/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, ReferenceError, 'function throws a reference error'); + * assert.throws(fn, ReferenceError, /function throws a reference error/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errt, errs, msg) { + if ('string' === typeof errt || errt instanceof RegExp) { + errs = errt; + errt = null; + } + + var assertErr = new Assertion(fn, msg).to.throw(errt, errs); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * assert.doesNotThrow(fn, Error, 'function does not throw'); + * + * @name doesNotThrow + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, type, msg) { + if ('string' === typeof type) { + msg = type; + type = null; + } + + new Assertion(fn, msg).to.not.Throw(type); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + throw new Error('Invalid operator "' + operator + '"'); + } + var test = new Assertion(ok, msg); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members. + * Order is not taken into account. + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members - using a deep equality checking. + * Order is not taken into account. + * + * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.deep.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset`. + * Order is not taken into account. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` - using deep equality checking. + * Order is not taken into account. + * Duplicates are ignored. + * + * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.deep.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property) + * + * Asserts that a function changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop) { + new Assertion(fn).to.change(obj, prop); + } + + /** + * ### .doesNotChange(function, object, property) + * + * Asserts that a function does not changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop) { + new Assertion(fn).to.not.change(obj, prop); + } + + /** + * ### .increases(function, object, property) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop) { + new Assertion(fn).to.increase(obj, prop); + } + + /** + * ### .doesNotIncrease(function, object, property) + * + * Asserts that a function does not increase object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop) { + new Assertion(fn).to.not.increase(obj, prop); + } + + /** + * ### .decreases(function, object, property) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop) { + new Assertion(fn).to.decrease(obj, prop); + } + + /** + * ### .doesNotDecrease(function, object, property) + * + * Asserts that a function does not decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop) { + new Assertion(fn).to.not.decrease(obj, prop); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freese({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg).to.not.be.frozen; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen'); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/interface/expect.js b/support/client/lib/vwf/view/chai/lib/chai/interface/expect.js new file mode 100644 index 000000000..a255c4543 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/interface/expect.js @@ -0,0 +1,34 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Expect + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/interface/should.js b/support/client/lib/vwf/view/chai/lib/chai/interface/should.js new file mode 100644 index 000000000..81165c68a --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/interface/should.js @@ -0,0 +1,201 @@ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String || this instanceof Number || this instanceof Boolean ) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Should + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/addChainableMethod.js b/support/client/lib/vwf/view/chai/lib/chai/utils/addChainableMethod.js new file mode 100644 index 000000000..ebc106773 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/addChainableMethod.js @@ -0,0 +1,112 @@ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var transferFlags = require('./transferFlags'); +var flag = require('./flag'); +var config = require('../config'); + +/*! + * Module variables + */ + +// Check whether `__proto__` is supported +var hasProtoSupport = '__proto__' in Object; + +// Without `__proto__` support, this module will need to add properties to a function. +// However, some Function.prototype methods cannot be overwritten, +// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69). +var excludeNames = /^(?:length|name|arguments|caller)$/; + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### addChainableMethod (ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function () { + chainableBehavior.chainingBehavior.call(this); + + var assert = function assert() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', assert); + var result = chainableBehavior.method.apply(this, arguments); + return result === undefined ? this : result; + }; + + // Use `__proto__` if available + if (hasProtoSupport) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = assert.__proto__ = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (!excludeNames.test(asserterName)) { + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(assert, asserterName, pd); + } + }); + } + + transferFlags(this, assert); + return assert; + } + , configurable: true + }); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/addMethod.js b/support/client/lib/vwf/view/chai/lib/chai/utils/addMethod.js new file mode 100644 index 000000000..a2676cdbf --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/addMethod.js @@ -0,0 +1,44 @@ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); + +/** + * ### .addMethod (ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ +var flag = require('./flag'); + +module.exports = function (ctx, name, method) { + ctx[name] = function () { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', ctx[name]); + var result = method.apply(this, arguments); + return result === undefined ? this : result; + }; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/addProperty.js b/support/client/lib/vwf/view/chai/lib/chai/utils/addProperty.js new file mode 100644 index 000000000..07d624cd2 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/addProperty.js @@ -0,0 +1,48 @@ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); +var flag = require('./flag'); + +/** + * ### addProperty (ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + Object.defineProperty(ctx, name, + { get: function addProperty() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', addProperty); + + var result = getter.call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/expectTypes.js b/support/client/lib/vwf/view/chai/lib/chai/utils/expectTypes.js new file mode 100644 index 000000000..4dd5b2971 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/expectTypes.js @@ -0,0 +1,42 @@ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function (obj, types) { + var obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + if (!types.some(function (expected) { return type(obj) === expected; })) { + throw new AssertionError( + 'object tested must be ' + str + ', but ' + type(obj) + ' given' + ); + } +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/flag.js b/support/client/lib/vwf/view/chai/lib/chai/utils/flag.js new file mode 100644 index 000000000..ef13236e0 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/flag.js @@ -0,0 +1,33 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function (obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getActual.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getActual.js new file mode 100644 index 000000000..ced30797b --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getActual.js @@ -0,0 +1,20 @@ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function (obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getEnumerableProperties.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getEnumerableProperties.js new file mode 100644 index 000000000..a84252cfd --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getEnumerableProperties.js @@ -0,0 +1,26 @@ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getMessage.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getMessage.js new file mode 100644 index 000000000..dedd8f9d8 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getMessage.js @@ -0,0 +1,51 @@ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , inspect = require('./inspect') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getName.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getName.js new file mode 100644 index 000000000..d45a69dfe --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getName.js @@ -0,0 +1,22 @@ +/*! + * Chai - getName utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getName(func) + * + * Gets the name of a function, in a cross-browser way. + * + * @param {Function} a function (usually a constructor) + * @namespace Utils + * @name getName + */ + +module.exports = function (func) { + if (func.name) return func.name; + + var match = /^\s?function ([^(]*)\(/.exec(func); + return match && match[1] ? match[1] : ""; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getPathInfo.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getPathInfo.js new file mode 100644 index 000000000..371982312 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getPathInfo.js @@ -0,0 +1,111 @@ +/*! + * Chai - getPathInfo utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var hasProperty = require('./hasProperty'); + +/** + * ### .getPathInfo(path, object) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {String} path + * @param {Object} object + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +module.exports = function getPathInfo(path, obj) { + var parsed = parsePath(path), + last = parsed[parsed.length - 1]; + + var info = { + parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj, + name: last.p || last.i, + value: _getPathValue(parsed, obj) + }; + info.exists = hasProperty(info.name, info.parent); + + return info; +}; + + +/*! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `_getPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be as near infinitely deep and nested + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath (path) { + var str = path.replace(/([^\\])\[/g, '$1.[') + , parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function (value) { + var re = /^\[(\d+)\]$/ + , mArr = re.exec(value); + if (mArr) return { i: parseFloat(mArr[1]) }; + else return { p: value.replace(/\\([.\[\]])/g, '$1') }; + }); +} + + +/*! + * ## _getPathValue(parsed, obj) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(parsed, obj); + * + * @param {Object} parsed definition from `parsePath`. + * @param {Object} object to search against + * @param {Number} object to search against + * @returns {Object|Undefined} value + * @api private + */ + +function _getPathValue (parsed, obj, index) { + var tmp = obj + , res; + + index = (index === undefined ? parsed.length : index); + + for (var i = 0, l = index; i < l; i++) { + var part = parsed[i]; + if (tmp) { + if ('undefined' !== typeof part.p) + tmp = tmp[part.p]; + else if ('undefined' !== typeof part.i) + tmp = tmp[part.i]; + if (i == (l - 1)) res = tmp; + } else { + res = undefined; + } + } + return res; +} diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getPathValue.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getPathValue.js new file mode 100644 index 000000000..ed4cbfbf6 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getPathValue.js @@ -0,0 +1,43 @@ +/*! + * Chai - getPathValue utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +var getPathInfo = require('./getPathInfo'); + +/** + * ### .getPathValue(path, object) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue('prop1.str', obj); // Hello + * getPathValue('prop1.att[2]', obj); // b + * getPathValue('prop2.arr[0].nested', obj); // Universe + * + * @param {String} path + * @param {Object} object + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ +module.exports = function(path, obj) { + var info = getPathInfo(path, obj); + return info.value; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/getProperties.js b/support/client/lib/vwf/view/chai/lib/chai/utils/getProperties.js new file mode 100644 index 000000000..ccf9631ab --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/getProperties.js @@ -0,0 +1,36 @@ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/hasProperty.js b/support/client/lib/vwf/view/chai/lib/chai/utils/hasProperty.js new file mode 100644 index 000000000..a86a7329f --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/hasProperty.js @@ -0,0 +1,64 @@ +/*! + * Chai - hasProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has + * named property or numeric array index. + * + * Basically does the same thing as the `in` + * operator but works properly with natives + * and null/undefined values. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty('str', obj); // true + * hasProperty('constructor', obj); // true + * hasProperty('bar', obj); // false + * + * hasProperty('length', obj.str); // true + * hasProperty(1, obj.str); // true + * hasProperty(5, obj.str); // false + * + * hasProperty('length', obj.arr); // true + * hasProperty(2, obj.arr); // true + * hasProperty(3, obj.arr); // false + * + * @param {Objuect} object + * @param {String|Number} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name getPathInfo + * @api public + */ + +var literals = { + 'number': Number + , 'string': String +}; + +module.exports = function hasProperty(name, obj) { + var ot = type(obj); + + // Bad Object, obviously no props at all + if(ot === 'null' || ot === 'undefined') + return false; + + // The `in` operator does not work with certain literals + // box these before the check + if(literals[ot] && typeof obj !== 'object') + obj = new literals[ot](obj); + + return name in obj; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/index.js b/support/client/lib/vwf/view/chai/lib/chai/utils/index.js new file mode 100644 index 000000000..3f9bf6ec8 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/index.js @@ -0,0 +1,130 @@ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Main exports + */ + +var exports = module.exports = {}; + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path value + */ + +exports.getPathValue = require('./getPathValue'); + +/*! + * Deep path info + */ + +exports.getPathInfo = require('./getPathInfo'); + +/*! + * Check if a property exists + */ + +exports.hasProperty = require('./hasProperty'); + +/*! + * Function name + */ + +exports.getName = require('./getName'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/inspect.js b/support/client/lib/vwf/view/chai/lib/chai/utils/inspect.js new file mode 100644 index 000000000..dd318991b --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/inspect.js @@ -0,0 +1,335 @@ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('./getName'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); + +module.exports = inspect; + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + // Some type of object without properties can be shortcutted. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/objDisplay.js b/support/client/lib/vwf/view/chai/lib/chai/utils/objDisplay.js new file mode 100644 index 000000000..68142581a --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/objDisplay.js @@ -0,0 +1,50 @@ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay (object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function (obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteChainableMethod.js b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteChainableMethod.js new file mode 100644 index 000000000..1ef7439cc --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteChainableMethod.js @@ -0,0 +1,54 @@ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteChainableMethod (ctx, name, method, chainingBehavior) + * + * Overwites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.length(3); + * expect(myFoo).to.have.length.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function () { + var result = chainingBehavior(_chainingBehavior).call(this); + return result === undefined ? this : result; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function () { + var result = method(_method).apply(this, arguments); + return result === undefined ? this : result; + }; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteMethod.js b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteMethod.js new file mode 100644 index 000000000..1d5f6bd53 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteMethod.js @@ -0,0 +1,52 @@ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteMethod (ctx, name, fn) + * + * Overwites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function (ctx, name, method) { + var _method = ctx[name] + , _super = function () { return this; }; + + if (_method && 'function' === typeof _method) + _super = _method; + + ctx[name] = function () { + var result = method(_super).apply(this, arguments); + return result === undefined ? this : result; + } +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteProperty.js b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteProperty.js new file mode 100644 index 000000000..a13e7b2ae --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/overwriteProperty.js @@ -0,0 +1,55 @@ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteProperty (ctx, name, fn) + * + * Overwites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function () { + var result = getter(_super).call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/test.js b/support/client/lib/vwf/view/chai/lib/chai/utils/test.js new file mode 100644 index 000000000..453d4c72f --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/test.js @@ -0,0 +1,28 @@ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag'); + +/** + * # test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; diff --git a/support/client/lib/vwf/view/chai/lib/chai/utils/transferFlags.js b/support/client/lib/vwf/view/chai/lib/chai/utils/transferFlags.js new file mode 100644 index 000000000..fa2c379d7 --- /dev/null +++ b/support/client/lib/vwf/view/chai/lib/chai/utils/transferFlags.js @@ -0,0 +1,45 @@ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, and `message`) + * will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAsseriton = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function (assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; diff --git a/support/client/lib/vwf/view/chai/package.json b/support/client/lib/vwf/view/chai/package.json new file mode 100644 index 000000000..77193a03a --- /dev/null +++ b/support/client/lib/vwf/view/chai/package.json @@ -0,0 +1,128 @@ +{ + "_args": [ + [ + { + "raw": "chai", + "scope": null, + "escapedName": "chai", + "name": "chai", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "D:\\Dev\\vwf-itdg" + ] + ], + "_from": "chai@latest", + "_id": "chai@3.5.0", + "_inCache": true, + "_location": "/chai", + "_nodeVersion": "5.5.0", + "_npmUser": { + "name": "chaijs", + "email": "chaijs@keithcirkel.co.uk" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "chai", + "scope": null, + "escapedName": "chai", + "name": "chai", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "_shasum": "4d02637b067fe958bdbfdd3a40ec56fef7373247", + "_shrinkwrap": null, + "_spec": "chai", + "_where": "D:\\Dev\\vwf-itdg", + "author": { + "name": "Jake Luer", + "email": "jake@alogicalparadox.com" + }, + "bugs": { + "url": "https://github.com/chaijs/chai/issues" + }, + "contributors": [ + { + "name": "Jake Luer", + "email": "jake@alogicalparadox.com" + }, + { + "name": "Domenic Denicola", + "email": "domenic@domenicdenicola.com", + "url": "http://domenicdenicola.com" + }, + { + "name": "Veselin Todorov", + "email": "hi@vesln.com" + }, + { + "name": "John Firebaugh", + "email": "john.firebaugh@gmail.com" + } + ], + "dependencies": { + "assertion-error": "^1.0.1", + "deep-eql": "^0.1.3", + "type-detect": "^1.0.0" + }, + "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", + "devDependencies": { + "browserify": "^10.2.1", + "bump-cli": "^1.1.3", + "istanbul": "^0.3.14", + "karma": "^0.13.16", + "karma-firefox-launcher": "^0.1.6", + "karma-mocha": "^0.1.10", + "karma-phantomjs-launcher": "^0.2.0", + "karma-sauce-launcher": "^0.2.11", + "mocha": "^2.2.5" + }, + "directories": {}, + "dist": { + "shasum": "4d02637b067fe958bdbfdd3a40ec56fef7373247", + "tarball": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz" + }, + "engines": { + "node": ">= 0.4.0" + }, + "gitHead": "4ca0218391cf947c6cfac2d1a7424a63a4b4c232", + "homepage": "http://chaijs.com", + "keywords": [ + "test", + "assertion", + "assert", + "testing", + "chai" + ], + "license": "MIT", + "main": "./index", + "maintainers": [ + { + "name": "jakeluer", + "email": "jake@alogicalparadox.com" + }, + { + "name": "chaijs", + "email": "chaijs@keithcirkel.co.uk" + } + ], + "name": "chai", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/chaijs/chai.git" + }, + "scripts": { + "test": "make test" + }, + "version": "3.5.0" +} diff --git a/support/client/lib/vwf/view/chai/sauce.browsers.js b/support/client/lib/vwf/view/chai/sauce.browsers.js new file mode 100644 index 000000000..690c7cca1 --- /dev/null +++ b/support/client/lib/vwf/view/chai/sauce.browsers.js @@ -0,0 +1,128 @@ + +/*! + * Chrome + */ + +exports['SL_Chrome'] = { + base: 'SauceLabs' + , browserName: 'chrome' +}; + +/*! + * Firefox + */ + +/*! + * TODO: Karma doesn't seem to like this, though sauce boots its up + * + +exports['SL_Firefox_23'] = { + base: 'SauceLabs' + , browserName: 'firefox' + , platform: 'Windows XP' + , version: '23' +}; + +*/ + +exports['SL_Firefox_22'] = { + base: 'SauceLabs' + , browserName: 'firefox' + , platform: 'Windows 7' + , version: '22' +}; + +/*! + * Opera + */ + +exports['SL_Opera_12'] = { + base: 'SauceLabs' + , browserName: 'opera' + , platform: 'Windows 7' + , version: '12' +}; + +exports['SL_Opera_11'] = { + base: 'SauceLabs' + , browserName: 'opera' + , platform: 'Windows 7' + , version: '11' +}; + +/*! + * Internet Explorer + */ + +exports['SL_IE_10'] = { + base: 'SauceLabs' + , browserName: 'internet explorer' + , platform: 'Windows 2012' + , version: '10' +}; + +/*! + * Safari + */ + +exports['SL_Safari_6'] = { + base: 'SauceLabs' + , browserName: 'safari' + , platform: 'Mac 10.8' + , version: '6' +}; + +exports['SL_Safari_5'] = { + base: 'SauceLabs' + , browserName: 'safari' + , platform: 'Mac 10.6' + , version: '5' +}; + +/*! + * iPhone + */ + +/*! + * TODO: These take forever to boot or shut down. Causes timeout. + * + +exports['SL_iPhone_6'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '6' +}; + +exports['SL_iPhone_5-1'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.8' + , version: '5.1' +}; + +exports['SL_iPhone_5'] = { + base: 'SauceLabs' + , browserName: 'iphone' + , platform: 'Mac 10.6' + , version: '5' +}; + +*/ + +/*! + * Android + */ + +/*! + * TODO: fails because of error serialization + * + +exports['SL_Android_4'] = { + base: 'SauceLabs' + , browserName: 'android' + , platform: 'Linux' + , version: '4' +}; + +*/ diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index c6aab4bdf..06c1a5cde 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1,110 +1,445 @@ "use strict"; -define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], - function( module, view, $, utility, color ) { +define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color", "vwf/utility/vertexSimplify/simplify" ], + function( module, view, $, utility, color, simplifyJs ) { - var self; + var viewDriver; var stageContainer; - var stageWidth = 800; - var stageHeight = 600; + var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; + var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; + var drawing_private = { + "drawingObject": null, + "drawingDef": null, + "drawingParentID": undefined, + "drawingChildName": "", + "initialDownPoint": [ -1, -1 ], + "previousPoint": [ -1, -1 ], + "imageDataURL": null + }; + var drawing_client = { + "drawing_mode": 'none', + "drawing_visible": 'inherit', + "drawing_color": 'black', + "drawing_width": 4, + "drawing_parentPath": '/', + "drawing_parentID": undefined, + "drawing_opacity": 1.0, + "nameIndex": 1, + "fontSize": 16, + "angle": 30, + "lineCap": 'round', + "lineJoin": 'round', + "dashLineStyle": null, + "fillStyle": null, + "zIndex": 4, + "shadows": {} + }; + var private_node = undefined; + var privateNodesToDelete = {}; + var activelyDrawing = false; + var clearBeforeDraw = false; + var lastRenderTime = 0; // last time whole scene was rendered + var renderTimeout = 1000; // ms between renders + var doRenderScene = false; + var eventHandlers = {}; + var _draggingNode; + + // Object implements tapHold behavior (kineticJS doesn't have a built-in one) + var tapHold = { + "node": null, + "initialPosition": [ 0, 0], + "timeout": 1500, // timeout in milliseconds + "moveThreshold": 64, // Square of the threshold + "timerId": null, + "protoFilter": null, + "isListening": false, + "start": function( node, position ) { + if ( this.isListening && !this.node && this.matchesProtoFilter( node.prototypes ) ) { + this.node = node; + this.initialPosition = position.client; + this.timerId = setTimeout( function(){ fireTapHold(); }, this.timeout ); + } + }, + "moved": function( node, position ) { + if ( node === this.node ) { + //console.info( " tapHold moved for node: " + this.node.ID + " at position: [ " + position.client[0] + ", " + position.client[1] + " ], timerId = " + this.timerId ); + if ( this.timerId ) { + var deltaPos = [ ( position.client[0] - this.initialPosition[0] ), + ( position.client[1] - this.initialPosition[1] ) ]; + var distanceSquared = ( ( deltaPos[0] * deltaPos[0] ) + ( deltaPos[1] * deltaPos[1] ) ); + if ( distanceSquared > this.moveThreshold ) { + this.cancel(); + } + } + } + }, + "cancel": function() { + if ( this.timerId ) { + clearTimeout( this.timerId ); + } + this.node = null; + this.initialPosition = [ 0, 0 ]; + this.timerId = null; + }, + "matchesProtoFilter": function( prototypes ) { + var found = false; + if ( this.protoFilter ) { + if ( prototypes ) { + var kIndex; + for ( var i = 0; i < prototypes.length && !found; i++ ) { + for ( var j = 0; j < this.protoFilter.length && !found; j++ ) { + found = ( prototypes[ i ] === this.protoFilter[ j ] ); + } + } + } + } else { + found = true; // Not filtering anything + } + return found; + }, + "registerForTapHoldEvents": function( protoFilters ) { + for ( var i = 0; i < protoFilters.length; i++ ) { + console.info( i + ". " + protoFilters[i] ); + } + this.protoFilter = protoFilters; + }, + "listenForTapHold": function( listen ) { + this.isListening = listen; + if ( !listen ) { + tapHold.cancel(); + } + } - function processEvent( e, node, propagate ) { - var returnData = { eventData: undefined, eventNodeData: undefined }; + }; - if ( !propagate ) { - // For the "dragend" event, kinetic sometimes sends us an event object that doesn't - // have all the expected functions and properties attached - e.evt.stopPropagation && e.evt.stopPropagation(); + function fireTapHold() { + if ( tapHold.node ) { + fireViewEvent( "tapHold", { + nodeID: tapHold.node.ID, + initialPosition: tapHold.initialPosition + } ); + tapHold.cancel(); } + } - var eventPosition; - var isTouchEvent = ( e.evt instanceof TouchEvent ); - if ( isTouchEvent ) { - eventPosition = e.evt.changedTouches[ 0 ]; - } else { - eventPosition = e.evt; - } + var swipe = { + "protoFilter": null, + "isListening": false, + "parentFilter": null, + "touchStartIsTap": null, + "swipedAcross": function( node, isTouchStart, eventData ) { + if ( this.isListening && this.isSwipe( node ) ) { + if ( isTouchStart && this.touchStartIsTap ) { + fireViewEvent( "tap", { + nodeID: node.ID, + eventData: eventData[ 0 ] + } ); + } else { + fireViewEvent( "swipe", { + nodeID: node.ID + } ); + } + } + }, + "isSwipe": function( node ) { + var found = false; + var prototypes = node.prototypes; + if ( this.parentFilter && ( !isChildOf( node.kineticObj, this.parentFilter ) ) ) { + return found; + } + if ( this.protoFilter ) { + if ( prototypes ) { + var kIndex; + for ( var i = 0; i < prototypes.length && !found; i++ ) { + for ( var j = 0; j < this.protoFilter.length && !found; j++ ) { + found = ( prototypes[ i ] === this.protoFilter[ j ] ); + } + } + } + } else { + found = true; // Not filtering anything + } + return found; + }, + "registerForSwipeEvents": function( protoFilters ) { + this.protoFilter = protoFilters; + }, + "listenForSwipes": function( params ) { + this.isListening = params.listen; + this.parentFilter = params.parent; + this.touchStartIsTap = params.touchStartIsTap; + } + }; + + // Attach handlers for mouse events + function attachMouseEvents( node ) { + + node.kineticObj.on( "mousemove", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + + drawMove( eData.eventData[ 0 ], node ); + + var userState = drawing_client; + + if ( !!userState[ "drawing_mode" ] ) { + switch ( userState[ "drawing_mode" ] ) { + case 'none': + case 'edit': + activelyDrawing = false; + break; + default: + break; + } + } else { + activelyDrawing = false; + } - var stage = node && node.stage; - returnData.eventData = [ convertBrowserEventDataToVwf( eventPosition, stage ) ]; + } ); - var eventDataElement = returnData.eventData[ 0 ]; - eventDataElement.button = e.evt.button; - eventDataElement.timeStamp = e.evt.timeStamp; - eventDataElement.shiftKey = e.evt.shiftKey; - eventDataElement.ctrlKey = e.evt.ctrlKey; - eventDataElement.altKey = e.evt.altKey; - eventDataElement.metaKey = e.evt.metaKey; + node.kineticObj.on( "mouseenter", function( evt ) { + if ( evt.evt.buttons ) { + swipe.swipedAcross( node ); + } + } ); - if ( isTouchEvent ) { - returnData.eventData[ 0 ].touches = []; - for ( var i = 0; i < e.evt.touches.length; i++ ) { - returnData.eventData[ 0 ].touches[ i ] = convertBrowserEventDataToVwf( - e.evt.touches[ i ], - stage - ); - } - } + // Note: We do not get this event if we are dragging something + node.kineticObj.on( "mouseleave", function( evt ) { + drawUp(); + if ( evt.evt.buttons ) { + swipe.swipedAcross( node ); + } + } ); + + node.kineticObj.on( "mousedown", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + + // Process drawing (if actively drawing) + drawDown( eData.eventData[0], node ); + var userState = drawing_client; + if ( !!userState[ "drawing_mode" ] ) { + switch ( userState[ "drawing_mode" ] ) { + case 'edit': + case 'none': + fireViewEvent( "pointerClick", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + break; + default: + activelyDrawing = true; + break; + } + } - if ( propagate ) { + } ); - var stageId = stage && stage.getId(); - var pointerPickID = e.targetNode ? e.targetNode.getId() : stageId; + // Note: We only get this event if the mouse is let go on the canvas + node.kineticObj.on( "mouseup", function( evt ) { + var eData = processEvent( evt, node ); - returnData.eventNodeData = { "": [ { - pickID: pointerPickID, - } ] }; + // Cancel tapHold event (if any) + tapHold.cancel(); - if ( self && self.state.nodes[ pointerPickID ] ) { - var childID = pointerPickID; - var child = self.state.nodes[ childID ]; - var parentID = child.parentID; - var parent = self.state.nodes[ child.parentID ]; - while ( child ) { + drawUp(); - returnData.eventNodeData[ childID ] = [ { - pickID: pointerPickID, - } ]; + activelyDrawing = false; - childID = parentID; - child = self.state.nodes[ childID ]; - parentID = child ? child.parentID : undefined; - parent = parentID ? self.state.nodes[ child.parentID ] : undefined; + fireViewEvent( "mouseup", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + } ); - } + node.kineticObj.on( "click", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + activelyDrawing = false; + + fireViewEvent( "pointerClick", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + } ); + + node.kineticObj.on( "dblclick", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + activelyDrawing = false; + + fireViewEvent( "pointerDoubleClick", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + } ); + + node.kineticObj.on( "dragstart", function( evt ) { + + _draggingNode = node; + + // We don't want to receive this event for the node's parents + evt.cancelBubble = true; + + // Fire a view-side event + var eData = processEvent( evt, node ); + fireViewEvent( "dragstart", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + + if ( node.dragToTop ) { + node.kineticObj.moveToTop(); } - } - return returnData; + swipe.swipedAcross( node ); + + } ); + + node.kineticObj.on( "dragmove", function( evt ) { + var eData = processEvent( evt, node ); + + tapHold.moved( node, eData.eventData[0] ); + activelyDrawing = false; + + } ); + + node.kineticObj.on( "dragend", evt => { + evt.cancelBubble = true; + + var nodeID = node.ID; + if ( nodeID !== _draggingNode.ID ) { + return; + } + + // Calculate and set the final mapPosition at the end of the drag + var mapPosition = setNewUnitMapPositionOnDrag(); + + // The node is no longer being dragged + _draggingNode = undefined; + activelyDrawing = false; + + // Fire a view-side event + var eData = processEvent( evt, node ); + var eventParams = { + nodeID: nodeID, + eventData: eData.eventData[ 0 ], + mapPosition: mapPosition + }; + fireViewEvent( "dragend", eventParams ); + } ); + } - function convertBrowserEventDataToVwf( browserEventData, stage ) { - var vwfEventData = { - "location": [ browserEventData.x, browserEventData.y ], - "stageRelative": [ browserEventData.pageX, browserEventData.pageY ], - "client": [ browserEventData.clientX, browserEventData.clientY ], - "screen": [ browserEventData.screenX, browserEventData.screenY ], - "layer": [ browserEventData.layerX, browserEventData.layerY ], - "page": [ browserEventData.pageX, browserEventData.pageY ], - "offset": [ browserEventData.offsetX, browserEventData.offsetY ], - "movement": [ browserEventData.webkitMovementX, browserEventData.webkitMovementY ] - }; + // Attach handlers for touch events + function attachTouchEvents( node ) { - if ( stage ) { - vwfEventData.stage = [ stage.x(), stage.y() ]; - vwfEventData.stageRelative = [ - ( browserEventData.pageX - stage.x() ) / stage.scaleX(), - ( browserEventData.pageY - stage.y() ) / stage.scaleY() - ]; - } - return vwfEventData; + var TOUCH_EVENT = true; + + node.kineticObj.on( "touchstart", function( evt ) { + var eData = processEvent( evt, node ); + + // Start tapHold + tapHold.start( node, eData.eventData[0].touches[0] ); + + drawDown( eData.eventData[0], node ); + + var userState = drawing_client; + if ( !!userState[ "drawing_mode" ] ) { + switch ( userState[ "drawing_mode" ] ) { + case 'none': + case 'edit': + activelyDrawing = false; + break; + default: + break; + } + } else { + activelyDrawing = false; + } + var prevPos; + if (node.kineticObj.attrs) { + prevPos = [node.kineticObj.attrs.x, node.kineticObj.attrs.y]; + } + swipe.swipedAcross( node, true, eData.eventData ); + + } ); + + node.kineticObj.on( "touchmove", function( evt ) { + var eData = processEvent( evt, node ); + + // If tapHold started, check that we haven't moved too much + tapHold.moved( node, eData.eventData[0].touches[0] ); + + drawMove( eData.eventData[ 0 ], node ); + + var userState = drawing_client; + if ( userState[ "drawing_mode" ] ) { + switch ( userState[ "drawing_mode" ] ) { + case 'edit': + case 'none': + break; + default: + activelyDrawing = true; + break; + } + } + + swipe.swipedAcross( node ); + } ); + + // Note: We only get this if the touchend occurs on the canvas + node.kineticObj.on( "touchend", function( evt ) { + + // Cancel tapHold event (if any) + tapHold.cancel(); + + drawUp(); + } ); + + node.kineticObj.on( "tap", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + activelyDrawing = false; + + fireViewEvent( "tap", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + swipe.swipedAcross( node, true, eData.eventData ); + } ); + + node.kineticObj.on( "dbltap", function( evt ) { + var eData = processEvent( evt, node ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + activelyDrawing = false; + + fireViewEvent( "doubleTap", { + nodeID: node.ID, + eventData: eData.eventData[ 0 ] + } ); + } ); } + // Create and return the view driver object ---------------------------------------------------- + return view.load( module, { initialize: function( options ) { - self = this; + viewDriver = this; this.arguments = Array.prototype.slice.call( arguments ); @@ -132,147 +467,54 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( !node ) { return; } - - var protos = node.prototypes; - if ( self.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { - - var stage = this.state.stage = node.kineticObj; - + + // If this node represents the public version of a private drawing that we hold locally, + // delete the private drawing (now that it exists publicly) + var privateNodesForThisParent = privateNodesToDelete[ nodeID ]; + if ( privateNodesForThisParent ) { + var privateDrawing = privateNodesForThisParent[ childName ]; + if ( privateDrawing ) { + clearPrivateDrawing( privateDrawing ); + delete privateNodesForThisParent[ childName ]; + if ( !Object.keys( privateNodesForThisParent ).length ) { + delete privateNodesToDelete[ nodeID ]; + } + } } - }, - initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback ) { - + var node = this.state.nodes[ childID ]; // If the "nodes" object does not have this object in it, it must not be one that // this driver cares about if ( !node ) { - - //var stage = this.state.stages[ childID ]; - //renderScene( stage ); return; } - if ( node.kineticObj ) { - - var mouseDown = false; - - var TOUCH_EVENT = true; - - node.kineticObj.on( "mousemove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); - } ); - - node.kineticObj.on( "mouseout", function( evt ) { - var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); - } ); - - node.kineticObj.on( "mouseenter", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); - } ); - - node.kineticObj.on( "mouseleave", function( evt ) { - var eData = processEvent( evt, node, false ); - // self.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); - } ); - - node.kineticObj.on( "mousedown", function( evt ) { - var eData = processEvent( evt, node, false ); - mouseDown = true; - //self.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); - } ); - - node.kineticObj.on( "mouseup", function( evt ) { - var eData = processEvent( evt, node, false ); - mouseDown = false; - //self.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); - if ( node.kineticObj.mouseDragging ) { - self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - node.kineticObj.mouseDragging = false; - } - } ); - - node.kineticObj.on( "click", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); - } ); - - node.kineticObj.on( "dblclick", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); - } ); - - node.kineticObj.on( "touchstart", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); - } ); - - node.kineticObj.on( "touchmove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); - } ); - - node.kineticObj.on( "touchend", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); - } ); - - node.kineticObj.on( "tap", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'tap', eData.eventData ); - } ); - - node.kineticObj.on( "dbltap", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); - } ); - - node.kineticObj.on( "dragstart", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); - node.kineticObj.mouseDragging = true; - } ); - - node.kineticObj.on( "dragmove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); - } ); - - // I couldn't get this to work, so instead I keep track of mouseDragging separately - // in dragstart and mouseup (Eric - 11/18/14) - // node.kineticObj.on( "dragend", function( evt ) { - // var eData = processEvent( evt, node, false ); - // //self.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); - // self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - // } ); - + var lastKernel = vwf_view; + while ( lastKernel.kernel ) { + lastKernel = lastKernel.kernel; } - }, + var objectDriver = lastKernel.models.object; + var disableScaleAndRotationForSpeed = + objectDriver.gettingProperty( childID, "disableScaleAndRotationForSpeed" ); + var prototypeID = objectDriver.prototype( childID ); + while ( ( disableScaleAndRotationForSpeed === undefined ) && ( prototypeID ) ) { + disableScaleAndRotationForSpeed = + objectDriver.gettingProperty( prototypeID, "disableScaleAndRotationForSpeed" ); + prototypeID = objectDriver.prototype( prototypeID ); + } + var transformsEnabled = disableScaleAndRotationForSpeed ? "position" : "all"; + node.kineticObj.transformsEnabled( transformsEnabled ); + }, // -- deletedNode ------------------------------------------------------------------------------ - //deletedNode: function( nodeID ) { }, + // deletedNode: function( nodeID ) { }, // -- addedChild ------------------------------------------------------------------------------- @@ -288,9 +530,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // -- initializedProperty ---------------------------------------------------------------------- - //initializedProperty: function (nodeID, propertyName, propertyValue) { }, - - // TODO: deletedProperty + initializedProperty: function ( nodeID, propertyName, propertyValue ) { + this.satProperty( nodeID, propertyName, propertyValue ); + }, // -- satProperty ------------------------------------------------------------------------------ @@ -303,159 +545,1420 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return; } + var drawThis = false; + var clearBefore = false; var kineticObj = node.kineticObj; - switch ( propertyName ) { - case "enableEvents": - var mouseDown = false; - var touch = false; - var mouseDownTime = null; - var mouseDownId = undefined; - var touchId = undefined; - var timer = new Date(); - - var protos = node.prototypes; - if ( self.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { - - var stage = kineticObj; - var TOUCH_EVENT = true; - - // these are the events for the global space, ie the stage - // we did originally implement the mouse events this way - // but then we added the events for the individual objects - // which appeared to work better. We were getting duplicate events - // which is why I moved these events down inside a property - // just in case they were needed for another apllication that - // is set up differently - - if ( Boolean( propertyValue ) ) { - - // defined handlers - stage.on( 'contentMousedown', function( evt ) { - var node = evt.targetNode; - mouseDownId = ( node !== undefined ) ? node.getId() : stage.getId(); - mouseDown = true; - mouseDownTime = timer.getTime(); - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here - - self.kernel.dispatchEvent( mouseDownId, 'pointerDown', eData.eventData, eData.eventNodeData ); - }); - - stage.on( 'contentMousemove', function( evt ) { - var node = evt.targetNode; - - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here - - self.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerMove', eData.eventData, eData.eventNodeData ); - }); - - stage.on( 'contentMouseup', function( evt ) { - var node = evt.targetNode; - mouseDown = false; - - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here - if ( timer.getTime() - mouseDownTime < 700.0 ) { - self.kernel.dispatchEvent( mouseDownId, 'pointerClick', eData.eventData, eData.eventNodeData ); - } - self.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerUp', eData.eventData, eData.eventNodeData ); - - mouseDownTime = null; - mouseDownId = null; - } ); - - } else { - // remove handlers - stage.off( 'contentMousedown' ); - stage.off( 'contentMousemove' ); - stage.off( 'contentMouseup' ); - // stage.off( 'contentTouchstart' ); - // stage.off( 'contentTouchmove' ); - // stage.off( 'contentTouchend' ); - // stage.off( 'contentTap' ); - } + switch ( propertyName ) { + case "supportMouseAndTouchEvents": + if ( ( propertyValue === true ) && ( !node.hasMouseAndTouchEvents ) ) { + attachMouseEvents( node ); + attachTouchEvents( node ); + node.hasMouseAndTouchEvents = true; } break; + case "position": + drawObject( kineticObj, true ); + break; + case "disableScaleAndRotationForSpeed": + kineticObj.transformsEnabled( propertyValue ? "position" : "all" ); + break; case "scale": - if ( !node.uniqueInView ) { + if ( node.model.scale !== undefined ) { kineticObj.scale( { - "x": kineticObj.modelScaleX, - "y": kineticObj.modelScaleY + "x": node.model.scale.x, + "y": node.model.scale.y } ); + drawThis = !activelyDrawing; } break; case "scaleX": - if ( !node.uniqueInView ) { - kineticObj.scaleX( kineticObj.modelScaleX ); + if ( node.model.scaleX !== undefined ) { + kineticObj.scaleX( node.model.scaleX ); + drawThis = !activelyDrawing; } break; case "scaleY": - if ( !node.uniqueInView ) { - kineticObj.scaleY( kineticObj.modelScaleY ); + if ( node.model.scaleX !== undefined ) { + kineticObj.scaleY( node.model.scaleX ); + drawThis = !activelyDrawing; + } + break; + case "rotation": + if ( node.model.rotation !== undefined ) { + kineticObj.rotation( node.model.rotation ); + drawThis = !activelyDrawing; } break; - } - }, + case "activeLayerID": + if ( this.kernel.client() === this.kernel.moniker() ) { + drawing_client.drawing_parentID = propertyValue; + } + break; + + case "text": + if ( isDrawingObject( nodeID ) ) { + var drawingObject = drawing_private.drawingObject; + drawingObject.text( propertyValue ); + drawObject( drawingObject, true ); + propagateNodeToModel( drawing_private ); + } + break; + + case "dragToTop": + // TODO: Currently getting from object driver. + // In future, this should be moved to model driver. + node.dragToTop = propertyValue; + break; + + case "visible": + var visible = propertyValue; + if ( this.state.pauseRendering ) { + drawThis = false; + } else { + drawThis = !activelyDrawing; + clearBefore = !visible; // If we're hiding object, we need to clear + } + break; + + case "pauseRendering": + if ( propertyValue !== this.state.pauseRendering ) { + var wasPaused = this.state.pauseRendering; + this.state.pauseRendering = propertyValue; + if ( wasPaused ) { + refreshState(); + } + } + drawThis = false; + break; + + case "attributes": + drawThis = !activelyDrawing; + break; + + case "radius": + case "fill": + case "opacity": + drawThis = true; + clearBefore = true; - firedEvent: function( nodeID, eventName ) { - if ( eventName == "draggingFromView" ) { - var clientThatSatProperty = self.kernel.client(); - var me = self.kernel.moniker(); + default: + drawThis = this.state.pauseRendering ? false : !activelyDrawing; + } + + if ( drawThis ) { + // If drawing from cache, refresh the cached object + viewDriver.state.refreshHitGraphFromCache( kineticObj ); + // Draw the object + drawObject( kineticObj, clearBefore ); + } - // If the transform property was initially updated by this view.... - if ( clientThatSatProperty == me ) { + }, - // Tell the model not to update the view on the next position update because - // kinetic has already done so - // (this event is fired right before this driver sets the model property, so we - // can be sure that the very next set of the position property is from us) - var node = this.state.nodes[ nodeID ]; - node.viewIgnoreNextPositionUpdate = true; + calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { + + if ( this.kernel.client() === this.kernel.moniker() ) { + switch ( methodName ) { + case "enableLayerHitGraph": + var layers = methodParameters[ 0 ]; + for ( var id in layers ) { + var layer = this.state.nodes[ nodeID ]; + if ( layer && ( layer.nodeType === "Layer" ) && layer.kineticObj ) { + ( layers[ id ] ? layer.kineticObj.enableHitGraph() : layer.kineticObj.disableHitGraph() ); + } + } + break; } } }, + firedEvent: function( nodeID, eventName, eventData ) { + switch ( eventName ) { + + case "draggingFromView": + + // If the transform property was initially updated by this view.... + var kernel = viewDriver.kernel; + if ( kernel.client() === kernel.moniker() ) { + + // Tell the model not to update the view on the next position update because + // kinetic has already done so + // (this event is fired right before this driver sets the model property, so we + // can be sure that the very next set of the position property is from us) + var node = this.state.nodes[ nodeID ]; + node.model.position.ignoreNextPositionUpdate = true; + } + break; + + default: + break; + } + + }, + + // firedEvent: function( nodeID, eventName ) { }, + ticked: function( vwfTime ) { - var nodeIDs = Object.keys( this.state.nodes ); - for ( var i = 0; i < nodeIDs.length; i++ ) { - var nodeID = nodeIDs[ i ]; + setNewUnitMapPositionOnDrag(); + }, + + // This is intended to be called directly from the application view + setViewProperty: function( id, propertyName, propertyValue, modelChangeShouldUpdateView ) { + var node = viewDriver.state.nodes[ id ]; + var kineticObj = ( node || {} ).kineticObj; + + if ( !kineticObj ) { + console.error( + "konva.setViewProperty: Attempted to set view property on a non-konva object" ); + return; + } + + if ( !utility.validObject( propertyValue ) ) { + console.error( + "konva.setViewProperty: Attempted to set view property with an invalid value" ); + return; + } + + // If we have not yet saved off the model value + // to keep it safe from unique-in-view property changes, do that now + if ( node.model[ propertyName ] === undefined ) { + node.model[ propertyName ] = { + "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), + "modelChangeShouldUpdateView": !!modelChangeShouldUpdateView + }; + } else { + + // If we had already saved off the model value, + // honor the new value that the caller has passed in for modelChangeShouldUpdateView + node.model[ propertyName ].modelChangeShouldUpdateView = + !!modelChangeShouldUpdateView; + } + + // Set the konva object property to use the unique-in-view value + viewDriver.state.setProperty( kineticObj, propertyName, propertyValue ); + }, + + setDrawingState: function ( stateObj ) { + + // Whenever the drawing state changes, ensure that the previous drawing is finished + // This is necessary for drawings that are be underway when the mode is changed + // Example: If the user draws off the side of the page and then changes the mode to Move + drawUp(); + + if ( stateObj !== undefined ) { + var userState = drawing_client; + for ( var property in stateObj ) { + userState[ property ] = stateObj[ property ]; + } + } + }, + + getDrawingState: function ( property ) { + if ( !!drawing_client ) { + return drawing_client[ property ]; + } + return undefined; + }, + + registerForTapHoldEvents: function( protoFilters ) { + tapHold.registerForTapHoldEvents( protoFilters ); + }, + + listenForTapHold: function( listen ) { + tapHold.listenForTapHold( listen ); + }, + + registerForSwipeEvents: function( protoFilters ) { + swipe.registerForSwipeEvents( protoFilters ); + }, + + listenForSwipes: function( params ) { + swipe.listenForSwipes( params ); + }, + + setListening: function( nodeID, listen ) { + this.state.nodes[ nodeID ].kineticObj.listening( listen ); + }, + + setChildListening: function( nodeID, childNames, listen ) { + var node = this.state.nodes[ nodeID ]; + + var kineticObj = node && node.kineticObj; + if ( !kineticObj ) { + view.logger.errorx( "setChildListening", + "Node '", nodeID, "' is not a konva node" ); + return; + } + + var children = kineticObj.children; + for ( var i = 0; i < children.length; i++ ) { + var child = children[ i ]; + var childWasRequested = child && ( childNames.indexOf( child.name() ) > -1 ); + childWasRequested && child.listening( listen ); + } + }, + + refreshChildrenHitGraphFromCache: function( nodeID ) { + if ( !!nodeID ) { var node = this.state.nodes[ nodeID ]; - // If users can drag this node and all clients should stay synchronized, we must - // pull the new node position out of kinetic and update the model with it - if ( node.kineticObj.draggable() && !node.uniqueInView ) { - var kineticX = node.kineticObj.x(); - var kineticY = node.kineticObj.y(); - - // If the position of this node has changes since it's last model value, set the - // model property with the new value - if ( ( node.kineticObj.modelX !== kineticX ) || - ( node.kineticObj.modelY !== kineticY ) ) { - - // Fire this event to notify the model that kinetic has already updated the - // view and it doesn't need to (if the model set the value, it would risk - // having the model set the view back to an old value, which results in - // jitter while the user is dragging the node) - vwf_view.kernel.fireEvent( nodeID, "draggingFromView" ); - vwf_view.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); + var kineticObj = node && node.kineticObj; + if ( !kineticObj ) { + view.logger.errorx( "refreshChildrenHitGraphFromCache", + "Node '", nodeID, "' is not a konva node" ); + return; + } + + // Recurse through children to refresh the ones using hitgraph from cache + var children = kineticObj.children || []; + for ( var i = 0; i < children.length; i++ ) { + var child = children[ i ]; + if ( viewDriver.state.refreshHitGraphFromCache( child ) ) { + child.draw(); + } else { + this.refreshChildrenHitGraphFromCache( child.getId() ); } } } - for ( var id in self.state.stages ){ - renderScene( self.state.stages[ id ] ); - } - - } - - - } ); + }, - function renderScene( stage ) { - //window.requestAnimationFrame( renderScene( stage ) ); - if ( stage !== undefined ) { - stage.batchDraw(); + on: function( eventName, callback ) { + eventHandlers[ eventName ] = callback; + }, + + setText: function( text ) { + if ( !createTextObject( text ) ) { + console.error( "setText: Could not create text object" ); + return; + } + var drawingObject = drawing_private.drawingObject; + drawingObject.fontSize( drawing_client.fontSize || 16 ); + drawingObject.fontStyle( 'bold' ); + drawingObject.text( text ); + drawingObject.fill( drawing_client.drawing_color ); + drawObject( drawingObject, true ); + propagateNodeToModel( drawing_private ); + }, + + getChildIdByName: function( parentID, childName ) { + var parent = viewDriver.state.nodes[ parentID ] || {}; + if ( parent.kineticObj ) { + var children = parent.kineticObj.children || []; + for ( var i = 0; i < children.length; i++ ) { + if ( children[ i ].name() === childName ) { + return children[ i ].getId(); + } + } + } + return undefined; + }, + + setImage: setImage, + refreshLayer: refreshLayer, + simplifyPoints: simplifyPoints + } ); + + // Private helper functions -------------------------------------------------------------------- + + function setNewUnitMapPositionOnDrag() { + + if ( !_draggingNode ) { + return; + } + + var newMapPosition; + var kineticObj = _draggingNode.kineticObj; + + if ( !kineticObj ) { + return; + } + + // If users can drag this node and all clients should stay synchronized, we must + // pull the new node position out of kinetic and update the model with it + var draggable = kineticObj.draggable(); + + var positionProperty = ( _draggingNode.model || {} ).position; + var modelChangeShouldUpdateView = ( positionProperty || {} ).modelChangeShouldUpdateView; + + if ( draggable && modelChangeShouldUpdateView ) { + var kineticX = kineticObj.x(); + var kineticY = kineticObj.y(); + + var iconID = + _draggingNode.children.filter( childID => childID.includes( "icon" ) )[ 0 ]; + var icon = viewDriver.state.nodes[ iconID ].kineticObj; + var symbolCenter = icon.attrs.symbolCenter || { + x: 0, + y: 0 + }; + var scale = kineticObj.scaleX(); + newMapPosition = { + x: kineticX + scale * symbolCenter.x, + y: kineticY + scale * symbolCenter.y, + } + + // If the position of this node has changed since its last model value, set the + // model property with the new value + if ( ( positionProperty.value.x !== kineticX ) || + ( positionProperty.value.y !== kineticY ) ) { + + // Fire this event to notify the model that kinetic has already updated the + // view and it doesn't need to (if the model set the value, it would risk + // having the model set the view back to an old value, which results in + // jitter while the user is dragging the node) + var nodeID = _draggingNode.ID; + viewDriver.kernel.fireEvent( nodeID, "draggingFromView" ); + + // Update the node's mapPosition + // Note: It is usually bad practice to use a potentially out-of-date model value + // (like symbolCenter) to calculate model state on the view side. + // Doing so on the model side ensures that all values are up to date. + // However, for integration with other applications who receive reflector + // traffic, it is important for them to see the mapPosition property get + // set. + // + // Since the "errors" that might be caused by having an out-of-date + // symbolCenter would be rare, we do this here. + // + // (The error would take the form that the user who dragged the symbol + // would see the symbol in the view where they dropped it. + // However, if the symbol had been rerendered between the drop and + // the model property getting set, the model value would be slightly + // different, such that all other users would see the unit in a different + // location. That would resolve the next time someone moved the unit.) + viewDriver.kernel.setProperty( nodeID, "mapPosition", newMapPosition ); + + render( kineticObj, false, true ); + } + } + return newMapPosition; + } + + function renderScene( stage, force, drawHit ) { + if ( stage && ( !activelyDrawing || force ) ) { + if ( stage.batchDraw instanceof Function ) { + batchRender( stage, force ); + } else { + render( stage, force, drawHit ); + } + doRenderScene = false; + } + } + + function render( kineticObj, force, drawHit ) { + var now = Date.now(); + if ( kineticObj && ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { + ( drawHit ? kineticObj.draw() : kineticObj.drawScene() ); + lastRenderTime = now; + } + } + + function batchRender( kineticObj, force ) { + var now = Date.now(); + if ( kineticObj && ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { + kineticObj.batchDraw(); + lastRenderTime = now; } } + function processEvent( e, node ) { + var returnData = { eventData: undefined, eventNodeData: undefined }; + + var isTouchEvent = !!e.evt.touches; + var eventPosition = isTouchEvent ? e.evt.changedTouches[ 0 ] : e.evt; + + var stage = node && node.stage; + returnData.eventData = [ convertBrowserEventDataToVwf( eventPosition, stage ) ]; + + var eventDataElement = returnData.eventData[ 0 ]; + eventDataElement.button = e.evt.button; + eventDataElement.timeStamp = e.evt.timeStamp; + eventDataElement.shiftKey = e.evt.shiftKey; + eventDataElement.ctrlKey = e.evt.ctrlKey; + eventDataElement.altKey = e.evt.altKey; + eventDataElement.metaKey = e.evt.metaKey; + + if ( isTouchEvent ) { + returnData.eventData[ 0 ].touches = []; + for ( var i = 0; i < e.evt.touches.length; i++ ) { + returnData.eventData[ 0 ].touches[ i ] = + convertBrowserEventDataToVwf( e.evt.touches[ i ], stage ); + } + } + + return returnData; + } + + function convertBrowserEventDataToVwf( browserEventData, stage ) { + var vwfEventData = { + "location": [ browserEventData.x, browserEventData.y ], + "stageRelative": [ browserEventData.pageX, browserEventData.pageY ], + "client": [ browserEventData.clientX, browserEventData.clientY ], + "screen": [ browserEventData.screenX, browserEventData.screenY ], + "layer": [ browserEventData.layerX, browserEventData.layerY ], + "page": [ browserEventData.pageX, browserEventData.pageY ], + "offset": [ browserEventData.offsetX, browserEventData.offsetY ], + "movement": [ browserEventData.webkitMovementX, browserEventData.webkitMovementY ] + }; + + if ( stage ) { + vwfEventData.stage = [ stage.x(), stage.y() ]; + vwfEventData.stageRelative = [ + ( browserEventData.pageX - stage.x() ) / stage.scaleX(), + ( browserEventData.pageY - stage.y() ) / stage.scaleY() + ]; + } + return vwfEventData; + } + + // When the user begins a new part of a drawing, + // check to see if this is for an existing drawing or the beginning of a new drawing. + // If it is the beginning of a new drawing, populate the drawing_private object with + // a new konva object and a VWF descriptor that will be used to create a model object + // when the user is done drawing + function drawDown( eventData, nodeData ) { + + var userState = drawing_client; + var privateState = drawing_private; + var drawingMode = userState.drawing_mode; + + if ( privateState.drawingObject || drawingMode === 'none' || drawingMode === 'edit' ) { + return; + } + + var compExtends = undefined; + var section = ( drawingMode === "freeDraw" || drawingMode === "line") ? "/lines" : "/shapes"; + + switch ( drawingMode ) { + + case "arc": + case "circle": + case "ellipse": + case "regularPolygon": + case "rect": + case "ring": + case "star": + case "wedge": + case "sprite": + case "image": + compExtends = [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') + break; + + case "text": + compExtends = "http://vwf.example.com/kinetic/rect.vwf"; + break; + + case "freeDraw": + case "polygon": + case "line": + case "borderRect": + case "arrow": + case "thickArrow": + compExtends = "http://vwf.example.com/kinetic/line.vwf"; + break; + + default: + break; + + } + + var eventPointDown = eventData.stageRelative; + + if ( compExtends !== undefined ) { + + privateState.initialDownPoint = eventPointDown; + var parentPath = userState.drawing_parentPath + section; + var parentIDs = viewDriver.kernel.find( viewDriver.kernel.application(), parentPath ); + + if ( parentIDs.length === 0 ) { + view.logger.errorx( "drawDown", "Could not find parent node '", parentPath, "'", + " - Cannot create drawn line" ); + return; + } + + var parentID = parentIDs[ 0 ]; + var shapeDef = { + "extends": compExtends, + "properties": getDefaultProperties( drawingMode, false, eventPointDown ) + }; + + var name = drawingMode + "-" + randomSuffix(); + var childID = parentID + ":" + name ; + private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObj; + + // Save data to be used to create the node in the model + drawing_private.drawingDef = shapeDef; + drawing_private.drawingParentID = parentID; + drawing_private.drawingChildName = name; + + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData ); + + } + + // Return a hex string representing a random 32-bit integer. + + function randomSuffix() { + return ( "00000000" + Math.floor( Math.random() * 0x100000000 ).toString( 16 ) ).substr( -8 ); + } + }; + + function drawMove( eventData, nodeData ) { + + var userState = drawing_client; + if ( ( userState.drawing_mode === 'none' ) || ( userState.drawing_mode === 'edit' ) ) { + return; + } + + if ( drawing_private.drawingObject ) { + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData ); + } + }; + + function drawUp() { + + var drawingObject = ( drawing_private || {} ).drawingObject; + if ( !drawingObject ) { + return; + } + + fireViewEvent( "drawingObjectCreated", { + nodeID: drawingObject.id() + } ); + + var drawAndPropagate = false; + + var userState = drawing_client; + drawingObject.setZIndex( userState.zIndex ); + + switch( userState.drawing_mode ) { + + case "text": + fireViewEvent( "textCreated", { + nodeID: drawingObject.id() + } ); + break; + + case "sprite": + case "image": + var stroke = drawingObject.stroke(); + if ( stroke ) { + fireViewEvent( "imageLocationSelected", { + nodeID: drawingObject.id() + } ); + } + + break; + + case "line": + drawAndPropagate = true; + break; + + case "freeDraw": + case "polygon": + case "circle": + case "ellipse": + case "rect": + case "arrow": + case "thickArrow": + drawingObject.dash( userState.dashLineStyle ); + switch ( userState.fillStyle ) { + case 'noFill': + drawingObject.fill( null ); + break; + + case 'solidFill': + case 'transparentFill': + var colorRGB = Konva.Util.getRGB( userState.drawing_color ); + var alpha = ( userState.fillStyle === 'transparentFill' ? 0.5 : 1.0 ); + var rgbaText = 'rgba( ' + colorRGB.r + ', ' + colorRGB.g + ', ' + colorRGB.b + ', ' + alpha + ' )'; + drawingObject.fill( rgbaText ); + break; + + default: + break; + } + if ( ( userState.drawing_mode === "freeDraw" ) || ( userState.drawing_mode === "polygon" ) ) { + // Optimize the number of vertices + if ( simplifyJs ) { + drawingObject.points( simplifyPoints( drawingObject.points(), 1 ) ); + } + } + + drawAndPropagate = true; + break; + + default: + break; + } + + if ( drawAndPropagate ) { + drawObject( drawingObject, true ); + + // Create a node in the model so it gets replicated on all clients + propagateNodeToModel( drawing_private ); + } + }; + + // Simplify konva points + // Konva points are in an array like [x1,y1,x2,y2,...xn,yn] + function simplifyPoints( points, tolerance, highestQuality ) { + var ptarray = []; + // Convert to array of x, y points + for ( var i = 0; i < points.length; i = i+2 ) { + var point = { x: points[ i ], y: points[ i+1 ] }; + ptarray.push( point ); + } + + // Optimize and reduce line segments + if ( ptarray.length > 2 ) { + ptarray = simplifyJs.simplify( ptarray, tolerance, highestQuality ); + } + + // Convert back to x, y list + var simplifiedPts = []; + for ( var j = 0; j < ptarray.length; j++ ) { + simplifiedPts.push( ptarray[j].x ); + simplifiedPts.push( ptarray[j].y ); + } + + return simplifiedPts; + }; + + function drawUpdate( nodeID, eventData, nodeData ) { + + var node = viewDriver.state.nodes[ nodeID ]; + + if ( drawing_private === undefined || + !isValid( drawing_client ) ) { + return; + } + + if ( drawing_private.drawingObject ) { + + var eventPoint = eventData.stageRelative; + var userState = drawing_client; + var privateState = drawing_private; + var drawingObject = privateState.drawingObject; + var pointAccepted = true; + + if ( drawingObject.visible !== userState.drawing_visible ) { + drawingObject.visible = userState.drawing_visible; + } + if ( drawingObject.listening !== userState.drawing_listening ) { + drawingObject.listening = userState.drawing_listening; + } + var diffX = eventPoint[ 0 ] - privateState.initialDownPoint[ 0 ]; + var diffY = eventPoint[ 1 ] - privateState.initialDownPoint[ 1 ]; + var pos = [ privateState.initialDownPoint[ 0 ], privateState.initialDownPoint[ 1 ] ]; + var width = diffX; + var height = diffY; + var dist = Math.sqrt( ( diffX * diffX ) + ( diffY * diffY ) ); + var angleDeg = Math.atan2( diffY, diffX ) * 180.0 / Math.PI; + + // this keeps the pos as the top left corner for the + // rectangular objects + switch ( userState.drawing_mode ) { + + case "line": + case "arrow": + case "thickArrow": + case "freeDraw": + case "polygon": + case "borderRect": + case "text": + break; + + default: + if ( diffX < 0 ) { + pos[ 0 ] += diffX; + width = Math.abs( diffX ); + } + if ( diffY < 0 ) { + pos[ 1 ] += diffY; + height = Math.abs( diffY ); + } + drawingObject.position( privateState.initialDownPoint ); + drawingObject.width( width ); + drawingObject.height( height ); + break; + } + + switch ( userState.drawing_mode ) { + + case "arc": + drawingObject.angle = userState.angle ? userState.angle : 30; + if ( dist > node.drawing_width ) { + drawingObject.innerRadius( dist - node.drawing_width ); + drawingObject.outerRadius( dist ); + } + clearBeforeDraw = true; + break; + + case "ellipse": + drawingObject.radius( { "x": width * 0.5, "y": height * 0.5 } ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( null ); + clearBeforeDraw = true; + break; + + case "circle": + drawingObject.radius( dist ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( null ); + clearBeforeDraw = true; + break; + + case "line": + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.points( [ 0, 0, diffX, diffY ] ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.dash( userState.dashLineStyle ); + clearBeforeDraw = true; + break; + + case "freeDraw": + case "polygon": + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + var points = drawingObject.points(); + var isFirstStrokeOfNewLine = false; + + if ( !points || ( points.length === 0 ) ) { + points = [ 0, 0, diffX, diffY ]; + isFirstStrokeOfNewLine = true; + } + + var posX = eventPoint[ 0 ] - drawingObject.x(); + var posY = eventPoint[ 1 ] - drawingObject.y(); + + if ( isFirstStrokeOfNewLine ) { + if ( ( Math.abs( posX ) + Math.abs( posY ) ) > 0 ) { + points = [ 0, 0, posX, posY ]; + privateState[ "previousPoint" ] = [ posX, posY ]; + } else { + pointAccepted = false; + } + privateState.previousPoint = [ posX, posY ]; + } else { + var dragDiff = [ + posX - privateState.previousPoint[ 0 ], + posY - privateState.previousPoint[ 1 ] + ]; + + if ( ( Math.abs( dragDiff[ 0 ] ) + Math.abs( dragDiff[ 1 ] ) ) > 0 ) { + points.push( posX ); + points.push( posY ); + privateState.previousPoint = [ posX, posY ]; + } else { + pointAccepted = false; + } + + } + drawingObject.points( points ); + + if ( userState.drawing_mode === 'polygon' ) { + drawingObject.closed( true ); + drawingObject.fill( null ); + clearBeforeDraw = true; + } + break; + + case "regularPolygon": + // needs defining + break; + + case "ring": + if ( dist > userState.drawing_width ) { + drawingObject.innerRadius( dist - userState.drawing_width ); + drawingObject.outerRadius( dist ); + clearBeforeDraw = true; + } + break; + + case "star": + drawingObject.points( 5 ); + drawingObject.innerRadius( dist * 80 ); + drawingObject.outerRadius( dist ); + clearBeforeDraw = true; + break; + + case "wedge": + // needs defining + drawingObject.angle( userState.angle ? userState.angle : 30 ); + drawingObject.radius( dist ); + drawingObject.clockwise( false ); + clearBeforeDraw = true; + break; + + case "borderRect": + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( userState.dashLineStyle ); + clearBeforeDraw = true; + break; + + case "arrow": + case "thickArrow": + var arrowWidthMult = ( userState.drawing_mode === 'arrow' ? 3 : 8 ); + + drawingObject.x( drawingObject.position[ 0 ] ); + drawingObject.y( drawingObject.position[ 1 ] ); + + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( null ); + drawingObject.fill( null ); + drawingObject.closed( true ); + var arrowThickness = userState.drawing_width * arrowWidthMult; + var headWidth = userState.drawing_width * arrowWidthMult * 2; + var headLength = userState.drawing_width * arrowWidthMult * 2; + var arrowLength = dist; + var arrowShaft = arrowLength - headLength; + var arrowPts = [ 0, 0, 0, arrowThickness, arrowShaft, arrowThickness, arrowShaft, headWidth, arrowLength, 0, arrowShaft, (-1 * headWidth), arrowShaft, (-1 * arrowThickness), 0, (-1 * arrowThickness) ]; + drawingObject.points( arrowPts ); + drawingObject.rotation( angleDeg ); + clearBeforeDraw = true; + break; + + case "sprite": + case "image": + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( 2 ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( [ 2, 5 ] ); + drawingObject.width( width ); + drawingObject.height( height ); + drawingObject.transformsEnabled( "all" ); + drawingObject.image( null ); + clearBeforeDraw = true; + break; + + case "text": + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.size( { "width": dist, "height": drawing_client.fontSize} ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( 2 ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( [ 2, 5 ] ); + drawingObject.fill( null ); + drawingObject.rotation( angleDeg ); + clearBeforeDraw = true; + break; + + case "rect": + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( null ); + drawingObject.size( { "width": width, "height": height} ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + clearBeforeDraw = true; + break; + + default: + break; + + } + + if ( pointAccepted ) { + + // Update the view to keep pace with user input + if ( drawingObject && activelyDrawing ) { + drawObject( drawingObject, clearBeforeDraw ); + clearBeforeDraw = false; + } + } + + } + }; + + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + + function refreshState() { + for ( var id in viewDriver.state.stages ) { + renderScene( viewDriver.state.stages[ id ], true ); + } + } + + function refreshLayer( layerID ) { + var layer = viewDriver.state.nodes[ layerID ]; + if ( layer && layer.kineticObj ) { + drawObject( layer.kineticObj, true ); + } + } + + function findChild( parent, names ) { + if ( names.length > 0 ) { + var childName = names.shift(); + while ( childName === "" ) { + childName = names.shift(); + } + if ( parent.children[ childName ] ) { + if ( names.length === 0 ) { + return parent.children[ childName ]; + } else { + return this.findChild( parent.children[ childName ], names ); + } + } + else { + return undefined; + } + } + return undefined; + } + + function findSection( parentID, name ) { + var parent = viewDriver.state.nodes[ parentID ]; + + if ( parent && parent.children ) { + for ( var i = 0; i < parent.children.length; i++ ) { + if ( parent.children[ i ].indexOf( name, parentID.length ) >= 0 ) { + var childID = parent.children[ i ]; + var child = viewDriver.state.nodes[ childID ]; + return child; + } + } + } + + return undefined; + } + + function createLocalKineticNode( parentID, drawingID, objDef, implementsID, source, type, name ) { + + var extendsID = objDef.extends; + + var node = viewDriver.state.createLocalNode( parentID, drawingID, extendsID, implementsID, source, type, null, name ); + node.prototypes = []; + node.prototypes.push( extendsID ); + + node.kineticObj = createKineticObject( node, objDef.properties ); + + viewDriver.state.addNodeToHierarchy( node ); + + return node; + } + + function createKineticObject( node, config ) { + var protos = node.prototypes; + var kineticObj = undefined; + + if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { + kineticObj = new Konva.Arc( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { + kineticObj = new Konva.BaseLayer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { + kineticObj = new Konva.Canvas( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { + kineticObj = new Konva.Circle( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { + kineticObj = new Konva.Ellipse( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { + kineticObj = new Konva.FastLayer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { + kineticObj = new Konva.Group( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/drawingGroup.vwf" ) ) { + kineticObj = new Konva.Group( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { + var imageObj = new Image(); + node.scaleOnLoad = config.scaleOnLoad; + kineticObj = new Konva.Image( { + image: imageObj + } ); + if ( node.source !== undefined ) { + imageObj.src = node.source; + } + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { + kineticObj = new Konva.Layer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { + kineticObj = new Konva.Line( config || { "points": [] } ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { + kineticObj = new Konva.Path( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { + kineticObj = new Konva.Rect( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { + kineticObj = new Konva.RegularPolygon( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { + kineticObj = new Konva.Ring( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { + var imageObj = new Image(); + node.scaleOnLoad = false; + kineticObj = new Konva.Sprite( { + image: imageObj + } ); + if ( node.source !== undefined ) { + imageObj.src = node.source; + } + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { + var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; + var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; + var stageContainer = ( config && config.container ) || 'vwf-root'; + var stageWidth = ( config && config.width ) || stageWidth; + var stageHeight = ( config && config.height ) || stageHeight; + var stageDef = { + "container": stageContainer, + "width": stageWidth, + "height": stageHeight + }; + kineticObj = new Konva.Stage( stageDef ); + viewDriver.state.stages[ node.ID ] = kineticObj; + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { + kineticObj = new Konva.Star( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { + kineticObj = new Konva.Text( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { + kineticObj = new Konva.TextPath( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { + kineticObj = new Konva.Wedge( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { + kineticObj = new Konva.Shape( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { + kineticObj = new Konva.Container( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { + kineticObj = new Konva.Node( config || {} ); + } + + return kineticObj; + } + + function getPrototypes( kernel, extendsID ) { + var prototypes = []; + var id = extendsID; + + while ( id !== undefined ) { + prototypes.push( id ); + id = kernel.prototype( id ); + } + + return prototypes; + } + + function isContainerDefinition( prototypes ) { + var found = false; + if ( prototypes ) { + for ( var i = 0; i < prototypes.length && !found; i++ ) { + found = ( prototypes[i] == "http://vwf.example.com/kinetic/container.vwf" ); + } + } + return found; + } + + function findLayer( kineticObj ) { + + var layer = undefined; + var parent = kineticObj; + while ( parent !== undefined && layer === undefined ) { + if ( parent.nodeType === "Layer" ) { + layer = parent; + } + parent = parent.parent; + } + return layer; + + } + + function isChildOf( kineticObj, parentID ) { + + var foundParent = false; + var parent = kineticObj; + while ( parent !== undefined && !foundParent ) { + if ( parent.id() === parentID ) { + foundParent = true; + } + parent = parent.parent; + } + return foundParent; + } + + function propagateNodeToModel( localDrawingInfo ) { + // Update the VWF node descriptor with attributes from the intermediate Kinetic nodes used + // while editing + var drawingDef = localDrawingInfo.drawingDef; + drawingDef.properties = + createDrawingDefProperties( drawingDef.properties, localDrawingInfo.drawingObject ); + + var drawingDefChildren = drawingDef.children; + for ( var childName in drawingDefChildren ) { + var child = localDrawingInfo.drawingObject[ childName ]; + if ( !child ) { + console.error( "propagateNodeToModel: No child named '", childName, "'" ); + continue; + } + var childDef = drawingDefChildren[ childName ]; + childDef.properties = createDrawingDefProperties( childDef.properties, child ); + } + + // Create the node in the model + viewDriver.kernel.createChild( localDrawingInfo.drawingParentID, + localDrawingInfo.drawingChildName, drawingDef ); + + var action = { + type: "drawing", + drawingInfo: localDrawingInfo, + drawingDef: drawingDef + }; + action.undo = function(){ + // Delete the drawing from the model + if (this.drawingInfo) { + viewDriver.kernel.deleteChild( this.drawingInfo.drawingParentID, + this.drawingInfo.drawingChildName); + } + }; + action.redo = function(){ + if (this.drawingInfo && this.drawingDef) { + viewDriver.kernel.createChild( this.drawingInfo.drawingParentID, + this.drawingInfo.drawingChildName, this.drawingDef ); + } + }; + + fireViewEvent( "action", action ); + // Delete the private node - we no longer need it + // Remove the kinetic object from the tree and destroy the object + markPrivateDrawingNodeForDeletion(); + + // Set a VWF descriptor's `properties` to describe a Kinetic node using its attributes + function createDrawingDefProperties( startingProperties, kineticNode ) { + + var properties = $.extend( {}, startingProperties, { + "attributes": $.extend( {}, kineticNode.getAttrs() ), + } ); + + properties.image = localDrawingInfo.imageDataURL || properties.image; + + // Remove attributes related to editing with the intermediate node. + delete properties.attributes.id; + delete properties.attributes.name; + + // Ensure that `radius` is the last attribute since `width` or `height` will override + // `radius` if both are provided. + switch ( kineticNode.className ) { + case "Circle": + case "Ellipse": + delete properties.attributes.height; + delete properties.attributes.width; + break; + } + + return properties; + + } + + } + + function drawObject( kineticObject, clearBefore ) { + + if ( clearBefore ) { + + // Draw the full layer + // (we need only draw an object if it is a child of a layer - + // otherwise, it is the stage itself and doesn't need redrawing) + var layer = findLayer( kineticObject ); + layer && layer.batchDraw(); + } else if ( kineticObject.batchDraw instanceof Function ) { + kineticObject.batchDraw(); + console.log( "Warning: drawObject called on state" ); + } else { + kineticObject.draw(); + } + } + + function getDefaultProperties( drawingMode, groupParent, eventPoint ) { + + var userState = drawing_client; + + var retObj = { + "visible": 'inherit', + "listening": 'inherit', + "opacity": userState.drawing_opacity, + "index": 4 + }; + + if ( userState.shadows ) { + for ( var shadowProp in userState.shadows ) { + retObj[ shadowProp ] = userState.shadows[ shadowProp ]; + } + } + + switch( drawingMode ) { + case "sprite": + case "text": + case "image": + retObj.opacity = 1.0; + retObj.scaleOnLoad = true; + if ( drawingMode === "text" ) { + retObj.disableScaleAndRotationForSpeed = false; + } + break; + case "arrow": + case "thickArrow": + retObj.disableScaleAndRotationForSpeed = false; + break; + default: + retObj.fill = userState.drawing_color; + break; + } + + if ( groupParent ) { + retObj.x = 0; + retObj.y = 0; + retObj.position = [ 0, 0 ]; + } else { + retObj.x = eventPoint[ 0 ]; + retObj.y = eventPoint[ 1 ]; + retObj.position = eventPoint; + } + + return retObj; + } + + function createTextObject( textValue ) { + + var textCreated = false; + + // Get the location and dimensions from the border rectangle + var position = [ drawing_private.drawingObject.x(), drawing_private.drawingObject.y() ]; + var width = drawing_private.drawingObject.width(); + var height = drawing_private.drawingObject.height(); + var childID = drawing_private.drawingObject.id(); + var parentID = drawing_private.drawingObject.parent.id(); + var name = drawing_private.drawingObject.name(); + var compExtends = "http://vwf.example.com/kinetic/text.vwf"; + var shapeDef = { + "extends": compExtends, + "properties": getDefaultProperties( "text", false, position ) + }; + shapeDef.properties.rotation = drawing_private.drawingObject.rotation(); + + // Delete the border rectangle + deletePrivateNode( false ); + drawing_private.drawingDef = shapeDef; + + // Create the text object + if ( textValue && ( textValue !== "" ) ) { + private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObj; + textCreated = true; + } else { + drawing_private = {}; + private_node = undefined; + } + + return textCreated; + } + + function setImage( imageUrl ) { + + var drawingObject = drawing_private.drawingObject; + if ( !drawingObject ) { + console.error( "setImage: There is no drawing object on which to set an image" ); + return; + } + drawingObject.stroke( null ); + drawingObject.strokeEnabled( false ); + if ( imageUrl ) { + var imageObj = new Image(); + + imageObj.onload = function() { + drawing_private.imageDataURL = imageUrl; + + // Set the width and height to maintain aspect ratio + var imgAspectRatio = imageObj.width / imageObj.height; + var width = drawingObject.width(); + var height = drawingObject.height(); + + // Use the larger dimension to set the width and height + if ( width >= height ) { + height = width / imgAspectRatio; + } else { + width = height * imgAspectRatio; + } + drawingObject.width( width ); + drawingObject.height( height ); + + // Propagate the node to the model + propagateNodeToModel( drawing_private ); + }; + + imageObj.onerror = function() { + deletePrivateNode( true ); + }; + + imageObj.src = imageUrl; + } else { + deletePrivateNode( true ); + } + } + + function deletePrivateNode( fullyDelete ) { + + // Find this object's layer so we can redraw it once we have cleared the private object + var layer = findLayer( drawing_private.drawingObject ); + + clearPrivateDrawing( drawing_private ); + + if ( fullyDelete ) { + drawing_private = {}; + private_node = undefined; + } + + if ( layer ) { + layer.batchDraw(); + } + } + + function markPrivateDrawingNodeForDeletion() { + + // Mark this private drawing object for deletion + // It will be deleted when createdNode notifies us that + // the public version of the drawing has been created + var parentID = drawing_private.drawingParentID; + var nodeName = drawing_private.drawingChildName; + privateNodesToDelete[ parentID ] = privateNodesToDelete[ parentID ] || {}; + privateNodesToDelete[ parentID ][ nodeName ] = drawing_private; + + // Unset the private drawing node + drawing_private = {}; + private_node = undefined; + } + + function isDrawingObject( nodeID ) { + var drawingObject = drawing_private && drawing_private.drawingObject; + return drawingObject && ( nodeID === drawingObject.id() ); + } + + function clearPrivateDrawing( privateDrawingState ) { + privateDrawingState.drawingObject.remove(); + privateDrawingState.drawingObject.destroy(); + privateDrawingState.drawingObject = null; + privateDrawingState.imageDataURL = null; + } + + function fireViewEvent( eventName, parameters ) { + var eventHandler = eventHandlers[ eventName ]; + if ( typeof eventHandler === "function" ) { + eventHandler( parameters ); + } + } -}); \ No newline at end of file +} ); diff --git a/support/client/lib/vwf/view/mil-sym.js b/support/client/lib/vwf/view/mil-sym.js index 5454f60c0..e47bcf0bf 100644 --- a/support/client/lib/vwf/view/mil-sym.js +++ b/support/client/lib/vwf/view/mil-sym.js @@ -14,9 +14,15 @@ /// @module vwf/view/test /// @requires vwf/view -define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { +define( [ "module", "vwf/view", "mil-sym/cws", "jquery" ], function( module, view, cws, $ ) { var self; + var eventHandlers = {}; + var _rendererReady = false; + var _graphicFormats = { "KML": 0, + "GeoJSON": 2, + "GeoCanvas": 3, + "GeoSVG": 6}; return view.load( module, { @@ -45,6 +51,7 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { rs.setSymbologyStandard( rs.Symbology_2525C ); rs.setTextOutlineWidth( 1 ); + pollForFontsLoaded(); }, // createdNode: function( nodeID, childID, childExtendsID, childImplementsIDs, @@ -95,24 +102,8 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { // -- calledMethod ----------------------------------------------------------------------------- - calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { - if ( nodeID === this.kernel.application() ) { - var clientThatCalledMethod = this.kernel.client(); - var me = this.kernel.moniker(); - switch ( methodName ) { - case "insertUnits": - if ( clientThatCalledMethod === me ) { - addInsertableUnits( methodParameters[ 0 ] ); - } - break; - case "getUnitSymbol": - if ( clientThatCalledMethod === me ) { - getUnitSymbol( methodParameters[ 0 ], methodParameters[ 1 ], methodParameters[ 2 ], methodParameters[ 3 ], methodParameters[ 4 ], methodParameters[ 5 ] ); - } - break; - } - } - }, + // calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { + // }, // -- firedEvent ----------------------------------------------------------------------------- @@ -124,7 +115,18 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { // ticked: function() { // }, - + renderUnitSymbol: renderUnitSymbol, + rendererReady: rendererReady, + addInsertableUnits: addInsertableUnits, + getUpdatedUnitSymbolID: getUpdatedUnitSymbolID, + getMissionGraphicDefinition: getMissionGraphicDefinition, + renderMissionGraphic: renderMissionGraphic, + getDefaultSymbolFillColor: getDefaultSymbolFillColor, + getUnitImage: getUnitImage, + + on: function( eventName, callback ) { + eventHandlers[ eventName ] = callback; + } } ); function addInsertableUnits( units ) { @@ -185,7 +187,7 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { }; description = cws.description( fullName, unit.tag ); - actualName = cws.decode( cws.postTag( fullName, unit.tag ) ).replace( ".", " " ); + actualName = cws.descriptionFromSymbolId( unit.symbolID ) || cws.decode( cws.postTag( fullName, unit.tag ) ).replace( ".", " " ); unitDef = { "fullName": fullName, @@ -195,129 +197,147 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { "description": description, "tag": unit.tag, "symbolID": unit.symbolID, - "image": image + "image": image, + "specialModifiers": unit.specialModifiers }; - self.kernel.fireEvent( appID, "insertableUnitAdded", [ unitDef ] ); + fireViewEvent( "insertableUnitAdded", { + unit: unitDef + } ); } } else { self.logger.warnx( "Unable to find: " + unitsToAdd[ i ] + " in " + battleDivision ); } } } - - self.kernel.fireEvent( appID, "unitLoadingComplete", [ true ] ); + fireViewEvent( "unitLoadingComplete" ); } } - function getUnitSymbol( symbolID, affiliation, echelonID, modifierList, unit, options ) { - var updatedUnit = {}; + function renderUnitSymbol( symbolID, affiliation, echelonID, modifierList, unit ) { + + if ( !cws ) { + self.logger.errorx( "cws is undefined - unable to render unit icon" ); + return; + } + + var updatedUnit = $.extend( true, {}, unit ); var appID = self.kernel.application(); var renderer = armyc2.c2sd.renderer; var msa = renderer.utilities.MilStdAttributes; var rs = renderer.utilities.RendererSettings; var symUtil = renderer.utilities.SymbolUtilities; - var modifiers = {}; + + // Set affiliation in unit symbol id + updatedUnit.symbolID = cws.addAffiliationToSymbolId( symbolID, affiliation ); + + // Add echelon + if ( echelonID != undefined ) { + updatedUnit.symbolID = cws.addEchelonToSymbolId( updatedUnit.symbolID, echelonID ); + } + + // Define the list of valid modifiers + updatedUnit.validModifiers = [ "pixelSize", "iconcolor", "lineColor", "fillColor" ]; + var aliases = Object.keys( cws.aliasModifiers ); + for ( var i = 0; i < aliases.length; i++ ) { - self.logger.info(" Mil-SymJS SymbolID before echelon and affiliation: " + symbolID ); - - if ( cws ) { - updatedUnit = unit; + var alias = aliases[ i ]; + var modObj = cws.aliasModifiers[ alias ]; - // Set affiliation in unit symbol id - updatedUnit.symbolID = cws.addAffiliationToSymbolId( symbolID, affiliation ); - - // Add echelon - if ( echelonID != undefined ) { - self.logger.info(" Mil-SymJS Adding Echelon: " + echelonID ); - updatedUnit.symbolID = cws.addEchelonToSymbolId( updatedUnit.symbolID, echelonID ); - self.logger.info(" Mil-SymJS SymbolID after echelon and affiliation: " + updatedUnit.symbolID ); - } - - // Add modifiers - modifiers[ msa.PixelSize ] = "60"; - for ( var prop in modifierList ) { - if (modifierList[prop] != undefined) { - switch ( prop ) { - case "pixelSize": - case "PixelSize": - modifiers[ msa.PixelSize ] = modifierList[ prop ]; - break; - case "icon": - case "Icon": - modifiers[ msa.Icon ] = modifierList[ prop ]; - break; - default: - modifiers[ prop ] = modifierList[ prop ]; - break; - } - } + var modifier = renderer.utilities.ModifiersUnits[ modObj.modifier ]; + // Query mil-sym to see if this symbol has this modifier + if ( symUtil.hasModifier( updatedUnit.symbolID, + modifier, + rs.getSymbologyStandard() ) ) { + // Add to the array of valid modifiers + updatedUnit.validModifiers.push( alias ); } - - // Define the list of valid modifiers - updatedUnit.validModifiers = []; - - updatedUnit.validModifiers.push( "pixelSize" ); - var aliases = Object.keys( cws.aliasModifiers ); - for ( var i = 0; i < aliases.length; i++ ) { - - var alias = aliases[ i ]; - var modObj = cws.aliasModifiers[ alias ]; - - var modifier = renderer.utilities.ModifiersUnits[ modObj.modifier ]; - if ( symUtil.hasModifier( updatedUnit.symbolID, - modifier, - rs.getSymbologyStandard() ) ) { - // Add to the array of valid modifiers - updatedUnit.validModifiers.push( alias ); - } - } - - // Render the unit image - - // if icon == true then you'll get no modifiers - modifiers[ msa.Icon ] = false; - - modifiers[ msa.SymbologyStandard ] = rs.Symbology_2525C; - var img = renderer.MilStdIconRenderer.Render( updatedUnit.symbolID, modifiers ); - if ( img ) { - var imgBounds = img.getImageBounds(); - updatedUnit.image["selected"] = { - "url": img.toDataUrl(), - "width": imgBounds.width, - "height": imgBounds.height + } + // If there is a special modifier defined for this symbol, + // add it as a valid modifier + for ( var j = 0; j < ( updatedUnit.specialModifiers || [] ).length; j++ ) { + updatedUnit.validModifiers.push( updatedUnit.specialModifiers[ j ] ); + } + + // Gather the modifiers that will be passed into the render function + var modifiers = {}; + modifiers[ msa.PixelSize ] = "60"; // default + for ( var prop in modifierList ) { + if (modifierList[prop] != undefined) { + switch ( prop.toLowerCase() ) { + case "pixelsize": + modifiers[ msa.PixelSize ] = modifierList[ prop ]; + break; + case "linecolor": + modifiers[ msa.LineColor ] = modifierList[ prop ]; + break; + case "fillcolor": + modifiers[ msa.FillColor ] = modifierList[ prop ]; + break; + case "iconcolor": + modifiers[ msa.IconColor ] = modifierList[ prop ]; + break; + case "icon": + // We ignore this value - it must be "false" or we'll get no modifiers + break; + default: + modifiers[ prop ] = modifierList[ prop ]; + break; } } } + modifiers[ msa.Icon ] = false; // Override whatever value might have been passed in + modifiers[ msa.SymbologyStandard ] = rs.Symbology_2525C; - var unitEvent = "selectedUnitSymbolRendered"; - if ( (options.request) && (options.unitID) ) { - switch ( options.request ) { - case "addQuickUnit": - unitEvent = "quickUnitAdded"; - self.kernel.fireEvent( appID, unitEvent, [ options.unitID, updatedUnit ] ); - break; - case "addFavoriteUnit": - unitEvent = "favoriteUnitAdded"; - self.kernel.fireEvent( appID, unitEvent, [ options.unitID, updatedUnit ] ); - break; - case "addRecentUnit": - var unitEvent = "recentUnitAdded"; - self.kernel.fireEvent( appID, unitEvent, [ options.unitID, updatedUnit ] ); - break; - case "renderSelectedUnit": - default: - // If nothing else, make this the selected unit - self.kernel.fireEvent( appID, unitEvent, [ updatedUnit ] ); - break; + // Render the image + var img = renderer.MilStdIconRenderer.Render( updatedUnit.symbolID, modifiers ); + if ( img ) { + updatedUnit.image = updatedUnit.image || {}; + var imgBounds = img.getImageBounds(); + updatedUnit.image.selected = { + "url": img.toDataUrl(), + "width": imgBounds.width, + "height": imgBounds.height, + "center": img.getCenterPoint() } } - else { - self.kernel.fireEvent( appID, unitEvent, [ updatedUnit ] ); - } + + return updatedUnit; } + function getUpdatedUnitSymbolID( symbolID, affiliation, echelonID, status, mobility ) { + + if ( !cws ) { + self.logger.errorx( "cws is undefined - unable to render unit icon" ); + return; + } + + var updatedUnitSymbolID = symbolID; + + // Set affiliation in unit symbol id + if ( !!affiliation ) { + updatedUnitSymbolID = cws.addAffiliationToSymbolId( symbolID, affiliation ); + } + + // Add echelon + if ( !!echelonID ) { + updatedUnitSymbolID = cws.addEchelonToSymbolId( updatedUnitSymbolID, echelonID ); + } + + // Add status + if ( !!status ) { + updatedUnitSymbolID = cws.addUnitStatusToSymbolId( updatedUnitSymbolID, status ); + } + + // Add mobility + if ( !!mobility ) { + updatedUnitSymbolID = cws.addMobilityToSymbolId( updatedUnitSymbolID, mobility ); + } + + return updatedUnitSymbolID; + } + function getUnitImage( symbolID ) { var renderer = armyc2.c2sd.renderer; var msa = renderer.utilities.MilStdAttributes; @@ -336,4 +356,105 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { } } + function renderMissionGraphic( symbolID, affiliation, modifiers, controlPoints, bounds, msnGfx, format ) { + + if ( !cws ) { + self.logger.errorx( "cws is undefined - unable to render unit icon" ); + return; + } + + var rendererMP = sec.web.renderer.SECWebRenderer; + var scale = 100.0; + var appID = self.kernel.application(); + var renderer = armyc2.c2sd.renderer; + var msa = renderer.utilities.MilStdAttributes; + var rs = renderer.utilities.RendererSettings; + var symUtil = renderer.utilities.SymbolUtilities; + var milSymControlPts = convertXYVertexArrayToMilSymControlPts( controlPoints ); + + // Set affiliation in symbol id + symbolCode = cws.addAffiliationToSymbolId( symbolID, affiliation ); + + // Convert modifiers to actual names and types + var actualNameModifiers = {}; + for ( mod in modifiers ) { + var modObj = cws.modifierByAlias( mod ); + var modActualName = self.state.getModifierActualName( modObj ); + actualNameModifiers[ modActualName ] = self.state.convertModifierValue( modObj, modifiers[ mod ] ); + } + + var img = rendererMP.RenderSymbol2D( "ID", "Name", "Description", symbolCode, milSymControlPts, bounds[0], bounds[1], null, actualNameModifiers, format ); + + return img; + } + + // Take an array [x1,y1,xy,y2,...xn,yn] and convert to + // mil-sym control point string "x1,y1 x2,y2 ... xn,yn" + function convertXYVertexArrayToMilSymControlPts( xyVertexPts ) { + var milSymControlPts = ""; + // xyVertexPts is an array where even numbered elements are x and odd are y + // mil-sym style is a string where pairs of x and y are separated by spaces + for ( var i = 0; i < xyVertexPts.length; i=i+2 ) { + milSymControlPts = milSymControlPts + xyVertexPts[i] + "," + xyVertexPts[i+1]; + if ( i < xyVertexPts.length-2 ) { + milSymControlPts = milSymControlPts + " "; + } + } + + return milSymControlPts; + } + + function getMissionGraphicDefinition( category, fullName ) { + var missionGraphicDef = {}; + + if ( !cws ) { + self.logger.errorx( "cws is undefined - unable to retrieve object" ); + return; + } + + if ( !!category && !!cws[category] ) { + if ( !!fullName && !!cws[category][fullName] ) { + missionGraphicDef = cws[category][fullName]; + } else { + missionGraphicDef = cws[category]; + } + } + + return missionGraphicDef; + } + + function fireViewEvent( eventName, parameters ) { + var eventHandler = eventHandlers[ eventName ]; + if ( typeof eventHandler === "function" ) { + eventHandler( parameters ); + } + } + + function pollForFontsLoaded() { + if ( armyc2.c2sd.renderer.utilities.RendererUtilities.fontsLoaded() ) { + _rendererReady = true; + fireViewEvent( "milSymRendererReady" ); + } else { + setTimeout( pollForFontsLoaded, 500 ); + } + } + + function rendererReady() { + return _rendererReady; + } + + function getDefaultSymbolFillColor( symbolID, affiliation ) { + var color = '000000'; + + /* TODO: handle different color sets depending upon symbol type */ + + var colors = { friendly: '80E0FF', + hostile: 'FF8080', + neutral: 'AAFFAA', + unknown: 'FFFF80' }; + color = colors[ affiliation ]; + + return color; + } + } ); diff --git a/support/client/lib/vwf/view/mocha.js b/support/client/lib/vwf/view/mocha.js new file mode 100644 index 000000000..2a9574be2 --- /dev/null +++ b/support/client/lib/vwf/view/mocha.js @@ -0,0 +1,50 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under +// the License. + +/// @module vwf/view/mocha +/// @requires vwf/view + +define( [ + "module", "vwf/view", "jquery", "vwf/view/mocha/mocha", "vwf/view/chai/chai", "test/index" +], function( module, view, $, mocha, chai, test ) { + + // vwf/view/mocha.js is a driver used for unit tests based on mocha + chai. + + return view.load( module, { + + // == Module Definition ==================================================================== + + // -- initialize --------------------------------------------------------------------------- + + initialize: function() { + + // Initialize mocha and chai + mocha.setup( "bdd" ); + window.assert = chai.assert; + + // Load the stylesheet and create the mocha div in which it will place its results + $( "body" ) + .append( "" ) + .append( "
" ); + }, + + initializedNode: function( nodeID, childID ) { + if ( childID === vwf_view.kernel.application() ) { + test(); + window.runTests = function() { + $( "body" ).css( "overflowY", "scroll" ); + mocha.run(); + }; + } + } + + } ); + +} ); diff --git a/support/client/lib/vwf/view/mocha/CHANGELOG.md b/support/client/lib/vwf/view/mocha/CHANGELOG.md new file mode 100644 index 000000000..b659a4efa --- /dev/null +++ b/support/client/lib/vwf/view/mocha/CHANGELOG.md @@ -0,0 +1,1489 @@ +# 3.2.0 / 2016-11-24 + +## :newspaper: News + +### Mocha is now a JS Foundation Project! + +Mocha is proud to have joined the [JS Foundation](https://js.foundation). For more information, [read the announcement](https://js.foundation/announcements/2016/10/17/Linux-Foundation-Unites-JavaScript-Community-Open-Web-Development/). + +### Contributor License Agreement + +Under the foundation, all contributors to Mocha must sign the [JS Foundation CLA](https://js.foundation/CLA/) before their code can be merged. When sending a PR--if you have not already signed the CLA--a friendly bot will ask you to do so. + +Mocha remains licensed under the [MIT license](https://github.com/mochajs/mocha/blob/master/LICENSE). + +## :bug: Bug Fix + +- [#2535]: Fix crash when `--watch` encounters broken symlinks ([@villesau]) +- [#2593]: Fix (old) regression; incorrect symbol shown in `list` reporter ([@Aldaviva]) +- [#2584]: Fix potential error when running XUnit reporter ([@vobujs]) + +## :tada: Enhancement + +- [#2294]: Improve timeout error messaging ([@jeversmann], [@boneskull]) +- [#2520]: Add info about `--inspect` flag to CLI help ([@ughitsaaron]) + +## :nut_and_bolt: Other + +- [#2570]: Use [karma-mocha](https://npmjs.com/package/karma-mocha) proper ([@boneskull]) +- Licenses updated to reflect new copyright, add link to license and browser matrix to `README.md` ([@boneskull], [@ScottFreeCode], [@dasilvacontin]) + +[#2294]: https://github.com/mochajs/mocha/issues/2294 +[#2535]: https://github.com/mochajs/mocha/issues/2535 +[#2520]: https://github.com/mochajs/mocha/pull/2520 +[#2593]: https://github.com/mochajs/mocha/pull/2593 +[#2584]: https://github.com/mochajs/mocha/issues/2584 +[#2570]: https://github.com/mochajs/mocha/issues/2570 +[@Aldaviva]: https://github.com/Aldaviva +[@jeversmann]: https://github.com/jeversmann +[@ughitsaaron]: https://github.com/ughitsaaron +[@villesau]: https://github.com/villesau +[@vobujs]: https://github.com/vobujs + +Thanks to all our contributors, sponsors and backers! Keep on the lookout for a public roadmap and new contribution guide coming soon. + +# 3.1.2 / 2016-10-10 + +## :bug: Bug Fix + +- [#2528]: Recovery gracefully if an `Error`'s `stack` property isn't writable ([@boneskull]) + +[#2528]: https://github.com/mochajs/mocha/issues/2528 + +# 3.1.1 / 2016-10-09 + +## :bug: Bug Fix + +- [#1417]: Don't report `done()` was called multiple times when it wasn't ([@frankleonrose]) + +## :nut_and_bolt: Other + +- [#2490]: Lint with [semistandard](https://npmjs.com/package/semistandard) config ([@makepanic]) +- [#2525]: Lint all `.js` files ([@boneskull]) +- [#2524]: Provide workaround for developers unable to run browser tests on macOS Sierra ([@boneskull]) + +[#1417]: https://github.com/mochajs/mocha/issues/1417 +[#2490]: https://github.com/mochajs/mocha/issues/2490 +[#2525]: https://github.com/mochajs/mocha/issues/2525 +[#2524]: https://github.com/mochajs/mocha/issues/2524 +[@makepanic]: https://github.com/makepanic +[@frankleonrose]: https://github.com/frankleonrose + +# 3.1.0 / 2016-09-27 + +## :tada: Enhancement + +- [#2357]: Support `--inspect` on command-line ([@simov]) +- [#2194]: Human-friendly error if no files are matched on command-line ([@Munter]) +- [#1744]: Human-friendly error if a Suite has no callback (BDD/TDD only) ([@anton]) + +## :bug: Bug Fix + +- [#2488]: Fix case in which *variables beginning with lowercase "D"* may not have been reported properly as global leaks ([@JustATrick]) :laughing: +- [#2465]: Always halt execution in async function when `this.skip()` is called ([@boneskull]) +- [#2445]: Exits with expected code 130 when `SIGINT` encountered; exit code can no longer rollover at 256 ([@Munter]) +- [#2315]: Fix uncaught TypeError thrown from callback stack ([@1999]) +- Fix broken `only()`/`skip()` in IE7/IE8 ([@boneskull]) +- [#2502]: Fix broken stack trace filter on Node.js under Windows ([@boneskull]) +- [#2496]: Fix diff output for objects instantiated with `String` constructor ([more](https://youtrack.jetbrains.com/issue/WEB-23383)) ([@boneskull]) + +[#2496]: https://github.com/mochajs/mocha/issues/2496 +[#2502]: https://github.com/mochajs/mocha/issues/2502 +[#2315]: https://github.com/mochajs/mocha/issues/2315 +[#2445]: https://github.com/mochajs/mocha/pull/2445 +[#2465]: https://github.com/mochajs/mocha/issues/2465 +[#2488]: https://github.com/mochajs/mocha/issues/2488 +[#1744]: https://github.com/mochajs/mocha/issues/1744 +[#2194]: https://github.com/mochajs/mocha/issues/2194 +[#2357]: https://github.com/mochajs/mocha/issues/2357 +[@1999]: https://github.com/1999 +[@JustATrick]: https://github.com/JustATrick +[@anton]: https://github.com/anton +[@simov]: https://github.com/simov + +# 3.0.2 / 2016-08-08 + +## :bug: Bug Fix + +- [#2424]: Fix error loading Mocha via Require.js ([@boneskull]) +- [#2417]: Fix execution of *deeply* nested `describe.only()` suites ([@not-an-aardvark]) +- Remove references to `json-cov` and `html-cov` reporters in CLI ([@boneskull]) + +[#2417]: https://github.com/mochajs/mocha/issues/2417 +[#2424]: https://github.com/mochajs/mocha/issues/2424 + +# 3.0.1 / 2016-08-03 + +## :bug: Bug Fix + +- [#2406]: Restore execution of nested `describe.only()` suites ([@not-an-aardvark]) + +[#2406]: https://github.com/mochajs/mocha/issues/2406 +[@not-an-aardvark]: https://github.com/not-an-aardvark + +# 3.0.0 / 2016-07-31 + +## :boom: Breaking Changes + +- :warning: Due to the increasing difficulty of applying security patches made within its dependency tree, as well as looming incompatibilities with Node.js v7.0, **Mocha no longer supports Node.js v0.8**. +- :warning: **Mocha may no longer be installed by versions of `npm` less than `1.4.0`.** Previously, this requirement only affected Mocha's development dependencies. In short, this allows Mocha to depend on packages which have dependencies fixed to major versions (`^`). +- `.only()` is no longer "fuzzy", can be used multiple times, and generally just works like you think it should. :joy: +- To avoid common bugs, when a test injects a callback function (suggesting asynchronous execution), calls it, *and* returns a `Promise`, Mocha will now throw an exception: + + ```js + const assert = require('assert'); + + it('should complete this test', function (done) { + return new Promise(function (resolve) { + assert.ok(true); + resolve(); + }) + .then(done); + }); + ``` + + The above test will fail with `Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.`. +- When a test timeout value *greater than* `2147483648` is specified in any context (`--timeout`, `mocha.setup()`, per-suite, per-test, etc.), the timeout will be *disabled* and the test(s) will be allowed to run indefinitely. This is equivalent to specifying a timeout value of `0`. See [MDN](https://developer.mozilla.org/docs/Web/API/WindowTimers/setTimeout#Maximum_delay_value) for reasoning. +- The `dot` reporter now uses more visually distinctive characters when indicating "pending" and "failed" tests. +- Mocha no longer supports [component](https://www.npmjs.com/package/component). +- The long-forsaken `HTMLCov` and `JSONCov` reporters--and any relationship to the "node-jscoverage" project--have been removed. +- `spec` reporter now omits leading carriage returns (`\r`) in non-TTY environment. + +## :tada: Enhancements + +- [#808]: Allow regular-expression-like strings in `--grep` and browser's `grep` querystring; enables flags such as `i` for case-insensitive matches and `u` for unicode. ([@a8m]) +- [#2000]: Use distinctive characters in `dot` reporter; `,` will denote a "pending" test and `!` will denote a "failing" test. ([@elliottcable]) +- [#1632]: Throw a useful exception when a suite or test lacks a title. ([@a8m]) +- [#1481]: Better `.only()` behavior. ([@a8m]) +- [#2334]: Allow `this.skip()` in async tests and hooks. ([@boneskull]) +- [#1320]: Throw a useful exception when test resolution method is overspecified. ([@jugglinmike]) +- [#2364]: Support `--preserve-symlinks`. ([@rosswarren]) + +## :bug: Bug Fixes + +- [#2259]: Restore ES3 compatibility. Specifically, support an environment lacking `Date.prototype.toISOString()`, `JSON`, or has a non-standard implementation of `JSON`. ([@ndhoule], [@boneskull]) +- [#2286]: Fix `after()` failing to execute if test skipped using `this.skip()` in `beforeEach()`; no longer marks the entire suite as "pending". ([@dasilvacontin], [@boneskull]) +- [#2208]: Fix function name display in `markdown` and `html` (browser) reporters. ([@ScottFreeCode]) +- [#2299]: Fix progress bar in `html` (browser) reporter. ([@AviVahl]) +- [#2307]: Fix `doc` reporter crashing when test fails. ([@jleyba]) +- [#2323]: Ensure browser entry point (`browser-entry.js`) is published to npm (for use with bundlers). ([@boneskull]) +- [#2310]: Ensure custom reporter with an absolute path works in Windows. ([@silentcloud]) +- [#2311]: Fix problem wherein calling `this.slow()` without a value would blast any previously set value. ([@boneskull]) +- [#1813]: Ensure Mocha's own test suite will run in Windows. ([@tswaters], [@TimothyGu], [@boneskull]) +- [#2317]: Ensure all interfaces are displayed in `--help` on CLI. ([@ScottFreeCode]) +- [#1644]: Don't exhibit undefined behavior when calling `this.timeout()` with very large values ([@callumacrae], [@boneskull]) +- [#2361]: Don't truncate name of thrown anonymous exception. ([@boneskull]) +- [#2367]: Fix invalid CSS. ([@bensontrent]) +- [#2401]: Remove carriage return before each test line in spec reporter. ([@Munter]) + +## :nut_and_bolt: Other + +- Upgrade production dependencies to address security advisories (and because now we can): `glob`, `commander`, `escape-string-regexp`, +and `supports-color`. ([@boneskull], [@RobLoach]) +- Add Windows to CI. ([@boneskull], [@TimothyGu]) +- Ensure appropriate `engines` field in `package.json`. ([@shinnn], [@boneskull]) +- [#2348]: Upgrade ESLint to v2 ([@anthony-redfox]) + +We :heart: our [backers and sponsors](https://opencollective.com/mochajs)! + +:shipit: + +[#2401]: https://github.com/mochajs/mocha/pull/2401 +[#2348]: https://github.com/mochajs/mocha/issues/2348 +[#808]: https://github.com/mochajs/mocha/issues/808 +[#2361]: https://github.com/mochajs/mocha/pull/2361 +[#2367]: https://github.com/mochajs/mocha/pull/2367 +[#2364]: https://github.com/mochajs/mocha/pull/2364 +[#1320]: https://github.com/mochajs/mocha/pull/1320 +[#2307]: https://github.com/mochajs/mocha/pull/2307 +[#2259]: https://github.com/mochajs/mocha/pull/2259 +[#2208]: https://github.com/mochajs/mocha/pull/2208 +[#2299]: https://github.com/mochajs/mocha/pull/2299 +[#2286]: https://github.com/mochajs/mocha/issues/2286 +[#1644]: https://github.com/mochajs/mocha/issues/1644 +[#2310]: https://github.com/mochajs/mocha/issues/2310 +[#2311]: https://github.com/mochajs/mocha/issues/2311 +[#2323]: https://github.com/mochajs/mocha/issues/2323 +[#2000]: https://github.com/mochajs/mocha/pull/2000 +[#1632]: https://github.com/mochajs/mocha/issues/1632 +[#1813]: https://github.com/mochajs/mocha/issues/1813 +[#2334]: https://github.com/mochajs/mocha/issues/2334 +[#2317]: https://github.com/mochajs/mocha/issues/2317 +[#1481]: https://github.com/mochajs/mocha/issues/1481 +[@elliottcable]: https://github.com/elliottcable +[@RobLoach]: https://github.com/robloach +[@AviVahl]: https://github.com/avivahl +[@silentcloud]: https://github.com/silentcloud +[@tswaters]: https://github.com/tswaters +[@jleyba]: https://github.com/jleyba +[@TimothyGu]: https://github.com/timothygu +[@callumacrae]: https://github.com/callumacrae +[@shinnn]: https://github.com/shinnn +[@bensontrent]: https://github.com/bensontrent +[@jugglinmike]: https://github.com/jugglinmike +[@rosswarren]: https://github.com/rosswarren +[@anthony-redfox]: https://github.com/anthony-redfox +[@Munter]: https://github.com/munter + +# 2.5.3 / 2016-05-25 + +- [#2112] - Fix HTML reporter regression causing duplicate error output ([@danielstjules] via 6d24063) +- [#2119] - Make HTML reporter failure/passed links preventDefault to avoid SPA's hash navigation ([@jimenglish81] via 9e93efc) + +[@danielstjules]: https://github.com/danielstjules +[@jimenglish81]: https://github.com/jimenglish81 +[#2112]: https://github.com/mochajs/mocha/pull/2112 +[#2119]: https://github.com/mochajs/mocha/pull/2119 + +# 2.5.2 / 2016-05-24 + +- [#2178] - Avoid double and triple xUnit XML escaping ([@graingert] via 49b5ff1) + +[@graingert]: https://github.com/graingert +[#2178]: https://github.com/mochajs/mocha/pull/2178 + +# 2.5.1 / 2016-05-23 + +- Fix [to-iso-string](https://npmjs.com/package/to-iso-string) dependency ([@boneskull] via bd9450b) + +Thanks @entertainyou, @SimenB, @just-paja for the heads-up. + +# 2.5.0 / 2016-05-23 + +> This has been awhile coming! We needed to feel confident that the next release wouldn't break browser compatibility (e.g. the last few patch releases). +> +> ### Browser Tests in CI +> +> We now run unit tests against PhantomJS v1.x and an assortment of browsers on [SauceLabs](https://saucelabs.com), including: +> - Internet Explorer v8.0 +> - Chrome (latest) +> - Firefox (latest) +> - Safari (latest) +> - Microsoft Edge (latest) +> +> To accomplish this, we now run Mocha's unit tests (and a handful of integration tests) via [Karma](https://npmjs.com/package/karma) and a modified [karma-mocha](https://npmjs.com/package/karma-mocha). Along the way, we had to solve issue [#880] (apologies to @mderijcke and @sukima who had PRs addressing this), as well as replace most usages of [should](https://npmjs.com/package/should) with [expect.js](https://npmjs.com/package/expect.js) for IE8. +> +> Going forward, when sending PRs, your code will *only* run against PhantomJS v1.x (and not hit SauceLabs) [because security](https://docs.travis-ci.com/user/pull-requests/#Security-Restrictions-when-testing-Pull-Requests). +> +> ### Node.js 6.x +> Node.js 6.x "just worked" before, but now it's in the CI matrix, so it's "officially" supported. Mocha *still retains support* for Node.js 0.8.x. +> +> ### "Minor" Release +> You'll see mostly bug fixes below, but also a couple features--as such, it's a "minor" release. +> +> ### TYVM +> +> Thanks to everyone who contributed, and our fabulous [sponsors and backers](https://opencollective.com/mochajs)! + +- [#2079] - Add browser checks to CI; update [browserify](https://npmjs.com/package/browserify) to v13.0.0 ([@dasilvacontin], [@ScottFreeCode], [@boneskull] via c04c1d7, 0b1e9b3, 0dde0fa, f8a3d86, 9e8cbaa) +- [#880] - Make Mocha browserifyable ([@boneskull] via 524862b) +- [#2121] - Update [glob](https://npmjs.com/package/glob) to v3.2.11 ([@astorije] via 7920fc4) +- [#2126] - Fix dupe error messages in stack trace filter ([@Turbo87] via 4301caa) +- [#2109] - Fix certain diffs when objects cannot be coerced into primitives ([@joshlory] via 61fbb7f) +- [#1827] - Fix TWBS/`mocha.css` collisions ([@irnc] via 0543798) +- [#1760], [#1936] - Fix `this.skip()` in HTML reporter ([@mislav] via cb4248b) +- [#2115] - Fix exceptions thrown from hooks in HTML reporter ([@danielstjules] via e290bc0) +- [#2089] - Handle Symbol values in `util.stringify()` ([@ryym] via ea61d05) +- [#2097] - Fix diff for objects overriding `Object.prototype.hasOwnProperty` ([@mantoni] via b20fdfe) +- [#2101] - Properly handle non-string "messages" thrown from assertion libraries ([@jkimbo] via 9c41051) +- [#2124] - Update [growl](https://npmjs.com/package/growl) ([@benjamine] via 9ae6a85) +- [#2162], [#2205] - JSDoc fixes ([@OlegTsyba] via 8031f20, [@ScottFreeCode] via f83b1d9) +- [#2132] - Remove Growl-related cruft ([@julienw] via 00d6469) +- [#2172] - Add [OpenCollective](https://opencollective.com) badge, sponsors & backers ([@xdamman], [@boneskull] via caee94f) +- [#1841] - Add new logo, banner assets ([@dasilvacontin] via 00fd0e1) +- [#2214] - Update `README.md` header ([@dasilvacontin] via c0f9be2) +- [#2236] - Better checks for Node.js v0.8 compatibility in CI ([@dasilvacontin] via ba5637d) +- [#2239] - Add Node.js v6.x to CI matrix ([@boneskull] via 3904da4) + +[#880]: https://github.com/mochajs/mocha/issues/880 +[#1841]: https://github.com/mochajs/mocha/pull/1841 +[#2239]: https://github.com/mochajs/mocha/issues/2239 +[#2153]: https://github.com/mochajs/mocha/pull/2153 +[#2214]: https://github.com/mochajs/mocha/pull/2214 +[#2236]: https://github.com/mochajs/mocha/pull/2236 +[#2079]: https://github.com/mochajs/mocha/issues/2079 +[#2231]: https://github.com/mochajs/mocha/pull/2231 +[#2089]: https://github.com/mochajs/mocha/issues/2089 +[#2097]: https://github.com/mochajs/mocha/pull/2097 +[#1760]: https://github.com/mochajs/mocha/issues/1760 +[#1936]: https://github.com/mochajs/mocha/issues/1936 +[#2115]: https://github.com/mochajs/mocha/pull/2115 +[#1827]: https://github.com/mochajs/mocha/pull/1827 +[#2101]: https://github.com/mochajs/mocha/pull/2101 +[#2124]: https://github.com/mochajs/mocha/pull/2124 +[#2109]: https://github.com/mochajs/mocha/issues/2109 +[#2162]: https://github.com/mochajs/mocha/pull/2162 +[#2132]: https://github.com/mochajs/mocha/issues/2132 +[#2126]: https://github.com/mochajs/mocha/issues/2126 +[#2121]: https://github.com/mochajs/mocha/issues/2121 +[#2205]: https://github.com/mochajs/mocha/pull/2205 +[#2172]: https://github.com/mochajs/mocha/pull/2172 +[@xdamman]: https://github.com/xdamman +[@Turbo87]: https://github.com/Turbo87 +[@OlegTsyba]: https://github.com/OlegTsyba +[@ryym]: https://github.com/ryym +[@mantoni]: https://github.com/mantoni +[@mislav]: https://github.com/mislav +[@irnc]: https://github.com/irnc +[@jkimbo]: https://github.com/jkimbo +[@benjamine]: https://github.com/benjamine +[@joshlory]: https://github.com/joshlory +[@julienw]: https://github.com/julienw +[@ScottFreeCode]: https://github.com/ScottFreeCode +[@astorije]: https://github.com/astorije +[@dasilvacontin]: https://github.com/dasilvacontin + +2.4.5 / 2016-01-28 +================== + +* [#2080], [#2078], [#2072], [#2073], [#1200] - Revert changes to console colors in changeset [1192914](https://github.com/mochajs/mocha/commit/119291449cd03a11cdeda9e37cf718a69a012896) and subsequent related changes thereafter. Restores compatibility with IE8 & PhantomJS. See also [mantoni/mochify.js#129](https://github.com/mantoni/mochify.js/issues/129) and [openlayers/ol3#4746](https://github.com/openlayers/ol3/pull/4746) ([@boneskull]) +* [#2082] - Fix several test assertions ([@mislav]) + +[#1200]: https://github.com/mochajs/mocha/issues/1200 +[#2082]: https://github.com/mochajs/mocha/pull/2082 + +2.4.4 / 2016-01-27 +================== + +* [#2080] - Fix broken RequireJS compatibility ([@boneskull]) + +[#2080]: https://github.com/mochajs/mocha/issues/2080 + +2.4.3 / 2016-01-27 +================== + +* [#2078] - Fix broken IE8 ([@boneskull]) + +[#2078]: https://github.com/mochajs/mocha/issues/2078 + +2.4.2 / 2016-01-26 +================== + +* [#2053] - Fix web worker compatibility ([@mislav]) +* [#2072] - Fix Windows color output ([@thedark1337]) +* [#2073] - Fix colors in `progress` and `landing` reporters ([@gyandeeps]) + +[#2053]: https://github.com/mochajs/mocha/pull/2053 +[#2072]: https://github.com/mochajs/mocha/pull/2072 +[#2073]: https://github.com/mochajs/mocha/pull/2073 +[@gyandeeps]: https://github.com/gyandeeps +[@thedark1337]: https://github.com/thedark1337 + +2.4.1 / 2016-01-26 +================== + +* [#2067] - Fix HTML/doc reporter regressions ([@danielstjules]) + +[#2067]: https://github.com/mochajs/mocha/pull/2067 + +2.4.0 / 2016-01-25 +================== + +* [#1945] - Correctly skip tests when skipping in suite's before() ([@ryanshawty]) +* [#2056] - chore(license): update license year to 2016 ([@pra85]) +* [#2048] - Fix `this.skip` from spec with HTML reporter ([@mislav]) +* [#2033] - Update tests for newer versions of should.js ([@tomhughes]) +* [#2037] - Fix for memory leak caused by referenced to deferred test ([@bd82]) +* [#2038] - Also run Travis-CI on node.js 4 & 5 ([@bd82]) +* [#2028] - Remove reference to test before afterAll hook runs ([@stonelgh]) +* Bump mkdirp to 0.5.1 to support strict mode ([@danielstjules]) +* [#1977] - safely stringify PhantomJS undefined value ([@ahamid]) +* Add the ability to retry tests ([@@longlho]) +* [#1982] - Enable --log-timer-events option [@Alaneor] +* Fix #1980: Load mocha.opts from bin/mocha and bin/_mocha ([@danielstjules]) +* [#1976] - Simplify function call ([@iclanzan]) +* [#1963] - Add support --perf-basic-prof ([@robraux]) +* [#1981] - Fix HTML reporter handling of done and exceptions ([@Standard8]) +* [#1993] - propagate "file" property for "exports" interface ([@segrey]) +* [#1999] - Add support for strict mode ([@tmont]) +* [#2005] - XUnit Reporter Writes to stdout, falls back to console.log ([@jonnyreeves]) +* [#2021] - Fix non ES5 compliant regexp ([@zetaben]) +* [#1965] - Don't double install BDD UI ([@cowboyd]) +* [#1995] - Make sure the xunit output dir exists before writing to it ([@ianwremmel]) +* Use chalk for the base reporter colors; closes #1200 ([@boneskull]) +* Fix requiring custom interfaces ([@jgkim]) +* [#1967] Silence Bluebird js warnings ([@krisr]) + +[#1945]: https://github.com/mochajs/mocha/pull/1945 +[#2056]: https://github.com/mochajs/mocha/pull/2056 +[#2048]: https://github.com/mochajs/mocha/pull/2048 +[#2033]: https://github.com/mochajs/mocha/pull/2033 +[#2037]: https://github.com/mochajs/mocha/pull/2037 +[#2038]: https://github.com/mochajs/mocha/pull/2038 +[#2028]: https://github.com/mochajs/mocha/pull/2028 +[#1977]: https://github.com/mochajs/mocha/pull/1977 +[#1982]: https://github.com/mochajs/mocha/pull/1982 +[#1976]: https://github.com/mochajs/mocha/pull/1976 +[#1963]: https://github.com/mochajs/mocha/pull/1963 +[#1981]: https://github.com/mochajs/mocha/pull/1981 +[#1993]: https://github.com/mochajs/mocha/pull/1993 +[#1999]: https://github.com/mochajs/mocha/pull/1999 +[#2005]: https://github.com/mochajs/mocha/pull/2005 +[#2021]: https://github.com/mochajs/mocha/pull/2021 +[1965#]: https://github.com/mochajs/mocha/pull/1965 +[#1995]: https://github.com/mochajs/mocha/pull/1995 +[#1967]: https://github.com/mochajs/mocha/pull/1967 +[@ryanshawty]: https://github.com/ryanshawty +[@pra85]: https://github.com/pra85 +[@mislav]: https://github.com/mislav +[@tomhughes]: https://github.com/tomhughes +[@bd82]: https://github.com/bd82 +[@stonelgh]: https://github.com/stonelgh +[@danielstjules]: https://github.com/danielstjules +[@ahamid]: https://github.com/ahamid +[@longlho]: https://github.com/longlho +[@Alaneor]: https://github.com/Alaneor +[@iclanzan]: https://github.com/iclanzan +[@robraux]: https://github.com/robraux +[@Standard8]: https://github.com/Standard8 +[@segrey]: https://github.com/segrey +[@tmont]: https://github.com/tmont +[@jonnyreeves]: https://github.com/jonnyreeves +[@zetaben]: https://github.com/zetaben +[@cowboyd]: https://github.com/cowboyd +[@ianwremmel]: https://github.com/ianwremmel +[@boneskull]: https://github.com/boneskull +[@jgkim]: https://github.com/jgkim +[@krisr]: https://github.com/krisr + +2.3.4 / 2015-11-15 +================== + + * Update debug dependency to 2.2.0 + * remove duplication of mocha.opts on process.argv + * Fix typo in test/reporters/nyan.js + +2.3.3 / 2015-09-19 +================== + + * [#1875] - Fix Markdown reporter exceeds maximum call stack size ([@danielstjules]) + * [#1864] - Fix xunit missing output with --reporter-options output ([@danielstjules]) + * [#1846] - Support all harmony flags ([@danielstjules]) + * Fix fragile xunit reporter spec ([@danielstjules]) + * [#1669] - Fix catch uncaught errors outside test suite execution ([@danielstjules]) + * [#1868] - Revert jade to support npm < v1.3.7 ([@danielstjules]) + * [#1766] - Don't remove modules/components from stack trace in the browser ([@danielstjules]) + * [#1798] - Fix correctly attribute mutiple done err with hooks ([@danielstjules]) + * Fix use utils.reduce for IE8 compatibility ([@wsw0108]) + * Some linting errors fixed by [@danielstjules] + * Call the inspect() function if message is not set ([@kevinburke]) + +[#1875]: https://github.com/mochajs/mocha/issues/1875 +[#1864]: https://github.com/mochajs/mocha/issues/1864 +[#1846]: https://github.com/mochajs/mocha/issues/1846 +[#1669]: https://github.com/mochajs/mocha/issues/1669 +[#1868]: https://github.com/mochajs/mocha/issues/1868 +[#1766]: https://github.com/mochajs/mocha/issues/1766 +[#1798]: https://github.com/mochajs/mocha/issues/1798 +[@danielstjules]: https://github.com/danielstjules +[@wsw0108]: https://github.com/wsw0108 +[@kevinburke]: https://github.com/kevinburke + +2.3.2 / 2015-09-07 +================== + * [#1868] - Fix compatibility with older versions of NPM ([@boneskull]) + + [#1868]: https://github.com/mochajs/mocha/issues/1868 + +2.3.1 / 2015-09-06 +================== + + * [#1812] - Fix: Bail flag causes before() hooks to be run even after a failure ([@aaroncrows]) + + [#1812]: https://github.com/mochajs/mocha/issues/1812 + [aaroncrows]: https://github.com/aaroncrows + +2.3.0 / 2015-08-30 +================== + + * [#553] - added --allowUncaught option ([@amsul]) + * [#1490] - Allow --async-only to be satisfied by returning a promise ([@jlai]) + * [#1829] - support --max-old-space-size ([@gigadude]) + * [#1811] - upgrade Jade dependency ([@outsideris]) + * [#1769] - Fix async hook error handling ([@ajaykodali]) + * [#1230] - More descriptive beforeEach/afterEach messages ([@duncanbeevers]) + * [#1787] - Scope loading behaviour instead of using early return ([@aryeguy]) + * [#1789] - Fix: html-runner crashing ([@sunesimonsen]) + * [#1749] - Fix maximum call stack error on large amount of tests ([@tinganho]) + * [#1230] - Decorate failed hook titles with test title ([@duncanbeevers]) + * [#1260] - Build using Browserify ([@ndhoule]) + * [#1728] - Don't use `__proto__` ([@ndhoule]) + * [#1781] - Fix hook error tests ([@glenjamin]) + * [#1754] - Allow boolean --reporter-options ([@papandreou]) + * [#1766] - Fix overly aggressive stack suppression ([@moll]) + * [#1752] - Avoid potential infinite loop ([@gsilk]) + * [#1761] - Fix problems running under PhantomJS ([@chromakode]) + * [#1700] - Fix more problems running under PhantomJS ([@jbnicolai]) + * [#1774] - Support escaped spaces in CLI options ([@adamgruber]) + * [#1687] - Fix HTML reporter links with special chars ([@benvinegar]) + * [#1359] - Adopt code style and enforce it using ESLint ([@ndhoule] w/ assist from [@jbnicolai] & [@boneskull]) + * various refactors ([@jbnicolai]) + * [#1758] - Add cross-frame compatible Error checking ([@outdooricon]) + * [#1741] - Remove moot `version` property from bower.json ([@kkirsche]) + * [#1739] - Improve `HISTORY.md` ([@rstacruz]) + * [#1730] - Support more io.js flags ([@ryedog]) + * [#1349] - Allow HTML in HTML reporter errors ([@papandreou] / [@sunesimonsen]) + * [#1572] - Prevent default browser behavior for failure/pass links ([@jschilli]) + * [#1630] - Support underscored harmony flags ([@dominicbarnes]) + * [#1718] - Support more harmony flags ([@slyg]) + * [#1689] - Add stack to JSON-stream reporter ([@jonathandelgado]) + * [#1654] - Fix `ReferenceError` "location is not defined" ([@jakemmarsh]) + + [#553]: https://github.com/mochajs/mocha/issues/553 + [#1490]: https://github.com/mochajs/mocha/issues/1490 + [#1829]: https://github.com/mochajs/mocha/issues/1829 + [#1811]: https://github.com/mochajs/mocha/issues/1811 + [#1769]: https://github.com/mochajs/mocha/issues/1769 + [#1230]: https://github.com/mochajs/mocha/issues/1230 + [#1787]: https://github.com/mochajs/mocha/issues/1787 + [#1789]: https://github.com/mochajs/mocha/issues/1789 + [#1749]: https://github.com/mochajs/mocha/issues/1749 + [#1230]: https://github.com/mochajs/mocha/issues/1230 + [#1260]: https://github.com/mochajs/mocha/issues/1260 + [#1728]: https://github.com/mochajs/mocha/issues/1728 + [#1781]: https://github.com/mochajs/mocha/issues/1781 + [#1754]: https://github.com/mochajs/mocha/issues/1754 + [#1766]: https://github.com/mochajs/mocha/issues/1766 + [#1752]: https://github.com/mochajs/mocha/issues/1752 + [#1761]: https://github.com/mochajs/mocha/issues/1761 + [#1700]: https://github.com/mochajs/mocha/issues/1700 + [#1774]: https://github.com/mochajs/mocha/issues/1774 + [#1687]: https://github.com/mochajs/mocha/issues/1687 + [#1359]: https://github.com/mochajs/mocha/issues/1359 + [#1758]: https://github.com/mochajs/mocha/issues/1758 + [#1741]: https://github.com/mochajs/mocha/issues/1741 + [#1739]: https://github.com/mochajs/mocha/issues/1739 + [#1730]: https://github.com/mochajs/mocha/issues/1730 + [#1349]: https://github.com/mochajs/mocha/issues/1349 + [#1572]: https://github.com/mochajs/mocha/issues/1572 + [#1630]: https://github.com/mochajs/mocha/issues/1630 + [#1718]: https://github.com/mochajs/mocha/issues/1718 + [#1689]: https://github.com/mochajs/mocha/issues/1689 + [#1654]: https://github.com/mochajs/mocha/issues/1654 + [@adamgruber]: https://github.com/adamgruber + [@ajaykodali]: https://github.com/ajaykodali + [@amsul]: https://github.com/amsul + [@aryeguy]: https://github.com/aryeguy + [@benvinegar]: https://github.com/benvinegar + [@boneskull]: https://github.com/boneskull + [@chromakode]: https://github.com/chromakode + [@dominicbarnes]: https://github.com/dominicbarnes + [@duncanbeevers]: https://github.com/duncanbeevers + [@gigadude]: https://github.com/gigadude + [@glenjamin]: https://github.com/glenjamin + [@gsilk]: https://github.com/gsilk + [@jakemmarsh]: https://github.com/jakemmarsh + [@jbnicolai]: https://github.com/jbnicolai + [@jlai]: https://github.com/jlai + [@jonathandelgado]: https://github.com/jonathandelgado + [@jschilli]: https://github.com/jschilli + [@kkirsche]: https://github.com/kkirsche + [@moll]: https://github.com/moll + [@ndhoule]: https://github.com/ndhoule + [@outdooricon]: https://github.com/outdooricon + [@outsideris]: https://github.com/outsideris + [@papandreou]: https://github.com/papandreou + [@rstacruz]: https://github.com/rstacruz + [@ryedog]: https://github.com/ryedog + [@slyg]: https://github.com/slyg + [@sunesimonsen]: https://github.com/sunesimonsen + [@tinganho]: https://github.com/tinganho + +2.2.5 / 2015-05-14 +================== + + * [#1699] - Upgrade jsdiff to v1.4.0 ([@nylen]) + * [#1648] - fix diff background colors in the console ([@nylen]) + * [#1327] - fix tests running twice, a regression issue. ([#1686], [@danielstjules]) + * [#1675] - add integration tests ([@danielstjules]) + * [#1682] - use a valid SPDX license identifier in package.json ([@kemitchell]) + * [#1660] - fix assertion of invalid dates ([#1661], [@a8m]) + * [#1241] - fix issue with multiline diffs appearing as single line ([#1655], [@a8m]) + +[#1699]: https://github.com/mochajs/mocha/issues/1699 +[#1648]: https://github.com/mochajs/mocha/issues/1648 +[#1327]: https://github.com/mochajs/mocha/issues/1327 +[#1686]: https://github.com/mochajs/mocha/issues/1686 +[#1675]: https://github.com/mochajs/mocha/issues/1675 +[#1682]: https://github.com/mochajs/mocha/issues/1682 +[#1660]: https://github.com/mochajs/mocha/issues/1660 +[#1661]: https://github.com/mochajs/mocha/issues/1661 +[#1241]: https://github.com/mochajs/mocha/issues/1241 +[#1655]: https://github.com/mochajs/mocha/issues/1655 +[@nylen]: https://github.com/nylen +[@danielstjules]: https://github.com/danielstjules +[@kemitchell]: https://github.com/kemitchell +[@a8m]: https://github.com/a8m + +2.2.4 / 2015-04-08 +================== + + * Load mocha.opts in _mocha for now (close #1645) + +2.2.3 / 2015-04-07 +================== + + * fix(reporter/base): string diff - issue #1241 + * fix(reporter/base): string diff - issue #1241 + * fix(reporter/base): don't show diffs for errors without expectation + * fix(reporter/base): don't assume error message is first line of stack + * improve: dry up reporter/base test + * fix(reporter/base): explicitly ignore showDiff #1614 + * Add iojs to travis build + * Pass `--allow-natives-syntax` flag to node. + * Support --harmony_classes flag for io.js + * Fix 1556: Update utils.clean to handle newlines in func declarations + * Fix 1606: fix err handling in IE <= 8 and non-ES5 browsers + * Fix 1585: make _mocha executable again + * chore(package.json): add a8m as a contributor + * Fixed broken link on html-cov reporter + * support --es_staging flag + * fix issue where menu overlaps content. + * update contributors in package.json + * Remove trailing whitespace from reporter output + * Remove contributors list from readme + * log third-party reporter errors + * [Fix] Exclude not own properties when looping on options + * fix: support node args in mocha.opts (close #1573) + * fix(reporter/base): string diff - issue #1241 + +2.2.1 / 2015-03-09 +================== + + * Fix passing of args intended for node/iojs. + +2.2.0 / 2015-03-06 +================== + + * Update mocha.js + * Add --fgrep. Use grep for RegExp, fgrep for str + * Ignore async global errors after spec resolution + * Fixing errors that prevent mocha.js from loading in the browser - fixes #1558 + * fix(utils): issue #1558 + make + * add ability to delay root suite; closes #362, closes #1124 + * fix insanity in http tests + * update travis: add node 0.12, add gitter, remove slack + * building + * resolve #1548: ensure the environment's "node" executable is used + * reporters/base: use supports-color to detect colorable term + * travis: use docker containers + * small fix: commander option for --expose-gc + * Ignore asynchronous errors after global failure + * Improve error output when a test fails with a non-error + * updated travis badge, uses svg instead of img + * Allow skip from test context for #332 + * [JSHINT] Unnecessary semicolon fixed in bin/_mocha + * Added a reminder about the done() callback to test timeout error messages + * fixes #1496, in Mocha.run(fn), check if fn exists before executing it, added tests too + * Add Harmony Proxy flag for iojs + * test(utils|ms|*): test existing units + * add support for some iojs flags + * fix(utils.stringify): issue #1229, diff viewer + * Remove slack link + * Prevent multiple 'grep=' querystring params in html reporter + * Use grep as regexp (close #1381) + * utils.stringify should handle objects without an Object prototype + * in runnable test, comparing to undefined error's message rather than a literal + * Fix test running output truncation on async STDIO + * ammended for deprecated customFds option in child_process + +2.1.0 / 2014-12-23 +================== + + * showDiff: don’t stringify strings + * Clean up unused module dependencies. + * Filter zero-length strings from mocha.opts + * only write to stdout in reporters + * Revert "only write to stdout in reporters" + * Print colored output only to a tty + * update summary in README.md + * rename Readme.md/History.md to README.md/HISTORY.md because neurotic + * add .mailmap to fix "git shortlog" or "git summary" output + * fixes #1461: nyan-reporter now respects Base.useColors, fixed bug where Base.color would not return a string when str wasn't a string. + * Use existing test URL builder in failed replay links + * modify .travis.yml: use travis_retry; closes #1449 + * fix -t 0 behavior; closes #1446 + * fix tests (whoops) + * improve diff behavior + * Preserve pathname when linking to individual tests + * Fix test + * Tiny typo in comments fixed + * after hooks now being called on failed tests when using bail, fixes #1093 + * fix throwing undefined/null now makes tests fail, fixes #1395 + * compiler extensions are added as watched extensions, removed non-standard extensions from watch regex, resolves #1221 + * prefix/namespace for suite titles in markdown reporter, fixes #554 + * fix more bad markdown in CONTRIBUTING.md + * fix bad markdown in CONTRIBUTING.md + * add setImmediate/clearImmediate to globals; closes #1435 + * Fix buffer diffs (closes #1132, closes #1433) + * add a CONTRIBUTING.md. closes #882 + * fix intermittent build failures (maybe). closes #1407 + * add Slack notification to .travis.yml + * Fix slack link + * Add slack room to readme + * Update maintainers + * update maintainers and contributors + * resolves #1393: kill children with more effort on SIGINT + * xunit reporter support for optionally writing to a file + * if a reporter has a .done method, call it before exiting + * add support for reporter options + * only write to stdout in reporters + +2.0.0 / 2014-10-21 +================== + + * remove: support for node 0.6.x, 0.4.x + * fix: landing reporter with non ansi characters (#211) + * fix: html reporter - preserve query params when navigating to suites/tests (#1358) + * fix: json stream reporter add error message to failed test + * fix: fixes for visionmedia -> mochajs + * fix: use stdio, fixes node deprecation warnings (#1391) + +1.21.5 / 2014-10-11 +================== + + * fix: build for NodeJS v0.6.x + * fix: do not attempt to highlight syntax when non-HTML reporter is used + * update: escape-string-regexp to 1.0.2. + * fix: botched indentation in canonicalize() + * fix: .gitignore: ignore .patch and .diff files + * fix: changed 'Catched' to 'Caught' in uncaught exception error handler messages + * add: `pending` field for json reporter + * fix: Runner.prototype.uncaught: don't double-end runnables that already have a state. + * fix: --recursive, broken by f0facd2e + * update: replaces escapeRegexp with the escape-string-regexp package. + * update: commander to 2.3.0. + * update: diff to 1.0.8. + * fix: ability to disable syntax highlighting (#1329) + * fix: added empty object to errorJSON() call to catch when no error is present + * fix: never time out after calling enableTimeouts(false) + * fix: timeout(0) will work at suite level (#1300) + * Fix for --watch+only() issue (#888 ) + * fix: respect err.showDiff, add Base reporter test (#810) + +1.22.1-3 / 2014-07-27 +================== + + * fix: disabling timeouts with this.timeout(0) (#1301) + +1.22.1-3 / 2014-07-27 +================== + + * fix: local uis and reporters (#1288) + * fix: building 1.21.0's changes in the browser (#1284) + +1.21.0 / 2014-07-23 +================== + + * add: --no-timeouts option (#1262, #1268) + * add: --*- deprecation node flags (#1217) + * add: --watch-extensions argument (#1247) + * change: spec reporter is default (#1228) + * fix: diff output showing incorrect +/- (#1182) + * fix: diffs of circular structures (#1179) + * fix: re-render the progress bar when progress has changed only (#1151) + * fix support for environments with global and window (#1159) + * fix: reverting to previously defined onerror handler (#1178) + * fix: stringify non error objects passed to done() (#1270) + * fix: using local ui, reporters (#1267) + * fix: cleaning es6 arrows (#1176) + * fix: don't include attrs in failure tag for xunit (#1244) + * fix: fail tests that return a promise if promise is rejected w/o a reason (#1224) + * fix: showing failed tests in doc reporter (#1117) + * fix: dot reporter dots being off (#1204) + * fix: catch empty throws (#1219) + * fix: honoring timeout for sync operations (#1242) + * update: growl to 1.8.0 + +1.20.1 / 2014-06-03 +================== + + * update: should dev dependency to ~4.0.0 (#1231) + +1.20.0 / 2014-05-28 +================== + + * add: filenames to suite objects (#1222) + +1.19.0 / 2014-05-17 +================== + + * add: browser script option to package.json + * add: export file in Mocha.Test objects (#1174) + * add: add docs for wrapped node flags + * fix: mocha.run() to return error status in browser (#1216) + * fix: clean() to show failure details (#1205) + * fix: regex that generates html for new keyword (#1201) + * fix: sibling suites have inherited but separate contexts (#1164) + + +1.18.2 / 2014-03-18 +================== + + * fix: html runner was prevented from using #mocha as the default root el (#1162) + +1.18.1 / 2014-03-18 +================== + + * fix: named before/after hooks in bdd, tdd, qunit interfaces (#1161) + +1.18.0 / 2014-03-13 +================== + + * add: promise support (#329) + * add: named before/after hooks (#966) + +1.17.1 / 2014-01-22 +================== + + * fix: expected messages in should.js (should.js#168) + * fix: expect errno global in node versions < v0.9.11 (#1111) + * fix: unreliable checkGlobals optimization (#1110) + +1.17.0 / 2014-01-09 +================== + + * add: able to require globals (describe, it, etc.) through mocha (#1077) + * fix: abort previous run on --watch change (#1100) + * fix: reset context for each --watch triggered run (#1099) + * fix: error when cli can't resolve path or pattern (#799) + * fix: canonicalize objects before stringifying and diffing them (#1079) + * fix: make CR call behave like carriage return for non tty (#1087) + + +1.16.2 / 2013-12-23 +================== + + * fix: couple issues with ie 8 (#1082, #1081) + * fix: issue running the xunit reporter in browsers (#1068) + * fix: issue with firefox < 3.5 (#725) + + +1.16.1 / 2013-12-19 +================== + + * fix: recompiled for missed changes from the last release + + +1.16.0 / 2013-12-19 +================== + + * add: Runnable.globals(arr) for per test global whitelist (#1046) + * add: mocha.throwError(err) for assertion libs to call (#985) + * remove: --watch's spinner (#806) + * fix: duplicate test output for multi-line specs in spec reporter (#1006) + * fix: gracefully exit on SIGINT (#1063) + * fix expose the specified ui only in the browser (#984) + * fix: ensure process exit code is preserved when using --no-exit (#1059) + * fix: return true from window.onerror handler (#868) + * fix: xunit reporter to use process.stdout.write (#1068) + * fix: utils.clean(str) indentation (#761) + * fix: xunit reporter returning test duration a NaN (#1039) + +1.15.1 / 2013-12-03 +================== + + * fix: recompiled for missed changes from the last release + +1.15.0 / 2013-12-02 +================== + + * add: `--no-exit` to prevent `process.exit()` (#1018) + * fix: using inline diffs (#1044) + * fix: show pending test details in xunit reporter (#1051) + * fix: faster global leak detection (#1024) + * fix: yui compression (#1035) + * fix: wrapping long lines in test results (#1030, #1031) + * fix: handle errors in hooks (#1043) + +1.14.0 / 2013-11-02 +================== + + * add: unified diff (#862) + * add: set MOCHA_COLORS env var to use colors (#965) + * add: able to override tests links in html reporters (#776) + * remove: teamcity reporter (#954) + * update: commander dependency to 2.0.0 (#1010) + * fix: mocha --ui will try to require the ui if not built in, as --reporter does (#1022) + * fix: send cursor commands only if isatty (#184, #1003) + * fix: include assertion message in base reporter (#993, #991) + * fix: consistent return of it, it.only, and describe, describe.only (#840) + +1.13.0 / 2013-09-15 +================== + + * add: sort test files with --sort (#813) + * update: diff depedency to 1.0.7 + * update: glob dependency to 3.2.3 (#927) + * fix: diffs show whitespace differences (#976) + * fix: improve global leaks (#783) + * fix: firefox window.getInterface leak + * fix: accessing iframe via window[iframeIndex] leak + * fix: faster global leak checking + * fix: reporter pending css selector (#970) + +1.12.1 / 2013-08-29 +================== + + * remove test.js from .gitignore + * update included version of ms.js + +1.12.0 / 2013-07-01 +================== + + * add: prevent diffs for differing types. Closes #900 + * add `Mocha.process` hack for phantomjs + * fix: use compilers with requires + * fix regexps in diffs. Closes #890 + * fix xunit NaN on failure. Closes #894 + * fix: strip tab indentation in `clean` utility method + * fix: textmate bundle installation + +1.11.0 / 2013-06-12 +================== + + * add --prof support + * add --harmony support + * add --harmony-generators support + * add "Uncaught " prefix to uncaught exceptions + * add web workers support + * add `suite.skip()` + * change to output # of pending / passing even on failures. Closes #872 + * fix: prevent hooks from being called if we are bailing + * fix `this.timeout(0)` + +1.10.0 / 2013-05-21 +================== + + * add add better globbing support for windows via `glob` module + * add support to pass through flags such as --debug-brk=1234. Closes #852 + * add test.only, test.skip to qunit interface + * change to always use word-based diffs for now. Closes #733 + * change `mocha init` tests.html to index.html + * fix `process` global leak in the browser + * fix: use resolve() instead of join() for --require + * fix: filterLeaks() condition to not consider indices in global object as leaks + * fix: restrict mocha.css styling to #mocha id + * fix: save timer references to avoid Sinon interfering in the browser build. + +1.9.0 / 2013-04-03 +================== + + * add improved setImmediate implementation + * replace --ignore-leaks with --check-leaks + * change default of ignoreLeaks to true. Closes #791 + * remove scrolling for HTML reporter + * fix retina support + * fix tmbundle, restrict to js scope + +1.8.2 / 2013-03-11 +================== + + * add `setImmediate` support for 0.10.x + * fix mocha -w spinner on windows + +1.8.1 / 2013-01-09 +================== + + * fix .bail() arity check causing it to default to true + +1.8.0 / 2013-01-08 +================== + + * add Mocha() options bail support + * add `Mocha#bail()` method + * add instanceof check back for inheriting from Error + * add component.json + * add diff.js to browser build + * update growl + * fix TAP reporter failures comment :D + +1.7.4 / 2012-12-06 +================== + + * add total number of passes and failures to TAP + * remove .bind() calls. re #680 + * fix indexOf. Closes #680 + +1.7.3 / 2012-11-30 +================== + + * fix uncaught error support for the browser + * revert uncaught "fix" which breaks node + +1.7.2 / 2012-11-28 +================== + + * fix uncaught errors to expose the original error message + +1.7.0 / 2012-11-07 +================== + + * add `--async-only` support to prevent false positives for missing `done()` + * add sorting by filename in code coverage + * add HTML 5 doctype to browser template. + * add play button to html reporter to rerun a single test + * add `this.timeout(ms)` as Suite#timeout(ms). Closes #599 + * update growl dependency to 1.6.x + * fix encoding of test-case ?grep. Closes #637 + * fix unicode chars on windows + * fix dom globals in Opera/IE. Closes #243 + * fix markdown reporter a tags + * fix `this.timeout("5s")` support + +1.6.0 / 2012-10-02 +================== + + * add object diffs when `err.showDiff` is present + * add hiding of empty suites when pass/failures are toggled + * add faster `.length` checks to `checkGlobals()` before performing the filter + +1.5.0 / 2012-09-21 +================== + + * add `ms()` to `.slow()` and `.timeout()` + * add `Mocha#checkLeaks()` to re-enable global leak checks + * add `this.slow()` option [aheckmann] + * add tab, CR, LF to error diffs for now + * add faster `.checkGlobals()` solution [guille] + * remove `fn.call()` from reduce util + * remove `fn.call()` from filter util + * fix forEach. Closes #582 + * fix relaying of signals [TooTallNate] + * fix TAP reporter grep number + +1.4.2 / 2012-09-01 +================== + + * add support to multiple `Mocha#globals()` calls, and strings + * add `mocha.reporter()` constructor support [jfirebaugh] + * add `mocha.timeout()` + * move query-string parser to utils.js + * move highlight code to utils.js + * fix third-party reporter support [exogen] + * fix client-side API to match node-side [jfirebaugh] + * fix mocha in iframe [joliss] + +1.4.1 / 2012-08-28 +================== + + * add missing `Markdown` export + * fix `Mocha#grep()`, escape regexp strings + * fix reference error when `devicePixelRatio` is not defined. Closes #549 + +1.4.0 / 2012-08-22 +================== + + * add mkdir -p to `mocha init`. Closes #539 + * add `.only()`. Closes #524 + * add `.skip()`. Closes #524 + * change str.trim() to use utils.trim(). Closes #533 + * fix HTML progress indicator retina display + * fix url-encoding of click-to-grep HTML functionality + +1.3.2 / 2012-08-01 +================== + + * fix exports double-execution regression. Closes #531 + +1.3.1 / 2012-08-01 +================== + + * add passes/failures toggling to HTML reporter + * add pending state to `xit()` and `xdescribe()` [Brian Moore] + * add the @charset "UTF-8"; to fix #522 with FireFox. [Jonathan Creamer] + * add border-bottom to #stats links + * add check for runnable in `Runner#uncaught()`. Closes #494 + * add 0.4 and 0.6 back to travis.yml + * add `-E, --growl-errors` to growl on failures only + * add prefixes to debug() names. Closes #497 + * add `Mocha#invert()` to js api + * change dot reporter to use sexy unicode dots + * fix error when clicking pending test in HTML reporter + * fix `make tm` + +1.3.0 / 2012-07-05 +================== + + * add window scrolling to `HTML` reporter + * add v8 `--trace-*` option support + * add support for custom reports via `--reporter MODULE` + * add `--invert` switch to invert `--grep` matches + * fix export of `Nyan` reporter. Closes #495 + * fix escaping of `HTML` suite titles. Closes #486 + * fix `done()` called multiple times with an error test + * change `--grep` - regexp escape the input + +1.2.2 / 2012-06-28 +================== + + * Added 0.8.0 support + +1.2.1 / 2012-06-25 +================== + + * Added `this.test.error(err)` support to after each hooks. Closes #287 + * Added: export top-level suite on global mocha object (mocha.suite). Closes #448 + * Fixed `js` code block format error in markdown reporter + * Fixed deprecation warning when using `path.existsSync` + * Fixed --globals with wildcard + * Fixed chars in nyan when his head moves back + * Remove `--growl` from test/mocha.opts. Closes #289 + +1.2.0 / 2012-06-17 +================== + + * Added `nyan` reporter [Atsuya Takagi] + * Added `mocha init ` to copy client files + * Added "specify" synonym for "it" [domenic] + * Added global leak wildcard support [nathanbowser] + * Fixed runner emitter leak. closes #432 + * Fixed omission of .js extension. Closes #454 + +1.1.0 / 2012-05-30 +================== + + * Added: check each `mocha(1)` arg for directories to walk + * Added `--recursive` [tricknotes] + * Added `context` for BDD [hokaccha] + * Added styling for new clickable titles + * Added clickable suite titles to HTML reporter + * Added warning when strings are thrown as errors + * Changed: green arrows again in HTML reporter styling + * Changed ul/li elements instead of divs for better copy-and-pasting [joliss] + * Fixed issue #325 - add better grep support to js api + * Fixed: save timer references to avoid Sinon interfering. + +1.0.3 / 2012-04-30 +================== + + * Fixed string diff newlines + * Fixed: removed mocha.css target. Closes #401 + +1.0.2 / 2012-04-25 +================== + + * Added HTML reporter duration. Closes #47 + * Fixed: one postMessage event listener [exogen] + * Fixed: allow --globals to be used multiple times. Closes #100 [brendannee] + * Fixed #158: removes jquery include from browser tests + * Fixed grep. Closes #372 [brendannee] + * Fixed #166 - When grepping don't display the empty suites + * Removed test/browser/style.css. Closes #385 + +1.0.1 / 2012-04-04 +================== + + * Fixed `.timeout()` in hooks + * Fixed: allow callback for `mocha.run()` in client version + * Fixed browser hook error display. Closes #361 + +1.0.0 / 2012-03-24 +================== + + * Added js API. Closes #265 + * Added: initial run of tests with `--watch`. Closes #345 + * Added: mark `location` as a global on the CS. Closes #311 + * Added `markdown` reporter (github flavour) + * Added: scrolling menu to coverage.html. Closes #335 + * Added source line to html report for Safari [Tyson Tate] + * Added "min" reporter, useful for `--watch` [Jakub Nešetřil] + * Added support for arbitrary compilers via . Closes #338 [Ian Young] + * Added Teamcity export to lib/reporters/index [Michael Riley] + * Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky] + * Fixed terrible FF / Opera stack traces + +0.14.1 / 2012-03-06 +================== + + * Added lib-cov to _.npmignore_ + * Added reporter to `mocha.run([reporter])` as argument + * Added some margin-top to the HTML reporter + * Removed jQuery dependency + * Fixed `--watch`: purge require cache. Closes #266 + +0.14.0 / 2012-03-01 +================== + + * Added string diff support for terminal reporters + +0.13.0 / 2012-02-23 +================== + + * Added preliminary test coverage support. Closes #5 + * Added `HTMLCov` reporter + * Added `JSONCov` reporter [kunklejr] + * Added `xdescribe()` and `xit()` to the BDD interface. Closes #263 (docs * Changed: make json reporter output pretty json + * Fixed node-inspector support, swapped `--debug` for `debug` to match node. +needed) +Closes #247 + +0.12.1 / 2012-02-14 +================== + + * Added `npm docs mocha` support [TooTallNate] + * Added a `Context` object used for hook and test-case this. Closes #253 + * Fixed `Suite#clone()` `.ctx` reference. Closes #262 + +0.12.0 / 2012-02-02 +================== + + * Added .coffee `--watch` support. Closes #242 + * Added support to `--require` files relative to the CWD. Closes #241 + * Added quick n dirty syntax highlighting. Closes #248 + * Changed: made HTML progress indicator smaller + * Fixed xunit errors attribute [dhendo] + +0.10.2 / 2012-01-21 +================== + + * Fixed suite count in reporter stats. Closes #222 + * Fixed `done()` after timeout error reporting [Phil Sung] + * Changed the 0-based errors to 1 + +0.10.1 / 2012-01-17 +================== + + * Added support for node 0.7.x + * Fixed absolute path support. Closes #215 [kompiro] + * Fixed `--no-colors` option [Jussi Virtanen] + * Fixed Arial CSS typo in the correct file + +0.10.0 / 2012-01-13 +================== + + * Added `-b, --bail` to exit on first exception [guillermo] + * Added support for `-gc` / `--expose-gc` [TooTallNate] + * Added `qunit`-inspired interface + * Added MIT LICENSE. Closes #194 + * Added: `--watch` all .js in the CWD. Closes #139 + * Fixed `self.test` reference in runner. Closes #189 + * Fixed double reporting of uncaught exceptions after timeout. Closes #195 + +0.8.2 / 2012-01-05 +================== + + * Added test-case context support. Closes #113 + * Fixed exit status. Closes #187 + * Update commander. Closes #190 + +0.8.1 / 2011-12-30 +================== + + * Fixed reporting of uncaught exceptions. Closes #183 + * Fixed error message defaulting [indutny] + * Changed mocha(1) from bash to node for windows [Nathan Rajlich] + +0.8.0 / 2011-12-28 +================== + + * Added `XUnit` reporter [FeeFighters/visionmedia] + * Added `say(1)` notification support [Maciej Małecki] + * Changed: fail when done() is invoked with a non-Error. Closes #171 + * Fixed `err.stack`, defaulting to message. Closes #180 + * Fixed: `make tm` mkdir -p the dest. Closes #137 + * Fixed mocha(1) --help bin name + * Fixed `-d` for `--debug` support + +0.7.1 / 2011-12-22 +================== + + * Removed `mocha-debug(1)`, use `mocha --debug` + * Fixed CWD relative requires + * Fixed growl issue on windows [Raynos] + * Fixed: platform specific line endings [TooTallNate] + * Fixed: escape strings in HTML reporter. Closes #164 + +0.7.0 / 2011-12-18 +================== + + * Added support for IE{7,8} [guille] + * Changed: better browser nextTick implementation [guille] + +0.6.0 / 2011-12-18 +================== + + * Added setZeroTimeout timeout for browser (nicer stack traces). Closes #153 + * Added "view source" on hover for HTML reporter to make it obvious + * Changed: replace custom growl with growl lib + * Fixed duplicate reporting for HTML reporter. Closes #154 + * Fixed silent hook errors in the HTML reporter. Closes #150 + +0.5.0 / 2011-12-14 +================== + + * Added: push node_modules directory onto module.paths for relative require Closes #93 + * Added teamcity reporter [blindsey] + * Fixed: recover from uncaught exceptions for tests. Closes #94 + * Fixed: only emit "test end" for uncaught within test, not hook + +0.4.0 / 2011-12-14 +================== + + * Added support for test-specific timeouts via `this.timeout(0)`. Closes #134 + * Added guillermo's client-side EventEmitter. Closes #132 + * Added progress indicator to the HTML reporter + * Fixed slow browser tests. Closes #135 + * Fixed "suite" color for light terminals + * Fixed `require()` leak spotted by [guillermo] + +0.3.6 / 2011-12-09 +================== + + * Removed suite merging (for now) + +0.3.5 / 2011-12-08 +================== + + * Added support for `window.onerror` [guillermo] + * Fixed: clear timeout on uncaught exceptions. Closes #131 [guillermo] + * Added `mocha.css` to PHONY list. + * Added `mocha.js` to PHONY list. + +0.3.4 / 2011-12-08 +================== + + * Added: allow `done()` to be called with non-Error + * Added: return Runner from `mocha.run()`. Closes #126 + * Fixed: run afterEach even on failures. Closes #125 + * Fixed clobbering of current runnable. Closes #121 + +0.3.3 / 2011-12-08 +================== + + * Fixed hook timeouts. Closes #120 + * Fixed uncaught exceptions in hooks + +0.3.2 / 2011-12-05 +================== + + * Fixed weird reporting when `err.message` is not present + +0.3.1 / 2011-12-04 +================== + + * Fixed hook event emitter leak. Closes #117 + * Fixed: export `Spec` constructor. Closes #116 + +0.3.0 / 2011-12-04 +================== + + * Added `-w, --watch`. Closes #72 + * Added `--ignore-leaks` to ignore global leak checking + * Added browser `?grep=pattern` support + * Added `--globals ` to specify accepted globals. Closes #99 + * Fixed `mocha-debug(1)` on some systems. Closes #232 + * Fixed growl total, use `runner.total` + +0.2.0 / 2011-11-30 +================== + + * Added `--globals ` to specify accepted globals. Closes #99 + * Fixed funky highlighting of messages. Closes #97 + * Fixed `mocha-debug(1)`. Closes #232 + * Fixed growl total, use runner.total + +0.1.0 / 2011-11-29 +================== + + * Added `suiteSetup` and `suiteTeardown` to TDD interface [David Henderson] + * Added growl icons. Closes #84 + * Fixed coffee-script support + +0.0.8 / 2011-11-25 +================== + + * Fixed: use `Runner#total` for accurate reporting + +0.0.7 / 2011-11-25 +================== + + * Added `Hook` + * Added `Runnable` + * Changed: `Test` is `Runnable` + * Fixed global leak reporting in hooks + * Fixed: > 2 calls to done() only report the error once + * Fixed: clear timer on failure. Closes #80 + +0.0.6 / 2011-11-25 +================== + + * Fixed return on immediate async error. Closes #80 + +0.0.5 / 2011-11-24 +================== + + * Fixed: make mocha.opts whitespace less picky [kkaefer] + +0.0.4 / 2011-11-24 +================== + + * Added `--interfaces` + * Added `--reporters` + * Added `-c, --colors`. Closes #69 + * Fixed hook timeouts + +0.0.3 / 2011-11-23 +================== + + * Added `-C, --no-colors` to explicitly disable + * Added coffee-script support + +0.0.2 / 2011-11-22 +================== + + * Fixed global leak detection due to Safari bind() change + * Fixed: escape html entities in Doc reporter + * Fixed: escape html entities in HTML reporter + * Fixed pending test support for HTML reporter. Closes #66 + +0.0.1 / 2011-11-22 +================== + + * Added `--timeout` second shorthand support, ex `--timeout 3s`. + * Fixed "test end" event for uncaughtExceptions. Closes #61 + +0.0.1-alpha6 / 2011-11-19 +================== + + * Added travis CI support (needs enabling when public) + * Added preliminary browser support + * Added `make mocha.css` target. Closes #45 + * Added stack trace to TAP errors. Closes #52 + * Renamed tearDown to teardown. Closes #49 + * Fixed: cascading hooksc. Closes #30 + * Fixed some colors for non-tty + * Fixed errors thrown in sync test-cases due to nextTick + * Fixed Base.window.width... again give precedence to 0.6.x + +0.0.1-alpha5 / 2011-11-17 +================== + + * Added `doc` reporter. Closes #33 + * Added suite merging. Closes #28 + * Added TextMate bundle and `make tm`. Closes #20 + +0.0.1-alpha4 / 2011-11-15 +================== + + * Fixed getWindowSize() for 0.4.x + +0.0.1-alpha3 / 2011-11-15 +================== + + * Added `-s, --slow ` to specify "slow" test threshold + * Added `mocha-debug(1)` + * Added `mocha.opts` support. Closes #31 + * Added: default [files] to _test/*.js_ + * Added protection against multiple calls to `done()`. Closes #35 + * Changed: bright yellow for slow Dot reporter tests + +0.0.1-alpha1 / 2011-11-08 +================== + + * Missed this one :) + +0.0.1-alpha1 / 2011-11-08 +================== + + * Initial release diff --git a/support/client/lib/vwf/view/mocha/LICENSE b/support/client/lib/vwf/view/mocha/LICENSE new file mode 100644 index 000000000..cb43e880f --- /dev/null +++ b/support/client/lib/vwf/view/mocha/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2016 JS Foundation and contributors, https://js.foundation + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/support/client/lib/vwf/view/mocha/README.md b/support/client/lib/vwf/view/mocha/README.md new file mode 100644 index 000000000..7dd521d4a --- /dev/null +++ b/support/client/lib/vwf/view/mocha/README.md @@ -0,0 +1,84 @@ +

+

+ Mocha test framework +

+ +[![Build Status](https://api.travis-ci.org/mochajs/mocha.svg?branch=master)](http://travis-ci.org/mochajs/mocha) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![OpenCollective](https://opencollective.com/mochajs/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/mochajs/sponsors/badge.svg)](#sponsors) +
Mocha Browser Support h/t SauceLabs + + Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://mochajs.org). + +## Links + + - [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md) + - [Google Group](http://groups.google.com/group/mochajs) + - [Wiki](https://github.com/mochajs/mocha/wiki) + - Mocha [Extensions and reporters](https://github.com/mochajs/mocha/wiki) + + +## Backers + +[Become a backer]((https://opencollective.com/mochajs#backer)) and show your support to our open source project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone. Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org)--who doesn't want a little extra exposure? [Here's the info](https://opencollective.com/mochajs#sponsor). + + + + + + + + + + + + + + + + + + + + + + +## License + +[MIT](LICENSE) diff --git a/support/client/lib/vwf/view/mocha/bin/.eslintrc b/support/client/lib/vwf/view/mocha/bin/.eslintrc new file mode 100644 index 000000000..db7424631 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/bin/.eslintrc @@ -0,0 +1,3 @@ +--- +rules: + no-process-exit: 0 diff --git a/support/client/lib/vwf/view/mocha/bin/_mocha b/support/client/lib/vwf/view/mocha/bin/_mocha new file mode 100644 index 000000000..61aac40d3 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/bin/_mocha @@ -0,0 +1,545 @@ +#!/usr/bin/env node +'use strict'; + +/* eslint no-unused-vars: off */ + +/** + * Module dependencies. + */ + +var program = require('commander'); +var path = require('path'); +var fs = require('fs'); +var resolve = path.resolve; +var exists = fs.existsSync || path.existsSync; +var Mocha = require('../'); +var utils = Mocha.utils; +var interfaceNames = Object.keys(Mocha.interfaces); +var join = path.join; +var cwd = process.cwd(); +var getOptions = require('./options'); +var mocha = new Mocha(); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; + +/** + * Files. + */ + +var files = []; + +/** + * Globals. + */ + +var globals = []; + +/** + * Requires. + */ + +var requires = []; + +/** + * Images. + */ + +var images = { + fail: path.join(__dirname, '..', 'images', 'error.png'), + pass: path.join(__dirname, '..', 'images', 'ok.png') +}; + +// options + +program + .version(JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')).version) + .usage('[debug] [options] [files]') + .option('-A, --async-only', 'force all tests to take a callback (async) or return a promise') + .option('-c, --colors', 'force enabling of colors') + .option('-C, --no-colors', 'force disabling of colors') + .option('-G, --growl', 'enable growl notification support') + .option('-O, --reporter-options ', 'reporter-specific options') + .option('-R, --reporter ', 'specify the reporter to use', 'spec') + .option('-S, --sort', 'sort test files') + .option('-b, --bail', 'bail after first test failure') + .option('-d, --debug', "enable node's debugger, synonym for node --debug") + .option('-g, --grep ', 'only run tests matching ') + .option('-f, --fgrep ', 'only run tests containing ') + .option('-gc, --expose-gc', 'expose gc extension') + .option('-i, --invert', 'inverts --grep and --fgrep matches') + .option('-r, --require ', 'require the given module') + .option('-s, --slow ', '"slow" test threshold in milliseconds [75]') + .option('-t, --timeout ', 'set test-case timeout in milliseconds [2000]') + .option('-u, --ui ', 'specify user-interface (' + interfaceNames.join('|') + ')', 'bdd') + .option('-w, --watch', 'watch files for changes') + .option('--check-leaks', 'check for global variable leaks') + .option('--full-trace', 'display the full stack trace') + .option('--compilers :,...', 'use the given module(s) to compile files', list, []) + .option('--debug-brk', "enable node's debugger breaking on the first line") + .option('--globals ', 'allow the given comma-delimited global [names]', list, []) + .option('--es_staging', 'enable all staged features') + .option('--harmony<_classes,_generators,...>', 'all node --harmony* flags are available') + .option('--preserve-symlinks', 'Instructs the module loader to preserve symbolic links when resolving and caching modules') + .option('--icu-data-dir', 'include ICU data') + .option('--inline-diffs', 'display actual/expected differences inline within each string') + .option('--inspect', 'activate devtools in chrome') + .option('--interfaces', 'display available interfaces') + .option('--no-deprecation', 'silence deprecation warnings') + .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit') + .option('--no-timeouts', 'disables timeouts, given implicitly with --debug') + .option('--opts ', 'specify opts path', 'test/mocha.opts') + .option('--perf-basic-prof', 'enable perf linux profiler (basic support)') + .option('--prof', 'log statistical profiling information') + .option('--log-timer-events', 'Time events including external callbacks') + .option('--recursive', 'include sub directories') + .option('--reporters', 'display available reporters') + .option('--retries ', 'set numbers of time to retry a failed test case') + .option('--throw-deprecation', 'throw an exception anytime a deprecated function is used') + .option('--trace', 'trace function calls') + .option('--trace-deprecation', 'show stack traces on deprecations') + .option('--use_strict', 'enforce strict mode') + .option('--watch-extensions ,...', 'additional extensions to monitor with --watch', list, []) + .option('--delay', 'wait for async suite definition'); + +program._name = 'mocha'; + +// init command + +program + .command('init ') + .description('initialize a client-side mocha setup at ') + .action(function (path) { + var mkdir = require('mkdirp'); + mkdir.sync(path); + var css = fs.readFileSync(join(__dirname, '..', 'mocha.css')); + var js = fs.readFileSync(join(__dirname, '..', 'mocha.js')); + var tmpl = fs.readFileSync(join(__dirname, '..', 'lib/template.html')); + fs.writeFileSync(join(path, 'mocha.css'), css); + fs.writeFileSync(join(path, 'mocha.js'), js); + fs.writeFileSync(join(path, 'tests.js'), ''); + fs.writeFileSync(join(path, 'index.html'), tmpl); + process.exit(0); + }); + +// --globals + +program.on('globals', function (val) { + globals = globals.concat(list(val)); +}); + +// --reporters + +program.on('reporters', function () { + console.log(); + console.log(' dot - dot matrix'); + console.log(' doc - html documentation'); + console.log(' spec - hierarchical spec list'); + console.log(' json - single json object'); + console.log(' progress - progress bar'); + console.log(' list - spec-style listing'); + console.log(' tap - test-anything-protocol'); + console.log(' landing - unicode landing strip'); + console.log(' xunit - xunit reporter'); + console.log(' min - minimal reporter (great with --watch)'); + console.log(' json-stream - newline delimited json events'); + console.log(' markdown - markdown documentation (github flavour)'); + console.log(' nyan - nyan cat!'); + console.log(); + process.exit(); +}); + +// --interfaces + +program.on('interfaces', function () { + console.log(''); + interfaceNames.forEach(function (interfaceName) { + console.log(' ' + interfaceName); + }); + console.log(''); + process.exit(); +}); + +// -r, --require + +module.paths.push(cwd, join(cwd, 'node_modules')); + +program.on('require', function (mod) { + var abs = exists(mod) || exists(mod + '.js'); + if (abs) { + mod = resolve(mod); + } + requires.push(mod); +}); + +// If not already done, load mocha.opts +if (!process.env.LOADED_MOCHA_OPTS) { + getOptions(); +} + +// parse args + +program.parse(process.argv); + +// infinite stack traces + +Error.stackTraceLimit = Infinity; // TODO: config + +// reporter options + +var reporterOptions = {}; +if (program.reporterOptions !== undefined) { + program.reporterOptions.split(',').forEach(function (opt) { + var L = opt.split('='); + if (L.length > 2 || L.length === 0) { + throw new Error("invalid reporter option '" + opt + "'"); + } else if (L.length === 2) { + reporterOptions[L[0]] = L[1]; + } else { + reporterOptions[L[0]] = true; + } + }); +} + +// reporter + +mocha.reporter(program.reporter, reporterOptions); + +// load reporter + +var Reporter = null; +try { + Reporter = require('../lib/reporters/' + program.reporter); +} catch (err) { + try { + Reporter = require(program.reporter); + } catch (err2) { + throw new Error('reporter "' + program.reporter + '" does not exist'); + } +} + +// --no-colors + +if (!program.colors) { + mocha.useColors(false); +} + +// --colors + +if (~process.argv.indexOf('--colors') || ~process.argv.indexOf('-c')) { + mocha.useColors(true); +} + +// --inline-diffs + +if (program.inlineDiffs) { + mocha.useInlineDiffs(true); +} + +// --slow + +if (program.slow) { + mocha.suite.slow(program.slow); +} + +// --no-timeouts + +if (!program.timeouts) { + mocha.enableTimeouts(false); +} + +// --timeout + +if (program.timeout) { + mocha.suite.timeout(program.timeout); +} + +// --bail + +mocha.suite.bail(program.bail); + +// --grep + +if (program.grep) { + mocha.grep(program.grep); +} + +// --fgrep + +if (program.fgrep) { + mocha.fgrep(program.fgrep); +} + +// --invert + +if (program.invert) { + mocha.invert(); +} + +// --check-leaks + +if (program.checkLeaks) { + mocha.checkLeaks(); +} + +// --stack-trace + +if (program.fullTrace) { + mocha.fullTrace(); +} + +// --growl + +if (program.growl) { + mocha.growl(); +} + +// --async-only + +if (program.asyncOnly) { + mocha.asyncOnly(); +} + +// --delay + +if (program.delay) { + mocha.delay(); +} + +// --globals + +mocha.globals(globals); + +// --retries + +if (program.retries) { + mocha.suite.retries(program.retries); +} + +// custom compiler support + +var extensions = ['js']; +program.compilers.forEach(function (c) { + var idx = c.indexOf(':'); + var ext = c.slice(0, idx); + var mod = c.slice(idx + 1); + + if (mod[0] === '.') { + mod = join(process.cwd(), mod); + } + require(mod); + extensions.push(ext); + program.watchExtensions.push(ext); +}); + +// requires + +requires.forEach(function (mod) { + require(mod); +}); + +// interface + +mocha.ui(program.ui); + +// args + +var args = program.args; + +// default files to test/*.{js,coffee} + +if (!args.length) { + args.push('test'); +} + +args.forEach(function (arg) { + var newFiles; + try { + newFiles = utils.lookupFiles(arg, extensions, program.recursive); + } catch (err) { + if (err.message.indexOf('cannot resolve path') === 0) { + console.error('Warning: Could not find any test files matching pattern: ' + arg); + return; + } + + throw err; + } + + files = files.concat(newFiles); +}); + +if (!files.length) { + console.error('No test files found'); + process.exit(1); +} + +// resolve + +files = files.map(function (path) { + return resolve(path); +}); + +if (program.sort) { + files.sort(); +} + +// --watch + +var runner; +var loadAndRun; +var purge; +var rerun; + +if (program.watch) { + console.log(); + hideCursor(); + process.on('SIGINT', function () { + showCursor(); + console.log('\n'); + process.exit(130); + }); + + var watchFiles = utils.files(cwd, [ 'js' ].concat(program.watchExtensions)); + var runAgain = false; + + loadAndRun = function loadAndRun () { + try { + mocha.files = files; + runAgain = false; + runner = mocha.run(function () { + runner = null; + if (runAgain) { + rerun(); + } + }); + } catch (e) { + console.log(e.stack); + } + }; + + purge = function purge () { + watchFiles.forEach(function (file) { + delete require.cache[file]; + }); + }; + + loadAndRun(); + + rerun = function rerun () { + purge(); + stop(); + if (!program.grep) { + mocha.grep(null); + } + mocha.suite = mocha.suite.clone(); + mocha.suite.ctx = new Mocha.Context(); + mocha.ui(program.ui); + loadAndRun(); + }; + + utils.watch(watchFiles, function () { + runAgain = true; + if (runner) { + runner.abort(); + } else { + rerun(); + } + }); +} else { +// load + + mocha.files = files; + runner = mocha.run(program.exit ? exit : exitLater); +} + +function exitLater (code) { + process.on('exit', function () { + process.exit(Math.min(code, 255)); + }); +} + +function exit (code) { + // flush output for Node.js Windows pipe bug + // https://github.com/joyent/node/issues/6247 is just one bug example + // https://github.com/visionmedia/mocha/issues/333 has a good discussion + function done () { + if (!(draining--)) { + process.exit(Math.min(code, 255)); + } + } + + var draining = 0; + var streams = [process.stdout, process.stderr]; + + streams.forEach(function (stream) { + // submit empty write request and wait for completion + draining += 1; + stream.write('', done); + }); + + done(); +} + +process.on('SIGINT', function () { + runner.abort(); + + // This is a hack: + // Instead of `process.exit(130)`, set runner.failures to 130 (exit code for SIGINT) + // The amount of failures will be emitted as error code later + runner.failures = 130; +}); + +/** + * Parse list. + */ + +function list (str) { + return str.split(/ *, */); +} + +/** + * Hide the cursor. + */ + +function hideCursor () { + process.stdout.write('\u001b[?25l'); +} + +/** + * Show the cursor. + */ + +function showCursor () { + process.stdout.write('\u001b[?25h'); +} + +/** + * Stop play()ing. + */ + +function stop () { + process.stdout.write('\u001b[2K'); + clearInterval(play.timer); +} + +/** + * Play the given array of strings. + */ + +function play (arr, interval) { + var len = arr.length; + interval = interval || 100; + var i = 0; + + play.timer = setInterval(function () { + var str = arr[i++ % len]; + process.stdout.write('\u001b[0G' + str); + }, interval); +} diff --git a/support/client/lib/vwf/view/mocha/bin/mocha b/support/client/lib/vwf/view/mocha/bin/mocha new file mode 100644 index 000000000..c6aaa97b0 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/bin/mocha @@ -0,0 +1,83 @@ +#!/usr/bin/env node + +'use strict'; + +/** + * This tiny wrapper file checks for known node flags and appends them + * when found, before invoking the "real" _mocha(1) executable. + */ + +var spawn = require('child_process').spawn; +var path = require('path'); +var getOptions = require('./options'); +var args = [path.join(__dirname, '_mocha')]; + +// Load mocha.opts into process.argv +// Must be loaded here to handle node-specific options +getOptions(); + +process.argv.slice(2).forEach(function (arg) { + var flag = arg.split('=')[0]; + + switch (flag) { + case '-d': + args.unshift('--debug'); + args.push('--no-timeouts'); + break; + case 'debug': + case '--debug': + case '--debug-brk': + case '--inspect': + args.unshift(arg); + args.push('--no-timeouts'); + break; + case '-gc': + case '--expose-gc': + args.unshift('--expose-gc'); + break; + case '--gc-global': + case '--es_staging': + case '--no-deprecation': + case '--prof': + case '--log-timer-events': + case '--throw-deprecation': + case '--trace-deprecation': + case '--use_strict': + case '--allow-natives-syntax': + case '--perf-basic-prof': + args.unshift(arg); + break; + default: + if (arg.indexOf('--harmony') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--trace') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--icu-data-dir') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--max-old-space-size') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--preserve-symlinks') === 0) { + args.unshift(arg); + } else { + args.push(arg); + } + break; + } +}); + +var proc = spawn(process.execPath, args, { stdio: 'inherit' }); +proc.on('exit', function (code, signal) { + process.on('exit', function () { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exit(code); + } + }); +}); + +// terminate children. +process.on('SIGINT', function () { + proc.kill('SIGINT'); // calls runner.abort() + proc.kill('SIGTERM'); // if that didn't work, we're probably in an infinite loop, so make it die. +}); diff --git a/support/client/lib/vwf/view/mocha/bin/options.js b/support/client/lib/vwf/view/mocha/bin/options.js new file mode 100644 index 000000000..be5a60c9c --- /dev/null +++ b/support/client/lib/vwf/view/mocha/bin/options.js @@ -0,0 +1,41 @@ +'use strict'; + +/** + * Dependencies. + */ + +var fs = require('fs'); + +/** + * Export `getOptions`. + */ + +module.exports = getOptions; + +/** + * Get options. + */ + +function getOptions () { + var optsPath = process.argv.indexOf('--opts') === -1 + ? 'test/mocha.opts' + : process.argv[process.argv.indexOf('--opts') + 1]; + + try { + var opts = fs.readFileSync(optsPath, 'utf8') + .replace(/\\\s/g, '%20') + .split(/\s/) + .filter(Boolean) + .map(function (value) { + return value.replace(/%20/g, ' '); + }); + + process.argv = process.argv + .slice(0, 2) + .concat(opts.concat(process.argv.slice(2))); + } catch (err) { + // ignore + } + + process.env.LOADED_MOCHA_OPTS = true; +} diff --git a/support/client/lib/vwf/view/mocha/bower.json b/support/client/lib/vwf/view/mocha/bower.json new file mode 100644 index 000000000..e96cc9526 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/bower.json @@ -0,0 +1,38 @@ +{ + "name": "mocha", + "homepage": "https://mochajs.org", + "description": "simple, flexible, fun test framework", + "repository": { + "type": "git", + "url": "git://github.com/mochajs/mocha.git" + }, + "main": [ + "mocha.js", + "mocha.css" + ], + "ignore": [ + "bin", + "editors", + "images", + "lib", + "scripts", + "test", + "assets", + "media", + ".*", + "index.js", + "karma.conf.js", + "browser-entry.js", + "Makefile", + "package.json", + "appveyor.yml" + ], + "keywords": [ + "mocha", + "test", + "bdd", + "tdd", + "tap" + ], + "license": "MIT" +} diff --git a/support/client/lib/vwf/view/mocha/browser-entry.js b/support/client/lib/vwf/view/mocha/browser-entry.js new file mode 100644 index 000000000..1d5ef5a1c --- /dev/null +++ b/support/client/lib/vwf/view/mocha/browser-entry.js @@ -0,0 +1,187 @@ +'use strict'; + +/* eslint no-unused-vars: off */ +/* eslint-env commonjs */ + +/** + * Shim process.stdout. + */ + +process.stdout = require('browser-stdout')(); + +var Mocha = require('./lib/mocha'); + +/** + * Create a Mocha instance. + * + * @return {undefined} + */ + +var mocha = new Mocha({ reporter: 'html' }); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; + +var uncaughtExceptionHandlers = []; + +var originalOnerrorHandler = global.onerror; + +/** + * Remove uncaughtException listener. + * Revert to original onerror handler if previously defined. + */ + +process.removeListener = function (e, fn) { + if (e === 'uncaughtException') { + if (originalOnerrorHandler) { + global.onerror = originalOnerrorHandler; + } else { + global.onerror = function () {}; + } + var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn); + if (i !== -1) { + uncaughtExceptionHandlers.splice(i, 1); + } + } +}; + +/** + * Implements uncaughtException listener. + */ + +process.on = function (e, fn) { + if (e === 'uncaughtException') { + global.onerror = function (err, url, line) { + fn(new Error(err + ' (' + url + ':' + line + ')')); + return !mocha.allowUncaught; + }; + uncaughtExceptionHandlers.push(fn); + } +}; + +// The BDD UI is registered by default, but no UI will be functional in the +// browser without an explicit call to the overridden `mocha.ui` (see below). +// Ensure that this default UI does not expose its methods to the global scope. +mocha.suite.removeAllListeners('pre-require'); + +var immediateQueue = []; +var immediateTimeout; + +function timeslice () { + var immediateStart = new Date().getTime(); + while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) { + immediateQueue.shift()(); + } + if (immediateQueue.length) { + immediateTimeout = setTimeout(timeslice, 0); + } else { + immediateTimeout = null; + } +} + +/** + * High-performance override of Runner.immediately. + */ + +Mocha.Runner.immediately = function (callback) { + immediateQueue.push(callback); + if (!immediateTimeout) { + immediateTimeout = setTimeout(timeslice, 0); + } +}; + +/** + * Function to allow assertion libraries to throw errors directly into mocha. + * This is useful when running tests in a browser because window.onerror will + * only receive the 'message' attribute of the Error. + */ +mocha.throwError = function (err) { + Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) { + fn(err); + }); + throw err; +}; + +/** + * Override ui to ensure that the ui functions are initialized. + * Normally this would happen in Mocha.prototype.loadFiles. + */ + +mocha.ui = function (ui) { + Mocha.prototype.ui.call(this, ui); + this.suite.emit('pre-require', global, null, this); + return this; +}; + +/** + * Setup mocha with the given setting options. + */ + +mocha.setup = function (opts) { + if (typeof opts === 'string') { + opts = { ui: opts }; + } + for (var opt in opts) { + if (opts.hasOwnProperty(opt)) { + this[opt](opts[opt]); + } + } + return this; +}; + +/** + * Run mocha, returning the Runner. + */ + +mocha.run = function (fn) { + var options = mocha.options; + mocha.globals('location'); + + var query = Mocha.utils.parseQuery(global.location.search || ''); + if (query.grep) { + mocha.grep(query.grep); + } + if (query.fgrep) { + mocha.fgrep(query.fgrep); + } + if (query.invert) { + mocha.invert(); + } + + return Mocha.prototype.run.call(mocha, function (err) { + // The DOM Document is not available in Web Workers. + var document = global.document; + if (document && document.getElementById('mocha') && options.noHighlighting !== true) { + Mocha.utils.highlightTags('code'); + } + if (fn) { + fn(err); + } + }); +}; + +/** + * Expose the process shim. + * https://github.com/mochajs/mocha/pull/916 + */ + +Mocha.process = process; + +/** + * Expose mocha. + */ + +global.Mocha = Mocha; +global.mocha = mocha; + +// this allows test/acceptance/required-tokens.js to pass; thus, +// you can now do `const describe = require('mocha').describe` in a +// browser context (assuming browserification). should fix #880 +module.exports = global; diff --git a/support/client/lib/vwf/view/mocha/images/error.png b/support/client/lib/vwf/view/mocha/images/error.png new file mode 100644 index 000000000..a07a1ba5e Binary files /dev/null and b/support/client/lib/vwf/view/mocha/images/error.png differ diff --git a/support/client/lib/vwf/view/mocha/images/ok.png b/support/client/lib/vwf/view/mocha/images/ok.png new file mode 100644 index 000000000..b3623a599 Binary files /dev/null and b/support/client/lib/vwf/view/mocha/images/ok.png differ diff --git a/support/client/lib/vwf/view/mocha/index.js b/support/client/lib/vwf/view/mocha/index.js new file mode 100644 index 000000000..d2b7d1960 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib/mocha'); diff --git a/support/client/lib/vwf/view/mocha/lib/browser/.eslintrc.yaml b/support/client/lib/vwf/view/mocha/lib/browser/.eslintrc.yaml new file mode 100644 index 000000000..d85f537d3 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/browser/.eslintrc.yaml @@ -0,0 +1,4 @@ +env: + node: false + browser: false + commonjs: true diff --git a/support/client/lib/vwf/view/mocha/lib/browser/debug.js b/support/client/lib/vwf/view/mocha/lib/browser/debug.js new file mode 100644 index 000000000..3d12160f1 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/browser/debug.js @@ -0,0 +1,7 @@ +'use strict'; + +function noop () {} + +module.exports = function () { + return noop; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/browser/events.js b/support/client/lib/vwf/view/mocha/lib/browser/events.js new file mode 100644 index 000000000..e46a9f5f0 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/browser/events.js @@ -0,0 +1,195 @@ +'use strict'; + +/** + * Module exports. + */ + +exports.EventEmitter = EventEmitter; + +/** + * Object#toString reference. + */ +var objToString = Object.prototype.toString; + +/** + * Check if a value is an array. + * + * @api private + * @param {*} val The value to test. + * @return {boolean} true if the value is an array, otherwise false. + */ +function isArray (val) { + return objToString.call(val) === '[object Array]'; +} + +/** + * Event emitter constructor. + * + * @api public + */ +function EventEmitter () {} + +/** + * Add a listener. + * + * @api public + * @param {string} name Event name. + * @param {Function} fn Event handler. + * @return {EventEmitter} Emitter instance. + */ +EventEmitter.prototype.on = function (name, fn) { + if (!this.$events) { + this.$events = {}; + } + + if (!this.$events[name]) { + this.$events[name] = fn; + } else if (isArray(this.$events[name])) { + this.$events[name].push(fn); + } else { + this.$events[name] = [this.$events[name], fn]; + } + + return this; +}; + +EventEmitter.prototype.addListener = EventEmitter.prototype.on; + +/** + * Adds a volatile listener. + * + * @api public + * @param {string} name Event name. + * @param {Function} fn Event handler. + * @return {EventEmitter} Emitter instance. + */ +EventEmitter.prototype.once = function (name, fn) { + var self = this; + + function on () { + self.removeListener(name, on); + fn.apply(this, arguments); + } + + on.listener = fn; + this.on(name, on); + + return this; +}; + +/** + * Remove a listener. + * + * @api public + * @param {string} name Event name. + * @param {Function} fn Event handler. + * @return {EventEmitter} Emitter instance. + */ +EventEmitter.prototype.removeListener = function (name, fn) { + if (this.$events && this.$events[name]) { + var list = this.$events[name]; + + if (isArray(list)) { + var pos = -1; + + for (var i = 0, l = list.length; i < l; i++) { + if (list[i] === fn || (list[i].listener && list[i].listener === fn)) { + pos = i; + break; + } + } + + if (pos < 0) { + return this; + } + + list.splice(pos, 1); + + if (!list.length) { + delete this.$events[name]; + } + } else if (list === fn || (list.listener && list.listener === fn)) { + delete this.$events[name]; + } + } + + return this; +}; + +/** + * Remove all listeners for an event. + * + * @api public + * @param {string} name Event name. + * @return {EventEmitter} Emitter instance. + */ +EventEmitter.prototype.removeAllListeners = function (name) { + if (name === undefined) { + this.$events = {}; + return this; + } + + if (this.$events && this.$events[name]) { + this.$events[name] = null; + } + + return this; +}; + +/** + * Get all listeners for a given event. + * + * @api public + * @param {string} name Event name. + * @return {EventEmitter} Emitter instance. + */ +EventEmitter.prototype.listeners = function (name) { + if (!this.$events) { + this.$events = {}; + } + + if (!this.$events[name]) { + this.$events[name] = []; + } + + if (!isArray(this.$events[name])) { + this.$events[name] = [this.$events[name]]; + } + + return this.$events[name]; +}; + +/** + * Emit an event. + * + * @api public + * @param {string} name Event name. + * @return {boolean} true if at least one handler was invoked, else false. + */ +EventEmitter.prototype.emit = function (name) { + if (!this.$events) { + return false; + } + + var handler = this.$events[name]; + + if (!handler) { + return false; + } + + var args = Array.prototype.slice.call(arguments, 1); + + if (typeof handler === 'function') { + handler.apply(this, args); + } else if (isArray(handler)) { + var listeners = handler.slice(); + + for (var i = 0, l = listeners.length; i < l; i++) { + listeners[i].apply(this, args); + } + } else { + return false; + } + + return true; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/browser/progress.js b/support/client/lib/vwf/view/mocha/lib/browser/progress.js new file mode 100644 index 000000000..2b23656b9 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/browser/progress.js @@ -0,0 +1,119 @@ +'use strict'; + +/** + * Expose `Progress`. + */ + +module.exports = Progress; + +/** + * Initialize a new `Progress` indicator. + */ +function Progress () { + this.percent = 0; + this.size(0); + this.fontSize(11); + this.font('helvetica, arial, sans-serif'); +} + +/** + * Set progress size to `size`. + * + * @api public + * @param {number} size + * @return {Progress} Progress instance. + */ +Progress.prototype.size = function (size) { + this._size = size; + return this; +}; + +/** + * Set text to `text`. + * + * @api public + * @param {string} text + * @return {Progress} Progress instance. + */ +Progress.prototype.text = function (text) { + this._text = text; + return this; +}; + +/** + * Set font size to `size`. + * + * @api public + * @param {number} size + * @return {Progress} Progress instance. + */ +Progress.prototype.fontSize = function (size) { + this._fontSize = size; + return this; +}; + +/** + * Set font to `family`. + * + * @param {string} family + * @return {Progress} Progress instance. + */ +Progress.prototype.font = function (family) { + this._font = family; + return this; +}; + +/** + * Update percentage to `n`. + * + * @param {number} n + * @return {Progress} Progress instance. + */ +Progress.prototype.update = function (n) { + this.percent = n; + return this; +}; + +/** + * Draw on `ctx`. + * + * @param {CanvasRenderingContext2d} ctx + * @return {Progress} Progress instance. + */ +Progress.prototype.draw = function (ctx) { + try { + var percent = Math.min(this.percent, 100); + var size = this._size; + var half = size / 2; + var x = half; + var y = half; + var rad = half - 1; + var fontSize = this._fontSize; + + ctx.font = fontSize + 'px ' + this._font; + + var angle = Math.PI * 2 * (percent / 100); + ctx.clearRect(0, 0, size, size); + + // outer circle + ctx.strokeStyle = '#9f9f9f'; + ctx.beginPath(); + ctx.arc(x, y, rad, 0, angle, false); + ctx.stroke(); + + // inner circle + ctx.strokeStyle = '#eee'; + ctx.beginPath(); + ctx.arc(x, y, rad - 1, 0, angle, true); + ctx.stroke(); + + // text + var text = this._text || (percent | 0) + '%'; + var w = ctx.measureText(text).width; + + ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1); + } catch (err) { + // don't fail if we can't render progress + } + return this; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/browser/tty.js b/support/client/lib/vwf/view/mocha/lib/browser/tty.js new file mode 100644 index 000000000..c77f7e99a --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/browser/tty.js @@ -0,0 +1,13 @@ +'use strict'; + +exports.isatty = function isatty () { + return true; +}; + +exports.getWindowSize = function getWindowSize () { + if ('innerHeight' in global) { + return [global.innerHeight, global.innerWidth]; + } + // In a Web Worker, the DOM Window is not available. + return [640, 480]; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/context.js b/support/client/lib/vwf/view/mocha/lib/context.js new file mode 100644 index 000000000..019fe8891 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/context.js @@ -0,0 +1,112 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var JSON = require('json3'); + +/** + * Expose `Context`. + */ + +module.exports = Context; + +/** + * Initialize a new `Context`. + * + * @api private + */ +function Context () {} + +/** + * Set or get the context `Runnable` to `runnable`. + * + * @api private + * @param {Runnable} runnable + * @return {Context} + */ +Context.prototype.runnable = function (runnable) { + if (!arguments.length) { + return this._runnable; + } + this.test = this._runnable = runnable; + return this; +}; + +/** + * Set test timeout `ms`. + * + * @api private + * @param {number} ms + * @return {Context} self + */ +Context.prototype.timeout = function (ms) { + if (!arguments.length) { + return this.runnable().timeout(); + } + this.runnable().timeout(ms); + return this; +}; + +/** + * Set test timeout `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Context} self + */ +Context.prototype.enableTimeouts = function (enabled) { + this.runnable().enableTimeouts(enabled); + return this; +}; + +/** + * Set test slowness threshold `ms`. + * + * @api private + * @param {number} ms + * @return {Context} self + */ +Context.prototype.slow = function (ms) { + this.runnable().slow(ms); + return this; +}; + +/** + * Mark a test as skipped. + * + * @api private + * @return {Context} self + */ +Context.prototype.skip = function () { + this.runnable().skip(); + return this; +}; + +/** + * Allow a number of retries on failed tests + * + * @api private + * @param {number} n + * @return {Context} self + */ +Context.prototype.retries = function (n) { + if (!arguments.length) { + return this.runnable().retries(); + } + this.runnable().retries(n); + return this; +}; + +/** + * Inspect the context void of `._runnable`. + * + * @api private + * @return {string} + */ +Context.prototype.inspect = function () { + return JSON.stringify(this, function (key, val) { + return key === 'runnable' || key === 'test' ? undefined : val; + }, 2); +}; diff --git a/support/client/lib/vwf/view/mocha/lib/hook.js b/support/client/lib/vwf/view/mocha/lib/hook.js new file mode 100644 index 000000000..392a4cfb4 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/hook.js @@ -0,0 +1,48 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Runnable = require('./runnable'); +var inherits = require('./utils').inherits; + +/** + * Expose `Hook`. + */ + +module.exports = Hook; + +/** + * Initialize a new `Hook` with the given `title` and callback `fn`. + * + * @param {String} title + * @param {Function} fn + * @api private + */ +function Hook (title, fn) { + Runnable.call(this, title, fn); + this.type = 'hook'; +} + +/** + * Inherit from `Runnable.prototype`. + */ +inherits(Hook, Runnable); + +/** + * Get or set the test `err`. + * + * @param {Error} err + * @return {Error} + * @api public + */ +Hook.prototype.error = function (err) { + if (!arguments.length) { + err = this._error; + this._error = null; + return err; + } + + this._error = err; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/bdd.js b/support/client/lib/vwf/view/mocha/lib/interfaces/bdd.js new file mode 100644 index 000000000..33efc169a --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/bdd.js @@ -0,0 +1,115 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Test = require('../test'); + +/** + * BDD-style interface: + * + * describe('Array', function() { + * describe('#indexOf()', function() { + * it('should return -1 when not present', function() { + * // ... + * }); + * + * it('should return the index when present', function() { + * // ... + * }); + * }); + * }); + * + * @param {Suite} suite Root suite. + */ +module.exports = function (suite) { + var suites = [suite]; + + suite.on('pre-require', function (context, file, mocha) { + var common = require('./common')(suites, context, mocha); + + context.before = common.before; + context.after = common.after; + context.beforeEach = common.beforeEach; + context.afterEach = common.afterEach; + context.run = mocha.options.delay && common.runWithSuite(suite); + /** + * Describe a "suite" with the given `title` + * and callback `fn` containing nested suites + * and/or tests. + */ + + context.describe = context.context = function (title, fn) { + return common.suite.create({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Pending describe. + */ + + context.xdescribe = context.xcontext = context.describe.skip = function (title, fn) { + return common.suite.skip({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Exclusive suite. + */ + + context.describe.only = function (title, fn) { + return common.suite.only({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Describe a specification or test-case + * with the given `title` and callback `fn` + * acting as a thunk. + */ + + context.it = context.specify = function (title, fn) { + var suite = suites[0]; + if (suite.isPending()) { + fn = null; + } + var test = new Test(title, fn); + test.file = file; + suite.addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.it.only = function (title, fn) { + return common.test.only(mocha, context.it(title, fn)); + }; + + /** + * Pending test case. + */ + + context.xit = context.xspecify = context.it.skip = function (title) { + context.it(title); + }; + + /** + * Number of attempts to retry. + */ + context.it.retries = function (n) { + context.retries(n); + }; + }); +}; diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/common.js b/support/client/lib/vwf/view/mocha/lib/interfaces/common.js new file mode 100644 index 000000000..01f1a8936 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/common.js @@ -0,0 +1,158 @@ +'use strict'; + +var Suite = require('../suite'); + +/** + * Functions common to more than one interface. + * + * @param {Suite[]} suites + * @param {Context} context + * @param {Mocha} mocha + * @return {Object} An object containing common functions. + */ +module.exports = function (suites, context, mocha) { + return { + /** + * This is only present if flag --delay is passed into Mocha. It triggers + * root suite execution. + * + * @param {Suite} suite The root suite. + * @return {Function} A function which runs the root suite + */ + runWithSuite: function runWithSuite (suite) { + return function run () { + suite.run(); + }; + }, + + /** + * Execute before running tests. + * + * @param {string} name + * @param {Function} fn + */ + before: function (name, fn) { + suites[0].beforeAll(name, fn); + }, + + /** + * Execute after running tests. + * + * @param {string} name + * @param {Function} fn + */ + after: function (name, fn) { + suites[0].afterAll(name, fn); + }, + + /** + * Execute before each test case. + * + * @param {string} name + * @param {Function} fn + */ + beforeEach: function (name, fn) { + suites[0].beforeEach(name, fn); + }, + + /** + * Execute after each test case. + * + * @param {string} name + * @param {Function} fn + */ + afterEach: function (name, fn) { + suites[0].afterEach(name, fn); + }, + + suite: { + /** + * Create an exclusive Suite; convenience function + * See docstring for create() below. + * + * @param {Object} opts + * @returns {Suite} + */ + only: function only (opts) { + mocha.options.hasOnly = true; + opts.isOnly = true; + return this.create(opts); + }, + + /** + * Create a Suite, but skip it; convenience function + * See docstring for create() below. + * + * @param {Object} opts + * @returns {Suite} + */ + skip: function skip (opts) { + opts.pending = true; + return this.create(opts); + }, + + /** + * Creates a suite. + * @param {Object} opts Options + * @param {string} opts.title Title of Suite + * @param {Function} [opts.fn] Suite Function (not always applicable) + * @param {boolean} [opts.pending] Is Suite pending? + * @param {string} [opts.file] Filepath where this Suite resides + * @param {boolean} [opts.isOnly] Is Suite exclusive? + * @returns {Suite} + */ + create: function create (opts) { + var suite = Suite.create(suites[0], opts.title); + suite.pending = Boolean(opts.pending); + suite.file = opts.file; + suites.unshift(suite); + if (opts.isOnly) { + suite.parent._onlySuites = suite.parent._onlySuites.concat(suite); + mocha.options.hasOnly = true; + } + if (typeof opts.fn === 'function') { + opts.fn.call(suite); + suites.shift(); + } else if (typeof opts.fn === 'undefined' && !suite.pending) { + throw new Error('Suite "' + suite.fullTitle() + '" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.'); + } + + return suite; + } + }, + + test: { + + /** + * Exclusive test-case. + * + * @param {Object} mocha + * @param {Function} test + * @returns {*} + */ + only: function (mocha, test) { + test.parent._onlyTests = test.parent._onlyTests.concat(test); + mocha.options.hasOnly = true; + return test; + }, + + /** + * Pending test case. + * + * @param {string} title + */ + skip: function (title) { + context.test(title); + }, + + /** + * Number of retry attempts + * + * @param {number} n + */ + retries: function (n) { + context.retries(n); + } + } + }; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/exports.js b/support/client/lib/vwf/view/mocha/lib/interfaces/exports.js new file mode 100644 index 000000000..debfaee3b --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/exports.js @@ -0,0 +1,63 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Suite = require('../suite'); +var Test = require('../test'); + +/** + * Exports-style (as Node.js module) interface: + * + * exports.Array = { + * '#indexOf()': { + * 'should return -1 when the value is not present': function() { + * + * }, + * + * 'should return the correct index when the value is present': function() { + * + * } + * } + * }; + * + * @param {Suite} suite Root suite. + */ +module.exports = function (suite) { + var suites = [suite]; + + suite.on('require', visit); + + function visit (obj, file) { + var suite; + for (var key in obj) { + if (typeof obj[key] === 'function') { + var fn = obj[key]; + switch (key) { + case 'before': + suites[0].beforeAll(fn); + break; + case 'after': + suites[0].afterAll(fn); + break; + case 'beforeEach': + suites[0].beforeEach(fn); + break; + case 'afterEach': + suites[0].afterEach(fn); + break; + default: + var test = new Test(key, fn); + test.file = file; + suites[0].addTest(test); + } + } else { + suite = Suite.create(suites[0], key); + suites.unshift(suite); + visit(obj[key], file); + suites.shift(); + } + } + } +}; diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/index.js b/support/client/lib/vwf/view/mocha/lib/interfaces/index.js new file mode 100644 index 000000000..0bd810abb --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/index.js @@ -0,0 +1,6 @@ +'use strict'; + +exports.bdd = require('./bdd'); +exports.tdd = require('./tdd'); +exports.qunit = require('./qunit'); +exports.exports = require('./exports'); diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/qunit.js b/support/client/lib/vwf/view/mocha/lib/interfaces/qunit.js new file mode 100644 index 000000000..44491db92 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/qunit.js @@ -0,0 +1,99 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Test = require('../test'); + +/** + * QUnit-style interface: + * + * suite('Array'); + * + * test('#length', function() { + * var arr = [1,2,3]; + * ok(arr.length == 3); + * }); + * + * test('#indexOf()', function() { + * var arr = [1,2,3]; + * ok(arr.indexOf(1) == 0); + * ok(arr.indexOf(2) == 1); + * ok(arr.indexOf(3) == 2); + * }); + * + * suite('String'); + * + * test('#length', function() { + * ok('foo'.length == 3); + * }); + * + * @param {Suite} suite Root suite. + */ +module.exports = function (suite) { + var suites = [suite]; + + suite.on('pre-require', function (context, file, mocha) { + var common = require('./common')(suites, context, mocha); + + context.before = common.before; + context.after = common.after; + context.beforeEach = common.beforeEach; + context.afterEach = common.afterEach; + context.run = mocha.options.delay && common.runWithSuite(suite); + /** + * Describe a "suite" with the given `title`. + */ + + context.suite = function (title) { + if (suites.length > 1) { + suites.shift(); + } + return common.suite.create({ + title: title, + file: file, + fn: false + }); + }; + + /** + * Exclusive Suite. + */ + + context.suite.only = function (title) { + if (suites.length > 1) { + suites.shift(); + } + return common.suite.only({ + title: title, + file: file, + fn: false + }); + }; + + /** + * Describe a specification or test-case + * with the given `title` and callback `fn` + * acting as a thunk. + */ + + context.test = function (title, fn) { + var test = new Test(title, fn); + test.file = file; + suites[0].addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function (title, fn) { + return common.test.only(mocha, context.test(title, fn)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; diff --git a/support/client/lib/vwf/view/mocha/lib/interfaces/tdd.js b/support/client/lib/vwf/view/mocha/lib/interfaces/tdd.js new file mode 100644 index 000000000..253e22157 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/interfaces/tdd.js @@ -0,0 +1,106 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Test = require('../test'); + +/** + * TDD-style interface: + * + * suite('Array', function() { + * suite('#indexOf()', function() { + * suiteSetup(function() { + * + * }); + * + * test('should return -1 when not present', function() { + * + * }); + * + * test('should return the index when present', function() { + * + * }); + * + * suiteTeardown(function() { + * + * }); + * }); + * }); + * + * @param {Suite} suite Root suite. + */ +module.exports = function (suite) { + var suites = [suite]; + + suite.on('pre-require', function (context, file, mocha) { + var common = require('./common')(suites, context, mocha); + + context.setup = common.beforeEach; + context.teardown = common.afterEach; + context.suiteSetup = common.before; + context.suiteTeardown = common.after; + context.run = mocha.options.delay && common.runWithSuite(suite); + + /** + * Describe a "suite" with the given `title` and callback `fn` containing + * nested suites and/or tests. + */ + context.suite = function (title, fn) { + return common.suite.create({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Pending suite. + */ + context.suite.skip = function (title, fn) { + return common.suite.skip({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Exclusive test-case. + */ + context.suite.only = function (title, fn) { + return common.suite.only({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Describe a specification or test-case with the given `title` and + * callback `fn` acting as a thunk. + */ + context.test = function (title, fn) { + var suite = suites[0]; + if (suite.isPending()) { + fn = null; + } + var test = new Test(title, fn); + test.file = file; + suite.addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function (title, fn) { + return common.test.only(mocha, context.test(title, fn)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; diff --git a/support/client/lib/vwf/view/mocha/lib/mocha.js b/support/client/lib/vwf/view/mocha/lib/mocha.js new file mode 100644 index 000000000..dcc1492f5 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/mocha.js @@ -0,0 +1,522 @@ +'use strict'; + +/*! + * mocha + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var escapeRe = require('escape-string-regexp'); +var path = require('path'); +var reporters = require('./reporters'); +var utils = require('./utils'); + +/** + * Expose `Mocha`. + */ + +exports = module.exports = Mocha; + +/** + * To require local UIs and reporters when running in node. + */ + +if (!process.browser) { + var cwd = process.cwd(); + module.paths.push(cwd, path.join(cwd, 'node_modules')); +} + +/** + * Expose internals. + */ + +exports.utils = utils; +exports.interfaces = require('./interfaces'); +exports.reporters = reporters; +exports.Runnable = require('./runnable'); +exports.Context = require('./context'); +exports.Runner = require('./runner'); +exports.Suite = require('./suite'); +exports.Hook = require('./hook'); +exports.Test = require('./test'); + +/** + * Return image `name` path. + * + * @api private + * @param {string} name + * @return {string} + */ +function image (name) { + return path.join(__dirname, '../images', name + '.png'); +} + +/** + * Set up mocha with `options`. + * + * Options: + * + * - `ui` name "bdd", "tdd", "exports" etc + * - `reporter` reporter instance, defaults to `mocha.reporters.spec` + * - `globals` array of accepted globals + * - `timeout` timeout in milliseconds + * - `retries` number of times to retry failed tests + * - `bail` bail on the first test failure + * - `slow` milliseconds to wait before considering a test slow + * - `ignoreLeaks` ignore global leaks + * - `fullTrace` display the full stack-trace on failing + * - `grep` string or regexp to filter tests with + * + * @param {Object} options + * @api public + */ +function Mocha (options) { + options = options || {}; + this.files = []; + this.options = options; + if (options.grep) { + this.grep(new RegExp(options.grep)); + } + if (options.fgrep) { + this.fgrep(options.fgrep); + } + this.suite = new exports.Suite('', new exports.Context()); + this.ui(options.ui); + this.bail(options.bail); + this.reporter(options.reporter, options.reporterOptions); + if (typeof options.timeout !== 'undefined' && options.timeout !== null) { + this.timeout(options.timeout); + } + if (typeof options.retries !== 'undefined' && options.retries !== null) { + this.retries(options.retries); + } + this.useColors(options.useColors); + if (options.enableTimeouts !== null) { + this.enableTimeouts(options.enableTimeouts); + } + if (options.slow) { + this.slow(options.slow); + } +} + +/** + * Enable or disable bailing on the first failure. + * + * @api public + * @param {boolean} [bail] + */ +Mocha.prototype.bail = function (bail) { + if (!arguments.length) { + bail = true; + } + this.suite.bail(bail); + return this; +}; + +/** + * Add test `file`. + * + * @api public + * @param {string} file + */ +Mocha.prototype.addFile = function (file) { + this.files.push(file); + return this; +}; + +/** + * Set reporter to `reporter`, defaults to "spec". + * + * @param {String|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + * @api public + * @param {string|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + */ +Mocha.prototype.reporter = function (reporter, reporterOptions) { + if (typeof reporter === 'function') { + this._reporter = reporter; + } else { + reporter = reporter || 'spec'; + var _reporter; + // Try to load a built-in reporter. + if (reporters[reporter]) { + _reporter = reporters[reporter]; + } + // Try to load reporters from process.cwd() and node_modules + if (!_reporter) { + try { + _reporter = require(reporter); + } catch (err) { + err.message.indexOf('Cannot find module') !== -1 + ? console.warn('"' + reporter + '" reporter not found') + : console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack); + } + } + if (!_reporter && reporter === 'teamcity') { + console.warn('The Teamcity reporter was moved to a package named ' + + 'mocha-teamcity-reporter ' + + '(https://npmjs.org/package/mocha-teamcity-reporter).'); + } + if (!_reporter) { + throw new Error('invalid reporter "' + reporter + '"'); + } + this._reporter = _reporter; + } + this.options.reporterOptions = reporterOptions; + return this; +}; + +/** + * Set test UI `name`, defaults to "bdd". + * + * @api public + * @param {string} bdd + */ +Mocha.prototype.ui = function (name) { + name = name || 'bdd'; + this._ui = exports.interfaces[name]; + if (!this._ui) { + try { + this._ui = require(name); + } catch (err) { + throw new Error('invalid interface "' + name + '"'); + } + } + this._ui = this._ui(this.suite); + + this.suite.on('pre-require', function (context) { + exports.afterEach = context.afterEach || context.teardown; + exports.after = context.after || context.suiteTeardown; + exports.beforeEach = context.beforeEach || context.setup; + exports.before = context.before || context.suiteSetup; + exports.describe = context.describe || context.suite; + exports.it = context.it || context.test; + exports.setup = context.setup || context.beforeEach; + exports.suiteSetup = context.suiteSetup || context.before; + exports.suiteTeardown = context.suiteTeardown || context.after; + exports.suite = context.suite || context.describe; + exports.teardown = context.teardown || context.afterEach; + exports.test = context.test || context.it; + exports.run = context.run; + }); + + return this; +}; + +/** + * Load registered files. + * + * @api private + */ +Mocha.prototype.loadFiles = function (fn) { + var self = this; + var suite = this.suite; + this.files.forEach(function (file) { + file = path.resolve(file); + suite.emit('pre-require', global, file, self); + suite.emit('require', require(file), file, self); + suite.emit('post-require', global, file, self); + }); + fn && fn(); +}; + +/** + * Enable growl support. + * + * @api private + */ +Mocha.prototype._growl = function (runner, reporter) { + var notify = require('growl'); + + runner.on('end', function () { + var stats = reporter.stats; + if (stats.failures) { + var msg = stats.failures + ' of ' + runner.total + ' tests failed'; + notify(msg, { name: 'mocha', title: 'Failed', image: image('error') }); + } else { + notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', { + name: 'mocha', + title: 'Passed', + image: image('ok') + }); + } + }); +}; + +/** + * Escape string and add it to grep as a regexp. + * + * @api public + * @param str + * @returns {Mocha} + */ +Mocha.prototype.fgrep = function (str) { + return this.grep(new RegExp(escapeRe(str))); +}; + +/** + * Add regexp to grep, if `re` is a string it is escaped. + * + * @param {RegExp|String} re + * @return {Mocha} + * @api public + * @param {RegExp|string} re + * @return {Mocha} + */ +Mocha.prototype.grep = function (re) { + if (utils.isString(re)) { + // extract args if it's regex-like, i.e: [string, pattern, flag] + var arg = re.match(/^\/(.*)\/(g|i|)$|.*/); + this.options.grep = new RegExp(arg[1] || arg[0], arg[2]); + } else { + this.options.grep = re; + } + return this; +}; +/** + * Invert `.grep()` matches. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.invert = function () { + this.options.invert = true; + return this; +}; + +/** + * Ignore global leaks. + * + * @param {Boolean} ignore + * @return {Mocha} + * @api public + * @param {boolean} ignore + * @return {Mocha} + */ +Mocha.prototype.ignoreLeaks = function (ignore) { + this.options.ignoreLeaks = Boolean(ignore); + return this; +}; + +/** + * Enable global leak checking. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.checkLeaks = function () { + this.options.ignoreLeaks = false; + return this; +}; + +/** + * Display long stack-trace on failing + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.fullTrace = function () { + this.options.fullStackTrace = true; + return this; +}; + +/** + * Enable growl support. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.growl = function () { + this.options.growl = true; + return this; +}; + +/** + * Ignore `globals` array or string. + * + * @param {Array|String} globals + * @return {Mocha} + * @api public + * @param {Array|string} globals + * @return {Mocha} + */ +Mocha.prototype.globals = function (globals) { + this.options.globals = (this.options.globals || []).concat(globals); + return this; +}; + +/** + * Emit color output. + * + * @param {Boolean} colors + * @return {Mocha} + * @api public + * @param {boolean} colors + * @return {Mocha} + */ +Mocha.prototype.useColors = function (colors) { + if (colors !== undefined) { + this.options.useColors = colors; + } + return this; +}; + +/** + * Use inline diffs rather than +/-. + * + * @param {Boolean} inlineDiffs + * @return {Mocha} + * @api public + * @param {boolean} inlineDiffs + * @return {Mocha} + */ +Mocha.prototype.useInlineDiffs = function (inlineDiffs) { + this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; + return this; +}; + +/** + * Set the timeout in milliseconds. + * + * @param {Number} timeout + * @return {Mocha} + * @api public + * @param {number} timeout + * @return {Mocha} + */ +Mocha.prototype.timeout = function (timeout) { + this.suite.timeout(timeout); + return this; +}; + +/** + * Set the number of times to retry failed tests. + * + * @param {Number} retry times + * @return {Mocha} + * @api public + */ +Mocha.prototype.retries = function (n) { + this.suite.retries(n); + return this; +}; + +/** + * Set slowness threshold in milliseconds. + * + * @param {Number} slow + * @return {Mocha} + * @api public + * @param {number} slow + * @return {Mocha} + */ +Mocha.prototype.slow = function (slow) { + this.suite.slow(slow); + return this; +}; + +/** + * Enable timeouts. + * + * @param {Boolean} enabled + * @return {Mocha} + * @api public + * @param {boolean} enabled + * @return {Mocha} + */ +Mocha.prototype.enableTimeouts = function (enabled) { + this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true); + return this; +}; + +/** + * Makes all tests async (accepting a callback) + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.asyncOnly = function () { + this.options.asyncOnly = true; + return this; +}; + +/** + * Disable syntax highlighting (in browser). + * + * @api public + */ +Mocha.prototype.noHighlighting = function () { + this.options.noHighlighting = true; + return this; +}; + +/** + * Enable uncaught errors to propagate (in browser). + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.allowUncaught = function () { + this.options.allowUncaught = true; + return this; +}; + +/** + * Delay root suite execution. + * @returns {Mocha} + */ +Mocha.prototype.delay = function delay () { + this.options.delay = true; + return this; +}; + +/** + * Run tests and invoke `fn()` when complete. + * + * @api public + * @param {Function} fn + * @return {Runner} + */ +Mocha.prototype.run = function (fn) { + if (this.files.length) { + this.loadFiles(); + } + var suite = this.suite; + var options = this.options; + options.files = this.files; + var runner = new exports.Runner(suite, options.delay); + var reporter = new this._reporter(runner, options); + runner.ignoreLeaks = options.ignoreLeaks !== false; + runner.fullStackTrace = options.fullStackTrace; + runner.hasOnly = options.hasOnly; + runner.asyncOnly = options.asyncOnly; + runner.allowUncaught = options.allowUncaught; + if (options.grep) { + runner.grep(options.grep, options.invert); + } + if (options.globals) { + runner.globals(options.globals); + } + if (options.growl) { + this._growl(runner, reporter); + } + if (options.useColors !== undefined) { + exports.reporters.Base.useColors = options.useColors; + } + exports.reporters.Base.inlineDiffs = options.useInlineDiffs; + + function done (failures) { + if (reporter.done) { + reporter.done(failures, fn); + } else { + fn && fn(failures); + } + } + + return runner.run(done); +}; diff --git a/support/client/lib/vwf/view/mocha/lib/ms.js b/support/client/lib/vwf/view/mocha/lib/ms.js new file mode 100644 index 000000000..959085605 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/ms.js @@ -0,0 +1,130 @@ +'use strict'; + +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @api public + * @param {string|number} val + * @param {Object} options + * @return {string|number} + */ +module.exports = function (val, options) { + options = options || {}; + if (typeof val === 'string') { + return parse(val); + } + // https://github.com/mochajs/mocha/pull/1035 + return options['long'] ? longFormat(val) : shortFormat(val); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @api private + * @param {string} str + * @return {number} + */ +function parse (str) { + var match = (/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 's': + return n * s; + case 'ms': + return n; + default: + // No default case + } +} + +/** + * Short format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function shortFormat (ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function longFormat (ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} + +/** + * Pluralization helper. + * + * @api private + * @param {number} ms + * @param {number} n + * @param {string} name + */ +function plural (ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; +} diff --git a/support/client/lib/vwf/view/mocha/lib/pending.js b/support/client/lib/vwf/view/mocha/lib/pending.js new file mode 100644 index 000000000..c78010461 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/pending.js @@ -0,0 +1,16 @@ +'use strict'; + +/** + * Expose `Pending`. + */ + +module.exports = Pending; + +/** + * Initialize a new `Pending` error with the given message. + * + * @param {string} message + */ +function Pending (message) { + this.message = message; +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/base.js b/support/client/lib/vwf/view/mocha/lib/reporters/base.js new file mode 100644 index 000000000..205488426 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/base.js @@ -0,0 +1,491 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var tty = require('tty'); +var diff = require('diff'); +var ms = require('../ms'); +var utils = require('../utils'); +var supportsColor = process.browser ? null : require('supports-color'); + +/** + * Expose `Base`. + */ + +exports = module.exports = Base; + +/** + * Save timer references to avoid Sinon interfering. + * See: https://github.com/mochajs/mocha/issues/237 + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Check if both stdio streams are associated with a tty. + */ + +var isatty = tty.isatty(1) && tty.isatty(2); + +/** + * Enable coloring by default, except in the browser interface. + */ + +exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined)); + +/** + * Inline diffs instead of +/- + */ + +exports.inlineDiffs = false; + +/** + * Default color map. + */ + +exports.colors = { + pass: 90, + fail: 31, + 'bright pass': 92, + 'bright fail': 91, + 'bright yellow': 93, + pending: 36, + suite: 0, + 'error title': 0, + 'error message': 31, + 'error stack': 90, + checkmark: 32, + fast: 90, + medium: 33, + slow: 31, + green: 32, + light: 90, + 'diff gutter': 90, + 'diff added': 32, + 'diff removed': 31 +}; + +/** + * Default symbol map. + */ + +exports.symbols = { + ok: '✓', + err: '✖', + dot: '․', + comma: ',', + bang: '!' +}; + +// With node.js on Windows: use symbols available in terminal default fonts +if (process.platform === 'win32') { + exports.symbols.ok = '\u221A'; + exports.symbols.err = '\u00D7'; + exports.symbols.dot = '.'; +} + +/** + * Color `str` with the given `type`, + * allowing colors to be disabled, + * as well as user-defined color + * schemes. + * + * @param {string} type + * @param {string} str + * @return {string} + * @api private + */ +var color = exports.color = function (type, str) { + if (!exports.useColors) { + return String(str); + } + return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m'; +}; + +/** + * Expose term window size, with some defaults for when stderr is not a tty. + */ + +exports.window = { + width: 75 +}; + +if (isatty) { + exports.window.width = process.stdout.getWindowSize + ? process.stdout.getWindowSize(1)[0] + : tty.getWindowSize()[1]; +} + +/** + * Expose some basic cursor interactions that are common among reporters. + */ + +exports.cursor = { + hide: function () { + isatty && process.stdout.write('\u001b[?25l'); + }, + + show: function () { + isatty && process.stdout.write('\u001b[?25h'); + }, + + deleteLine: function () { + isatty && process.stdout.write('\u001b[2K'); + }, + + beginningOfLine: function () { + isatty && process.stdout.write('\u001b[0G'); + }, + + CR: function () { + if (isatty) { + exports.cursor.deleteLine(); + exports.cursor.beginningOfLine(); + } else { + process.stdout.write('\r'); + } + } +}; + +/** + * Outut the given `failures` as a list. + * + * @param {Array} failures + * @api public + */ + +exports.list = function (failures) { + console.log(); + failures.forEach(function (test, i) { + // format + var fmt = color('error title', ' %s) %s:\n') + + color('error message', ' %s') + + color('error stack', '\n%s\n'); + + // msg + var msg; + var err = test.err; + var message; + if (err.message && typeof err.message.toString === 'function') { + message = err.message + ''; + } else if (typeof err.inspect === 'function') { + message = err.inspect() + ''; + } else { + message = ''; + } + var stack = err.stack || message; + var index = message ? stack.indexOf(message) : -1; + var actual = err.actual; + var expected = err.expected; + var escape = true; + + if (index === -1) { + msg = message; + } else { + index += message.length; + msg = stack.slice(0, index); + // remove msg from stack + stack = stack.slice(index + 1); + } + + // uncaught + if (err.uncaught) { + msg = 'Uncaught ' + msg; + } + // explicitly show diff + if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) { + escape = false; + if (!(utils.isString(actual) && utils.isString(expected))) { + err.actual = actual = utils.stringify(actual); + err.expected = expected = utils.stringify(expected); + } + + fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n'); + var match = message.match(/^([^:]+): expected/); + msg = '\n ' + color('error message', match ? match[1] : msg); + + if (exports.inlineDiffs) { + msg += inlineDiff(err, escape); + } else { + msg += unifiedDiff(err, escape); + } + } + + // indent stack trace + stack = stack.replace(/^/gm, ' '); + + console.log(fmt, (i + 1), test.fullTitle(), msg, stack); + }); +}; + +/** + * Initialize a new `Base` reporter. + * + * All other reporters generally + * inherit from this reporter, providing + * stats such as test duration, number + * of tests passed / failed etc. + * + * @param {Runner} runner + * @api public + */ + +function Base (runner) { + var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }; + var failures = this.failures = []; + + if (!runner) { + return; + } + this.runner = runner; + + runner.stats = stats; + + runner.on('start', function () { + stats.start = new Date(); + }); + + runner.on('suite', function (suite) { + stats.suites = stats.suites || 0; + suite.root || stats.suites++; + }); + + runner.on('test end', function () { + stats.tests = stats.tests || 0; + stats.tests++; + }); + + runner.on('pass', function (test) { + stats.passes = stats.passes || 0; + + if (test.duration > test.slow()) { + test.speed = 'slow'; + } else if (test.duration > test.slow() / 2) { + test.speed = 'medium'; + } else { + test.speed = 'fast'; + } + + stats.passes++; + }); + + runner.on('fail', function (test, err) { + stats.failures = stats.failures || 0; + stats.failures++; + test.err = err; + failures.push(test); + }); + + runner.on('end', function () { + stats.end = new Date(); + stats.duration = new Date() - stats.start; + }); + + runner.on('pending', function () { + stats.pending++; + }); +} + +/** + * Output common epilogue used by many of + * the bundled reporters. + * + * @api public + */ +Base.prototype.epilogue = function () { + var stats = this.stats; + var fmt; + + console.log(); + + // passes + fmt = color('bright pass', ' ') + + color('green', ' %d passing') + + color('light', ' (%s)'); + + console.log(fmt, + stats.passes || 0, + ms(stats.duration)); + + // pending + if (stats.pending) { + fmt = color('pending', ' ') + + color('pending', ' %d pending'); + + console.log(fmt, stats.pending); + } + + // failures + if (stats.failures) { + fmt = color('fail', ' %d failing'); + + console.log(fmt, stats.failures); + + Base.list(this.failures); + console.log(); + } + + console.log(); +}; + +/** + * Pad the given `str` to `len`. + * + * @api private + * @param {string} str + * @param {string} len + * @return {string} + */ +function pad (str, len) { + str = String(str); + return Array(len - str.length + 1).join(' ') + str; +} + +/** + * Returns an inline diff between 2 strings with coloured ANSI output + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} Diff + */ +function inlineDiff (err, escape) { + var msg = errorDiff(err, 'WordsWithSpace', escape); + + // linenos + var lines = msg.split('\n'); + if (lines.length > 4) { + var width = String(lines.length).length; + msg = lines.map(function (str, i) { + return pad(++i, width) + ' |' + ' ' + str; + }).join('\n'); + } + + // legend + msg = '\n' + + color('diff removed', 'actual') + + ' ' + + color('diff added', 'expected') + + '\n\n' + + msg + + '\n'; + + // indent + msg = msg.replace(/^/gm, ' '); + return msg; +} + +/** + * Returns a unified diff between two strings. + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} The diff. + */ +function unifiedDiff (err, escape) { + var indent = ' '; + function cleanUp (line) { + if (escape) { + line = escapeInvisibles(line); + } + if (line[0] === '+') { + return indent + colorLines('diff added', line); + } + if (line[0] === '-') { + return indent + colorLines('diff removed', line); + } + if (line.match(/@@/)) { + return null; + } + if (line.match(/\\ No newline/)) { + return null; + } + return indent + line; + } + function notBlank (line) { + return typeof line !== 'undefined' && line !== null; + } + var msg = diff.createPatch('string', err.actual, err.expected); + var lines = msg.split('\n').splice(4); + return '\n ' + + colorLines('diff added', '+ expected') + ' ' + + colorLines('diff removed', '- actual') + + '\n\n' + + lines.map(cleanUp).filter(notBlank).join('\n'); +} + +/** + * Return a character diff for `err`. + * + * @api private + * @param {Error} err + * @param {string} type + * @param {boolean} escape + * @return {string} + */ +function errorDiff (err, type, escape) { + var actual = escape ? escapeInvisibles(err.actual) : err.actual; + var expected = escape ? escapeInvisibles(err.expected) : err.expected; + return diff['diff' + type](actual, expected).map(function (str) { + if (str.added) { + return colorLines('diff added', str.value); + } + if (str.removed) { + return colorLines('diff removed', str.value); + } + return str.value; + }).join(''); +} + +/** + * Returns a string with all invisible characters in plain text + * + * @api private + * @param {string} line + * @return {string} + */ +function escapeInvisibles (line) { + return line.replace(/\t/g, '') + .replace(/\r/g, '') + .replace(/\n/g, '\n'); +} + +/** + * Color lines for `str`, using the color `name`. + * + * @api private + * @param {string} name + * @param {string} str + * @return {string} + */ +function colorLines (name, str) { + return str.split('\n').map(function (str) { + return color(name, str); + }).join('\n'); +} + +/** + * Object#toString reference. + */ +var objToString = Object.prototype.toString; + +/** + * Check that a / b have the same type. + * + * @api private + * @param {Object} a + * @param {Object} b + * @return {boolean} + */ +function sameType (a, b) { + return objToString.call(a) === objToString.call(b); +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/doc.js b/support/client/lib/vwf/view/mocha/lib/reporters/doc.js new file mode 100644 index 000000000..aad1d9252 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/doc.js @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Expose `Doc`. + */ + +exports = module.exports = Doc; + +/** + * Initialize a new `Doc` reporter. + * + * @param {Runner} runner + * @api public + */ +function Doc (runner) { + Base.call(this, runner); + + var indents = 2; + + function indent () { + return Array(indents).join(' '); + } + + runner.on('suite', function (suite) { + if (suite.root) { + return; + } + ++indents; + console.log('%s
', indent()); + ++indents; + console.log('%s

%s

', indent(), utils.escape(suite.title)); + console.log('%s
', indent()); + }); + + runner.on('suite end', function (suite) { + if (suite.root) { + return; + } + console.log('%s
', indent()); + --indents; + console.log('%s
', indent()); + --indents; + }); + + runner.on('pass', function (test) { + console.log('%s
%s
', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.body)); + console.log('%s
%s
', indent(), code); + }); + + runner.on('fail', function (test, err) { + console.log('%s
%s
', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.body)); + console.log('%s
%s
', indent(), code); + console.log('%s
%s
', indent(), utils.escape(err)); + }); +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/dot.js b/support/client/lib/vwf/view/mocha/lib/reporters/dot.js new file mode 100644 index 000000000..81e106edd --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/dot.js @@ -0,0 +1,68 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; + +/** + * Expose `Dot`. + */ + +exports = module.exports = Dot; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @api public + * @param {Runner} runner + */ +function Dot (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var n = -1; + + runner.on('start', function () { + process.stdout.write('\n'); + }); + + runner.on('pending', function () { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('pending', Base.symbols.comma)); + }); + + runner.on('pass', function (test) { + if (++n % width === 0) { + process.stdout.write('\n '); + } + if (test.speed === 'slow') { + process.stdout.write(color('bright yellow', Base.symbols.dot)); + } else { + process.stdout.write(color(test.speed, Base.symbols.dot)); + } + }); + + runner.on('fail', function () { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('fail', Base.symbols.bang)); + }); + + runner.on('end', function () { + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Dot, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/html.js b/support/client/lib/vwf/view/mocha/lib/reporters/html.js new file mode 100644 index 000000000..9b9817c50 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/html.js @@ -0,0 +1,346 @@ +'use strict'; + +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var Progress = require('../browser/progress'); +var escapeRe = require('escape-string-regexp'); +var escape = utils.escape; + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `HTML`. + */ + +exports = module.exports = HTML; + +/** + * Stats template. + */ + +var statsTemplate = ''; + +/** + * Initialize a new `HTML` reporter. + * + * @api public + * @param {Runner} runner + */ +function HTML (runner) { + Base.call(this, runner); + + var self = this; + var stats = this.stats; + var stat = fragment(statsTemplate); + var items = stat.getElementsByTagName('li'); + var passes = items[1].getElementsByTagName('em')[0]; + var passesLink = items[1].getElementsByTagName('a')[0]; + var failures = items[2].getElementsByTagName('em')[0]; + var failuresLink = items[2].getElementsByTagName('a')[0]; + var duration = items[3].getElementsByTagName('em')[0]; + var canvas = stat.getElementsByTagName('canvas')[0]; + var report = fragment('
    '); + var stack = [report]; + var progress; + var ctx; + var root = document.getElementById('mocha'); + + if (canvas.getContext) { + var ratio = window.devicePixelRatio || 1; + canvas.style.width = canvas.width; + canvas.style.height = canvas.height; + canvas.width *= ratio; + canvas.height *= ratio; + ctx = canvas.getContext('2d'); + ctx.scale(ratio, ratio); + progress = new Progress(); + } + + if (!root) { + return error('#mocha div missing, add it to your document'); + } + + // pass toggle + on(passesLink, 'click', function (evt) { + evt.preventDefault(); + unhide(); + var name = (/pass/).test(report.className) ? '' : ' pass'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test pass'); + } + }); + + // failure toggle + on(failuresLink, 'click', function (evt) { + evt.preventDefault(); + unhide(); + var name = (/fail/).test(report.className) ? '' : ' fail'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test fail'); + } + }); + + root.appendChild(stat); + root.appendChild(report); + + if (progress) { + progress.size(40); + } + + runner.on('suite', function (suite) { + if (suite.root) { + return; + } + + // suite + var url = self.suiteURL(suite); + var el = fragment('
  • %s

  • ', url, escape(suite.title)); + + // container + stack[0].appendChild(el); + stack.unshift(document.createElement('ul')); + el.appendChild(stack[0]); + }); + + runner.on('suite end', function (suite) { + if (suite.root) { + updateStats(); + return; + } + stack.shift(); + }); + + runner.on('pass', function (test) { + var url = self.testURL(test); + var markup = '
  • %e%ems ' + + '

  • '; + var el = fragment(markup, test.speed, test.title, test.duration, url); + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('fail', function (test) { + var el = fragment('
  • %e

  • ', + test.title, self.testURL(test)); + var stackString; // Note: Includes leading newline + var message = test.err.toString(); + + // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we + // check for the result of the stringifying. + if (message === '[object Error]') { + message = test.err.message; + } + + if (test.err.stack) { + var indexOfMessage = test.err.stack.indexOf(test.err.message); + if (indexOfMessage === -1) { + stackString = test.err.stack; + } else { + stackString = test.err.stack.substr(test.err.message.length + indexOfMessage); + } + } else if (test.err.sourceURL && test.err.line !== undefined) { + // Safari doesn't give you a stack. Let's at least provide a source line. + stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')'; + } + + stackString = stackString || ''; + + if (test.err.htmlMessage && stackString) { + el.appendChild(fragment('
    %s\n
    %e
    ', + test.err.htmlMessage, stackString)); + } else if (test.err.htmlMessage) { + el.appendChild(fragment('
    %s
    ', test.err.htmlMessage)); + } else { + el.appendChild(fragment('
    %e%e
    ', message, stackString)); + } + + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('pending', function (test) { + var el = fragment('
  • %e

  • ', test.title); + appendToStack(el); + updateStats(); + }); + + function appendToStack (el) { + // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack. + if (stack[0]) { + stack[0].appendChild(el); + } + } + + function updateStats () { + // TODO: add to stats + var percent = stats.tests / runner.total * 100 | 0; + if (progress) { + progress.update(percent).draw(ctx); + } + + // update stats + var ms = new Date() - stats.start; + text(passes, stats.passes); + text(failures, stats.failures); + text(duration, (ms / 1000).toFixed(2)); + } +} + +/** + * Makes a URL, preserving querystring ("search") parameters. + * + * @param {string} s + * @return {string} A new URL. + */ +function makeUrl (s) { + var search = window.location.search; + + // Remove previous grep query parameter if present + if (search) { + search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?'); + } + + return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s)); +} + +/** + * Provide suite URL. + * + * @param {Object} [suite] + */ +HTML.prototype.suiteURL = function (suite) { + return makeUrl(suite.fullTitle()); +}; + +/** + * Provide test URL. + * + * @param {Object} [test] + */ +HTML.prototype.testURL = function (test) { + return makeUrl(test.fullTitle()); +}; + +/** + * Adds code toggle functionality for the provided test's list element. + * + * @param {HTMLLIElement} el + * @param {string} contents + */ +HTML.prototype.addCodeToggle = function (el, contents) { + var h2 = el.getElementsByTagName('h2')[0]; + + on(h2, 'click', function () { + pre.style.display = pre.style.display === 'none' ? 'block' : 'none'; + }); + + var pre = fragment('
    %e
    ', utils.clean(contents)); + el.appendChild(pre); + pre.style.display = 'none'; +}; + +/** + * Display error `msg`. + * + * @param {string} msg + */ +function error (msg) { + document.body.appendChild(fragment('
    %s
    ', msg)); +} + +/** + * Return a DOM fragment from `html`. + * + * @param {string} html + */ +function fragment (html) { + var args = arguments; + var div = document.createElement('div'); + var i = 1; + + div.innerHTML = html.replace(/%([se])/g, function (_, type) { + switch (type) { + case 's': return String(args[i++]); + case 'e': return escape(args[i++]); + // no default + } + }); + + return div.firstChild; +} + +/** + * Check for suites that do not have elements + * with `classname`, and hide them. + * + * @param {text} classname + */ +function hideSuitesWithout (classname) { + var suites = document.getElementsByClassName('suite'); + for (var i = 0; i < suites.length; i++) { + var els = suites[i].getElementsByClassName(classname); + if (!els.length) { + suites[i].className += ' hidden'; + } + } +} + +/** + * Unhide .hidden suites. + */ +function unhide () { + var els = document.getElementsByClassName('suite hidden'); + for (var i = 0; i < els.length; ++i) { + els[i].className = els[i].className.replace('suite hidden', 'suite'); + } +} + +/** + * Set an element's text contents. + * + * @param {HTMLElement} el + * @param {string} contents + */ +function text (el, contents) { + if (el.textContent) { + el.textContent = contents; + } else { + el.innerText = contents; + } +} + +/** + * Listen on `event` with callback `fn`. + */ +function on (el, event, fn) { + if (el.addEventListener) { + el.addEventListener(event, fn, false); + } else { + el.attachEvent('on' + event, fn); + } +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/index.js b/support/client/lib/vwf/view/mocha/lib/reporters/index.js new file mode 100644 index 000000000..d3b5481e4 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/index.js @@ -0,0 +1,19 @@ +'use strict'; + +// Alias exports to a their normalized format Mocha#reporter to prevent a need +// for dynamic (try/catch) requires, which Browserify doesn't handle. +exports.Base = exports.base = require('./base'); +exports.Dot = exports.dot = require('./dot'); +exports.Doc = exports.doc = require('./doc'); +exports.TAP = exports.tap = require('./tap'); +exports.JSON = exports.json = require('./json'); +exports.HTML = exports.html = require('./html'); +exports.List = exports.list = require('./list'); +exports.Min = exports.min = require('./min'); +exports.Spec = exports.spec = require('./spec'); +exports.Nyan = exports.nyan = require('./nyan'); +exports.XUnit = exports.xunit = require('./xunit'); +exports.Markdown = exports.markdown = require('./markdown'); +exports.Progress = exports.progress = require('./progress'); +exports.Landing = exports.landing = require('./landing'); +exports.JSONStream = exports['json-stream'] = require('./json-stream'); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/json-stream.js b/support/client/lib/vwf/view/mocha/lib/reporters/json-stream.js new file mode 100644 index 000000000..6126e47ea --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/json-stream.js @@ -0,0 +1,63 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var JSON = require('json3'); + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List (runner) { + Base.call(this, runner); + + var self = this; + var total = runner.total; + + runner.on('start', function () { + console.log(JSON.stringify(['start', { total: total }])); + }); + + runner.on('pass', function (test) { + console.log(JSON.stringify(['pass', clean(test)])); + }); + + runner.on('fail', function (test, err) { + test = clean(test); + test.err = err.message; + test.stack = err.stack || null; + console.log(JSON.stringify(['fail', test])); + }); + + runner.on('end', function () { + process.stdout.write(JSON.stringify(['end', self.stats])); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean (test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry() + }; +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/json.js b/support/client/lib/vwf/view/mocha/lib/reporters/json.js new file mode 100644 index 000000000..259a78212 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/json.js @@ -0,0 +1,92 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `JSON`. + */ + +exports = module.exports = JSONReporter; + +/** + * Initialize a new `JSON` reporter. + * + * @api public + * @param {Runner} runner + */ +function JSONReporter (runner) { + Base.call(this, runner); + + var self = this; + var tests = []; + var pending = []; + var failures = []; + var passes = []; + + runner.on('test end', function (test) { + tests.push(test); + }); + + runner.on('pass', function (test) { + passes.push(test); + }); + + runner.on('fail', function (test) { + failures.push(test); + }); + + runner.on('pending', function (test) { + pending.push(test); + }); + + runner.on('end', function () { + var obj = { + stats: self.stats, + tests: tests.map(clean), + pending: pending.map(clean), + failures: failures.map(clean), + passes: passes.map(clean) + }; + + runner.testResults = obj; + + process.stdout.write(JSON.stringify(obj, null, 2)); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean (test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry(), + err: errorJSON(test.err || {}) + }; +} + +/** + * Transform `error` into a JSON object. + * + * @api private + * @param {Error} err + * @return {Object} + */ +function errorJSON (err) { + var res = {}; + Object.getOwnPropertyNames(err).forEach(function (key) { + res[key] = err[key]; + }, err); + return res; +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/landing.js b/support/client/lib/vwf/view/mocha/lib/reporters/landing.js new file mode 100644 index 000000000..b8c7b5f20 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/landing.js @@ -0,0 +1,94 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var cursor = Base.cursor; +var color = Base.color; + +/** + * Expose `Landing`. + */ + +exports = module.exports = Landing; + +/** + * Airplane color. + */ + +Base.colors.plane = 0; + +/** + * Airplane crash color. + */ + +Base.colors['plane crash'] = 31; + +/** + * Runway color. + */ + +Base.colors.runway = 90; + +/** + * Initialize a new `Landing` reporter. + * + * @api public + * @param {Runner} runner + */ +function Landing (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var total = runner.total; + var stream = process.stdout; + var plane = color('plane', '✈'); + var crashed = -1; + var n = 0; + + function runway () { + var buf = Array(width).join('-'); + return ' ' + color('runway', buf); + } + + runner.on('start', function () { + stream.write('\n\n\n '); + cursor.hide(); + }); + + runner.on('test end', function (test) { + // check if the plane crashed + var col = crashed === -1 ? width * ++n / total | 0 : crashed; + + // show the crash + if (test.state === 'failed') { + plane = color('plane crash', '✈'); + crashed = col; + } + + // render landing strip + stream.write('\u001b[' + (width + 1) + 'D\u001b[2A'); + stream.write(runway()); + stream.write('\n '); + stream.write(color('runway', Array(col).join('⋅'))); + stream.write(plane); + stream.write(color('runway', Array(width - col).join('⋅') + '\n')); + stream.write(runway()); + stream.write('\u001b[0m'); + }); + + runner.on('end', function () { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Landing, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/list.js b/support/client/lib/vwf/view/mocha/lib/reporters/list.js new file mode 100644 index 000000000..a562cdb94 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/list.js @@ -0,0 +1,63 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List (runner) { + Base.call(this, runner); + + var self = this; + var n = 0; + + runner.on('start', function () { + console.log(); + }); + + runner.on('test', function (test) { + process.stdout.write(color('pass', ' ' + test.fullTitle() + ': ')); + }); + + runner.on('pending', function (test) { + var fmt = color('checkmark', ' -') + + color('pending', ' %s'); + console.log(fmt, test.fullTitle()); + }); + + runner.on('pass', function (test) { + var fmt = color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s: ') + + color(test.speed, '%dms'); + cursor.CR(); + console.log(fmt, test.fullTitle(), test.duration); + }); + + runner.on('fail', function (test) { + cursor.CR(); + console.log(color('fail', ' %d) %s'), ++n, test.fullTitle()); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(List, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/markdown.js b/support/client/lib/vwf/view/mocha/lib/reporters/markdown.js new file mode 100644 index 000000000..9c06616ea --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/markdown.js @@ -0,0 +1,99 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Constants + */ + +var SUITE_PREFIX = '$'; + +/** + * Expose `Markdown`. + */ + +exports = module.exports = Markdown; + +/** + * Initialize a new `Markdown` reporter. + * + * @api public + * @param {Runner} runner + */ +function Markdown (runner) { + Base.call(this, runner); + + var level = 0; + var buf = ''; + + function title (str) { + return Array(level).join('#') + ' ' + str; + } + + function mapTOC (suite, obj) { + var ret = obj; + var key = SUITE_PREFIX + suite.title; + + obj = obj[key] = obj[key] || { suite: suite }; + suite.suites.forEach(function (suite) { + mapTOC(suite, obj); + }); + + return ret; + } + + function stringifyTOC (obj, level) { + ++level; + var buf = ''; + var link; + for (var key in obj) { + if (key === 'suite') { + continue; + } + if (key !== SUITE_PREFIX) { + link = ' - [' + key.substring(1) + ']'; + link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n'; + buf += Array(level).join(' ') + link; + } + buf += stringifyTOC(obj[key], level); + } + return buf; + } + + function generateTOC (suite) { + var obj = mapTOC(suite, {}); + return stringifyTOC(obj, 0); + } + + generateTOC(runner.suite); + + runner.on('suite', function (suite) { + ++level; + var slug = utils.slug(suite.fullTitle()); + buf += '' + '\n'; + buf += title(suite.title) + '\n'; + }); + + runner.on('suite end', function () { + --level; + }); + + runner.on('pass', function (test) { + var code = utils.clean(test.body); + buf += test.title + '.\n'; + buf += '\n```js\n'; + buf += code + '\n'; + buf += '```\n\n'; + }); + + runner.on('end', function () { + process.stdout.write('# TOC\n'); + process.stdout.write(generateTOC(runner.suite)); + process.stdout.write(buf); + }); +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/min.js b/support/client/lib/vwf/view/mocha/lib/reporters/min.js new file mode 100644 index 000000000..0d772f960 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/min.js @@ -0,0 +1,38 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Min`. + */ + +exports = module.exports = Min; + +/** + * Initialize a new `Min` minimal test reporter (best used with --watch). + * + * @api public + * @param {Runner} runner + */ +function Min (runner) { + Base.call(this, runner); + + runner.on('start', function () { + // clear screen + process.stdout.write('\u001b[2J'); + // set cursor position + process.stdout.write('\u001b[1;3H'); + }); + + runner.on('end', this.epilogue.bind(this)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Min, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/nyan.js b/support/client/lib/vwf/view/mocha/lib/reporters/nyan.js new file mode 100644 index 000000000..1be49a97b --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/nyan.js @@ -0,0 +1,263 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Dot`. + */ + +exports = module.exports = NyanCat; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @param {Runner} runner + * @api public + */ + +function NyanCat (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var nyanCatWidth = this.nyanCatWidth = 11; + + this.colorIndex = 0; + this.numberOfLines = 4; + this.rainbowColors = self.generateColors(); + this.scoreboardWidth = 5; + this.tick = 0; + this.trajectories = [[], [], [], []]; + this.trajectoryWidthMax = (width - nyanCatWidth); + + runner.on('start', function () { + Base.cursor.hide(); + self.draw(); + }); + + runner.on('pending', function () { + self.draw(); + }); + + runner.on('pass', function () { + self.draw(); + }); + + runner.on('fail', function () { + self.draw(); + }); + + runner.on('end', function () { + Base.cursor.show(); + for (var i = 0; i < self.numberOfLines; i++) { + write('\n'); + } + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(NyanCat, Base); + +/** + * Draw the nyan cat + * + * @api private + */ + +NyanCat.prototype.draw = function () { + this.appendRainbow(); + this.drawScoreboard(); + this.drawRainbow(); + this.drawNyanCat(); + this.tick = !this.tick; +}; + +/** + * Draw the "scoreboard" showing the number + * of passes, failures and pending tests. + * + * @api private + */ + +NyanCat.prototype.drawScoreboard = function () { + var stats = this.stats; + + function draw (type, n) { + write(' '); + write(Base.color(type, n)); + write('\n'); + } + + draw('green', stats.passes); + draw('fail', stats.failures); + draw('pending', stats.pending); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Append the rainbow. + * + * @api private + */ + +NyanCat.prototype.appendRainbow = function () { + var segment = this.tick ? '_' : '-'; + var rainbowified = this.rainbowify(segment); + + for (var index = 0; index < this.numberOfLines; index++) { + var trajectory = this.trajectories[index]; + if (trajectory.length >= this.trajectoryWidthMax) { + trajectory.shift(); + } + trajectory.push(rainbowified); + } +}; + +/** + * Draw the rainbow. + * + * @api private + */ + +NyanCat.prototype.drawRainbow = function () { + var self = this; + + this.trajectories.forEach(function (line) { + write('\u001b[' + self.scoreboardWidth + 'C'); + write(line.join('')); + write('\n'); + }); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw the nyan cat + * + * @api private + */ +NyanCat.prototype.drawNyanCat = function () { + var self = this; + var startWidth = this.scoreboardWidth + this.trajectories[0].length; + var dist = '\u001b[' + startWidth + 'C'; + var padding = ''; + + write(dist); + write('_,------,'); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write('_|' + padding + '/\\_/\\ '); + write('\n'); + + write(dist); + padding = self.tick ? '_' : '__'; + var tail = self.tick ? '~' : '^'; + write(tail + '|' + padding + this.face() + ' '); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write(padding + '"" "" '); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw nyan cat face. + * + * @api private + * @return {string} + */ + +NyanCat.prototype.face = function () { + var stats = this.stats; + if (stats.failures) { + return '( x .x)'; + } else if (stats.pending) { + return '( o .o)'; + } else if (stats.passes) { + return '( ^ .^)'; + } + return '( - .-)'; +}; + +/** + * Move cursor up `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorUp = function (n) { + write('\u001b[' + n + 'A'); +}; + +/** + * Move cursor down `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorDown = function (n) { + write('\u001b[' + n + 'B'); +}; + +/** + * Generate rainbow colors. + * + * @api private + * @return {Array} + */ +NyanCat.prototype.generateColors = function () { + var colors = []; + + for (var i = 0; i < (6 * 7); i++) { + var pi3 = Math.floor(Math.PI / 3); + var n = (i * (1.0 / 6)); + var r = Math.floor(3 * Math.sin(n) + 3); + var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3); + var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3); + colors.push(36 * r + 6 * g + b + 16); + } + + return colors; +}; + +/** + * Apply rainbow to the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +NyanCat.prototype.rainbowify = function (str) { + if (!Base.useColors) { + return str; + } + var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length]; + this.colorIndex += 1; + return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m'; +}; + +/** + * Stdout helper. + * + * @param {string} string A message to write to stdout. + */ +function write (string) { + process.stdout.write(string); +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/progress.js b/support/client/lib/vwf/view/mocha/lib/reporters/progress.js new file mode 100644 index 000000000..378ce3827 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/progress.js @@ -0,0 +1,91 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `Progress`. + */ + +exports = module.exports = Progress; + +/** + * General progress bar color. + */ + +Base.colors.progress = 90; + +/** + * Initialize a new `Progress` bar test reporter. + * + * @api public + * @param {Runner} runner + * @param {Object} options + */ +function Progress (runner, options) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.50 | 0; + var total = runner.total; + var complete = 0; + var lastN = -1; + + // default chars + options = options || {}; + options.open = options.open || '['; + options.complete = options.complete || '▬'; + options.incomplete = options.incomplete || Base.symbols.dot; + options.close = options.close || ']'; + options.verbose = false; + + // tests started + runner.on('start', function () { + console.log(); + cursor.hide(); + }); + + // tests complete + runner.on('test end', function () { + complete++; + + var percent = complete / total; + var n = width * percent | 0; + var i = width - n; + + if (n === lastN && !options.verbose) { + // Don't re-render the line if it hasn't changed + return; + } + lastN = n; + + cursor.CR(); + process.stdout.write('\u001b[J'); + process.stdout.write(color('progress', ' ' + options.open)); + process.stdout.write(Array(n).join(options.complete)); + process.stdout.write(Array(i).join(options.incomplete)); + process.stdout.write(color('progress', options.close)); + if (options.verbose) { + process.stdout.write(color('progress', ' ' + complete + ' of ' + total)); + } + }); + + // tests are complete, output some stats + // and the failures if any + runner.on('end', function () { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Progress, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/spec.js b/support/client/lib/vwf/view/mocha/lib/reporters/spec.js new file mode 100644 index 000000000..993aff8dd --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/spec.js @@ -0,0 +1,81 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; + +/** + * Expose `Spec`. + */ + +exports = module.exports = Spec; + +/** + * Initialize a new `Spec` test reporter. + * + * @api public + * @param {Runner} runner + */ +function Spec (runner) { + Base.call(this, runner); + + var self = this; + var indents = 0; + var n = 0; + + function indent () { + return Array(indents).join(' '); + } + + runner.on('start', function () { + console.log(); + }); + + runner.on('suite', function (suite) { + ++indents; + console.log(color('suite', '%s%s'), indent(), suite.title); + }); + + runner.on('suite end', function () { + --indents; + if (indents === 1) { + console.log(); + } + }); + + runner.on('pending', function (test) { + var fmt = indent() + color('pending', ' - %s'); + console.log(fmt, test.title); + }); + + runner.on('pass', function (test) { + var fmt; + if (test.speed === 'fast') { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s'); + console.log(fmt, test.title); + } else { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s') + + color(test.speed, ' (%dms)'); + console.log(fmt, test.title, test.duration); + } + }); + + runner.on('fail', function (test) { + console.log(indent() + color('fail', ' %d) %s'), ++n, test.title); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Spec, Base); diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/tap.js b/support/client/lib/vwf/view/mocha/lib/reporters/tap.js new file mode 100644 index 000000000..e37ac1b16 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/tap.js @@ -0,0 +1,70 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `TAP`. + */ + +exports = module.exports = TAP; + +/** + * Initialize a new `TAP` reporter. + * + * @api public + * @param {Runner} runner + */ +function TAP (runner) { + Base.call(this, runner); + + var n = 1; + var passes = 0; + var failures = 0; + + runner.on('start', function () { + var total = runner.grepTotal(runner.suite); + console.log('%d..%d', 1, total); + }); + + runner.on('test end', function () { + ++n; + }); + + runner.on('pending', function (test) { + console.log('ok %d %s # SKIP -', n, title(test)); + }); + + runner.on('pass', function (test) { + passes++; + console.log('ok %d %s', n, title(test)); + }); + + runner.on('fail', function (test, err) { + failures++; + console.log('not ok %d %s', n, title(test)); + if (err.stack) { + console.log(err.stack.replace(/^/gm, ' ')); + } + }); + + runner.on('end', function () { + console.log('# tests ' + (passes + failures)); + console.log('# pass ' + passes); + console.log('# fail ' + failures); + }); +} + +/** + * Return a TAP-safe title of `test` + * + * @api private + * @param {Object} test + * @return {String} + */ +function title (test) { + return test.fullTitle().replace(/#/g, ''); +} diff --git a/support/client/lib/vwf/view/mocha/lib/reporters/xunit.js b/support/client/lib/vwf/view/mocha/lib/reporters/xunit.js new file mode 100644 index 000000000..ecfc8b233 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/reporters/xunit.js @@ -0,0 +1,168 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var inherits = utils.inherits; +var fs = require('fs'); +var escape = utils.escape; +var mkdirp = require('mkdirp'); +var path = require('path'); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `XUnit`. + */ + +exports = module.exports = XUnit; + +/** + * Initialize a new `XUnit` reporter. + * + * @api public + * @param {Runner} runner + */ +function XUnit (runner, options) { + Base.call(this, runner); + + var stats = this.stats; + var tests = []; + var self = this; + + if (options && options.reporterOptions && options.reporterOptions.output) { + if (!fs.createWriteStream) { + throw new Error('file output not supported in browser'); + } + mkdirp.sync(path.dirname(options.reporterOptions.output)); + self.fileStream = fs.createWriteStream(options.reporterOptions.output); + } + + runner.on('pending', function (test) { + tests.push(test); + }); + + runner.on('pass', function (test) { + tests.push(test); + }); + + runner.on('fail', function (test) { + tests.push(test); + }); + + runner.on('end', function () { + self.write(tag('testsuite', { + name: 'Mocha Tests', + tests: stats.tests, + failures: stats.failures, + errors: stats.failures, + skipped: stats.tests - stats.failures - stats.passes, + timestamp: (new Date()).toUTCString(), + time: (stats.duration / 1000) || 0 + }, false)); + + tests.forEach(function (t) { + self.test(t); + }); + + self.write(''); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(XUnit, Base); + +/** + * Override done to close the stream (if it's a file). + * + * @param failures + * @param {Function} fn + */ +XUnit.prototype.done = function (failures, fn) { + if (this.fileStream) { + this.fileStream.end(function () { + fn(failures); + }); + } else { + fn(failures); + } +}; + +/** + * Write out the given line. + * + * @param {string} line + */ +XUnit.prototype.write = function (line) { + if (this.fileStream) { + this.fileStream.write(line + '\n'); + } else if (typeof process === 'object' && process.stdout) { + process.stdout.write(line + '\n'); + } else { + console.log(line); + } +}; + +/** + * Output tag for the given `test.` + * + * @param {Test} test + */ +XUnit.prototype.test = function (test) { + var attrs = { + classname: test.parent.fullTitle(), + name: test.title, + time: (test.duration / 1000) || 0 + }; + + if (test.state === 'failed') { + var err = test.err; + this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack)))); + } else if (test.isPending()) { + this.write(tag('testcase', attrs, false, tag('skipped', {}, true))); + } else { + this.write(tag('testcase', attrs, true)); + } +}; + +/** + * HTML tag helper. + * + * @param name + * @param attrs + * @param close + * @param content + * @return {string} + */ +function tag (name, attrs, close, content) { + var end = close ? '/>' : '>'; + var pairs = []; + var tag; + + for (var key in attrs) { + if (Object.prototype.hasOwnProperty.call(attrs, key)) { + pairs.push(key + '="' + escape(attrs[key]) + '"'); + } + } + + tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end; + if (content) { + tag += content + ' Math.pow(2, 31)) { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = ms; + if (this.timer) { + this.resetTimeout(); + } + return this; +}; + +/** + * Set & get slow `ms`. + * + * @api private + * @param {number|string} ms + * @return {Runnable|number} ms or Runnable instance. + */ +Runnable.prototype.slow = function (ms) { + if (typeof ms === 'undefined') { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._slow = ms; + return this; +}; + +/** + * Set and get whether timeout is `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Runnable|boolean} enabled or Runnable instance. + */ +Runnable.prototype.enableTimeouts = function (enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Halt and mark as pending. + * + * @api public + */ +Runnable.prototype.skip = function () { + throw new Pending('sync skip'); +}; + +/** + * Check if this runnable or its parent suite is marked as pending. + * + * @api private + */ +Runnable.prototype.isPending = function () { + return this.pending || (this.parent && this.parent.isPending()); +}; + +/** + * Set number of retries. + * + * @api private + */ +Runnable.prototype.retries = function (n) { + if (!arguments.length) { + return this._retries; + } + this._retries = n; +}; + +/** + * Get current retry + * + * @api private + */ +Runnable.prototype.currentRetry = function (n) { + if (!arguments.length) { + return this._currentRetry; + } + this._currentRetry = n; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Runnable.prototype.fullTitle = function () { + return this.parent.fullTitle() + ' ' + this.title; +}; + +/** + * Clear the timeout. + * + * @api private + */ +Runnable.prototype.clearTimeout = function () { + clearTimeout(this.timer); +}; + +/** + * Inspect the runnable void of private properties. + * + * @api private + * @return {string} + */ +Runnable.prototype.inspect = function () { + return JSON.stringify(this, function (key, val) { + if (key[0] === '_') { + return; + } + if (key === 'parent') { + return '#'; + } + if (key === 'ctx') { + return '#'; + } + return val; + }, 2); +}; + +/** + * Reset the timeout. + * + * @api private + */ +Runnable.prototype.resetTimeout = function () { + var self = this; + var ms = this.timeout() || 1e9; + + if (!this._enableTimeouts) { + return; + } + this.clearTimeout(); + this.timer = setTimeout(function () { + if (!self._enableTimeouts) { + return; + } + self.callback(new Error('Timeout of ' + ms + + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.')); + self.timedOut = true; + }, ms); +}; + +/** + * Whitelist a list of globals for this test run. + * + * @api private + * @param {string[]} globals + */ +Runnable.prototype.globals = function (globals) { + if (!arguments.length) { + return this._allowedGlobals; + } + this._allowedGlobals = globals; +}; + +/** + * Run the test and invoke `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runnable.prototype.run = function (fn) { + var self = this; + var start = new Date(); + var ctx = this.ctx; + var finished; + var emitted; + + // Sometimes the ctx exists, but it is not runnable + if (ctx && ctx.runnable) { + ctx.runnable(this); + } + + // called multiple times + function multiple (err) { + if (emitted) { + return; + } + emitted = true; + self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate')); + } + + // finished + function done (err) { + var ms = self.timeout(); + if (self.timedOut) { + return; + } + if (finished) { + return multiple(err || self._trace); + } + + self.clearTimeout(); + self.duration = new Date() - start; + finished = true; + if (!err && self.duration > ms && self._enableTimeouts) { + err = new Error('Timeout of ' + ms + + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'); + } + fn(err); + } + + // for .resetTimeout() + this.callback = done; + + // explicit async with `done` argument + if (this.async) { + this.resetTimeout(); + + // allows skip() to be used in an explicit async context + this.skip = function asyncSkip () { + done(new Pending('async skip call')); + // halt execution. the Runnable will be marked pending + // by the previous call, and the uncaught handler will ignore + // the failure. + throw new Pending('async skip; aborting execution'); + }; + + if (this.allowUncaught) { + return callFnAsync(this.fn); + } + try { + callFnAsync(this.fn); + } catch (err) { + emitted = true; + done(utils.getError(err)); + } + return; + } + + if (this.allowUncaught) { + callFn(this.fn); + done(); + return; + } + + // sync or promise-returning + try { + if (this.isPending()) { + done(); + } else { + callFn(this.fn); + } + } catch (err) { + emitted = true; + done(utils.getError(err)); + } + + function callFn (fn) { + var result = fn.call(ctx); + if (result && typeof result.then === 'function') { + self.resetTimeout(); + result + .then(function () { + done(); + // Return null so libraries like bluebird do not warn about + // subsequently constructed Promises. + return null; + }, + function (reason) { + done(reason || new Error('Promise rejected with no or falsy reason')); + }); + } else { + if (self.asyncOnly) { + return done(new Error('--async-only option in use without declaring `done()` or returning a promise')); + } + + done(); + } + } + + function callFnAsync (fn) { + var result = fn.call(ctx, function (err) { + if (err instanceof Error || toString.call(err) === '[object Error]') { + return done(err); + } + if (err) { + if (Object.prototype.toString.call(err) === '[object Object]') { + return done(new Error('done() invoked with non-Error: ' + + JSON.stringify(err))); + } + return done(new Error('done() invoked with non-Error: ' + err)); + } + if (result && utils.isPromise(result)) { + return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.')); + } + + done(); + }); + } +}; diff --git a/support/client/lib/vwf/view/mocha/lib/runner.js b/support/client/lib/vwf/view/mocha/lib/runner.js new file mode 100644 index 000000000..697ffb65a --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/runner.js @@ -0,0 +1,963 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Pending = require('./pending'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:runner'); +var Runnable = require('./runnable'); +var filter = utils.filter; +var indexOf = utils.indexOf; +var some = utils.some; +var keys = utils.keys; +var stackFilter = utils.stackTraceFilter(); +var stringify = utils.stringify; +var type = utils.type; +var undefinedError = utils.undefinedError; +var isArray = utils.isArray; + +/** + * Non-enumerable globals. + */ + +var globals = [ + 'setTimeout', + 'clearTimeout', + 'setInterval', + 'clearInterval', + 'XMLHttpRequest', + 'Date', + 'setImmediate', + 'clearImmediate' +]; + +/** + * Expose `Runner`. + */ + +module.exports = Runner; + +/** + * Initialize a `Runner` for the given `suite`. + * + * Events: + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * - `pending` (test) test pending + * + * @api public + * @param {Suite} suite Root suite + * @param {boolean} [delay] Whether or not to delay execution of root suite + * until ready. + */ +function Runner (suite, delay) { + var self = this; + this._globals = []; + this._abort = false; + this._delay = delay; + this.suite = suite; + this.started = false; + this.total = suite.total(); + this.failures = 0; + this.on('test end', function (test) { + self.checkGlobals(test); + }); + this.on('hook end', function (hook) { + self.checkGlobals(hook); + }); + this._defaultGrep = /.*/; + this.grep(this._defaultGrep); + this.globals(this.globalProps().concat(extraGlobals())); +} + +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @api private + */ +Runner.immediately = global.setImmediate || process.nextTick; + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Runner, EventEmitter); + +/** + * Run tests with full titles matching `re`. Updates runner.total + * with number of tests matched. + * + * @param {RegExp} re + * @param {Boolean} invert + * @return {Runner} for chaining + * @api public + * @param {RegExp} re + * @param {boolean} invert + * @return {Runner} Runner instance. + */ +Runner.prototype.grep = function (re, invert) { + debug('grep %s', re); + this._grep = re; + this._invert = invert; + this.total = this.grepTotal(this.suite); + return this; +}; + +/** + * Returns the number of tests matching the grep search for the + * given suite. + * + * @param {Suite} suite + * @return {Number} + * @api public + * @param {Suite} suite + * @return {number} + */ +Runner.prototype.grepTotal = function (suite) { + var self = this; + var total = 0; + + suite.eachTest(function (test) { + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (match) { + total++; + } + }); + + return total; +}; + +/** + * Return a list of global properties. + * + * @return {Array} + * @api private + */ +Runner.prototype.globalProps = function () { + var props = keys(global); + + // non-enumerables + for (var i = 0; i < globals.length; ++i) { + if (~indexOf(props, globals[i])) { + continue; + } + props.push(globals[i]); + } + + return props; +}; + +/** + * Allow the given `arr` of globals. + * + * @param {Array} arr + * @return {Runner} for chaining + * @api public + * @param {Array} arr + * @return {Runner} Runner instance. + */ +Runner.prototype.globals = function (arr) { + if (!arguments.length) { + return this._globals; + } + debug('globals %j', arr); + this._globals = this._globals.concat(arr); + return this; +}; + +/** + * Check for global variable leaks. + * + * @api private + */ +Runner.prototype.checkGlobals = function (test) { + if (this.ignoreLeaks) { + return; + } + var ok = this._globals; + + var globals = this.globalProps(); + var leaks; + + if (test) { + ok = ok.concat(test._allowedGlobals || []); + } + + if (this.prevGlobalsLength === globals.length) { + return; + } + this.prevGlobalsLength = globals.length; + + leaks = filterLeaks(ok, globals); + this._globals = this._globals.concat(leaks); + + if (leaks.length > 1) { + this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + '')); + } else if (leaks.length) { + this.fail(test, new Error('global leak detected: ' + leaks[0])); + } +}; + +/** + * Fail the given `test`. + * + * @api private + * @param {Test} test + * @param {Error} err + */ +Runner.prototype.fail = function (test, err) { + if (test.isPending()) { + return; + } + + ++this.failures; + test.state = 'failed'; + + if (!(err instanceof Error || err && typeof err.message === 'string')) { + err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)'); + } + + try { + err.stack = (this.fullStackTrace || !err.stack) + ? err.stack + : stackFilter(err.stack); + } catch (ignored) { + // some environments do not take kindly to monkeying with the stack + } + + this.emit('fail', test, err); +}; + +/** + * Fail the given `hook` with `err`. + * + * Hook failures work in the following pattern: + * - If bail, then exit + * - Failed `before` hook skips all tests in a suite and subsuites, + * but jumps to corresponding `after` hook + * - Failed `before each` hook skips remaining tests in a + * suite and jumps to corresponding `after each` hook, + * which is run only once + * - Failed `after` hook does not alter + * execution order + * - Failed `after each` hook skips remaining tests in a + * suite and subsuites, but executes other `after each` + * hooks + * + * @api private + * @param {Hook} hook + * @param {Error} err + */ +Runner.prototype.failHook = function (hook, err) { + if (hook.ctx && hook.ctx.currentTest) { + hook.originalTitle = hook.originalTitle || hook.title; + hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"'; + } + + this.fail(hook, err); + if (this.suite.bail()) { + this.emit('end'); + } +}; + +/** + * Run hook `name` callbacks and then invoke `fn()`. + * + * @api private + * @param {string} name + * @param {Function} fn + */ + +Runner.prototype.hook = function (name, fn) { + var suite = this.suite; + var hooks = suite['_' + name]; + var self = this; + + function next (i) { + var hook = hooks[i]; + if (!hook) { + return fn(); + } + self.currentRunnable = hook; + + hook.ctx.currentTest = self.test; + + self.emit('hook', hook); + + if (!hook.listeners('error').length) { + hook.on('error', function (err) { + self.failHook(hook, err); + }); + } + + hook.run(function (err) { + var testError = hook.error(); + if (testError) { + self.fail(self.test, testError); + } + if (err) { + if (err instanceof Pending) { + if (name === 'beforeEach' || name === 'afterEach') { + self.test.pending = true; + } else { + utils.forEach(suite.tests, function (test) { + test.pending = true; + }); + // a pending hook won't be executed twice. + hook.pending = true; + } + } else { + self.failHook(hook, err); + + // stop executing hooks, notify callee of hook err + return fn(err); + } + } + self.emit('hook end', hook); + delete hook.ctx.currentTest; + next(++i); + }); + } + + Runner.immediately(function () { + next(0); + }); +}; + +/** + * Run hook `name` for the given array of `suites` + * in order, and callback `fn(err, errSuite)`. + * + * @api private + * @param {string} name + * @param {Array} suites + * @param {Function} fn + */ +Runner.prototype.hooks = function (name, suites, fn) { + var self = this; + var orig = this.suite; + + function next (suite) { + self.suite = suite; + + if (!suite) { + self.suite = orig; + return fn(); + } + + self.hook(name, function (err) { + if (err) { + var errSuite = self.suite; + self.suite = orig; + return fn(err, errSuite); + } + + next(suites.pop()); + }); + } + + next(suites.pop()); +}; + +/** + * Run hooks from the top level down. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookUp = function (name, fn) { + var suites = [this.suite].concat(this.parents()).reverse(); + this.hooks(name, suites, fn); +}; + +/** + * Run hooks from the bottom up. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookDown = function (name, fn) { + var suites = [this.suite].concat(this.parents()); + this.hooks(name, suites, fn); +}; + +/** + * Return an array of parent Suites from + * closest to furthest. + * + * @return {Array} + * @api private + */ +Runner.prototype.parents = function () { + var suite = this.suite; + var suites = []; + while (suite.parent) { + suite = suite.parent; + suites.push(suite); + } + return suites; +}; + +/** + * Run the current test and callback `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runner.prototype.runTest = function (fn) { + var self = this; + var test = this.test; + + if (!test) { + return; + } + if (this.asyncOnly) { + test.asyncOnly = true; + } + + if (this.allowUncaught) { + test.allowUncaught = true; + return test.run(fn); + } + try { + test.on('error', function (err) { + self.fail(test, err); + }); + test.run(fn); + } catch (err) { + fn(err); + } +}; + +/** + * Run tests in the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runTests = function (suite, fn) { + var self = this; + var tests = suite.tests.slice(); + var test; + + function hookErr (_, errSuite, after) { + // before/after Each hook for errSuite failed: + var orig = self.suite; + + // for failed 'after each' hook start from errSuite parent, + // otherwise start from errSuite itself + self.suite = after ? errSuite.parent : errSuite; + + if (self.suite) { + // call hookUp afterEach + self.hookUp('afterEach', function (err2, errSuite2) { + self.suite = orig; + // some hooks may fail even now + if (err2) { + return hookErr(err2, errSuite2, true); + } + // report error suite + fn(errSuite); + }); + } else { + // there is no need calling other 'after each' hooks + self.suite = orig; + fn(errSuite); + } + } + + function next (err, errSuite) { + // if we bail after first err + if (self.failures && suite._bail) { + return fn(); + } + + if (self._abort) { + return fn(); + } + + if (err) { + return hookErr(err, errSuite, true); + } + + // next test + test = tests.shift(); + + // all done + if (!test) { + return fn(); + } + + // grep + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (!match) { + // Run immediately only if we have defined a grep. When we + // define a grep — It can cause maximum callstack error if + // the grep is doing a large recursive loop by neglecting + // all tests. The run immediately function also comes with + // a performance cost. So we don't want to run immediately + // if we run the whole test suite, because running the whole + // test suite don't do any immediate recursive loops. Thus, + // allowing a JS runtime to breathe. + if (self._grep !== self._defaultGrep) { + Runner.immediately(next); + } else { + next(); + } + return; + } + + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + + // execute test and hook(s) + self.emit('test', self.test = test); + self.hookDown('beforeEach', function (err, errSuite) { + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + if (err) { + return hookErr(err, errSuite, false); + } + self.currentRunnable = self.test; + self.runTest(function (err) { + test = self.test; + if (err) { + var retry = test.currentRetry(); + if (err instanceof Pending) { + test.pending = true; + self.emit('pending', test); + } else if (retry < test.retries()) { + var clonedTest = test.clone(); + clonedTest.currentRetry(retry + 1); + tests.unshift(clonedTest); + + // Early return + hook trigger so that it doesn't + // increment the count wrong + return self.hookUp('afterEach', next); + } else { + self.fail(test, err); + } + self.emit('test end', test); + + if (err instanceof Pending) { + return next(); + } + + return self.hookUp('afterEach', next); + } + + test.state = 'passed'; + self.emit('pass', test); + self.emit('test end', test); + self.hookUp('afterEach', next); + }); + }); + } + + this.next = next; + this.hookErr = hookErr; + next(); +}; + +/** + * Run the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runSuite = function (suite, fn) { + var i = 0; + var self = this; + var total = this.grepTotal(suite); + var afterAllHookCalled = false; + + debug('run suite %s', suite.fullTitle()); + + if (!total || (self.failures && suite._bail)) { + return fn(); + } + + this.emit('suite', this.suite = suite); + + function next (errSuite) { + if (errSuite) { + // current suite failed on a hook from errSuite + if (errSuite === suite) { + // if errSuite is current suite + // continue to the next sibling suite + return done(); + } + // errSuite is among the parents of current suite + // stop execution of errSuite and all sub-suites + return done(errSuite); + } + + if (self._abort) { + return done(); + } + + var curr = suite.suites[i++]; + if (!curr) { + return done(); + } + + // Avoid grep neglecting large number of tests causing a + // huge recursive loop and thus a maximum call stack error. + // See comment in `this.runTests()` for more information. + if (self._grep !== self._defaultGrep) { + Runner.immediately(function () { + self.runSuite(curr, next); + }); + } else { + self.runSuite(curr, next); + } + } + + function done (errSuite) { + self.suite = suite; + self.nextSuite = next; + + if (afterAllHookCalled) { + fn(errSuite); + } else { + // mark that the afterAll block has been called once + // and so can be skipped if there is an error in it. + afterAllHookCalled = true; + + // remove reference to test + delete self.test; + + self.hook('afterAll', function () { + self.emit('suite end', suite); + fn(errSuite); + }); + } + } + + this.nextSuite = next; + + this.hook('beforeAll', function (err) { + if (err) { + return done(); + } + self.runTests(suite, next); + }); +}; + +/** + * Handle uncaught exceptions. + * + * @param {Error} err + * @api private + */ +Runner.prototype.uncaught = function (err) { + if (err) { + debug('uncaught exception %s', err !== function () { + return this; + }.call(err) ? err : (err.message || err)); + } else { + debug('uncaught undefined exception'); + err = undefinedError(); + } + err.uncaught = true; + + var runnable = this.currentRunnable; + + if (!runnable) { + runnable = new Runnable('Uncaught error outside test suite'); + runnable.parent = this.suite; + + if (this.started) { + this.fail(runnable, err); + } else { + // Can't recover from this failure + this.emit('start'); + this.fail(runnable, err); + this.emit('end'); + } + + return; + } + + runnable.clearTimeout(); + + // Ignore errors if complete or pending + if (runnable.state || runnable.isPending()) { + return; + } + this.fail(runnable, err); + + // recover from test + if (runnable.type === 'test') { + this.emit('test end', runnable); + this.hookUp('afterEach', this.next); + return; + } + + // recover from hooks + if (runnable.type === 'hook') { + var errSuite = this.suite; + // if hook failure is in afterEach block + if (runnable.fullTitle().indexOf('after each') > -1) { + return this.hookErr(err, errSuite, true); + } + // if hook failure is in beforeEach block + if (runnable.fullTitle().indexOf('before each') > -1) { + return this.hookErr(err, errSuite, false); + } + // if hook failure is in after or before blocks + return this.nextSuite(errSuite); + } + + // bail + this.emit('end'); +}; + +/** + * Cleans up the references to all the deferred functions + * (before/after/beforeEach/afterEach) and tests of a Suite. + * These must be deleted otherwise a memory leak can happen, + * as those functions may reference variables from closures, + * thus those variables can never be garbage collected as long + * as the deferred functions exist. + * + * @param {Suite} suite + */ +function cleanSuiteReferences (suite) { + function cleanArrReferences (arr) { + for (var i = 0; i < arr.length; i++) { + delete arr[i].fn; + } + } + + if (isArray(suite._beforeAll)) { + cleanArrReferences(suite._beforeAll); + } + + if (isArray(suite._beforeEach)) { + cleanArrReferences(suite._beforeEach); + } + + if (isArray(suite._afterAll)) { + cleanArrReferences(suite._afterAll); + } + + if (isArray(suite._afterEach)) { + cleanArrReferences(suite._afterEach); + } + + for (var i = 0; i < suite.tests.length; i++) { + delete suite.tests[i].fn; + } +} + +/** + * Run the root suite and invoke `fn(failures)` + * on completion. + * + * @param {Function} fn + * @return {Runner} for chaining + * @api public + * @param {Function} fn + * @return {Runner} Runner instance. + */ +Runner.prototype.run = function (fn) { + var self = this; + var rootSuite = this.suite; + + // If there is an `only` filter + if (this.hasOnly) { + filterOnly(rootSuite); + } + + fn = fn || function () {}; + + function uncaught (err) { + self.uncaught(err); + } + + function start () { + self.started = true; + self.emit('start'); + self.runSuite(rootSuite, function () { + debug('finished running'); + self.emit('end'); + }); + } + + debug('start'); + + // references cleanup to avoid memory leaks + this.on('suite end', cleanSuiteReferences); + + // callback + this.on('end', function () { + debug('end'); + process.removeListener('uncaughtException', uncaught); + fn(self.failures); + }); + + // uncaught exception + process.on('uncaughtException', uncaught); + + if (this._delay) { + // for reporters, I guess. + // might be nice to debounce some dots while we wait. + this.emit('waiting', rootSuite); + rootSuite.once('run', start); + } else { + start(); + } + + return this; +}; + +/** + * Cleanly abort execution. + * + * @api public + * @return {Runner} Runner instance. + */ +Runner.prototype.abort = function () { + debug('aborting'); + this._abort = true; + + return this; +}; + +/** + * Filter suites based on `isOnly` logic. + * + * @param {Array} suite + * @returns {Boolean} + * @api private + */ +function filterOnly (suite) { + if (suite._onlyTests.length) { + // If the suite contains `only` tests, run those and ignore any nested suites. + suite.tests = suite._onlyTests; + suite.suites = []; + } else { + // Otherwise, do not run any of the tests in this suite. + suite.tests = []; + utils.forEach(suite._onlySuites, function (onlySuite) { + // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite. + // Otherwise, all of the tests on this `only` suite should be run, so don't filter it. + if (hasOnly(onlySuite)) { + filterOnly(onlySuite); + } + }); + // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants. + suite.suites = filter(suite.suites, function (childSuite) { + return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite); + }); + } + // Keep the suite only if there is something to run + return suite.tests.length || suite.suites.length; +} + +/** + * Determines whether a suite has an `only` test or suite as a descendant. + * + * @param {Array} suite + * @returns {Boolean} + * @api private + */ +function hasOnly (suite) { + return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly); +} + +/** + * Filter leaks with the given globals flagged as `ok`. + * + * @api private + * @param {Array} ok + * @param {Array} globals + * @return {Array} + */ +function filterLeaks (ok, globals) { + return filter(globals, function (key) { + // Firefox and Chrome exposes iframes as index inside the window object + if (/^\d+/.test(key)) { + return false; + } + + // in firefox + // if runner runs in an iframe, this iframe's window.getInterface method + // not init at first it is assigned in some seconds + if (global.navigator && (/^getInterface/).test(key)) { + return false; + } + + // an iframe could be approached by window[iframeIndex] + // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak + if (global.navigator && (/^\d+/).test(key)) { + return false; + } + + // Opera and IE expose global variables for HTML element IDs (issue #243) + if (/^mocha-/.test(key)) { + return false; + } + + var matched = filter(ok, function (ok) { + if (~ok.indexOf('*')) { + return key.indexOf(ok.split('*')[0]) === 0; + } + return key === ok; + }); + return !matched.length && (!global.navigator || key !== 'onerror'); + }); +} + +/** + * Array of globals dependent on the environment. + * + * @return {Array} + * @api private + */ +function extraGlobals () { + if (typeof process === 'object' && typeof process.version === 'string') { + var parts = process.version.split('.'); + var nodeVersion = utils.reduce(parts, function (a, v) { + return a << 8 | v; + }); + + // 'errno' was renamed to process._errno in v0.9.11. + + if (nodeVersion < 0x00090B) { + return ['errno']; + } + } + + return []; +} diff --git a/support/client/lib/vwf/view/mocha/lib/suite.js b/support/client/lib/vwf/view/mocha/lib/suite.js new file mode 100644 index 000000000..13617ab91 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/suite.js @@ -0,0 +1,402 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Hook = require('./hook'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:suite'); +var milliseconds = require('./ms'); + +/** + * Expose `Suite`. + */ + +exports = module.exports = Suite; + +/** + * Create a new `Suite` with the given `title` and parent `Suite`. When a suite + * with the same title is already present, that suite is returned to provide + * nicer reporter and more flexible meta-testing. + * + * @api public + * @param {Suite} parent + * @param {string} title + * @return {Suite} + */ +exports.create = function (parent, title) { + var suite = new Suite(title, parent.ctx); + suite.parent = parent; + title = suite.fullTitle(); + parent.addSuite(suite); + return suite; +}; + +/** + * Initialize a new `Suite` with the given `title` and `ctx`. + * + * @api private + * @param {string} title + * @param {Context} parentContext + */ +function Suite (title, parentContext) { + if (!utils.isString(title)) { + throw new Error('Suite `title` should be a "string" but "' + typeof title + '" was given instead.'); + } + this.title = title; + function Context () {} + Context.prototype = parentContext; + this.ctx = new Context(); + this.suites = []; + this.tests = []; + this.pending = false; + this._beforeEach = []; + this._beforeAll = []; + this._afterEach = []; + this._afterAll = []; + this.root = !title; + this._timeout = 2000; + this._enableTimeouts = true; + this._slow = 75; + this._bail = false; + this._retries = -1; + this._onlyTests = []; + this._onlySuites = []; + this.delayed = false; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Suite, EventEmitter); + +/** + * Return a clone of this `Suite`. + * + * @api private + * @return {Suite} + */ +Suite.prototype.clone = function () { + var suite = new Suite(this.title); + debug('clone'); + suite.ctx = this.ctx; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + return suite; +}; + +/** + * Set timeout `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.timeout = function (ms) { + if (!arguments.length) { + return this._timeout; + } + if (ms.toString() === '0') { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = parseInt(ms, 10); + return this; +}; + +/** + * Set number of times to retry a failed test. + * + * @api private + * @param {number|string} n + * @return {Suite|number} for chaining + */ +Suite.prototype.retries = function (n) { + if (!arguments.length) { + return this._retries; + } + debug('retries %d', n); + this._retries = parseInt(n, 10) || 0; + return this; +}; + +/** + * Set timeout to `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Suite|boolean} self or enabled + */ +Suite.prototype.enableTimeouts = function (enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Set slow `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.slow = function (ms) { + if (!arguments.length) { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('slow %d', ms); + this._slow = ms; + return this; +}; + +/** + * Sets whether to bail after first error. + * + * @api private + * @param {boolean} bail + * @return {Suite|number} for chaining + */ +Suite.prototype.bail = function (bail) { + if (!arguments.length) { + return this._bail; + } + debug('bail %s', bail); + this._bail = bail; + return this; +}; + +/** + * Check if this suite or its parent suite is marked as pending. + * + * @api private + */ +Suite.prototype.isPending = function () { + return this.pending || (this.parent && this.parent.isPending()); +}; + +/** + * Run `fn(test[, done])` before running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeAll = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeAll.push(hook); + this.emit('beforeAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterAll = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterAll.push(hook); + this.emit('afterAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` before each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeEach = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeEach.push(hook); + this.emit('beforeEach', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterEach = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterEach.push(hook); + this.emit('afterEach', hook); + return this; +}; + +/** + * Add a test `suite`. + * + * @api private + * @param {Suite} suite + * @return {Suite} for chaining + */ +Suite.prototype.addSuite = function (suite) { + suite.parent = this; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + this.suites.push(suite); + this.emit('suite', suite); + return this; +}; + +/** + * Add a `test` to this suite. + * + * @api private + * @param {Test} test + * @return {Suite} for chaining + */ +Suite.prototype.addTest = function (test) { + test.parent = this; + test.timeout(this.timeout()); + test.retries(this.retries()); + test.enableTimeouts(this.enableTimeouts()); + test.slow(this.slow()); + test.ctx = this.ctx; + this.tests.push(test); + this.emit('test', test); + return this; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Suite.prototype.fullTitle = function () { + if (this.parent) { + var full = this.parent.fullTitle(); + if (full) { + return full + ' ' + this.title; + } + } + return this.title; +}; + +/** + * Return the total number of tests. + * + * @api public + * @return {number} + */ +Suite.prototype.total = function () { + return utils.reduce(this.suites, function (sum, suite) { + return sum + suite.total(); + }, 0) + this.tests.length; +}; + +/** + * Iterates through each suite recursively to find all tests. Applies a + * function in the format `fn(test)`. + * + * @api private + * @param {Function} fn + * @return {Suite} + */ +Suite.prototype.eachTest = function (fn) { + utils.forEach(this.tests, fn); + utils.forEach(this.suites, function (suite) { + suite.eachTest(fn); + }); + return this; +}; + +/** + * This will run the root suite if we happen to be running in delayed mode. + */ +Suite.prototype.run = function run () { + if (this.root) { + this.emit('run'); + } +}; diff --git a/support/client/lib/vwf/view/mocha/lib/template.html b/support/client/lib/vwf/view/mocha/lib/template.html new file mode 100644 index 000000000..36c5e0b69 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/template.html @@ -0,0 +1,18 @@ + + + + Mocha + + + + + +
    + + + + + + diff --git a/support/client/lib/vwf/view/mocha/lib/test.js b/support/client/lib/vwf/view/mocha/lib/test.js new file mode 100644 index 000000000..66bb57cb4 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/test.js @@ -0,0 +1,52 @@ +'use strict'; + +/** + * Module dependencies. + */ + +var Runnable = require('./runnable'); +var create = require('lodash.create'); +var isString = require('./utils').isString; + +/** + * Expose `Test`. + */ + +module.exports = Test; + +/** + * Initialize a new `Test` with the given `title` and callback `fn`. + * + * @api private + * @param {String} title + * @param {Function} fn + */ +function Test (title, fn) { + if (!isString(title)) { + throw new Error('Test `title` should be a "string" but "' + typeof title + '" was given instead.'); + } + Runnable.call(this, title, fn); + this.pending = !fn; + this.type = 'test'; +} + +/** + * Inherit from `Runnable.prototype`. + */ +Test.prototype = create(Runnable.prototype, { + constructor: Test +}); + +Test.prototype.clone = function () { + var test = new Test(this.title, this.fn); + test.timeout(this.timeout()); + test.slow(this.slow()); + test.enableTimeouts(this.enableTimeouts()); + test.retries(this.retries()); + test.currentRetry(this.currentRetry()); + test.globals(this.globals()); + test.parent = this.parent; + test.file = this.file; + test.ctx = this.ctx; + return test; +}; diff --git a/support/client/lib/vwf/view/mocha/lib/to-iso-string/LICENSE b/support/client/lib/vwf/view/mocha/lib/to-iso-string/LICENSE new file mode 100644 index 000000000..c25db5659 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/to-iso-string/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 Segment.io, Inc. (friends@segment.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/support/client/lib/vwf/view/mocha/lib/to-iso-string/index.js b/support/client/lib/vwf/view/mocha/lib/to-iso-string/index.js new file mode 100644 index 000000000..cd28d7be7 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/to-iso-string/index.js @@ -0,0 +1,37 @@ +'use strict'; + +/** + * Pad a `number` with a ten's place zero. + * + * @param {number} number + * @return {string} + */ +function pad(number) { + var n = number.toString(); + return n.length === 1 ? '0' + n : n; +} + +/** + * Turn a `date` into an ISO string. + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + * + * @param {Date} date + * @return {string} + */ +function toISOString(date) { + return date.getUTCFullYear() + + '-' + pad(date.getUTCMonth() + 1) + + '-' + pad(date.getUTCDate()) + + 'T' + pad(date.getUTCHours()) + + ':' + pad(date.getUTCMinutes()) + + ':' + pad(date.getUTCSeconds()) + + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) + + 'Z'; +} + +/* + * Exports. + */ + +module.exports = toISOString; diff --git a/support/client/lib/vwf/view/mocha/lib/utils.js b/support/client/lib/vwf/view/mocha/lib/utils.js new file mode 100644 index 000000000..bf430b916 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/lib/utils.js @@ -0,0 +1,803 @@ +'use strict'; + +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var JSON = require('json3'); +var basename = require('path').basename; +var debug = require('debug')('mocha:watch'); +var exists = require('fs').existsSync || require('path').existsSync; +var glob = require('glob'); +var path = require('path'); +var join = path.join; +var readdirSync = require('fs').readdirSync; +var statSync = require('fs').statSync; +var watchFile = require('fs').watchFile; +var lstatSync = require('fs').lstatSync; +var toISOString = require('./to-iso-string'); + +/** + * Ignored directories. + */ + +var ignore = ['node_modules', '.git']; + +exports.inherits = require('util').inherits; + +/** + * Escape special characters in the given string of html. + * + * @api private + * @param {string} html + * @return {string} + */ +exports.escape = function (html) { + return String(html) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +}; + +/** + * Array#forEach (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + */ +exports.forEach = function (arr, fn, scope) { + for (var i = 0, l = arr.length; i < l; i++) { + fn.call(scope, arr[i], i); + } +}; + +/** + * Test if the given obj is type of string. + * + * @api private + * @param {Object} obj + * @return {boolean} + */ +exports.isString = function (obj) { + return typeof obj === 'string'; +}; + +/** + * Array#map (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + * @return {Array} + */ +exports.map = function (arr, fn, scope) { + var result = []; + for (var i = 0, l = arr.length; i < l; i++) { + result.push(fn.call(scope, arr[i], i, arr)); + } + return result; +}; + +/** + * Array#indexOf (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Object} obj to find index of + * @param {number} start + * @return {number} + */ +var indexOf = exports.indexOf = function (arr, obj, start) { + for (var i = start || 0, l = arr.length; i < l; i++) { + if (arr[i] === obj) { + return i; + } + } + return -1; +}; + +/** + * Array#reduce (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} val Initial value. + * @return {*} + */ +var reduce = exports.reduce = function (arr, fn, val) { + var rval = val; + + for (var i = 0, l = arr.length; i < l; i++) { + rval = fn(rval, arr[i], i, arr); + } + + return rval; +}; + +/** + * Array#filter (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.filter = function (arr, fn) { + var ret = []; + + for (var i = 0, l = arr.length; i < l; i++) { + var val = arr[i]; + if (fn(val, i, arr)) { + ret.push(val); + } + } + + return ret; +}; + +/** + * Array#some (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.some = function (arr, fn) { + for (var i = 0, l = arr.length; i < l; i++) { + if (fn(arr[i])) { + return true; + } + } + return false; +}; + +/** + * Object.keys (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Array} keys + */ +exports.keys = typeof Object.keys === 'function' ? Object.keys : function (obj) { + var keys = []; + var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8 + + for (var key in obj) { + if (has.call(obj, key)) { + keys.push(key); + } + } + + return keys; +}; + +/** + * Watch the given `files` for changes + * and invoke `fn(file)` on modification. + * + * @api private + * @param {Array} files + * @param {Function} fn + */ +exports.watch = function (files, fn) { + var options = { interval: 100 }; + files.forEach(function (file) { + debug('file %s', file); + watchFile(file, options, function (curr, prev) { + if (prev.mtime < curr.mtime) { + fn(file); + } + }); + }); +}; + +/** + * Array.isArray (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Boolean} + */ +var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +exports.isArray = isArray; + +/** + * Buffer.prototype.toJSON polyfill. + * + * @type {Function} + */ +if (typeof Buffer !== 'undefined' && Buffer.prototype) { + Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () { + return Array.prototype.slice.call(this, 0); + }; +} + +/** + * Ignored files. + * + * @api private + * @param {string} path + * @return {boolean} + */ +function ignored (path) { + return !~ignore.indexOf(path); +} + +/** + * Lookup files in the given `dir`. + * + * @api private + * @param {string} dir + * @param {string[]} [ext=['.js']] + * @param {Array} [ret=[]] + * @return {Array} + */ +exports.files = function (dir, ext, ret) { + ret = ret || []; + ext = ext || ['js']; + + var re = new RegExp('\\.(' + ext.join('|') + ')$'); + + readdirSync(dir) + .filter(ignored) + .forEach(function (path) { + path = join(dir, path); + if (lstatSync(path).isDirectory()) { + exports.files(path, ext, ret); + } else if (path.match(re)) { + ret.push(path); + } + }); + + return ret; +}; + +/** + * Compute a slug from the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.slug = function (str) { + return str + .toLowerCase() + .replace(/ +/g, '-') + .replace(/[^-\w]/g, ''); +}; + +/** + * Strip the function definition from `str`, and re-indent for pre whitespace. + * + * @param {string} str + * @return {string} + */ +exports.clean = function (str) { + str = str + .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') + // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content + .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3'); + + var spaces = str.match(/^\n?( *)/)[1].length; + var tabs = str.match(/^\n?(\t*)/)[1].length; + var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}', 'gm'); + + str = str.replace(re, ''); + + return exports.trim(str); +}; + +/** + * Trim the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.trim = function (str) { + return str.replace(/^\s+|\s+$/g, ''); +}; + +/** + * Parse the given `qs`. + * + * @api private + * @param {string} qs + * @return {Object} + */ +exports.parseQuery = function (qs) { + return reduce(qs.replace('?', '').split('&'), function (obj, pair) { + var i = pair.indexOf('='); + var key = pair.slice(0, i); + var val = pair.slice(++i); + + obj[key] = decodeURIComponent(val); + return obj; + }, {}); +}; + +/** + * Highlight the given string of `js`. + * + * @api private + * @param {string} js + * @return {string} + */ +function highlight (js) { + return js + .replace(//g, '>') + .replace(/\/\/(.*)/gm, '//$1') + .replace(/('.*?')/gm, '$1') + .replace(/(\d+\.\d+)/gm, '$1') + .replace(/(\d+)/gm, '$1') + .replace(/\bnew[ \t]+(\w+)/gm, 'new $1') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '$1'); +} + +/** + * Highlight the contents of tag `name`. + * + * @api private + * @param {string} name + */ +exports.highlightTags = function (name) { + var code = document.getElementById('mocha').getElementsByTagName(name); + for (var i = 0, len = code.length; i < len; ++i) { + code[i].innerHTML = highlight(code[i].innerHTML); + } +}; + +/** + * If a value could have properties, and has none, this function is called, + * which returns a string representation of the empty value. + * + * Functions w/ no properties return `'[Function]'` + * Arrays w/ length === 0 return `'[]'` + * Objects w/ no properties return `'{}'` + * All else: return result of `value.toString()` + * + * @api private + * @param {*} value The value to inspect. + * @param {string} typeHint The type of the value + * @returns {string} + */ +function emptyRepresentation (value, typeHint) { + switch (typeHint) { + case 'function': + return '[Function]'; + case 'object': + return '{}'; + case 'array': + return '[]'; + default: + return value.toString(); + } +} + +/** + * Takes some variable and asks `Object.prototype.toString()` what it thinks it + * is. + * + * @api private + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString + * @param {*} value The value to test. + * @returns {string} Computed type + * @example + * type({}) // 'object' + * type([]) // 'array' + * type(1) // 'number' + * type(false) // 'boolean' + * type(Infinity) // 'number' + * type(null) // 'null' + * type(new Date()) // 'date' + * type(/foo/) // 'regexp' + * type('type') // 'string' + * type(global) // 'global' + * type(new String('foo') // 'object' + */ +var type = exports.type = function type (value) { + if (value === undefined) { + return 'undefined'; + } else if (value === null) { + return 'null'; + } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { + return 'buffer'; + } + return Object.prototype.toString.call(value) + .replace(/^\[.+\s(.+?)\]$/, '$1') + .toLowerCase(); +}; + +/** + * Stringify `value`. Different behavior depending on type of value: + * + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. + * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of function + * {@link emptyRepresentation}. + * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of + * JSON.stringify(). + * + * @api private + * @see exports.type + * @param {*} value + * @return {string} + */ +exports.stringify = function (value) { + var typeHint = type(value); + + if (!~indexOf(['object', 'array', 'function'], typeHint)) { + if (typeHint === 'buffer') { + var json = value.toJSON(); + // Based on the toJSON result + return jsonStringify(json.data && json.type ? json.data : json, 2) + .replace(/,(\n|$)/g, '$1'); + } + + // IE7/IE8 has a bizarre String constructor; needs to be coerced + // into an array and back to obj. + if (typeHint === 'string' && typeof value === 'object') { + value = reduce(value.split(''), function (acc, char, idx) { + acc[idx] = char; + return acc; + }, {}); + typeHint = 'object'; + } else { + return jsonStringify(value); + } + } + + for (var prop in value) { + if (Object.prototype.hasOwnProperty.call(value, prop)) { + return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\n|$)/g, '$1'); + } + } + + return emptyRepresentation(value, typeHint); +}; + +/** + * like JSON.stringify but more sense. + * + * @api private + * @param {Object} object + * @param {number=} spaces + * @param {number=} depth + * @returns {*} + */ +function jsonStringify (object, spaces, depth) { + if (typeof spaces === 'undefined') { + // primitive types + return _stringify(object); + } + + depth = depth || 1; + var space = spaces * depth; + var str = isArray(object) ? '[' : '{'; + var end = isArray(object) ? ']' : '}'; + var length = typeof object.length === 'number' ? object.length : exports.keys(object).length; + // `.repeat()` polyfill + function repeat (s, n) { + return new Array(n).join(s); + } + + function _stringify (val) { + switch (type(val)) { + case 'null': + case 'undefined': + val = '[' + val + ']'; + break; + case 'array': + case 'object': + val = jsonStringify(val, spaces, depth + 1); + break; + case 'boolean': + case 'regexp': + case 'symbol': + case 'number': + val = val === 0 && (1 / val) === -Infinity // `-0` + ? '-0' + : val.toString(); + break; + case 'date': + var sDate; + if (isNaN(val.getTime())) { // Invalid date + sDate = val.toString(); + } else { + sDate = val.toISOString ? val.toISOString() : toISOString(val); + } + val = '[Date: ' + sDate + ']'; + break; + case 'buffer': + var json = val.toJSON(); + // Based on the toJSON result + json = json.data && json.type ? json.data : json; + val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']'; + break; + default: + val = (val === '[Function]' || val === '[Circular]') + ? val + : JSON.stringify(val); // string + } + return val; + } + + for (var i in object) { + if (!Object.prototype.hasOwnProperty.call(object, i)) { + continue; // not my business + } + --length; + str += '\n ' + repeat(' ', space) + + (isArray(object) ? '' : '"' + i + '": ') + // key + _stringify(object[i]) + // value + (length ? ',' : ''); // comma + } + + return str + + // [], {} + (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end); +} + +/** + * Test if a value is a buffer. + * + * @api private + * @param {*} value The value to test. + * @return {boolean} True if `value` is a buffer, otherwise false + */ +exports.isBuffer = function (value) { + return typeof Buffer !== 'undefined' && Buffer.isBuffer(value); +}; + +/** + * Return a new Thing that has the keys in sorted order. Recursive. + * + * If the Thing... + * - has already been seen, return string `'[Circular]'` + * - is `undefined`, return string `'[undefined]'` + * - is `null`, return value `null` + * - is some other primitive, return the value + * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * + * @api private + * @see {@link exports.stringify} + * @param {*} value Thing to inspect. May or may not have properties. + * @param {Array} [stack=[]] Stack of seen values + * @param {string} [typeHint] Type hint + * @return {(Object|Array|Function|string|undefined)} + */ +exports.canonicalize = function canonicalize (value, stack, typeHint) { + var canonicalizedObj; + /* eslint-disable no-unused-vars */ + var prop; + /* eslint-enable no-unused-vars */ + typeHint = typeHint || type(value); + function withStack (value, fn) { + stack.push(value); + fn(); + stack.pop(); + } + + stack = stack || []; + + if (indexOf(stack, value) !== -1) { + return '[Circular]'; + } + + switch (typeHint) { + case 'undefined': + case 'buffer': + case 'null': + canonicalizedObj = value; + break; + case 'array': + withStack(value, function () { + canonicalizedObj = exports.map(value, function (item) { + return exports.canonicalize(item, stack); + }); + }); + break; + case 'function': + /* eslint-disable guard-for-in */ + for (prop in value) { + canonicalizedObj = {}; + break; + } + /* eslint-enable guard-for-in */ + if (!canonicalizedObj) { + canonicalizedObj = emptyRepresentation(value, typeHint); + break; + } + /* falls through */ + case 'object': + canonicalizedObj = canonicalizedObj || {}; + withStack(value, function () { + exports.forEach(exports.keys(value).sort(), function (key) { + canonicalizedObj[key] = exports.canonicalize(value[key], stack); + }); + }); + break; + case 'date': + case 'number': + case 'regexp': + case 'boolean': + case 'symbol': + canonicalizedObj = value; + break; + default: + canonicalizedObj = value + ''; + } + + return canonicalizedObj; +}; + +/** + * Lookup file names at the given `path`. + * + * @api public + * @param {string} path Base path to start searching from. + * @param {string[]} extensions File extensions to look for. + * @param {boolean} recursive Whether or not to recurse into subdirectories. + * @return {string[]} An array of paths. + */ +exports.lookupFiles = function lookupFiles (path, extensions, recursive) { + var files = []; + var re = new RegExp('\\.(' + extensions.join('|') + ')$'); + + if (!exists(path)) { + if (exists(path + '.js')) { + path += '.js'; + } else { + files = glob.sync(path); + if (!files.length) { + throw new Error("cannot resolve path (or pattern) '" + path + "'"); + } + return files; + } + } + + try { + var stat = statSync(path); + if (stat.isFile()) { + return path; + } + } catch (err) { + // ignore error + return; + } + + readdirSync(path).forEach(function (file) { + file = join(path, file); + try { + var stat = statSync(file); + if (stat.isDirectory()) { + if (recursive) { + files = files.concat(lookupFiles(file, extensions, recursive)); + } + return; + } + } catch (err) { + // ignore error + return; + } + if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') { + return; + } + files.push(file); + }); + + return files; +}; + +/** + * Generate an undefined error with a message warning the user. + * + * @return {Error} + */ + +exports.undefinedError = function () { + return new Error('Caught undefined error, did you throw without specifying what?'); +}; + +/** + * Generate an undefined error if `err` is not defined. + * + * @param {Error} err + * @return {Error} + */ + +exports.getError = function (err) { + return err || exports.undefinedError(); +}; + +/** + * @summary + * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * @description + * When invoking this function you get a filter function that get the Error.stack as an input, + * and return a prettify output. + * (i.e: strip Mocha and internal node functions from stack trace). + * @returns {Function} + */ +exports.stackTraceFilter = function () { + // TODO: Replace with `process.browser` + var is = typeof document === 'undefined' ? { node: true } : { browser: true }; + var slash = path.sep; + var cwd; + if (is.node) { + cwd = process.cwd() + slash; + } else { + cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\/[^\/]*$/, '/'); + slash = '/'; + } + + function isMochaInternal (line) { + return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) || + (~line.indexOf('node_modules' + slash + 'mocha.js')) || + (~line.indexOf('bower_components' + slash + 'mocha.js')) || + (~line.indexOf(slash + 'mocha.js')); + } + + function isNodeInternal (line) { + return (~line.indexOf('(timers.js:')) || + (~line.indexOf('(events.js:')) || + (~line.indexOf('(node.js:')) || + (~line.indexOf('(module.js:')) || + (~line.indexOf('GeneratorFunctionPrototype.next (native)')) || + false; + } + + return function (stack) { + stack = stack.split('\n'); + + stack = reduce(stack, function (list, line) { + if (isMochaInternal(line)) { + return list; + } + + if (is.node && isNodeInternal(line)) { + return list; + } + + // Clean up cwd(absolute) + if (/\(?.+:\d+:\d+\)?$/.test(line)) { + line = line.replace(cwd, ''); + } + + list.push(line); + return list; + }, []); + + return stack.join('\n'); + }; +}; + +/** + * Crude, but effective. + * @api + * @param {*} value + * @returns {boolean} Whether or not `value` is a Promise + */ +exports.isPromise = function isPromise (value) { + return typeof value === 'object' && typeof value.then === 'function'; +}; + +/** + * It's a noop. + * @api + */ +exports.noop = function () {}; diff --git a/support/client/lib/vwf/view/mocha/mocha.css b/support/client/lib/vwf/view/mocha/mocha.css new file mode 100644 index 000000000..ec96b003c --- /dev/null +++ b/support/client/lib/vwf/view/mocha/mocha.css @@ -0,0 +1,326 @@ +@charset "utf-8"; + +body { + margin:0; +} + +#mocha { + font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; + margin: 60px 50px; +} + +#mocha ul, +#mocha li { + margin: 0; + padding: 0; +} + +#mocha ul { + list-style: none; +} + +#mocha h1, +#mocha h2 { + margin: 0; +} + +#mocha h1 { + margin-top: 15px; + font-size: 1em; + font-weight: 200; +} + +#mocha h1 a { + text-decoration: none; + color: inherit; +} + +#mocha h1 a:hover { + text-decoration: underline; +} + +#mocha .suite .suite h1 { + margin-top: 0; + font-size: .8em; +} + +#mocha .hidden { + display: none; +} + +#mocha h2 { + font-size: 12px; + font-weight: normal; + cursor: pointer; +} + +#mocha .suite { + margin-left: 15px; +} + +#mocha .test { + margin-left: 15px; + overflow: hidden; +} + +#mocha .test.pending:hover h2::after { + content: '(pending)'; + font-family: arial, sans-serif; +} + +#mocha .test.pass.medium .duration { + background: #c09853; +} + +#mocha .test.pass.slow .duration { + background: #b94a48; +} + +#mocha .test.pass::before { + content: '✓'; + font-size: 12px; + display: block; + float: left; + margin-right: 5px; + color: #00d6b2; +} + +#mocha .test.pass .duration { + font-size: 9px; + margin-left: 5px; + padding: 2px 5px; + color: #fff; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -ms-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; +} + +#mocha .test.pass.fast .duration { + display: none; +} + +#mocha .test.pending { + color: #0b97c4; +} + +#mocha .test.pending::before { + content: '◦'; + color: #0b97c4; +} + +#mocha .test.fail { + color: #c00; +} + +#mocha .test.fail pre { + color: black; +} + +#mocha .test.fail::before { + content: '✖'; + font-size: 12px; + display: block; + float: left; + margin-right: 5px; + color: #c00; +} + +#mocha .test pre.error { + color: #c00; + max-height: 300px; + overflow: auto; +} + +#mocha .test .html-error { + overflow: auto; + color: black; + line-height: 1.5; + display: block; + float: left; + clear: left; + font: 12px/1.5 monaco, monospace; + margin: 5px; + padding: 15px; + border: 1px solid #eee; + max-width: 85%; /*(1)*/ + max-width: -webkit-calc(100% - 42px); + max-width: -moz-calc(100% - 42px); + max-width: calc(100% - 42px); /*(2)*/ + max-height: 300px; + word-wrap: break-word; + border-bottom-color: #ddd; + -webkit-box-shadow: 0 1px 3px #eee; + -moz-box-shadow: 0 1px 3px #eee; + box-shadow: 0 1px 3px #eee; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +#mocha .test .html-error pre.error { + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: 0; + -moz-box-shadow: 0; + box-shadow: 0; + padding: 0; + margin: 0; + margin-top: 18px; + max-height: none; +} + +/** + * (1): approximate for browsers not supporting calc + * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border) + * ^^ seriously + */ +#mocha .test pre { + display: block; + float: left; + clear: left; + font: 12px/1.5 monaco, monospace; + margin: 5px; + padding: 15px; + border: 1px solid #eee; + max-width: 85%; /*(1)*/ + max-width: -webkit-calc(100% - 42px); + max-width: -moz-calc(100% - 42px); + max-width: calc(100% - 42px); /*(2)*/ + word-wrap: break-word; + border-bottom-color: #ddd; + -webkit-box-shadow: 0 1px 3px #eee; + -moz-box-shadow: 0 1px 3px #eee; + box-shadow: 0 1px 3px #eee; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +#mocha .test h2 { + position: relative; +} + +#mocha .test a.replay { + position: absolute; + top: 3px; + right: 0; + text-decoration: none; + vertical-align: middle; + display: block; + width: 15px; + height: 15px; + line-height: 15px; + text-align: center; + background: #eee; + font-size: 15px; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + -webkit-transition:opacity 200ms; + -moz-transition:opacity 200ms; + -o-transition:opacity 200ms; + transition: opacity 200ms; + opacity: 0.3; + color: #888; +} + +#mocha .test:hover a.replay { + opacity: 1; +} + +#mocha-report.pass .test.fail { + display: none; +} + +#mocha-report.fail .test.pass { + display: none; +} + +#mocha-report.pending .test.pass, +#mocha-report.pending .test.fail { + display: none; +} +#mocha-report.pending .test.pass.pending { + display: block; +} + +#mocha-error { + color: #c00; + font-size: 1.5em; + font-weight: 100; + letter-spacing: 1px; +} + +#mocha-stats { + position: fixed; + top: 15px; + right: 10px; + font-size: 12px; + margin: 0; + color: #888; + z-index: 1; +} + +#mocha-stats .progress { + float: right; + padding-top: 0; + + /** + * Set safe initial values, so mochas .progress does not inherit these + * properties from Bootstrap .progress (which causes .progress height to + * equal line height set in Bootstrap). + */ + height: auto; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + background-color: initial; +} + +#mocha-stats em { + color: black; +} + +#mocha-stats a { + text-decoration: none; + color: inherit; +} + +#mocha-stats a:hover { + border-bottom: 1px solid #eee; +} + +#mocha-stats li { + display: inline-block; + margin: 0 5px; + list-style: none; + padding-top: 11px; +} + +#mocha-stats canvas { + width: 40px; + height: 40px; +} + +#mocha code .comment { color: #ddd; } +#mocha code .init { color: #2f6fad; } +#mocha code .string { color: #5890ad; } +#mocha code .keyword { color: #8a6343; } +#mocha code .number { color: #2f6fad; } + +@media screen and (max-device-width: 480px) { + #mocha { + margin: 60px 0px; + } + + #mocha #stats { + position: absolute; + } +} diff --git a/support/client/lib/vwf/view/mocha/mocha.js b/support/client/lib/vwf/view/mocha/mocha.js new file mode 100644 index 000000000..e316e5550 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/mocha.js @@ -0,0 +1,15559 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { + suites.shift(); + } + return common.suite.create({ + title: title, + file: file, + fn: false + }); + }; + + /** + * Exclusive Suite. + */ + + context.suite.only = function (title) { + if (suites.length > 1) { + suites.shift(); + } + return common.suite.only({ + title: title, + file: file, + fn: false + }); + }; + + /** + * Describe a specification or test-case + * with the given `title` and callback `fn` + * acting as a thunk. + */ + + context.test = function (title, fn) { + var test = new Test(title, fn); + test.file = file; + suites[0].addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function (title, fn) { + return common.test.only(mocha, context.test(title, fn)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; + +},{"../test":36,"./common":9}],13:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var Test = require('../test'); + +/** + * TDD-style interface: + * + * suite('Array', function() { + * suite('#indexOf()', function() { + * suiteSetup(function() { + * + * }); + * + * test('should return -1 when not present', function() { + * + * }); + * + * test('should return the index when present', function() { + * + * }); + * + * suiteTeardown(function() { + * + * }); + * }); + * }); + * + * @param {Suite} suite Root suite. + */ +module.exports = function (suite) { + var suites = [suite]; + + suite.on('pre-require', function (context, file, mocha) { + var common = require('./common')(suites, context, mocha); + + context.setup = common.beforeEach; + context.teardown = common.afterEach; + context.suiteSetup = common.before; + context.suiteTeardown = common.after; + context.run = mocha.options.delay && common.runWithSuite(suite); + + /** + * Describe a "suite" with the given `title` and callback `fn` containing + * nested suites and/or tests. + */ + context.suite = function (title, fn) { + return common.suite.create({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Pending suite. + */ + context.suite.skip = function (title, fn) { + return common.suite.skip({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Exclusive test-case. + */ + context.suite.only = function (title, fn) { + return common.suite.only({ + title: title, + file: file, + fn: fn + }); + }; + + /** + * Describe a specification or test-case with the given `title` and + * callback `fn` acting as a thunk. + */ + context.test = function (title, fn) { + var suite = suites[0]; + if (suite.isPending()) { + fn = null; + } + var test = new Test(title, fn); + test.file = file; + suite.addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function (title, fn) { + return common.test.only(mocha, context.test(title, fn)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; + +},{"../test":36,"./common":9}],14:[function(require,module,exports){ +(function (process,global,__dirname){ +'use strict'; + +/*! + * mocha + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var escapeRe = require('escape-string-regexp'); +var path = require('path'); +var reporters = require('./reporters'); +var utils = require('./utils'); + +/** + * Expose `Mocha`. + */ + +exports = module.exports = Mocha; + +/** + * To require local UIs and reporters when running in node. + */ + +if (!process.browser) { + var cwd = process.cwd(); + module.paths.push(cwd, path.join(cwd, 'node_modules')); +} + +/** + * Expose internals. + */ + +exports.utils = utils; +exports.interfaces = require('./interfaces'); +exports.reporters = reporters; +exports.Runnable = require('./runnable'); +exports.Context = require('./context'); +exports.Runner = require('./runner'); +exports.Suite = require('./suite'); +exports.Hook = require('./hook'); +exports.Test = require('./test'); + +/** + * Return image `name` path. + * + * @api private + * @param {string} name + * @return {string} + */ +function image (name) { + return path.join(__dirname, '../images', name + '.png'); +} + +/** + * Set up mocha with `options`. + * + * Options: + * + * - `ui` name "bdd", "tdd", "exports" etc + * - `reporter` reporter instance, defaults to `mocha.reporters.spec` + * - `globals` array of accepted globals + * - `timeout` timeout in milliseconds + * - `retries` number of times to retry failed tests + * - `bail` bail on the first test failure + * - `slow` milliseconds to wait before considering a test slow + * - `ignoreLeaks` ignore global leaks + * - `fullTrace` display the full stack-trace on failing + * - `grep` string or regexp to filter tests with + * + * @param {Object} options + * @api public + */ +function Mocha (options) { + options = options || {}; + this.files = []; + this.options = options; + if (options.grep) { + this.grep(new RegExp(options.grep)); + } + if (options.fgrep) { + this.fgrep(options.fgrep); + } + this.suite = new exports.Suite('', new exports.Context()); + this.ui(options.ui); + this.bail(options.bail); + this.reporter(options.reporter, options.reporterOptions); + if (typeof options.timeout !== 'undefined' && options.timeout !== null) { + this.timeout(options.timeout); + } + if (typeof options.retries !== 'undefined' && options.retries !== null) { + this.retries(options.retries); + } + this.useColors(options.useColors); + if (options.enableTimeouts !== null) { + this.enableTimeouts(options.enableTimeouts); + } + if (options.slow) { + this.slow(options.slow); + } +} + +/** + * Enable or disable bailing on the first failure. + * + * @api public + * @param {boolean} [bail] + */ +Mocha.prototype.bail = function (bail) { + if (!arguments.length) { + bail = true; + } + this.suite.bail(bail); + return this; +}; + +/** + * Add test `file`. + * + * @api public + * @param {string} file + */ +Mocha.prototype.addFile = function (file) { + this.files.push(file); + return this; +}; + +/** + * Set reporter to `reporter`, defaults to "spec". + * + * @param {String|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + * @api public + * @param {string|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + */ +Mocha.prototype.reporter = function (reporter, reporterOptions) { + if (typeof reporter === 'function') { + this._reporter = reporter; + } else { + reporter = reporter || 'spec'; + var _reporter; + // Try to load a built-in reporter. + if (reporters[reporter]) { + _reporter = reporters[reporter]; + } + // Try to load reporters from process.cwd() and node_modules + if (!_reporter) { + try { + _reporter = require(reporter); + } catch (err) { + err.message.indexOf('Cannot find module') !== -1 + ? console.warn('"' + reporter + '" reporter not found') + : console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack); + } + } + if (!_reporter && reporter === 'teamcity') { + console.warn('The Teamcity reporter was moved to a package named ' + + 'mocha-teamcity-reporter ' + + '(https://npmjs.org/package/mocha-teamcity-reporter).'); + } + if (!_reporter) { + throw new Error('invalid reporter "' + reporter + '"'); + } + this._reporter = _reporter; + } + this.options.reporterOptions = reporterOptions; + return this; +}; + +/** + * Set test UI `name`, defaults to "bdd". + * + * @api public + * @param {string} bdd + */ +Mocha.prototype.ui = function (name) { + name = name || 'bdd'; + this._ui = exports.interfaces[name]; + if (!this._ui) { + try { + this._ui = require(name); + } catch (err) { + throw new Error('invalid interface "' + name + '"'); + } + } + this._ui = this._ui(this.suite); + + this.suite.on('pre-require', function (context) { + exports.afterEach = context.afterEach || context.teardown; + exports.after = context.after || context.suiteTeardown; + exports.beforeEach = context.beforeEach || context.setup; + exports.before = context.before || context.suiteSetup; + exports.describe = context.describe || context.suite; + exports.it = context.it || context.test; + exports.setup = context.setup || context.beforeEach; + exports.suiteSetup = context.suiteSetup || context.before; + exports.suiteTeardown = context.suiteTeardown || context.after; + exports.suite = context.suite || context.describe; + exports.teardown = context.teardown || context.afterEach; + exports.test = context.test || context.it; + exports.run = context.run; + }); + + return this; +}; + +/** + * Load registered files. + * + * @api private + */ +Mocha.prototype.loadFiles = function (fn) { + var self = this; + var suite = this.suite; + this.files.forEach(function (file) { + file = path.resolve(file); + suite.emit('pre-require', global, file, self); + suite.emit('require', require(file), file, self); + suite.emit('post-require', global, file, self); + }); + fn && fn(); +}; + +/** + * Enable growl support. + * + * @api private + */ +Mocha.prototype._growl = function (runner, reporter) { + var notify = require('growl'); + + runner.on('end', function () { + var stats = reporter.stats; + if (stats.failures) { + var msg = stats.failures + ' of ' + runner.total + ' tests failed'; + notify(msg, { name: 'mocha', title: 'Failed', image: image('error') }); + } else { + notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', { + name: 'mocha', + title: 'Passed', + image: image('ok') + }); + } + }); +}; + +/** + * Escape string and add it to grep as a regexp. + * + * @api public + * @param str + * @returns {Mocha} + */ +Mocha.prototype.fgrep = function (str) { + return this.grep(new RegExp(escapeRe(str))); +}; + +/** + * Add regexp to grep, if `re` is a string it is escaped. + * + * @param {RegExp|String} re + * @return {Mocha} + * @api public + * @param {RegExp|string} re + * @return {Mocha} + */ +Mocha.prototype.grep = function (re) { + if (utils.isString(re)) { + // extract args if it's regex-like, i.e: [string, pattern, flag] + var arg = re.match(/^\/(.*)\/(g|i|)$|.*/); + this.options.grep = new RegExp(arg[1] || arg[0], arg[2]); + } else { + this.options.grep = re; + } + return this; +}; +/** + * Invert `.grep()` matches. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.invert = function () { + this.options.invert = true; + return this; +}; + +/** + * Ignore global leaks. + * + * @param {Boolean} ignore + * @return {Mocha} + * @api public + * @param {boolean} ignore + * @return {Mocha} + */ +Mocha.prototype.ignoreLeaks = function (ignore) { + this.options.ignoreLeaks = Boolean(ignore); + return this; +}; + +/** + * Enable global leak checking. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.checkLeaks = function () { + this.options.ignoreLeaks = false; + return this; +}; + +/** + * Display long stack-trace on failing + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.fullTrace = function () { + this.options.fullStackTrace = true; + return this; +}; + +/** + * Enable growl support. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.growl = function () { + this.options.growl = true; + return this; +}; + +/** + * Ignore `globals` array or string. + * + * @param {Array|String} globals + * @return {Mocha} + * @api public + * @param {Array|string} globals + * @return {Mocha} + */ +Mocha.prototype.globals = function (globals) { + this.options.globals = (this.options.globals || []).concat(globals); + return this; +}; + +/** + * Emit color output. + * + * @param {Boolean} colors + * @return {Mocha} + * @api public + * @param {boolean} colors + * @return {Mocha} + */ +Mocha.prototype.useColors = function (colors) { + if (colors !== undefined) { + this.options.useColors = colors; + } + return this; +}; + +/** + * Use inline diffs rather than +/-. + * + * @param {Boolean} inlineDiffs + * @return {Mocha} + * @api public + * @param {boolean} inlineDiffs + * @return {Mocha} + */ +Mocha.prototype.useInlineDiffs = function (inlineDiffs) { + this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; + return this; +}; + +/** + * Set the timeout in milliseconds. + * + * @param {Number} timeout + * @return {Mocha} + * @api public + * @param {number} timeout + * @return {Mocha} + */ +Mocha.prototype.timeout = function (timeout) { + this.suite.timeout(timeout); + return this; +}; + +/** + * Set the number of times to retry failed tests. + * + * @param {Number} retry times + * @return {Mocha} + * @api public + */ +Mocha.prototype.retries = function (n) { + this.suite.retries(n); + return this; +}; + +/** + * Set slowness threshold in milliseconds. + * + * @param {Number} slow + * @return {Mocha} + * @api public + * @param {number} slow + * @return {Mocha} + */ +Mocha.prototype.slow = function (slow) { + this.suite.slow(slow); + return this; +}; + +/** + * Enable timeouts. + * + * @param {Boolean} enabled + * @return {Mocha} + * @api public + * @param {boolean} enabled + * @return {Mocha} + */ +Mocha.prototype.enableTimeouts = function (enabled) { + this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true); + return this; +}; + +/** + * Makes all tests async (accepting a callback) + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.asyncOnly = function () { + this.options.asyncOnly = true; + return this; +}; + +/** + * Disable syntax highlighting (in browser). + * + * @api public + */ +Mocha.prototype.noHighlighting = function () { + this.options.noHighlighting = true; + return this; +}; + +/** + * Enable uncaught errors to propagate (in browser). + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.allowUncaught = function () { + this.options.allowUncaught = true; + return this; +}; + +/** + * Delay root suite execution. + * @returns {Mocha} + */ +Mocha.prototype.delay = function delay () { + this.options.delay = true; + return this; +}; + +/** + * Run tests and invoke `fn()` when complete. + * + * @api public + * @param {Function} fn + * @return {Runner} + */ +Mocha.prototype.run = function (fn) { + if (this.files.length) { + this.loadFiles(); + } + var suite = this.suite; + var options = this.options; + options.files = this.files; + var runner = new exports.Runner(suite, options.delay); + var reporter = new this._reporter(runner, options); + runner.ignoreLeaks = options.ignoreLeaks !== false; + runner.fullStackTrace = options.fullStackTrace; + runner.hasOnly = options.hasOnly; + runner.asyncOnly = options.asyncOnly; + runner.allowUncaught = options.allowUncaught; + if (options.grep) { + runner.grep(options.grep, options.invert); + } + if (options.globals) { + runner.globals(options.globals); + } + if (options.growl) { + this._growl(runner, reporter); + } + if (options.useColors !== undefined) { + exports.reporters.Base.useColors = options.useColors; + } + exports.reporters.Base.inlineDiffs = options.useInlineDiffs; + + function done (failures) { + if (reporter.done) { + reporter.done(failures, fn); + } else { + fn && fn(failures); + } + } + + return runner.run(done); +}; + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib") +},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":21,"./runnable":33,"./runner":34,"./suite":35,"./test":36,"./utils":38,"_process":67,"escape-string-regexp":47,"growl":49,"path":42}],15:[function(require,module,exports){ +'use strict'; + +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @api public + * @param {string|number} val + * @param {Object} options + * @return {string|number} + */ +module.exports = function (val, options) { + options = options || {}; + if (typeof val === 'string') { + return parse(val); + } + // https://github.com/mochajs/mocha/pull/1035 + return options['long'] ? longFormat(val) : shortFormat(val); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @api private + * @param {string} str + * @return {number} + */ +function parse (str) { + var match = (/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 's': + return n * s; + case 'ms': + return n; + default: + // No default case + } +} + +/** + * Short format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function shortFormat (ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function longFormat (ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} + +/** + * Pluralization helper. + * + * @api private + * @param {number} ms + * @param {number} n + * @param {string} name + */ +function plural (ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; +} + +},{}],16:[function(require,module,exports){ +'use strict'; + +/** + * Expose `Pending`. + */ + +module.exports = Pending; + +/** + * Initialize a new `Pending` error with the given message. + * + * @param {string} message + */ +function Pending (message) { + this.message = message; +} + +},{}],17:[function(require,module,exports){ +(function (process,global){ +'use strict'; + +/** + * Module dependencies. + */ + +var tty = require('tty'); +var diff = require('diff'); +var ms = require('../ms'); +var utils = require('../utils'); +var supportsColor = process.browser ? null : require('supports-color'); + +/** + * Expose `Base`. + */ + +exports = module.exports = Base; + +/** + * Save timer references to avoid Sinon interfering. + * See: https://github.com/mochajs/mocha/issues/237 + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Check if both stdio streams are associated with a tty. + */ + +var isatty = tty.isatty(1) && tty.isatty(2); + +/** + * Enable coloring by default, except in the browser interface. + */ + +exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined)); + +/** + * Inline diffs instead of +/- + */ + +exports.inlineDiffs = false; + +/** + * Default color map. + */ + +exports.colors = { + pass: 90, + fail: 31, + 'bright pass': 92, + 'bright fail': 91, + 'bright yellow': 93, + pending: 36, + suite: 0, + 'error title': 0, + 'error message': 31, + 'error stack': 90, + checkmark: 32, + fast: 90, + medium: 33, + slow: 31, + green: 32, + light: 90, + 'diff gutter': 90, + 'diff added': 32, + 'diff removed': 31 +}; + +/** + * Default symbol map. + */ + +exports.symbols = { + ok: '✓', + err: '✖', + dot: '․', + comma: ',', + bang: '!' +}; + +// With node.js on Windows: use symbols available in terminal default fonts +if (process.platform === 'win32') { + exports.symbols.ok = '\u221A'; + exports.symbols.err = '\u00D7'; + exports.symbols.dot = '.'; +} + +/** + * Color `str` with the given `type`, + * allowing colors to be disabled, + * as well as user-defined color + * schemes. + * + * @param {string} type + * @param {string} str + * @return {string} + * @api private + */ +var color = exports.color = function (type, str) { + if (!exports.useColors) { + return String(str); + } + return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m'; +}; + +/** + * Expose term window size, with some defaults for when stderr is not a tty. + */ + +exports.window = { + width: 75 +}; + +if (isatty) { + exports.window.width = process.stdout.getWindowSize + ? process.stdout.getWindowSize(1)[0] + : tty.getWindowSize()[1]; +} + +/** + * Expose some basic cursor interactions that are common among reporters. + */ + +exports.cursor = { + hide: function () { + isatty && process.stdout.write('\u001b[?25l'); + }, + + show: function () { + isatty && process.stdout.write('\u001b[?25h'); + }, + + deleteLine: function () { + isatty && process.stdout.write('\u001b[2K'); + }, + + beginningOfLine: function () { + isatty && process.stdout.write('\u001b[0G'); + }, + + CR: function () { + if (isatty) { + exports.cursor.deleteLine(); + exports.cursor.beginningOfLine(); + } else { + process.stdout.write('\r'); + } + } +}; + +/** + * Outut the given `failures` as a list. + * + * @param {Array} failures + * @api public + */ + +exports.list = function (failures) { + console.log(); + failures.forEach(function (test, i) { + // format + var fmt = color('error title', ' %s) %s:\n') + + color('error message', ' %s') + + color('error stack', '\n%s\n'); + + // msg + var msg; + var err = test.err; + var message; + if (err.message && typeof err.message.toString === 'function') { + message = err.message + ''; + } else if (typeof err.inspect === 'function') { + message = err.inspect() + ''; + } else { + message = ''; + } + var stack = err.stack || message; + var index = message ? stack.indexOf(message) : -1; + var actual = err.actual; + var expected = err.expected; + var escape = true; + + if (index === -1) { + msg = message; + } else { + index += message.length; + msg = stack.slice(0, index); + // remove msg from stack + stack = stack.slice(index + 1); + } + + // uncaught + if (err.uncaught) { + msg = 'Uncaught ' + msg; + } + // explicitly show diff + if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) { + escape = false; + if (!(utils.isString(actual) && utils.isString(expected))) { + err.actual = actual = utils.stringify(actual); + err.expected = expected = utils.stringify(expected); + } + + fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n'); + var match = message.match(/^([^:]+): expected/); + msg = '\n ' + color('error message', match ? match[1] : msg); + + if (exports.inlineDiffs) { + msg += inlineDiff(err, escape); + } else { + msg += unifiedDiff(err, escape); + } + } + + // indent stack trace + stack = stack.replace(/^/gm, ' '); + + console.log(fmt, (i + 1), test.fullTitle(), msg, stack); + }); +}; + +/** + * Initialize a new `Base` reporter. + * + * All other reporters generally + * inherit from this reporter, providing + * stats such as test duration, number + * of tests passed / failed etc. + * + * @param {Runner} runner + * @api public + */ + +function Base (runner) { + var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }; + var failures = this.failures = []; + + if (!runner) { + return; + } + this.runner = runner; + + runner.stats = stats; + + runner.on('start', function () { + stats.start = new Date(); + }); + + runner.on('suite', function (suite) { + stats.suites = stats.suites || 0; + suite.root || stats.suites++; + }); + + runner.on('test end', function () { + stats.tests = stats.tests || 0; + stats.tests++; + }); + + runner.on('pass', function (test) { + stats.passes = stats.passes || 0; + + if (test.duration > test.slow()) { + test.speed = 'slow'; + } else if (test.duration > test.slow() / 2) { + test.speed = 'medium'; + } else { + test.speed = 'fast'; + } + + stats.passes++; + }); + + runner.on('fail', function (test, err) { + stats.failures = stats.failures || 0; + stats.failures++; + test.err = err; + failures.push(test); + }); + + runner.on('end', function () { + stats.end = new Date(); + stats.duration = new Date() - stats.start; + }); + + runner.on('pending', function () { + stats.pending++; + }); +} + +/** + * Output common epilogue used by many of + * the bundled reporters. + * + * @api public + */ +Base.prototype.epilogue = function () { + var stats = this.stats; + var fmt; + + console.log(); + + // passes + fmt = color('bright pass', ' ') + + color('green', ' %d passing') + + color('light', ' (%s)'); + + console.log(fmt, + stats.passes || 0, + ms(stats.duration)); + + // pending + if (stats.pending) { + fmt = color('pending', ' ') + + color('pending', ' %d pending'); + + console.log(fmt, stats.pending); + } + + // failures + if (stats.failures) { + fmt = color('fail', ' %d failing'); + + console.log(fmt, stats.failures); + + Base.list(this.failures); + console.log(); + } + + console.log(); +}; + +/** + * Pad the given `str` to `len`. + * + * @api private + * @param {string} str + * @param {string} len + * @return {string} + */ +function pad (str, len) { + str = String(str); + return Array(len - str.length + 1).join(' ') + str; +} + +/** + * Returns an inline diff between 2 strings with coloured ANSI output + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} Diff + */ +function inlineDiff (err, escape) { + var msg = errorDiff(err, 'WordsWithSpace', escape); + + // linenos + var lines = msg.split('\n'); + if (lines.length > 4) { + var width = String(lines.length).length; + msg = lines.map(function (str, i) { + return pad(++i, width) + ' |' + ' ' + str; + }).join('\n'); + } + + // legend + msg = '\n' + + color('diff removed', 'actual') + + ' ' + + color('diff added', 'expected') + + '\n\n' + + msg + + '\n'; + + // indent + msg = msg.replace(/^/gm, ' '); + return msg; +} + +/** + * Returns a unified diff between two strings. + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} The diff. + */ +function unifiedDiff (err, escape) { + var indent = ' '; + function cleanUp (line) { + if (escape) { + line = escapeInvisibles(line); + } + if (line[0] === '+') { + return indent + colorLines('diff added', line); + } + if (line[0] === '-') { + return indent + colorLines('diff removed', line); + } + if (line.match(/@@/)) { + return null; + } + if (line.match(/\\ No newline/)) { + return null; + } + return indent + line; + } + function notBlank (line) { + return typeof line !== 'undefined' && line !== null; + } + var msg = diff.createPatch('string', err.actual, err.expected); + var lines = msg.split('\n').splice(4); + return '\n ' + + colorLines('diff added', '+ expected') + ' ' + + colorLines('diff removed', '- actual') + + '\n\n' + + lines.map(cleanUp).filter(notBlank).join('\n'); +} + +/** + * Return a character diff for `err`. + * + * @api private + * @param {Error} err + * @param {string} type + * @param {boolean} escape + * @return {string} + */ +function errorDiff (err, type, escape) { + var actual = escape ? escapeInvisibles(err.actual) : err.actual; + var expected = escape ? escapeInvisibles(err.expected) : err.expected; + return diff['diff' + type](actual, expected).map(function (str) { + if (str.added) { + return colorLines('diff added', str.value); + } + if (str.removed) { + return colorLines('diff removed', str.value); + } + return str.value; + }).join(''); +} + +/** + * Returns a string with all invisible characters in plain text + * + * @api private + * @param {string} line + * @return {string} + */ +function escapeInvisibles (line) { + return line.replace(/\t/g, '') + .replace(/\r/g, '') + .replace(/\n/g, '\n'); +} + +/** + * Color lines for `str`, using the color `name`. + * + * @api private + * @param {string} name + * @param {string} str + * @return {string} + */ +function colorLines (name, str) { + return str.split('\n').map(function (str) { + return color(name, str); + }).join('\n'); +} + +/** + * Object#toString reference. + */ +var objToString = Object.prototype.toString; + +/** + * Check that a / b have the same type. + * + * @api private + * @param {Object} a + * @param {Object} b + * @return {boolean} + */ +function sameType (a, b) { + return objToString.call(a) === objToString.call(b); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../ms":15,"../utils":38,"_process":67,"diff":46,"supports-color":42,"tty":5}],18:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Expose `Doc`. + */ + +exports = module.exports = Doc; + +/** + * Initialize a new `Doc` reporter. + * + * @param {Runner} runner + * @api public + */ +function Doc (runner) { + Base.call(this, runner); + + var indents = 2; + + function indent () { + return Array(indents).join(' '); + } + + runner.on('suite', function (suite) { + if (suite.root) { + return; + } + ++indents; + console.log('%s
    ', indent()); + ++indents; + console.log('%s

    %s

    ', indent(), utils.escape(suite.title)); + console.log('%s
    ', indent()); + }); + + runner.on('suite end', function (suite) { + if (suite.root) { + return; + } + console.log('%s
    ', indent()); + --indents; + console.log('%s
    ', indent()); + --indents; + }); + + runner.on('pass', function (test) { + console.log('%s
    %s
    ', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.body)); + console.log('%s
    %s
    ', indent(), code); + }); + + runner.on('fail', function (test, err) { + console.log('%s
    %s
    ', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.body)); + console.log('%s
    %s
    ', indent(), code); + console.log('%s
    %s
    ', indent(), utils.escape(err)); + }); +} + +},{"../utils":38,"./base":17}],19:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; + +/** + * Expose `Dot`. + */ + +exports = module.exports = Dot; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @api public + * @param {Runner} runner + */ +function Dot (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var n = -1; + + runner.on('start', function () { + process.stdout.write('\n'); + }); + + runner.on('pending', function () { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('pending', Base.symbols.comma)); + }); + + runner.on('pass', function (test) { + if (++n % width === 0) { + process.stdout.write('\n '); + } + if (test.speed === 'slow') { + process.stdout.write(color('bright yellow', Base.symbols.dot)); + } else { + process.stdout.write(color(test.speed, Base.symbols.dot)); + } + }); + + runner.on('fail', function () { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('fail', Base.symbols.bang)); + }); + + runner.on('end', function () { + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Dot, Base); + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],20:[function(require,module,exports){ +(function (global){ +'use strict'; + +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var Progress = require('../browser/progress'); +var escapeRe = require('escape-string-regexp'); +var escape = utils.escape; + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `HTML`. + */ + +exports = module.exports = HTML; + +/** + * Stats template. + */ + +var statsTemplate = ''; + +/** + * Initialize a new `HTML` reporter. + * + * @api public + * @param {Runner} runner + */ +function HTML (runner) { + Base.call(this, runner); + + var self = this; + var stats = this.stats; + var stat = fragment(statsTemplate); + var items = stat.getElementsByTagName('li'); + var passes = items[1].getElementsByTagName('em')[0]; + var passesLink = items[1].getElementsByTagName('a')[0]; + var failures = items[2].getElementsByTagName('em')[0]; + var failuresLink = items[2].getElementsByTagName('a')[0]; + var duration = items[3].getElementsByTagName('em')[0]; + var canvas = stat.getElementsByTagName('canvas')[0]; + var report = fragment('
      '); + var stack = [report]; + var progress; + var ctx; + var root = document.getElementById('mocha'); + + if (canvas.getContext) { + var ratio = window.devicePixelRatio || 1; + canvas.style.width = canvas.width; + canvas.style.height = canvas.height; + canvas.width *= ratio; + canvas.height *= ratio; + ctx = canvas.getContext('2d'); + ctx.scale(ratio, ratio); + progress = new Progress(); + } + + if (!root) { + return error('#mocha div missing, add it to your document'); + } + + // pass toggle + on(passesLink, 'click', function (evt) { + evt.preventDefault(); + unhide(); + var name = (/pass/).test(report.className) ? '' : ' pass'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test pass'); + } + }); + + // failure toggle + on(failuresLink, 'click', function (evt) { + evt.preventDefault(); + unhide(); + var name = (/fail/).test(report.className) ? '' : ' fail'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test fail'); + } + }); + + root.appendChild(stat); + root.appendChild(report); + + if (progress) { + progress.size(40); + } + + runner.on('suite', function (suite) { + if (suite.root) { + return; + } + + // suite + var url = self.suiteURL(suite); + var el = fragment('
    • %s

    • ', url, escape(suite.title)); + + // container + stack[0].appendChild(el); + stack.unshift(document.createElement('ul')); + el.appendChild(stack[0]); + }); + + runner.on('suite end', function (suite) { + if (suite.root) { + updateStats(); + return; + } + stack.shift(); + }); + + runner.on('pass', function (test) { + var url = self.testURL(test); + var markup = '
    • %e%ems ' + + '

    • '; + var el = fragment(markup, test.speed, test.title, test.duration, url); + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('fail', function (test) { + var el = fragment('
    • %e

    • ', + test.title, self.testURL(test)); + var stackString; // Note: Includes leading newline + var message = test.err.toString(); + + // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we + // check for the result of the stringifying. + if (message === '[object Error]') { + message = test.err.message; + } + + if (test.err.stack) { + var indexOfMessage = test.err.stack.indexOf(test.err.message); + if (indexOfMessage === -1) { + stackString = test.err.stack; + } else { + stackString = test.err.stack.substr(test.err.message.length + indexOfMessage); + } + } else if (test.err.sourceURL && test.err.line !== undefined) { + // Safari doesn't give you a stack. Let's at least provide a source line. + stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')'; + } + + stackString = stackString || ''; + + if (test.err.htmlMessage && stackString) { + el.appendChild(fragment('
      %s\n
      %e
      ', + test.err.htmlMessage, stackString)); + } else if (test.err.htmlMessage) { + el.appendChild(fragment('
      %s
      ', test.err.htmlMessage)); + } else { + el.appendChild(fragment('
      %e%e
      ', message, stackString)); + } + + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('pending', function (test) { + var el = fragment('
    • %e

    • ', test.title); + appendToStack(el); + updateStats(); + }); + + function appendToStack (el) { + // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack. + if (stack[0]) { + stack[0].appendChild(el); + } + } + + function updateStats () { + // TODO: add to stats + var percent = stats.tests / runner.total * 100 | 0; + if (progress) { + progress.update(percent).draw(ctx); + } + + // update stats + var ms = new Date() - stats.start; + text(passes, stats.passes); + text(failures, stats.failures); + text(duration, (ms / 1000).toFixed(2)); + } +} + +/** + * Makes a URL, preserving querystring ("search") parameters. + * + * @param {string} s + * @return {string} A new URL. + */ +function makeUrl (s) { + var search = window.location.search; + + // Remove previous grep query parameter if present + if (search) { + search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?'); + } + + return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s)); +} + +/** + * Provide suite URL. + * + * @param {Object} [suite] + */ +HTML.prototype.suiteURL = function (suite) { + return makeUrl(suite.fullTitle()); +}; + +/** + * Provide test URL. + * + * @param {Object} [test] + */ +HTML.prototype.testURL = function (test) { + return makeUrl(test.fullTitle()); +}; + +/** + * Adds code toggle functionality for the provided test's list element. + * + * @param {HTMLLIElement} el + * @param {string} contents + */ +HTML.prototype.addCodeToggle = function (el, contents) { + var h2 = el.getElementsByTagName('h2')[0]; + + on(h2, 'click', function () { + pre.style.display = pre.style.display === 'none' ? 'block' : 'none'; + }); + + var pre = fragment('
      %e
      ', utils.clean(contents)); + el.appendChild(pre); + pre.style.display = 'none'; +}; + +/** + * Display error `msg`. + * + * @param {string} msg + */ +function error (msg) { + document.body.appendChild(fragment('
      %s
      ', msg)); +} + +/** + * Return a DOM fragment from `html`. + * + * @param {string} html + */ +function fragment (html) { + var args = arguments; + var div = document.createElement('div'); + var i = 1; + + div.innerHTML = html.replace(/%([se])/g, function (_, type) { + switch (type) { + case 's': return String(args[i++]); + case 'e': return escape(args[i++]); + // no default + } + }); + + return div.firstChild; +} + +/** + * Check for suites that do not have elements + * with `classname`, and hide them. + * + * @param {text} classname + */ +function hideSuitesWithout (classname) { + var suites = document.getElementsByClassName('suite'); + for (var i = 0; i < suites.length; i++) { + var els = suites[i].getElementsByClassName(classname); + if (!els.length) { + suites[i].className += ' hidden'; + } + } +} + +/** + * Unhide .hidden suites. + */ +function unhide () { + var els = document.getElementsByClassName('suite hidden'); + for (var i = 0; i < els.length; ++i) { + els[i].className = els[i].className.replace('suite hidden', 'suite'); + } +} + +/** + * Set an element's text contents. + * + * @param {HTMLElement} el + * @param {string} contents + */ +function text (el, contents) { + if (el.textContent) { + el.textContent = contents; + } else { + el.innerText = contents; + } +} + +/** + * Listen on `event` with callback `fn`. + */ +function on (el, event, fn) { + if (el.addEventListener) { + el.addEventListener(event, fn, false); + } else { + el.attachEvent('on' + event, fn); + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../browser/progress":4,"../utils":38,"./base":17,"escape-string-regexp":47}],21:[function(require,module,exports){ +'use strict'; + +// Alias exports to a their normalized format Mocha#reporter to prevent a need +// for dynamic (try/catch) requires, which Browserify doesn't handle. +exports.Base = exports.base = require('./base'); +exports.Dot = exports.dot = require('./dot'); +exports.Doc = exports.doc = require('./doc'); +exports.TAP = exports.tap = require('./tap'); +exports.JSON = exports.json = require('./json'); +exports.HTML = exports.html = require('./html'); +exports.List = exports.list = require('./list'); +exports.Min = exports.min = require('./min'); +exports.Spec = exports.spec = require('./spec'); +exports.Nyan = exports.nyan = require('./nyan'); +exports.XUnit = exports.xunit = require('./xunit'); +exports.Markdown = exports.markdown = require('./markdown'); +exports.Progress = exports.progress = require('./progress'); +exports.Landing = exports.landing = require('./landing'); +exports.JSONStream = exports['json-stream'] = require('./json-stream'); + +},{"./base":17,"./doc":18,"./dot":19,"./html":20,"./json":23,"./json-stream":22,"./landing":24,"./list":25,"./markdown":26,"./min":27,"./nyan":28,"./progress":29,"./spec":30,"./tap":31,"./xunit":32}],22:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var JSON = require('json3'); + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List (runner) { + Base.call(this, runner); + + var self = this; + var total = runner.total; + + runner.on('start', function () { + console.log(JSON.stringify(['start', { total: total }])); + }); + + runner.on('pass', function (test) { + console.log(JSON.stringify(['pass', clean(test)])); + }); + + runner.on('fail', function (test, err) { + test = clean(test); + test.err = err.message; + test.stack = err.stack || null; + console.log(JSON.stringify(['fail', test])); + }); + + runner.on('end', function () { + process.stdout.write(JSON.stringify(['end', self.stats])); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean (test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry() + }; +} + +}).call(this,require('_process')) +},{"./base":17,"_process":67,"json3":54}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `JSON`. + */ + +exports = module.exports = JSONReporter; + +/** + * Initialize a new `JSON` reporter. + * + * @api public + * @param {Runner} runner + */ +function JSONReporter (runner) { + Base.call(this, runner); + + var self = this; + var tests = []; + var pending = []; + var failures = []; + var passes = []; + + runner.on('test end', function (test) { + tests.push(test); + }); + + runner.on('pass', function (test) { + passes.push(test); + }); + + runner.on('fail', function (test) { + failures.push(test); + }); + + runner.on('pending', function (test) { + pending.push(test); + }); + + runner.on('end', function () { + var obj = { + stats: self.stats, + tests: tests.map(clean), + pending: pending.map(clean), + failures: failures.map(clean), + passes: passes.map(clean) + }; + + runner.testResults = obj; + + process.stdout.write(JSON.stringify(obj, null, 2)); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean (test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry(), + err: errorJSON(test.err || {}) + }; +} + +/** + * Transform `error` into a JSON object. + * + * @api private + * @param {Error} err + * @return {Object} + */ +function errorJSON (err) { + var res = {}; + Object.getOwnPropertyNames(err).forEach(function (key) { + res[key] = err[key]; + }, err); + return res; +} + +}).call(this,require('_process')) +},{"./base":17,"_process":67}],24:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var cursor = Base.cursor; +var color = Base.color; + +/** + * Expose `Landing`. + */ + +exports = module.exports = Landing; + +/** + * Airplane color. + */ + +Base.colors.plane = 0; + +/** + * Airplane crash color. + */ + +Base.colors['plane crash'] = 31; + +/** + * Runway color. + */ + +Base.colors.runway = 90; + +/** + * Initialize a new `Landing` reporter. + * + * @api public + * @param {Runner} runner + */ +function Landing (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var total = runner.total; + var stream = process.stdout; + var plane = color('plane', '✈'); + var crashed = -1; + var n = 0; + + function runway () { + var buf = Array(width).join('-'); + return ' ' + color('runway', buf); + } + + runner.on('start', function () { + stream.write('\n\n\n '); + cursor.hide(); + }); + + runner.on('test end', function (test) { + // check if the plane crashed + var col = crashed === -1 ? width * ++n / total | 0 : crashed; + + // show the crash + if (test.state === 'failed') { + plane = color('plane crash', '✈'); + crashed = col; + } + + // render landing strip + stream.write('\u001b[' + (width + 1) + 'D\u001b[2A'); + stream.write(runway()); + stream.write('\n '); + stream.write(color('runway', Array(col).join('⋅'))); + stream.write(plane); + stream.write(color('runway', Array(width - col).join('⋅') + '\n')); + stream.write(runway()); + stream.write('\u001b[0m'); + }); + + runner.on('end', function () { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Landing, Base); + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],25:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List (runner) { + Base.call(this, runner); + + var self = this; + var n = 0; + + runner.on('start', function () { + console.log(); + }); + + runner.on('test', function (test) { + process.stdout.write(color('pass', ' ' + test.fullTitle() + ': ')); + }); + + runner.on('pending', function (test) { + var fmt = color('checkmark', ' -') + + color('pending', ' %s'); + console.log(fmt, test.fullTitle()); + }); + + runner.on('pass', function (test) { + var fmt = color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s: ') + + color(test.speed, '%dms'); + cursor.CR(); + console.log(fmt, test.fullTitle(), test.duration); + }); + + runner.on('fail', function (test) { + cursor.CR(); + console.log(color('fail', ' %d) %s'), ++n, test.fullTitle()); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(List, Base); + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],26:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Constants + */ + +var SUITE_PREFIX = '$'; + +/** + * Expose `Markdown`. + */ + +exports = module.exports = Markdown; + +/** + * Initialize a new `Markdown` reporter. + * + * @api public + * @param {Runner} runner + */ +function Markdown (runner) { + Base.call(this, runner); + + var level = 0; + var buf = ''; + + function title (str) { + return Array(level).join('#') + ' ' + str; + } + + function mapTOC (suite, obj) { + var ret = obj; + var key = SUITE_PREFIX + suite.title; + + obj = obj[key] = obj[key] || { suite: suite }; + suite.suites.forEach(function (suite) { + mapTOC(suite, obj); + }); + + return ret; + } + + function stringifyTOC (obj, level) { + ++level; + var buf = ''; + var link; + for (var key in obj) { + if (key === 'suite') { + continue; + } + if (key !== SUITE_PREFIX) { + link = ' - [' + key.substring(1) + ']'; + link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n'; + buf += Array(level).join(' ') + link; + } + buf += stringifyTOC(obj[key], level); + } + return buf; + } + + function generateTOC (suite) { + var obj = mapTOC(suite, {}); + return stringifyTOC(obj, 0); + } + + generateTOC(runner.suite); + + runner.on('suite', function (suite) { + ++level; + var slug = utils.slug(suite.fullTitle()); + buf += '' + '\n'; + buf += title(suite.title) + '\n'; + }); + + runner.on('suite end', function () { + --level; + }); + + runner.on('pass', function (test) { + var code = utils.clean(test.body); + buf += test.title + '.\n'; + buf += '\n```js\n'; + buf += code + '\n'; + buf += '```\n\n'; + }); + + runner.on('end', function () { + process.stdout.write('# TOC\n'); + process.stdout.write(generateTOC(runner.suite)); + process.stdout.write(buf); + }); +} + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],27:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Min`. + */ + +exports = module.exports = Min; + +/** + * Initialize a new `Min` minimal test reporter (best used with --watch). + * + * @api public + * @param {Runner} runner + */ +function Min (runner) { + Base.call(this, runner); + + runner.on('start', function () { + // clear screen + process.stdout.write('\u001b[2J'); + // set cursor position + process.stdout.write('\u001b[1;3H'); + }); + + runner.on('end', this.epilogue.bind(this)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Min, Base); + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],28:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Dot`. + */ + +exports = module.exports = NyanCat; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @param {Runner} runner + * @api public + */ + +function NyanCat (runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.75 | 0; + var nyanCatWidth = this.nyanCatWidth = 11; + + this.colorIndex = 0; + this.numberOfLines = 4; + this.rainbowColors = self.generateColors(); + this.scoreboardWidth = 5; + this.tick = 0; + this.trajectories = [[], [], [], []]; + this.trajectoryWidthMax = (width - nyanCatWidth); + + runner.on('start', function () { + Base.cursor.hide(); + self.draw(); + }); + + runner.on('pending', function () { + self.draw(); + }); + + runner.on('pass', function () { + self.draw(); + }); + + runner.on('fail', function () { + self.draw(); + }); + + runner.on('end', function () { + Base.cursor.show(); + for (var i = 0; i < self.numberOfLines; i++) { + write('\n'); + } + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(NyanCat, Base); + +/** + * Draw the nyan cat + * + * @api private + */ + +NyanCat.prototype.draw = function () { + this.appendRainbow(); + this.drawScoreboard(); + this.drawRainbow(); + this.drawNyanCat(); + this.tick = !this.tick; +}; + +/** + * Draw the "scoreboard" showing the number + * of passes, failures and pending tests. + * + * @api private + */ + +NyanCat.prototype.drawScoreboard = function () { + var stats = this.stats; + + function draw (type, n) { + write(' '); + write(Base.color(type, n)); + write('\n'); + } + + draw('green', stats.passes); + draw('fail', stats.failures); + draw('pending', stats.pending); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Append the rainbow. + * + * @api private + */ + +NyanCat.prototype.appendRainbow = function () { + var segment = this.tick ? '_' : '-'; + var rainbowified = this.rainbowify(segment); + + for (var index = 0; index < this.numberOfLines; index++) { + var trajectory = this.trajectories[index]; + if (trajectory.length >= this.trajectoryWidthMax) { + trajectory.shift(); + } + trajectory.push(rainbowified); + } +}; + +/** + * Draw the rainbow. + * + * @api private + */ + +NyanCat.prototype.drawRainbow = function () { + var self = this; + + this.trajectories.forEach(function (line) { + write('\u001b[' + self.scoreboardWidth + 'C'); + write(line.join('')); + write('\n'); + }); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw the nyan cat + * + * @api private + */ +NyanCat.prototype.drawNyanCat = function () { + var self = this; + var startWidth = this.scoreboardWidth + this.trajectories[0].length; + var dist = '\u001b[' + startWidth + 'C'; + var padding = ''; + + write(dist); + write('_,------,'); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write('_|' + padding + '/\\_/\\ '); + write('\n'); + + write(dist); + padding = self.tick ? '_' : '__'; + var tail = self.tick ? '~' : '^'; + write(tail + '|' + padding + this.face() + ' '); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write(padding + '"" "" '); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw nyan cat face. + * + * @api private + * @return {string} + */ + +NyanCat.prototype.face = function () { + var stats = this.stats; + if (stats.failures) { + return '( x .x)'; + } else if (stats.pending) { + return '( o .o)'; + } else if (stats.passes) { + return '( ^ .^)'; + } + return '( - .-)'; +}; + +/** + * Move cursor up `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorUp = function (n) { + write('\u001b[' + n + 'A'); +}; + +/** + * Move cursor down `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorDown = function (n) { + write('\u001b[' + n + 'B'); +}; + +/** + * Generate rainbow colors. + * + * @api private + * @return {Array} + */ +NyanCat.prototype.generateColors = function () { + var colors = []; + + for (var i = 0; i < (6 * 7); i++) { + var pi3 = Math.floor(Math.PI / 3); + var n = (i * (1.0 / 6)); + var r = Math.floor(3 * Math.sin(n) + 3); + var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3); + var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3); + colors.push(36 * r + 6 * g + b + 16); + } + + return colors; +}; + +/** + * Apply rainbow to the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +NyanCat.prototype.rainbowify = function (str) { + if (!Base.useColors) { + return str; + } + var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length]; + this.colorIndex += 1; + return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m'; +}; + +/** + * Stdout helper. + * + * @param {string} string A message to write to stdout. + */ +function write (string) { + process.stdout.write(string); +} + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],29:[function(require,module,exports){ +(function (process){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `Progress`. + */ + +exports = module.exports = Progress; + +/** + * General progress bar color. + */ + +Base.colors.progress = 90; + +/** + * Initialize a new `Progress` bar test reporter. + * + * @api public + * @param {Runner} runner + * @param {Object} options + */ +function Progress (runner, options) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * 0.50 | 0; + var total = runner.total; + var complete = 0; + var lastN = -1; + + // default chars + options = options || {}; + options.open = options.open || '['; + options.complete = options.complete || '▬'; + options.incomplete = options.incomplete || Base.symbols.dot; + options.close = options.close || ']'; + options.verbose = false; + + // tests started + runner.on('start', function () { + console.log(); + cursor.hide(); + }); + + // tests complete + runner.on('test end', function () { + complete++; + + var percent = complete / total; + var n = width * percent | 0; + var i = width - n; + + if (n === lastN && !options.verbose) { + // Don't re-render the line if it hasn't changed + return; + } + lastN = n; + + cursor.CR(); + process.stdout.write('\u001b[J'); + process.stdout.write(color('progress', ' ' + options.open)); + process.stdout.write(Array(n).join(options.complete)); + process.stdout.write(Array(i).join(options.incomplete)); + process.stdout.write(color('progress', options.close)); + if (options.verbose) { + process.stdout.write(color('progress', ' ' + complete + ' of ' + total)); + } + }); + + // tests are complete, output some stats + // and the failures if any + runner.on('end', function () { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Progress, Base); + +}).call(this,require('_process')) +},{"../utils":38,"./base":17,"_process":67}],30:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; + +/** + * Expose `Spec`. + */ + +exports = module.exports = Spec; + +/** + * Initialize a new `Spec` test reporter. + * + * @api public + * @param {Runner} runner + */ +function Spec (runner) { + Base.call(this, runner); + + var self = this; + var indents = 0; + var n = 0; + + function indent () { + return Array(indents).join(' '); + } + + runner.on('start', function () { + console.log(); + }); + + runner.on('suite', function (suite) { + ++indents; + console.log(color('suite', '%s%s'), indent(), suite.title); + }); + + runner.on('suite end', function () { + --indents; + if (indents === 1) { + console.log(); + } + }); + + runner.on('pending', function (test) { + var fmt = indent() + color('pending', ' - %s'); + console.log(fmt, test.title); + }); + + runner.on('pass', function (test) { + var fmt; + if (test.speed === 'fast') { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s'); + console.log(fmt, test.title); + } else { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s') + + color(test.speed, ' (%dms)'); + console.log(fmt, test.title, test.duration); + } + }); + + runner.on('fail', function (test) { + console.log(indent() + color('fail', ' %d) %s'), ++n, test.title); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Spec, Base); + +},{"../utils":38,"./base":17}],31:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `TAP`. + */ + +exports = module.exports = TAP; + +/** + * Initialize a new `TAP` reporter. + * + * @api public + * @param {Runner} runner + */ +function TAP (runner) { + Base.call(this, runner); + + var n = 1; + var passes = 0; + var failures = 0; + + runner.on('start', function () { + var total = runner.grepTotal(runner.suite); + console.log('%d..%d', 1, total); + }); + + runner.on('test end', function () { + ++n; + }); + + runner.on('pending', function (test) { + console.log('ok %d %s # SKIP -', n, title(test)); + }); + + runner.on('pass', function (test) { + passes++; + console.log('ok %d %s', n, title(test)); + }); + + runner.on('fail', function (test, err) { + failures++; + console.log('not ok %d %s', n, title(test)); + if (err.stack) { + console.log(err.stack.replace(/^/gm, ' ')); + } + }); + + runner.on('end', function () { + console.log('# tests ' + (passes + failures)); + console.log('# pass ' + passes); + console.log('# fail ' + failures); + }); +} + +/** + * Return a TAP-safe title of `test` + * + * @api private + * @param {Object} test + * @return {String} + */ +function title (test) { + return test.fullTitle().replace(/#/g, ''); +} + +},{"./base":17}],32:[function(require,module,exports){ +(function (process,global){ +'use strict'; + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var inherits = utils.inherits; +var fs = require('fs'); +var escape = utils.escape; +var mkdirp = require('mkdirp'); +var path = require('path'); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `XUnit`. + */ + +exports = module.exports = XUnit; + +/** + * Initialize a new `XUnit` reporter. + * + * @api public + * @param {Runner} runner + */ +function XUnit (runner, options) { + Base.call(this, runner); + + var stats = this.stats; + var tests = []; + var self = this; + + if (options && options.reporterOptions && options.reporterOptions.output) { + if (!fs.createWriteStream) { + throw new Error('file output not supported in browser'); + } + mkdirp.sync(path.dirname(options.reporterOptions.output)); + self.fileStream = fs.createWriteStream(options.reporterOptions.output); + } + + runner.on('pending', function (test) { + tests.push(test); + }); + + runner.on('pass', function (test) { + tests.push(test); + }); + + runner.on('fail', function (test) { + tests.push(test); + }); + + runner.on('end', function () { + self.write(tag('testsuite', { + name: 'Mocha Tests', + tests: stats.tests, + failures: stats.failures, + errors: stats.failures, + skipped: stats.tests - stats.failures - stats.passes, + timestamp: (new Date()).toUTCString(), + time: (stats.duration / 1000) || 0 + }, false)); + + tests.forEach(function (t) { + self.test(t); + }); + + self.write(''); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(XUnit, Base); + +/** + * Override done to close the stream (if it's a file). + * + * @param failures + * @param {Function} fn + */ +XUnit.prototype.done = function (failures, fn) { + if (this.fileStream) { + this.fileStream.end(function () { + fn(failures); + }); + } else { + fn(failures); + } +}; + +/** + * Write out the given line. + * + * @param {string} line + */ +XUnit.prototype.write = function (line) { + if (this.fileStream) { + this.fileStream.write(line + '\n'); + } else if (typeof process === 'object' && process.stdout) { + process.stdout.write(line + '\n'); + } else { + console.log(line); + } +}; + +/** + * Output tag for the given `test.` + * + * @param {Test} test + */ +XUnit.prototype.test = function (test) { + var attrs = { + classname: test.parent.fullTitle(), + name: test.title, + time: (test.duration / 1000) || 0 + }; + + if (test.state === 'failed') { + var err = test.err; + this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack)))); + } else if (test.isPending()) { + this.write(tag('testcase', attrs, false, tag('skipped', {}, true))); + } else { + this.write(tag('testcase', attrs, true)); + } +}; + +/** + * HTML tag helper. + * + * @param name + * @param attrs + * @param close + * @param content + * @return {string} + */ +function tag (name, attrs, close, content) { + var end = close ? '/>' : '>'; + var pairs = []; + var tag; + + for (var key in attrs) { + if (Object.prototype.hasOwnProperty.call(attrs, key)) { + pairs.push(key + '="' + escape(attrs[key]) + '"'); + } + } + + tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end; + if (content) { + tag += content + ' Math.pow(2, 31)) { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = ms; + if (this.timer) { + this.resetTimeout(); + } + return this; +}; + +/** + * Set & get slow `ms`. + * + * @api private + * @param {number|string} ms + * @return {Runnable|number} ms or Runnable instance. + */ +Runnable.prototype.slow = function (ms) { + if (typeof ms === 'undefined') { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._slow = ms; + return this; +}; + +/** + * Set and get whether timeout is `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Runnable|boolean} enabled or Runnable instance. + */ +Runnable.prototype.enableTimeouts = function (enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Halt and mark as pending. + * + * @api public + */ +Runnable.prototype.skip = function () { + throw new Pending('sync skip'); +}; + +/** + * Check if this runnable or its parent suite is marked as pending. + * + * @api private + */ +Runnable.prototype.isPending = function () { + return this.pending || (this.parent && this.parent.isPending()); +}; + +/** + * Set number of retries. + * + * @api private + */ +Runnable.prototype.retries = function (n) { + if (!arguments.length) { + return this._retries; + } + this._retries = n; +}; + +/** + * Get current retry + * + * @api private + */ +Runnable.prototype.currentRetry = function (n) { + if (!arguments.length) { + return this._currentRetry; + } + this._currentRetry = n; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Runnable.prototype.fullTitle = function () { + return this.parent.fullTitle() + ' ' + this.title; +}; + +/** + * Clear the timeout. + * + * @api private + */ +Runnable.prototype.clearTimeout = function () { + clearTimeout(this.timer); +}; + +/** + * Inspect the runnable void of private properties. + * + * @api private + * @return {string} + */ +Runnable.prototype.inspect = function () { + return JSON.stringify(this, function (key, val) { + if (key[0] === '_') { + return; + } + if (key === 'parent') { + return '#'; + } + if (key === 'ctx') { + return '#'; + } + return val; + }, 2); +}; + +/** + * Reset the timeout. + * + * @api private + */ +Runnable.prototype.resetTimeout = function () { + var self = this; + var ms = this.timeout() || 1e9; + + if (!this._enableTimeouts) { + return; + } + this.clearTimeout(); + this.timer = setTimeout(function () { + if (!self._enableTimeouts) { + return; + } + self.callback(new Error('Timeout of ' + ms + + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.')); + self.timedOut = true; + }, ms); +}; + +/** + * Whitelist a list of globals for this test run. + * + * @api private + * @param {string[]} globals + */ +Runnable.prototype.globals = function (globals) { + if (!arguments.length) { + return this._allowedGlobals; + } + this._allowedGlobals = globals; +}; + +/** + * Run the test and invoke `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runnable.prototype.run = function (fn) { + var self = this; + var start = new Date(); + var ctx = this.ctx; + var finished; + var emitted; + + // Sometimes the ctx exists, but it is not runnable + if (ctx && ctx.runnable) { + ctx.runnable(this); + } + + // called multiple times + function multiple (err) { + if (emitted) { + return; + } + emitted = true; + self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate')); + } + + // finished + function done (err) { + var ms = self.timeout(); + if (self.timedOut) { + return; + } + if (finished) { + return multiple(err || self._trace); + } + + self.clearTimeout(); + self.duration = new Date() - start; + finished = true; + if (!err && self.duration > ms && self._enableTimeouts) { + err = new Error('Timeout of ' + ms + + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'); + } + fn(err); + } + + // for .resetTimeout() + this.callback = done; + + // explicit async with `done` argument + if (this.async) { + this.resetTimeout(); + + // allows skip() to be used in an explicit async context + this.skip = function asyncSkip () { + done(new Pending('async skip call')); + // halt execution. the Runnable will be marked pending + // by the previous call, and the uncaught handler will ignore + // the failure. + throw new Pending('async skip; aborting execution'); + }; + + if (this.allowUncaught) { + return callFnAsync(this.fn); + } + try { + callFnAsync(this.fn); + } catch (err) { + emitted = true; + done(utils.getError(err)); + } + return; + } + + if (this.allowUncaught) { + callFn(this.fn); + done(); + return; + } + + // sync or promise-returning + try { + if (this.isPending()) { + done(); + } else { + callFn(this.fn); + } + } catch (err) { + emitted = true; + done(utils.getError(err)); + } + + function callFn (fn) { + var result = fn.call(ctx); + if (result && typeof result.then === 'function') { + self.resetTimeout(); + result + .then(function () { + done(); + // Return null so libraries like bluebird do not warn about + // subsequently constructed Promises. + return null; + }, + function (reason) { + done(reason || new Error('Promise rejected with no or falsy reason')); + }); + } else { + if (self.asyncOnly) { + return done(new Error('--async-only option in use without declaring `done()` or returning a promise')); + } + + done(); + } + } + + function callFnAsync (fn) { + var result = fn.call(ctx, function (err) { + if (err instanceof Error || toString.call(err) === '[object Error]') { + return done(err); + } + if (err) { + if (Object.prototype.toString.call(err) === '[object Object]') { + return done(new Error('done() invoked with non-Error: ' + + JSON.stringify(err))); + } + return done(new Error('done() invoked with non-Error: ' + err)); + } + if (result && utils.isPromise(result)) { + return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.')); + } + + done(); + }); + } +}; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./ms":15,"./pending":16,"./utils":38,"debug":2,"events":3,"json3":54,"lodash.create":60}],34:[function(require,module,exports){ +(function (process,global){ +'use strict'; + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Pending = require('./pending'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:runner'); +var Runnable = require('./runnable'); +var filter = utils.filter; +var indexOf = utils.indexOf; +var some = utils.some; +var keys = utils.keys; +var stackFilter = utils.stackTraceFilter(); +var stringify = utils.stringify; +var type = utils.type; +var undefinedError = utils.undefinedError; +var isArray = utils.isArray; + +/** + * Non-enumerable globals. + */ + +var globals = [ + 'setTimeout', + 'clearTimeout', + 'setInterval', + 'clearInterval', + 'XMLHttpRequest', + 'Date', + 'setImmediate', + 'clearImmediate' +]; + +/** + * Expose `Runner`. + */ + +module.exports = Runner; + +/** + * Initialize a `Runner` for the given `suite`. + * + * Events: + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * - `pending` (test) test pending + * + * @api public + * @param {Suite} suite Root suite + * @param {boolean} [delay] Whether or not to delay execution of root suite + * until ready. + */ +function Runner (suite, delay) { + var self = this; + this._globals = []; + this._abort = false; + this._delay = delay; + this.suite = suite; + this.started = false; + this.total = suite.total(); + this.failures = 0; + this.on('test end', function (test) { + self.checkGlobals(test); + }); + this.on('hook end', function (hook) { + self.checkGlobals(hook); + }); + this._defaultGrep = /.*/; + this.grep(this._defaultGrep); + this.globals(this.globalProps().concat(extraGlobals())); +} + +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @api private + */ +Runner.immediately = global.setImmediate || process.nextTick; + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Runner, EventEmitter); + +/** + * Run tests with full titles matching `re`. Updates runner.total + * with number of tests matched. + * + * @param {RegExp} re + * @param {Boolean} invert + * @return {Runner} for chaining + * @api public + * @param {RegExp} re + * @param {boolean} invert + * @return {Runner} Runner instance. + */ +Runner.prototype.grep = function (re, invert) { + debug('grep %s', re); + this._grep = re; + this._invert = invert; + this.total = this.grepTotal(this.suite); + return this; +}; + +/** + * Returns the number of tests matching the grep search for the + * given suite. + * + * @param {Suite} suite + * @return {Number} + * @api public + * @param {Suite} suite + * @return {number} + */ +Runner.prototype.grepTotal = function (suite) { + var self = this; + var total = 0; + + suite.eachTest(function (test) { + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (match) { + total++; + } + }); + + return total; +}; + +/** + * Return a list of global properties. + * + * @return {Array} + * @api private + */ +Runner.prototype.globalProps = function () { + var props = keys(global); + + // non-enumerables + for (var i = 0; i < globals.length; ++i) { + if (~indexOf(props, globals[i])) { + continue; + } + props.push(globals[i]); + } + + return props; +}; + +/** + * Allow the given `arr` of globals. + * + * @param {Array} arr + * @return {Runner} for chaining + * @api public + * @param {Array} arr + * @return {Runner} Runner instance. + */ +Runner.prototype.globals = function (arr) { + if (!arguments.length) { + return this._globals; + } + debug('globals %j', arr); + this._globals = this._globals.concat(arr); + return this; +}; + +/** + * Check for global variable leaks. + * + * @api private + */ +Runner.prototype.checkGlobals = function (test) { + if (this.ignoreLeaks) { + return; + } + var ok = this._globals; + + var globals = this.globalProps(); + var leaks; + + if (test) { + ok = ok.concat(test._allowedGlobals || []); + } + + if (this.prevGlobalsLength === globals.length) { + return; + } + this.prevGlobalsLength = globals.length; + + leaks = filterLeaks(ok, globals); + this._globals = this._globals.concat(leaks); + + if (leaks.length > 1) { + this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + '')); + } else if (leaks.length) { + this.fail(test, new Error('global leak detected: ' + leaks[0])); + } +}; + +/** + * Fail the given `test`. + * + * @api private + * @param {Test} test + * @param {Error} err + */ +Runner.prototype.fail = function (test, err) { + if (test.isPending()) { + return; + } + + ++this.failures; + test.state = 'failed'; + + if (!(err instanceof Error || err && typeof err.message === 'string')) { + err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)'); + } + + try { + err.stack = (this.fullStackTrace || !err.stack) + ? err.stack + : stackFilter(err.stack); + } catch (ignored) { + // some environments do not take kindly to monkeying with the stack + } + + this.emit('fail', test, err); +}; + +/** + * Fail the given `hook` with `err`. + * + * Hook failures work in the following pattern: + * - If bail, then exit + * - Failed `before` hook skips all tests in a suite and subsuites, + * but jumps to corresponding `after` hook + * - Failed `before each` hook skips remaining tests in a + * suite and jumps to corresponding `after each` hook, + * which is run only once + * - Failed `after` hook does not alter + * execution order + * - Failed `after each` hook skips remaining tests in a + * suite and subsuites, but executes other `after each` + * hooks + * + * @api private + * @param {Hook} hook + * @param {Error} err + */ +Runner.prototype.failHook = function (hook, err) { + if (hook.ctx && hook.ctx.currentTest) { + hook.originalTitle = hook.originalTitle || hook.title; + hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"'; + } + + this.fail(hook, err); + if (this.suite.bail()) { + this.emit('end'); + } +}; + +/** + * Run hook `name` callbacks and then invoke `fn()`. + * + * @api private + * @param {string} name + * @param {Function} fn + */ + +Runner.prototype.hook = function (name, fn) { + var suite = this.suite; + var hooks = suite['_' + name]; + var self = this; + + function next (i) { + var hook = hooks[i]; + if (!hook) { + return fn(); + } + self.currentRunnable = hook; + + hook.ctx.currentTest = self.test; + + self.emit('hook', hook); + + if (!hook.listeners('error').length) { + hook.on('error', function (err) { + self.failHook(hook, err); + }); + } + + hook.run(function (err) { + var testError = hook.error(); + if (testError) { + self.fail(self.test, testError); + } + if (err) { + if (err instanceof Pending) { + if (name === 'beforeEach' || name === 'afterEach') { + self.test.pending = true; + } else { + utils.forEach(suite.tests, function (test) { + test.pending = true; + }); + // a pending hook won't be executed twice. + hook.pending = true; + } + } else { + self.failHook(hook, err); + + // stop executing hooks, notify callee of hook err + return fn(err); + } + } + self.emit('hook end', hook); + delete hook.ctx.currentTest; + next(++i); + }); + } + + Runner.immediately(function () { + next(0); + }); +}; + +/** + * Run hook `name` for the given array of `suites` + * in order, and callback `fn(err, errSuite)`. + * + * @api private + * @param {string} name + * @param {Array} suites + * @param {Function} fn + */ +Runner.prototype.hooks = function (name, suites, fn) { + var self = this; + var orig = this.suite; + + function next (suite) { + self.suite = suite; + + if (!suite) { + self.suite = orig; + return fn(); + } + + self.hook(name, function (err) { + if (err) { + var errSuite = self.suite; + self.suite = orig; + return fn(err, errSuite); + } + + next(suites.pop()); + }); + } + + next(suites.pop()); +}; + +/** + * Run hooks from the top level down. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookUp = function (name, fn) { + var suites = [this.suite].concat(this.parents()).reverse(); + this.hooks(name, suites, fn); +}; + +/** + * Run hooks from the bottom up. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookDown = function (name, fn) { + var suites = [this.suite].concat(this.parents()); + this.hooks(name, suites, fn); +}; + +/** + * Return an array of parent Suites from + * closest to furthest. + * + * @return {Array} + * @api private + */ +Runner.prototype.parents = function () { + var suite = this.suite; + var suites = []; + while (suite.parent) { + suite = suite.parent; + suites.push(suite); + } + return suites; +}; + +/** + * Run the current test and callback `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runner.prototype.runTest = function (fn) { + var self = this; + var test = this.test; + + if (!test) { + return; + } + if (this.asyncOnly) { + test.asyncOnly = true; + } + + if (this.allowUncaught) { + test.allowUncaught = true; + return test.run(fn); + } + try { + test.on('error', function (err) { + self.fail(test, err); + }); + test.run(fn); + } catch (err) { + fn(err); + } +}; + +/** + * Run tests in the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runTests = function (suite, fn) { + var self = this; + var tests = suite.tests.slice(); + var test; + + function hookErr (_, errSuite, after) { + // before/after Each hook for errSuite failed: + var orig = self.suite; + + // for failed 'after each' hook start from errSuite parent, + // otherwise start from errSuite itself + self.suite = after ? errSuite.parent : errSuite; + + if (self.suite) { + // call hookUp afterEach + self.hookUp('afterEach', function (err2, errSuite2) { + self.suite = orig; + // some hooks may fail even now + if (err2) { + return hookErr(err2, errSuite2, true); + } + // report error suite + fn(errSuite); + }); + } else { + // there is no need calling other 'after each' hooks + self.suite = orig; + fn(errSuite); + } + } + + function next (err, errSuite) { + // if we bail after first err + if (self.failures && suite._bail) { + return fn(); + } + + if (self._abort) { + return fn(); + } + + if (err) { + return hookErr(err, errSuite, true); + } + + // next test + test = tests.shift(); + + // all done + if (!test) { + return fn(); + } + + // grep + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (!match) { + // Run immediately only if we have defined a grep. When we + // define a grep — It can cause maximum callstack error if + // the grep is doing a large recursive loop by neglecting + // all tests. The run immediately function also comes with + // a performance cost. So we don't want to run immediately + // if we run the whole test suite, because running the whole + // test suite don't do any immediate recursive loops. Thus, + // allowing a JS runtime to breathe. + if (self._grep !== self._defaultGrep) { + Runner.immediately(next); + } else { + next(); + } + return; + } + + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + + // execute test and hook(s) + self.emit('test', self.test = test); + self.hookDown('beforeEach', function (err, errSuite) { + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + if (err) { + return hookErr(err, errSuite, false); + } + self.currentRunnable = self.test; + self.runTest(function (err) { + test = self.test; + if (err) { + var retry = test.currentRetry(); + if (err instanceof Pending) { + test.pending = true; + self.emit('pending', test); + } else if (retry < test.retries()) { + var clonedTest = test.clone(); + clonedTest.currentRetry(retry + 1); + tests.unshift(clonedTest); + + // Early return + hook trigger so that it doesn't + // increment the count wrong + return self.hookUp('afterEach', next); + } else { + self.fail(test, err); + } + self.emit('test end', test); + + if (err instanceof Pending) { + return next(); + } + + return self.hookUp('afterEach', next); + } + + test.state = 'passed'; + self.emit('pass', test); + self.emit('test end', test); + self.hookUp('afterEach', next); + }); + }); + } + + this.next = next; + this.hookErr = hookErr; + next(); +}; + +/** + * Run the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runSuite = function (suite, fn) { + var i = 0; + var self = this; + var total = this.grepTotal(suite); + var afterAllHookCalled = false; + + debug('run suite %s', suite.fullTitle()); + + if (!total || (self.failures && suite._bail)) { + return fn(); + } + + this.emit('suite', this.suite = suite); + + function next (errSuite) { + if (errSuite) { + // current suite failed on a hook from errSuite + if (errSuite === suite) { + // if errSuite is current suite + // continue to the next sibling suite + return done(); + } + // errSuite is among the parents of current suite + // stop execution of errSuite and all sub-suites + return done(errSuite); + } + + if (self._abort) { + return done(); + } + + var curr = suite.suites[i++]; + if (!curr) { + return done(); + } + + // Avoid grep neglecting large number of tests causing a + // huge recursive loop and thus a maximum call stack error. + // See comment in `this.runTests()` for more information. + if (self._grep !== self._defaultGrep) { + Runner.immediately(function () { + self.runSuite(curr, next); + }); + } else { + self.runSuite(curr, next); + } + } + + function done (errSuite) { + self.suite = suite; + self.nextSuite = next; + + if (afterAllHookCalled) { + fn(errSuite); + } else { + // mark that the afterAll block has been called once + // and so can be skipped if there is an error in it. + afterAllHookCalled = true; + + // remove reference to test + delete self.test; + + self.hook('afterAll', function () { + self.emit('suite end', suite); + fn(errSuite); + }); + } + } + + this.nextSuite = next; + + this.hook('beforeAll', function (err) { + if (err) { + return done(); + } + self.runTests(suite, next); + }); +}; + +/** + * Handle uncaught exceptions. + * + * @param {Error} err + * @api private + */ +Runner.prototype.uncaught = function (err) { + if (err) { + debug('uncaught exception %s', err !== function () { + return this; + }.call(err) ? err : (err.message || err)); + } else { + debug('uncaught undefined exception'); + err = undefinedError(); + } + err.uncaught = true; + + var runnable = this.currentRunnable; + + if (!runnable) { + runnable = new Runnable('Uncaught error outside test suite'); + runnable.parent = this.suite; + + if (this.started) { + this.fail(runnable, err); + } else { + // Can't recover from this failure + this.emit('start'); + this.fail(runnable, err); + this.emit('end'); + } + + return; + } + + runnable.clearTimeout(); + + // Ignore errors if complete or pending + if (runnable.state || runnable.isPending()) { + return; + } + this.fail(runnable, err); + + // recover from test + if (runnable.type === 'test') { + this.emit('test end', runnable); + this.hookUp('afterEach', this.next); + return; + } + + // recover from hooks + if (runnable.type === 'hook') { + var errSuite = this.suite; + // if hook failure is in afterEach block + if (runnable.fullTitle().indexOf('after each') > -1) { + return this.hookErr(err, errSuite, true); + } + // if hook failure is in beforeEach block + if (runnable.fullTitle().indexOf('before each') > -1) { + return this.hookErr(err, errSuite, false); + } + // if hook failure is in after or before blocks + return this.nextSuite(errSuite); + } + + // bail + this.emit('end'); +}; + +/** + * Cleans up the references to all the deferred functions + * (before/after/beforeEach/afterEach) and tests of a Suite. + * These must be deleted otherwise a memory leak can happen, + * as those functions may reference variables from closures, + * thus those variables can never be garbage collected as long + * as the deferred functions exist. + * + * @param {Suite} suite + */ +function cleanSuiteReferences (suite) { + function cleanArrReferences (arr) { + for (var i = 0; i < arr.length; i++) { + delete arr[i].fn; + } + } + + if (isArray(suite._beforeAll)) { + cleanArrReferences(suite._beforeAll); + } + + if (isArray(suite._beforeEach)) { + cleanArrReferences(suite._beforeEach); + } + + if (isArray(suite._afterAll)) { + cleanArrReferences(suite._afterAll); + } + + if (isArray(suite._afterEach)) { + cleanArrReferences(suite._afterEach); + } + + for (var i = 0; i < suite.tests.length; i++) { + delete suite.tests[i].fn; + } +} + +/** + * Run the root suite and invoke `fn(failures)` + * on completion. + * + * @param {Function} fn + * @return {Runner} for chaining + * @api public + * @param {Function} fn + * @return {Runner} Runner instance. + */ +Runner.prototype.run = function (fn) { + var self = this; + var rootSuite = this.suite; + + // If there is an `only` filter + if (this.hasOnly) { + filterOnly(rootSuite); + } + + fn = fn || function () {}; + + function uncaught (err) { + self.uncaught(err); + } + + function start () { + self.started = true; + self.emit('start'); + self.runSuite(rootSuite, function () { + debug('finished running'); + self.emit('end'); + }); + } + + debug('start'); + + // references cleanup to avoid memory leaks + this.on('suite end', cleanSuiteReferences); + + // callback + this.on('end', function () { + debug('end'); + process.removeListener('uncaughtException', uncaught); + fn(self.failures); + }); + + // uncaught exception + process.on('uncaughtException', uncaught); + + if (this._delay) { + // for reporters, I guess. + // might be nice to debounce some dots while we wait. + this.emit('waiting', rootSuite); + rootSuite.once('run', start); + } else { + start(); + } + + return this; +}; + +/** + * Cleanly abort execution. + * + * @api public + * @return {Runner} Runner instance. + */ +Runner.prototype.abort = function () { + debug('aborting'); + this._abort = true; + + return this; +}; + +/** + * Filter suites based on `isOnly` logic. + * + * @param {Array} suite + * @returns {Boolean} + * @api private + */ +function filterOnly (suite) { + if (suite._onlyTests.length) { + // If the suite contains `only` tests, run those and ignore any nested suites. + suite.tests = suite._onlyTests; + suite.suites = []; + } else { + // Otherwise, do not run any of the tests in this suite. + suite.tests = []; + utils.forEach(suite._onlySuites, function (onlySuite) { + // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite. + // Otherwise, all of the tests on this `only` suite should be run, so don't filter it. + if (hasOnly(onlySuite)) { + filterOnly(onlySuite); + } + }); + // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants. + suite.suites = filter(suite.suites, function (childSuite) { + return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite); + }); + } + // Keep the suite only if there is something to run + return suite.tests.length || suite.suites.length; +} + +/** + * Determines whether a suite has an `only` test or suite as a descendant. + * + * @param {Array} suite + * @returns {Boolean} + * @api private + */ +function hasOnly (suite) { + return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly); +} + +/** + * Filter leaks with the given globals flagged as `ok`. + * + * @api private + * @param {Array} ok + * @param {Array} globals + * @return {Array} + */ +function filterLeaks (ok, globals) { + return filter(globals, function (key) { + // Firefox and Chrome exposes iframes as index inside the window object + if (/^\d+/.test(key)) { + return false; + } + + // in firefox + // if runner runs in an iframe, this iframe's window.getInterface method + // not init at first it is assigned in some seconds + if (global.navigator && (/^getInterface/).test(key)) { + return false; + } + + // an iframe could be approached by window[iframeIndex] + // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak + if (global.navigator && (/^\d+/).test(key)) { + return false; + } + + // Opera and IE expose global variables for HTML element IDs (issue #243) + if (/^mocha-/.test(key)) { + return false; + } + + var matched = filter(ok, function (ok) { + if (~ok.indexOf('*')) { + return key.indexOf(ok.split('*')[0]) === 0; + } + return key === ok; + }); + return !matched.length && (!global.navigator || key !== 'onerror'); + }); +} + +/** + * Array of globals dependent on the environment. + * + * @return {Array} + * @api private + */ +function extraGlobals () { + if (typeof process === 'object' && typeof process.version === 'string') { + var parts = process.version.split('.'); + var nodeVersion = utils.reduce(parts, function (a, v) { + return a << 8 | v; + }); + + // 'errno' was renamed to process._errno in v0.9.11. + + if (nodeVersion < 0x00090B) { + return ['errno']; + } + } + + return []; +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./pending":16,"./runnable":33,"./utils":38,"_process":67,"debug":2,"events":3}],35:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Hook = require('./hook'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:suite'); +var milliseconds = require('./ms'); + +/** + * Expose `Suite`. + */ + +exports = module.exports = Suite; + +/** + * Create a new `Suite` with the given `title` and parent `Suite`. When a suite + * with the same title is already present, that suite is returned to provide + * nicer reporter and more flexible meta-testing. + * + * @api public + * @param {Suite} parent + * @param {string} title + * @return {Suite} + */ +exports.create = function (parent, title) { + var suite = new Suite(title, parent.ctx); + suite.parent = parent; + title = suite.fullTitle(); + parent.addSuite(suite); + return suite; +}; + +/** + * Initialize a new `Suite` with the given `title` and `ctx`. + * + * @api private + * @param {string} title + * @param {Context} parentContext + */ +function Suite (title, parentContext) { + if (!utils.isString(title)) { + throw new Error('Suite `title` should be a "string" but "' + typeof title + '" was given instead.'); + } + this.title = title; + function Context () {} + Context.prototype = parentContext; + this.ctx = new Context(); + this.suites = []; + this.tests = []; + this.pending = false; + this._beforeEach = []; + this._beforeAll = []; + this._afterEach = []; + this._afterAll = []; + this.root = !title; + this._timeout = 2000; + this._enableTimeouts = true; + this._slow = 75; + this._bail = false; + this._retries = -1; + this._onlyTests = []; + this._onlySuites = []; + this.delayed = false; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Suite, EventEmitter); + +/** + * Return a clone of this `Suite`. + * + * @api private + * @return {Suite} + */ +Suite.prototype.clone = function () { + var suite = new Suite(this.title); + debug('clone'); + suite.ctx = this.ctx; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + return suite; +}; + +/** + * Set timeout `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.timeout = function (ms) { + if (!arguments.length) { + return this._timeout; + } + if (ms.toString() === '0') { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = parseInt(ms, 10); + return this; +}; + +/** + * Set number of times to retry a failed test. + * + * @api private + * @param {number|string} n + * @return {Suite|number} for chaining + */ +Suite.prototype.retries = function (n) { + if (!arguments.length) { + return this._retries; + } + debug('retries %d', n); + this._retries = parseInt(n, 10) || 0; + return this; +}; + +/** + * Set timeout to `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Suite|boolean} self or enabled + */ +Suite.prototype.enableTimeouts = function (enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Set slow `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.slow = function (ms) { + if (!arguments.length) { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('slow %d', ms); + this._slow = ms; + return this; +}; + +/** + * Sets whether to bail after first error. + * + * @api private + * @param {boolean} bail + * @return {Suite|number} for chaining + */ +Suite.prototype.bail = function (bail) { + if (!arguments.length) { + return this._bail; + } + debug('bail %s', bail); + this._bail = bail; + return this; +}; + +/** + * Check if this suite or its parent suite is marked as pending. + * + * @api private + */ +Suite.prototype.isPending = function () { + return this.pending || (this.parent && this.parent.isPending()); +}; + +/** + * Run `fn(test[, done])` before running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeAll = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeAll.push(hook); + this.emit('beforeAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterAll = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterAll.push(hook); + this.emit('afterAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` before each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeEach = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeEach.push(hook); + this.emit('beforeEach', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterEach = function (title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterEach.push(hook); + this.emit('afterEach', hook); + return this; +}; + +/** + * Add a test `suite`. + * + * @api private + * @param {Suite} suite + * @return {Suite} for chaining + */ +Suite.prototype.addSuite = function (suite) { + suite.parent = this; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + this.suites.push(suite); + this.emit('suite', suite); + return this; +}; + +/** + * Add a `test` to this suite. + * + * @api private + * @param {Test} test + * @return {Suite} for chaining + */ +Suite.prototype.addTest = function (test) { + test.parent = this; + test.timeout(this.timeout()); + test.retries(this.retries()); + test.enableTimeouts(this.enableTimeouts()); + test.slow(this.slow()); + test.ctx = this.ctx; + this.tests.push(test); + this.emit('test', test); + return this; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Suite.prototype.fullTitle = function () { + if (this.parent) { + var full = this.parent.fullTitle(); + if (full) { + return full + ' ' + this.title; + } + } + return this.title; +}; + +/** + * Return the total number of tests. + * + * @api public + * @return {number} + */ +Suite.prototype.total = function () { + return utils.reduce(this.suites, function (sum, suite) { + return sum + suite.total(); + }, 0) + this.tests.length; +}; + +/** + * Iterates through each suite recursively to find all tests. Applies a + * function in the format `fn(test)`. + * + * @api private + * @param {Function} fn + * @return {Suite} + */ +Suite.prototype.eachTest = function (fn) { + utils.forEach(this.tests, fn); + utils.forEach(this.suites, function (suite) { + suite.eachTest(fn); + }); + return this; +}; + +/** + * This will run the root suite if we happen to be running in delayed mode. + */ +Suite.prototype.run = function run () { + if (this.root) { + this.emit('run'); + } +}; + +},{"./hook":7,"./ms":15,"./utils":38,"debug":2,"events":3}],36:[function(require,module,exports){ +'use strict'; + +/** + * Module dependencies. + */ + +var Runnable = require('./runnable'); +var create = require('lodash.create'); +var isString = require('./utils').isString; + +/** + * Expose `Test`. + */ + +module.exports = Test; + +/** + * Initialize a new `Test` with the given `title` and callback `fn`. + * + * @api private + * @param {String} title + * @param {Function} fn + */ +function Test (title, fn) { + if (!isString(title)) { + throw new Error('Test `title` should be a "string" but "' + typeof title + '" was given instead.'); + } + Runnable.call(this, title, fn); + this.pending = !fn; + this.type = 'test'; +} + +/** + * Inherit from `Runnable.prototype`. + */ +Test.prototype = create(Runnable.prototype, { + constructor: Test +}); + +Test.prototype.clone = function () { + var test = new Test(this.title, this.fn); + test.timeout(this.timeout()); + test.slow(this.slow()); + test.enableTimeouts(this.enableTimeouts()); + test.retries(this.retries()); + test.currentRetry(this.currentRetry()); + test.globals(this.globals()); + test.parent = this.parent; + test.file = this.file; + test.ctx = this.ctx; + return test; +}; + +},{"./runnable":33,"./utils":38,"lodash.create":60}],37:[function(require,module,exports){ +'use strict'; + +/** + * Pad a `number` with a ten's place zero. + * + * @param {number} number + * @return {string} + */ +function pad(number) { + var n = number.toString(); + return n.length === 1 ? '0' + n : n; +} + +/** + * Turn a `date` into an ISO string. + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + * + * @param {Date} date + * @return {string} + */ +function toISOString(date) { + return date.getUTCFullYear() + + '-' + pad(date.getUTCMonth() + 1) + + '-' + pad(date.getUTCDate()) + + 'T' + pad(date.getUTCHours()) + + ':' + pad(date.getUTCMinutes()) + + ':' + pad(date.getUTCSeconds()) + + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) + + 'Z'; +} + +/* + * Exports. + */ + +module.exports = toISOString; + +},{}],38:[function(require,module,exports){ +(function (process,Buffer){ +'use strict'; + +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var JSON = require('json3'); +var basename = require('path').basename; +var debug = require('debug')('mocha:watch'); +var exists = require('fs').existsSync || require('path').existsSync; +var glob = require('glob'); +var path = require('path'); +var join = path.join; +var readdirSync = require('fs').readdirSync; +var statSync = require('fs').statSync; +var watchFile = require('fs').watchFile; +var lstatSync = require('fs').lstatSync; +var toISOString = require('./to-iso-string'); + +/** + * Ignored directories. + */ + +var ignore = ['node_modules', '.git']; + +exports.inherits = require('util').inherits; + +/** + * Escape special characters in the given string of html. + * + * @api private + * @param {string} html + * @return {string} + */ +exports.escape = function (html) { + return String(html) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +}; + +/** + * Array#forEach (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + */ +exports.forEach = function (arr, fn, scope) { + for (var i = 0, l = arr.length; i < l; i++) { + fn.call(scope, arr[i], i); + } +}; + +/** + * Test if the given obj is type of string. + * + * @api private + * @param {Object} obj + * @return {boolean} + */ +exports.isString = function (obj) { + return typeof obj === 'string'; +}; + +/** + * Array#map (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + * @return {Array} + */ +exports.map = function (arr, fn, scope) { + var result = []; + for (var i = 0, l = arr.length; i < l; i++) { + result.push(fn.call(scope, arr[i], i, arr)); + } + return result; +}; + +/** + * Array#indexOf (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Object} obj to find index of + * @param {number} start + * @return {number} + */ +var indexOf = exports.indexOf = function (arr, obj, start) { + for (var i = start || 0, l = arr.length; i < l; i++) { + if (arr[i] === obj) { + return i; + } + } + return -1; +}; + +/** + * Array#reduce (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} val Initial value. + * @return {*} + */ +var reduce = exports.reduce = function (arr, fn, val) { + var rval = val; + + for (var i = 0, l = arr.length; i < l; i++) { + rval = fn(rval, arr[i], i, arr); + } + + return rval; +}; + +/** + * Array#filter (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.filter = function (arr, fn) { + var ret = []; + + for (var i = 0, l = arr.length; i < l; i++) { + var val = arr[i]; + if (fn(val, i, arr)) { + ret.push(val); + } + } + + return ret; +}; + +/** + * Array#some (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.some = function (arr, fn) { + for (var i = 0, l = arr.length; i < l; i++) { + if (fn(arr[i])) { + return true; + } + } + return false; +}; + +/** + * Object.keys (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Array} keys + */ +exports.keys = typeof Object.keys === 'function' ? Object.keys : function (obj) { + var keys = []; + var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8 + + for (var key in obj) { + if (has.call(obj, key)) { + keys.push(key); + } + } + + return keys; +}; + +/** + * Watch the given `files` for changes + * and invoke `fn(file)` on modification. + * + * @api private + * @param {Array} files + * @param {Function} fn + */ +exports.watch = function (files, fn) { + var options = { interval: 100 }; + files.forEach(function (file) { + debug('file %s', file); + watchFile(file, options, function (curr, prev) { + if (prev.mtime < curr.mtime) { + fn(file); + } + }); + }); +}; + +/** + * Array.isArray (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Boolean} + */ +var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +exports.isArray = isArray; + +/** + * Buffer.prototype.toJSON polyfill. + * + * @type {Function} + */ +if (typeof Buffer !== 'undefined' && Buffer.prototype) { + Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () { + return Array.prototype.slice.call(this, 0); + }; +} + +/** + * Ignored files. + * + * @api private + * @param {string} path + * @return {boolean} + */ +function ignored (path) { + return !~ignore.indexOf(path); +} + +/** + * Lookup files in the given `dir`. + * + * @api private + * @param {string} dir + * @param {string[]} [ext=['.js']] + * @param {Array} [ret=[]] + * @return {Array} + */ +exports.files = function (dir, ext, ret) { + ret = ret || []; + ext = ext || ['js']; + + var re = new RegExp('\\.(' + ext.join('|') + ')$'); + + readdirSync(dir) + .filter(ignored) + .forEach(function (path) { + path = join(dir, path); + if (lstatSync(path).isDirectory()) { + exports.files(path, ext, ret); + } else if (path.match(re)) { + ret.push(path); + } + }); + + return ret; +}; + +/** + * Compute a slug from the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.slug = function (str) { + return str + .toLowerCase() + .replace(/ +/g, '-') + .replace(/[^-\w]/g, ''); +}; + +/** + * Strip the function definition from `str`, and re-indent for pre whitespace. + * + * @param {string} str + * @return {string} + */ +exports.clean = function (str) { + str = str + .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') + // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content + .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3'); + + var spaces = str.match(/^\n?( *)/)[1].length; + var tabs = str.match(/^\n?(\t*)/)[1].length; + var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}', 'gm'); + + str = str.replace(re, ''); + + return exports.trim(str); +}; + +/** + * Trim the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.trim = function (str) { + return str.replace(/^\s+|\s+$/g, ''); +}; + +/** + * Parse the given `qs`. + * + * @api private + * @param {string} qs + * @return {Object} + */ +exports.parseQuery = function (qs) { + return reduce(qs.replace('?', '').split('&'), function (obj, pair) { + var i = pair.indexOf('='); + var key = pair.slice(0, i); + var val = pair.slice(++i); + + obj[key] = decodeURIComponent(val); + return obj; + }, {}); +}; + +/** + * Highlight the given string of `js`. + * + * @api private + * @param {string} js + * @return {string} + */ +function highlight (js) { + return js + .replace(//g, '>') + .replace(/\/\/(.*)/gm, '//$1') + .replace(/('.*?')/gm, '$1') + .replace(/(\d+\.\d+)/gm, '$1') + .replace(/(\d+)/gm, '$1') + .replace(/\bnew[ \t]+(\w+)/gm, 'new $1') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '$1'); +} + +/** + * Highlight the contents of tag `name`. + * + * @api private + * @param {string} name + */ +exports.highlightTags = function (name) { + var code = document.getElementById('mocha').getElementsByTagName(name); + for (var i = 0, len = code.length; i < len; ++i) { + code[i].innerHTML = highlight(code[i].innerHTML); + } +}; + +/** + * If a value could have properties, and has none, this function is called, + * which returns a string representation of the empty value. + * + * Functions w/ no properties return `'[Function]'` + * Arrays w/ length === 0 return `'[]'` + * Objects w/ no properties return `'{}'` + * All else: return result of `value.toString()` + * + * @api private + * @param {*} value The value to inspect. + * @param {string} typeHint The type of the value + * @returns {string} + */ +function emptyRepresentation (value, typeHint) { + switch (typeHint) { + case 'function': + return '[Function]'; + case 'object': + return '{}'; + case 'array': + return '[]'; + default: + return value.toString(); + } +} + +/** + * Takes some variable and asks `Object.prototype.toString()` what it thinks it + * is. + * + * @api private + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString + * @param {*} value The value to test. + * @returns {string} Computed type + * @example + * type({}) // 'object' + * type([]) // 'array' + * type(1) // 'number' + * type(false) // 'boolean' + * type(Infinity) // 'number' + * type(null) // 'null' + * type(new Date()) // 'date' + * type(/foo/) // 'regexp' + * type('type') // 'string' + * type(global) // 'global' + * type(new String('foo') // 'object' + */ +var type = exports.type = function type (value) { + if (value === undefined) { + return 'undefined'; + } else if (value === null) { + return 'null'; + } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { + return 'buffer'; + } + return Object.prototype.toString.call(value) + .replace(/^\[.+\s(.+?)\]$/, '$1') + .toLowerCase(); +}; + +/** + * Stringify `value`. Different behavior depending on type of value: + * + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. + * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of function + * {@link emptyRepresentation}. + * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of + * JSON.stringify(). + * + * @api private + * @see exports.type + * @param {*} value + * @return {string} + */ +exports.stringify = function (value) { + var typeHint = type(value); + + if (!~indexOf(['object', 'array', 'function'], typeHint)) { + if (typeHint === 'buffer') { + var json = value.toJSON(); + // Based on the toJSON result + return jsonStringify(json.data && json.type ? json.data : json, 2) + .replace(/,(\n|$)/g, '$1'); + } + + // IE7/IE8 has a bizarre String constructor; needs to be coerced + // into an array and back to obj. + if (typeHint === 'string' && typeof value === 'object') { + value = reduce(value.split(''), function (acc, char, idx) { + acc[idx] = char; + return acc; + }, {}); + typeHint = 'object'; + } else { + return jsonStringify(value); + } + } + + for (var prop in value) { + if (Object.prototype.hasOwnProperty.call(value, prop)) { + return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\n|$)/g, '$1'); + } + } + + return emptyRepresentation(value, typeHint); +}; + +/** + * like JSON.stringify but more sense. + * + * @api private + * @param {Object} object + * @param {number=} spaces + * @param {number=} depth + * @returns {*} + */ +function jsonStringify (object, spaces, depth) { + if (typeof spaces === 'undefined') { + // primitive types + return _stringify(object); + } + + depth = depth || 1; + var space = spaces * depth; + var str = isArray(object) ? '[' : '{'; + var end = isArray(object) ? ']' : '}'; + var length = typeof object.length === 'number' ? object.length : exports.keys(object).length; + // `.repeat()` polyfill + function repeat (s, n) { + return new Array(n).join(s); + } + + function _stringify (val) { + switch (type(val)) { + case 'null': + case 'undefined': + val = '[' + val + ']'; + break; + case 'array': + case 'object': + val = jsonStringify(val, spaces, depth + 1); + break; + case 'boolean': + case 'regexp': + case 'symbol': + case 'number': + val = val === 0 && (1 / val) === -Infinity // `-0` + ? '-0' + : val.toString(); + break; + case 'date': + var sDate; + if (isNaN(val.getTime())) { // Invalid date + sDate = val.toString(); + } else { + sDate = val.toISOString ? val.toISOString() : toISOString(val); + } + val = '[Date: ' + sDate + ']'; + break; + case 'buffer': + var json = val.toJSON(); + // Based on the toJSON result + json = json.data && json.type ? json.data : json; + val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']'; + break; + default: + val = (val === '[Function]' || val === '[Circular]') + ? val + : JSON.stringify(val); // string + } + return val; + } + + for (var i in object) { + if (!Object.prototype.hasOwnProperty.call(object, i)) { + continue; // not my business + } + --length; + str += '\n ' + repeat(' ', space) + + (isArray(object) ? '' : '"' + i + '": ') + // key + _stringify(object[i]) + // value + (length ? ',' : ''); // comma + } + + return str + + // [], {} + (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end); +} + +/** + * Test if a value is a buffer. + * + * @api private + * @param {*} value The value to test. + * @return {boolean} True if `value` is a buffer, otherwise false + */ +exports.isBuffer = function (value) { + return typeof Buffer !== 'undefined' && Buffer.isBuffer(value); +}; + +/** + * Return a new Thing that has the keys in sorted order. Recursive. + * + * If the Thing... + * - has already been seen, return string `'[Circular]'` + * - is `undefined`, return string `'[undefined]'` + * - is `null`, return value `null` + * - is some other primitive, return the value + * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * + * @api private + * @see {@link exports.stringify} + * @param {*} value Thing to inspect. May or may not have properties. + * @param {Array} [stack=[]] Stack of seen values + * @param {string} [typeHint] Type hint + * @return {(Object|Array|Function|string|undefined)} + */ +exports.canonicalize = function canonicalize (value, stack, typeHint) { + var canonicalizedObj; + /* eslint-disable no-unused-vars */ + var prop; + /* eslint-enable no-unused-vars */ + typeHint = typeHint || type(value); + function withStack (value, fn) { + stack.push(value); + fn(); + stack.pop(); + } + + stack = stack || []; + + if (indexOf(stack, value) !== -1) { + return '[Circular]'; + } + + switch (typeHint) { + case 'undefined': + case 'buffer': + case 'null': + canonicalizedObj = value; + break; + case 'array': + withStack(value, function () { + canonicalizedObj = exports.map(value, function (item) { + return exports.canonicalize(item, stack); + }); + }); + break; + case 'function': + /* eslint-disable guard-for-in */ + for (prop in value) { + canonicalizedObj = {}; + break; + } + /* eslint-enable guard-for-in */ + if (!canonicalizedObj) { + canonicalizedObj = emptyRepresentation(value, typeHint); + break; + } + /* falls through */ + case 'object': + canonicalizedObj = canonicalizedObj || {}; + withStack(value, function () { + exports.forEach(exports.keys(value).sort(), function (key) { + canonicalizedObj[key] = exports.canonicalize(value[key], stack); + }); + }); + break; + case 'date': + case 'number': + case 'regexp': + case 'boolean': + case 'symbol': + canonicalizedObj = value; + break; + default: + canonicalizedObj = value + ''; + } + + return canonicalizedObj; +}; + +/** + * Lookup file names at the given `path`. + * + * @api public + * @param {string} path Base path to start searching from. + * @param {string[]} extensions File extensions to look for. + * @param {boolean} recursive Whether or not to recurse into subdirectories. + * @return {string[]} An array of paths. + */ +exports.lookupFiles = function lookupFiles (path, extensions, recursive) { + var files = []; + var re = new RegExp('\\.(' + extensions.join('|') + ')$'); + + if (!exists(path)) { + if (exists(path + '.js')) { + path += '.js'; + } else { + files = glob.sync(path); + if (!files.length) { + throw new Error("cannot resolve path (or pattern) '" + path + "'"); + } + return files; + } + } + + try { + var stat = statSync(path); + if (stat.isFile()) { + return path; + } + } catch (err) { + // ignore error + return; + } + + readdirSync(path).forEach(function (file) { + file = join(path, file); + try { + var stat = statSync(file); + if (stat.isDirectory()) { + if (recursive) { + files = files.concat(lookupFiles(file, extensions, recursive)); + } + return; + } + } catch (err) { + // ignore error + return; + } + if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') { + return; + } + files.push(file); + }); + + return files; +}; + +/** + * Generate an undefined error with a message warning the user. + * + * @return {Error} + */ + +exports.undefinedError = function () { + return new Error('Caught undefined error, did you throw without specifying what?'); +}; + +/** + * Generate an undefined error if `err` is not defined. + * + * @param {Error} err + * @return {Error} + */ + +exports.getError = function (err) { + return err || exports.undefinedError(); +}; + +/** + * @summary + * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * @description + * When invoking this function you get a filter function that get the Error.stack as an input, + * and return a prettify output. + * (i.e: strip Mocha and internal node functions from stack trace). + * @returns {Function} + */ +exports.stackTraceFilter = function () { + // TODO: Replace with `process.browser` + var is = typeof document === 'undefined' ? { node: true } : { browser: true }; + var slash = path.sep; + var cwd; + if (is.node) { + cwd = process.cwd() + slash; + } else { + cwd = (typeof location === 'undefined' ? window.location : location).href.replace(/\/[^\/]*$/, '/'); + slash = '/'; + } + + function isMochaInternal (line) { + return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) || + (~line.indexOf('node_modules' + slash + 'mocha.js')) || + (~line.indexOf('bower_components' + slash + 'mocha.js')) || + (~line.indexOf(slash + 'mocha.js')); + } + + function isNodeInternal (line) { + return (~line.indexOf('(timers.js:')) || + (~line.indexOf('(events.js:')) || + (~line.indexOf('(node.js:')) || + (~line.indexOf('(module.js:')) || + (~line.indexOf('GeneratorFunctionPrototype.next (native)')) || + false; + } + + return function (stack) { + stack = stack.split('\n'); + + stack = reduce(stack, function (list, line) { + if (isMochaInternal(line)) { + return list; + } + + if (is.node && isNodeInternal(line)) { + return list; + } + + // Clean up cwd(absolute) + if (/\(?.+:\d+:\d+\)?$/.test(line)) { + line = line.replace(cwd, ''); + } + + list.push(line); + return list; + }, []); + + return stack.join('\n'); + }; +}; + +/** + * Crude, but effective. + * @api + * @param {*} value + * @returns {boolean} Whether or not `value` is a Promise + */ +exports.isPromise = function isPromise (value) { + return typeof value === 'object' && typeof value.then === 'function'; +}; + +/** + * It's a noop. + * @api + */ +exports.noop = function () {}; + +}).call(this,require('_process'),require("buffer").Buffer) +},{"./to-iso-string":37,"_process":67,"buffer":44,"debug":2,"fs":42,"glob":42,"json3":54,"path":42,"util":84}],39:[function(require,module,exports){ +'use strict' + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function placeHoldersCount (b64) { + var len = b64.length + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 +} + +function byteLength (b64) { + // base64 is 4/3 + up to two characters of the original data + return b64.length * 3 / 4 - placeHoldersCount(b64) +} + +function toByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + var len = b64.length + placeHolders = placeHoldersCount(b64) + + arr = new Arr(len * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len + + var L = 0 + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] + arr[L++] = (tmp >> 16) & 0xFF + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[L++] = tmp & 0xFF + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var output = '' + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + output += lookup[tmp >> 2] + output += lookup[(tmp << 4) & 0x3F] + output += '==' + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) + output += lookup[tmp >> 10] + output += lookup[(tmp >> 4) & 0x3F] + output += lookup[(tmp << 2) & 0x3F] + output += '=' + } + + parts.push(output) + + return parts.join('') +} + +},{}],40:[function(require,module,exports){ + +},{}],41:[function(require,module,exports){ +(function (process){ +var WritableStream = require('stream').Writable +var inherits = require('util').inherits + +module.exports = BrowserStdout + + +inherits(BrowserStdout, WritableStream) + +function BrowserStdout(opts) { + if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts) + + opts = opts || {} + WritableStream.call(this, opts) + this.label = (opts.label !== undefined) ? opts.label : 'stdout' +} + +BrowserStdout.prototype._write = function(chunks, encoding, cb) { + var output = chunks.toString ? chunks.toString() : chunks + if (this.label === false) { + console.log(output) + } else { + console.log(this.label+':', output) + } + process.nextTick(cb) +} + +}).call(this,require('_process')) +},{"_process":67,"stream":79,"util":84}],42:[function(require,module,exports){ +arguments[4][40][0].apply(exports,arguments) +},{"dup":40}],43:[function(require,module,exports){ +(function (global){ +'use strict'; + +var buffer = require('buffer'); +var Buffer = buffer.Buffer; +var SlowBuffer = buffer.SlowBuffer; +var MAX_LEN = buffer.kMaxLength || 2147483647; +exports.alloc = function alloc(size, fill, encoding) { + if (typeof Buffer.alloc === 'function') { + return Buffer.alloc(size, fill, encoding); + } + if (typeof encoding === 'number') { + throw new TypeError('encoding must not be number'); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + var enc = encoding; + var _fill = fill; + if (_fill === undefined) { + enc = undefined; + _fill = 0; + } + var buf = new Buffer(size); + if (typeof _fill === 'string') { + var fillBuf = new Buffer(_fill, enc); + var flen = fillBuf.length; + var i = -1; + while (++i < size) { + buf[i] = fillBuf[i % flen]; + } + } else { + buf.fill(_fill); + } + return buf; +} +exports.allocUnsafe = function allocUnsafe(size) { + if (typeof Buffer.allocUnsafe === 'function') { + return Buffer.allocUnsafe(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + return new Buffer(size); +} +exports.from = function from(value, encodingOrOffset, length) { + if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { + return Buffer.from(value, encodingOrOffset, length); + } + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number'); + } + if (typeof value === 'string') { + return new Buffer(value, encodingOrOffset); + } + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + var offset = encodingOrOffset; + if (arguments.length === 1) { + return new Buffer(value); + } + if (typeof offset === 'undefined') { + offset = 0; + } + var len = length; + if (typeof len === 'undefined') { + len = value.byteLength - offset; + } + if (offset >= value.byteLength) { + throw new RangeError('\'offset\' is out of bounds'); + } + if (len > value.byteLength - offset) { + throw new RangeError('\'length\' is out of bounds'); + } + return new Buffer(value.slice(offset, offset + len)); + } + if (Buffer.isBuffer(value)) { + var out = new Buffer(value.length); + value.copy(out, 0, 0, value.length); + return out; + } + if (value) { + if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { + return new Buffer(value); + } + if (value.type === 'Buffer' && Array.isArray(value.data)) { + return new Buffer(value.data); + } + } + + throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); +} +exports.allocUnsafeSlow = function allocUnsafeSlow(size) { + if (typeof Buffer.allocUnsafeSlow === 'function') { + return Buffer.allocUnsafeSlow(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size >= MAX_LEN) { + throw new RangeError('size is too large'); + } + return new SlowBuffer(size); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"buffer":44}],44:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + +'use strict' + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('isarray') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() + +function typedArraySupport () { + try { + var arr = new Uint8Array(1) + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) + } + that.length = length + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192 // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} + +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0 + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + var actual = that.write(string, encoding) + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual) + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + that = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array) + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array) + } + return that +} + +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len) + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } + } + + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length + } + return buffer +} + +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +function slowToString (encoding, start, end) { + var loweredCase = false + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true + +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) + } + return this +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +} + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start] + } + } + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":39,"ieee754":50,"isarray":53}],45:[function(require,module,exports){ +(function (Buffer){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) +},{"../../is-buffer/index.js":52}],46:[function(require,module,exports){ +/* See LICENSE file for terms of use */ + +/* + * Text diff implementation. + * + * This library supports the following APIS: + * JsDiff.diffChars: Character by character diff + * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * JsDiff.diffLines: Line based diff + * + * JsDiff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ +(function(global, undefined) { + var objectPrototypeToString = Object.prototype.toString; + + /*istanbul ignore next*/ + function map(arr, mapper, that) { + if (Array.prototype.map) { + return Array.prototype.map.call(arr, mapper, that); + } + + var other = new Array(arr.length); + + for (var i = 0, n = arr.length; i < n; i++) { + other[i] = mapper.call(that, arr[i], i, arr); + } + return other; + } + function clonePath(path) { + return { newPos: path.newPos, components: path.components.slice(0) }; + } + function removeEmpty(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + } + function escapeHTML(s) { + var n = s; + n = n.replace(/&/g, '&'); + n = n.replace(//g, '>'); + n = n.replace(/"/g, '"'); + + return n; + } + + // This function handles the presence of circular references by bailing out when encountering an + // object that is already on the "stack" of items being processed. + function canonicalize(obj, stack, replacementStack) { + stack = stack || []; + replacementStack = replacementStack || []; + + var i; + + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + + var canonicalizedObj; + + if ('[object Array]' === objectPrototypeToString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); + } else if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = [], + key; + for (key in obj) { + sortedKeys.push(key); + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); + } else { + canonicalizedObj = obj; + } + return canonicalizedObj; + } + + function buildValues(components, newString, oldString, useLongestToken) { + var componentPos = 0, + componentLen = components.length, + newPos = 0, + oldPos = 0; + + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && useLongestToken) { + var value = newString.slice(newPos, newPos + component.count); + value = map(value, function(value, i) { + var oldValue = oldString[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); + + component.value = value.join(''); + } else { + component.value = newString.slice(newPos, newPos + component.count).join(''); + } + newPos += component.count; + + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = oldString.slice(oldPos, oldPos + component.count).join(''); + oldPos += component.count; + + // Reverse add and remove so removes are output first to match common convention + // The diffing algorithm is tied to add then remove output and this is the simplest + // route to get the desired output with minimal overhead. + if (componentPos && components[componentPos - 1].added) { + var tmp = components[componentPos - 1]; + components[componentPos - 1] = components[componentPos]; + components[componentPos] = tmp; + } + } + } + + return components; + } + + function Diff(ignoreWhitespace) { + this.ignoreWhitespace = ignoreWhitespace; + } + Diff.prototype = { + diff: function(oldString, newString, callback) { + var self = this; + + function done(value) { + if (callback) { + setTimeout(function() { callback(undefined, value); }, 0); + return true; + } else { + return value; + } + } + + // Handle the identity case (this is due to unrolling editLength == 0 + if (newString === oldString) { + return done([{ value: newString }]); + } + if (!newString) { + return done([{ value: oldString, removed: true }]); + } + if (!oldString) { + return done([{ value: newString, added: true }]); + } + + newString = this.tokenize(newString); + oldString = this.tokenize(oldString); + + var newLen = newString.length, oldLen = oldString.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + var bestPath = [{ newPos: -1, components: [] }]; + + // Seed editLength = 0, i.e. the content starts with the same values + var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + // Identity per the equality and tokenizer + return done([{value: newString.join('')}]); + } + + // Main worker method. checks all permutations of a given edit length for acceptance. + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath; + var addPath = bestPath[diagonalPath - 1], + removePath = bestPath[diagonalPath + 1], + oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + // No one else is going to attempt to use this value, clear it + bestPath[diagonalPath - 1] = undefined; + } + + var canAdd = addPath && addPath.newPos + 1 < newLen, + canRemove = removePath && 0 <= oldPos && oldPos < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + bestPath[diagonalPath] = undefined; + continue; + } + + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the new string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { + basePath = clonePath(removePath); + self.pushComponent(basePath.components, undefined, true); + } else { + basePath = addPath; // No need to clone, we've pulled it from the list + basePath.newPos++; + self.pushComponent(basePath.components, true, undefined); + } + + oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); + + // If we have hit the end of both strings, then we are done + if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + return done(buildValues(basePath.components, newString, oldString, self.useLongestToken)); + } else { + // Otherwise track this path as a potential candidate and continue. + bestPath[diagonalPath] = basePath; + } + } + + editLength++; + } + + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced. + if (callback) { + (function exec() { + setTimeout(function() { + // This should not happen, but we want to be safe. + /*istanbul ignore next */ + if (editLength > maxEditLength) { + return callback(); + } + + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + } + }, + + pushComponent: function(components, added, removed) { + var last = components[components.length - 1]; + if (last && last.added === added && last.removed === removed) { + // We need to clone here as the component clone operation is just + // as shallow array clone + components[components.length - 1] = {count: last.count + 1, added: added, removed: removed }; + } else { + components.push({count: 1, added: added, removed: removed }); + } + }, + extractCommon: function(basePath, newString, oldString, diagonalPath) { + var newLen = newString.length, + oldLen = oldString.length, + newPos = basePath.newPos, + oldPos = newPos - diagonalPath, + + commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; + } + + if (commonCount) { + basePath.components.push({count: commonCount}); + } + + basePath.newPos = newPos; + return oldPos; + }, + + equals: function(left, right) { + var reWhitespace = /\S/; + return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); + }, + tokenize: function(value) { + return value.split(''); + } + }; + + var CharDiff = new Diff(); + + var WordDiff = new Diff(true); + var WordWithSpaceDiff = new Diff(); + WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\s+|\b)/)); + }; + + var CssDiff = new Diff(true); + CssDiff.tokenize = function(value) { + return removeEmpty(value.split(/([{}:;,]|\s+)/)); + }; + + var LineDiff = new Diff(); + + var TrimmedLineDiff = new Diff(); + TrimmedLineDiff.ignoreTrim = true; + + LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) { + var retLines = [], + lines = value.split(/^/m); + for (var i = 0; i < lines.length; i++) { + var line = lines[i], + lastLine = lines[i - 1], + lastLineLastChar = lastLine && lastLine[lastLine.length - 1]; + + // Merge lines that may contain windows new lines + if (line === '\n' && lastLineLastChar === '\r') { + retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\r\n'; + } else { + if (this.ignoreTrim) { + line = line.trim(); + // add a newline unless this is the last line. + if (i < lines.length - 1) { + line += '\n'; + } + } + retLines.push(line); + } + } + + return retLines; + }; + + var PatchDiff = new Diff(); + PatchDiff.tokenize = function(value) { + var ret = [], + linesAndNewlines = value.split(/(\n|\r\n)/); + + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; + + if (i % 2) { + ret[ret.length - 1] += line; + } else { + ret.push(line); + } + } + return ret; + }; + + var SentenceDiff = new Diff(); + SentenceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); + }; + + var JsonDiff = new Diff(); + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + JsonDiff.useLongestToken = true; + JsonDiff.tokenize = LineDiff.tokenize; + JsonDiff.equals = function(left, right) { + return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); + }; + + var JsDiff = { + Diff: Diff, + + diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); }, + diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); }, + diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); }, + diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); }, + diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); }, + + diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, + + diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); }, + diffJson: function(oldObj, newObj, callback) { + return JsonDiff.diff( + typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '), + typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '), + callback + ); + }, + + createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) { + var ret = []; + + if (oldFileName == newFileName) { + ret.push('Index: ' + oldFileName); + } + ret.push('==================================================================='); + ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)); + ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)); + + var diff = PatchDiff.diff(oldStr, newStr); + diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier + + // Formats a given set of lines for printing as context lines in a patch + function contextLines(lines) { + return map(lines, function(entry) { return ' ' + entry; }); + } + + // Outputs the no newline at end of file warning if needed + function eofNL(curRange, i, current) { + var last = diff[diff.length - 2], + isLast = i === diff.length - 2, + isLastOfType = i === diff.length - 3 && current.added !== last.added; + + // Figure out if this is the last line for the given file and missing NL + if (!(/\n$/.test(current.value)) && (isLast || isLastOfType)) { + curRange.push('\\ No newline at end of file'); + } + } + + var oldRangeStart = 0, newRangeStart = 0, curRange = [], + oldLine = 1, newLine = 1; + for (var i = 0; i < diff.length; i++) { + var current = diff[i], + lines = current.lines || current.value.replace(/\n$/, '').split('\n'); + current.lines = lines; + + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + + if (prev) { + curRange = contextLines(prev.lines.slice(-4)); + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + + // Output our changes + curRange.push.apply(curRange, map(lines, function(entry) { + return (current.added ? '+' : '-') + entry; + })); + eofNL(curRange, i, current); + + // Track the updated file position + if (current.added) { + newLine += lines.length; + } else { + oldLine += lines.length; + } + } else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= 8 && i < diff.length - 2) { + // Overlapping + curRange.push.apply(curRange, contextLines(lines)); + } else { + // end the range and output + var contextSize = Math.min(lines.length, 4); + ret.push( + '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) + + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) + + ' @@'); + ret.push.apply(ret, curRange); + ret.push.apply(ret, contextLines(lines.slice(0, contextSize))); + if (lines.length <= 4) { + eofNL(ret, i, current); + } + + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } + + return ret.join('\n') + '\n'; + }, + + createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { + return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); + }, + + applyPatch: function(oldStr, uniDiff) { + var diffstr = uniDiff.split('\n'), + hunks = [], + i = 0, + remEOFNL = false, + addEOFNL = false; + + // Skip to the first change hunk + while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { + i++; + } + + // Parse the unified diff + for (; i < diffstr.length; i++) { + if (diffstr[i][0] === '@') { + var chnukHeader = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/); + hunks.unshift({ + start: chnukHeader[3], + oldlength: +chnukHeader[2], + removed: [], + newlength: chnukHeader[4], + added: [] + }); + } else if (diffstr[i][0] === '+') { + hunks[0].added.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '-') { + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === ' ') { + hunks[0].added.push(diffstr[i].substr(1)); + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '\\') { + if (diffstr[i - 1][0] === '+') { + remEOFNL = true; + } else if (diffstr[i - 1][0] === '-') { + addEOFNL = true; + } + } + } + + // Apply the diff to the input + var lines = oldStr.split('\n'); + for (i = hunks.length - 1; i >= 0; i--) { + var hunk = hunks[i]; + // Sanity check the input string. Bail if we don't match. + for (var j = 0; j < hunk.oldlength; j++) { + if (lines[hunk.start - 1 + j] !== hunk.removed[j]) { + return false; + } + } + Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added)); + } + + // Handle EOFNL insertion/removal + if (remEOFNL) { + while (!lines[lines.length - 1]) { + lines.pop(); + } + } else if (addEOFNL) { + lines.push(''); + } + return lines.join('\n'); + }, + + convertChangesToXML: function(changes) { + var ret = []; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + + ret.push(escapeHTML(change.value)); + + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + } + return ret.join(''); + }, + + // See: http://code.google.com/p/google-diff-match-patch/wiki/API + convertChangesToDMP: function(changes) { + var ret = [], + change, + operation; + for (var i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } else if (change.removed) { + operation = -1; + } else { + operation = 0; + } + + ret.push([operation, change.value]); + } + return ret; + }, + + canonicalize: canonicalize + }; + + /*istanbul ignore next */ + /*global module */ + if (typeof module !== 'undefined' && module.exports) { + module.exports = JsDiff; + } else if (false) { + /*global define */ + define([], function() { return JsDiff; }); + } else if (typeof global.JsDiff === 'undefined') { + global.JsDiff = JsDiff; + } +}(this)); + +},{}],47:[function(require,module,exports){ +'use strict'; + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return str.replace(matchOperatorsRe, '\\$&'); +}; + +},{}],48:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],49:[function(require,module,exports){ +(function (process){ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) + +/** + * Module dependencies. + */ + +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; + +function which(name) { + var paths = process.env.PATH.split(':'); + var loc; + + for (var i = 0, len = paths.length; i < len; ++i) { + loc = path.join(paths[i], name); + if (exists(loc)) return loc; + } +} + +switch(os.type()) { + case 'Darwin': + if (which('terminal-notifier')) { + cmd = { + type: "Darwin-NotificationCenter" + , pkg: "terminal-notifier" + , msg: '-message' + , title: '-title' + , subtitle: '-subtitle' + , icon: '-appIcon' + , sound: '-sound' + , url: '-open' + , priority: { + cmd: '-execute' + , range: [] + } + }; + } else { + cmd = { + type: "Darwin-Growl" + , pkg: "growlnotify" + , msg: '-m' + , sticky: '--sticky' + , priority: { + cmd: '--priority' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + , "Very Low" + , "Moderate" + , "Normal" + , "High" + , "Emergency" + ] + } + }; + } + break; + case 'Linux': + if (which('growl')) { + cmd = { + type: "Linux-Growl" + , pkg: "growl" + , msg: '-m' + , title: '-title' + , subtitle: '-subtitle' + , host: { + cmd: '-H' + , hostname: '192.168.33.1' + } + }; + } else { + cmd = { + type: "Linux" + , pkg: "notify-send" + , msg: '' + , sticky: '-t 0' + , icon: '-i' + , priority: { + cmd: '-u' + , range: [ + "low" + , "normal" + , "critical" + ] + } + }; + } + break; + case 'Windows_NT': + cmd = { + type: "Windows" + , pkg: "growlnotify" + , msg: '' + , sticky: '/s:true' + , title: '/t:' + , icon: '/i:' + , url: '/cu:' + , priority: { + cmd: '/p:' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + ] + } + }; + break; +} + +/** + * Expose `growl`. + */ + +exports = module.exports = growl; + +/** + * Node-growl version. + */ + +exports.version = '1.4.1' + +/** + * Send growl notification _msg_ with _options_. + * + * Options: + * + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - priority Specify an int or named key (default is 0) + * - name Application name (defaults to growlnotify) + * - sound Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon + * + * Examples: + * + * growl('New email') + * growl('5 new emails', { title: 'Thunderbird' }) + * growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' }) + * growl('Email sent', function(){ + * // ... notification sent + * }) + * + * @param {string} msg + * @param {object} options + * @param {function} fn + * @api public + */ + +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; + + if (options.exec) { + cmd = { + type: "Custom" + , pkg: options.exec + , range: [] + }; + } + + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; + + // image + if (image = options.image) { + switch(cmd.type) { + case 'Darwin-Growl': + var flag, ext = path.extname(image).substr(1) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, quote(image)) + break; + case 'Darwin-NotificationCenter': + args.push(cmd.icon, quote(image)); + break; + case 'Linux': + args.push(cmd.icon, quote(image)); + // libnotify defaults to sticky, set a hint for transient notifications + if (!options.sticky) args.push('--hint=int:transient:1'); + break; + case 'Windows': + args.push(cmd.icon + quote(image)); + break; + } + } + + // sticky + if (options.sticky) args.push(cmd.sticky); + + // priority + if (options.priority) { + var priority = options.priority + ''; + var checkindexOf = cmd.priority.range.indexOf(priority); + if (~cmd.priority.range.indexOf(priority)) { + args.push(cmd.priority, options.priority); + } + } + + //sound + if(options.sound && cmd.type === 'Darwin-NotificationCenter'){ + args.push(cmd.sound, options.sound) + } + + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } + + switch(cmd.type) { + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); + break; + case 'Darwin-NotificationCenter': + args.push(cmd.msg); + var stringifiedMsg = quote(msg); + var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n'); + args.push(escapedMsg); + if (options.title) { + args.push(cmd.title); + args.push(quote(options.title)); + } + if (options.subtitle) { + args.push(cmd.subtitle); + args.push(quote(options.subtitle)); + } + if (options.url) { + args.push(cmd.url); + args.push(quote(options.url)); + } + break; + case 'Linux-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); + if (cmd.host) { + args.push(cmd.host.cmd, cmd.host.hostname) + } + break; + case 'Linux': + if (options.title) { + args.push(quote(options.title)); + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + } else { + args.push(quote(msg).replace(/\\n/g, '\n')); + } + break; + case 'Windows': + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(cmd.title + quote(options.title)); + if (options.url) args.push(cmd.url + quote(options.url)); + break; + case 'Custom': + args[0] = (function(origCommand) { + var message = options.title + ? options.title + ': ' + msg + : msg; + var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message)); + if (command === origCommand) args.push(quote(message)); + return command; + })(args[0]); + break; + } + + // execute + exec(args.join(' '), fn); +}; + +}).call(this,require('_process')) +},{"_process":67,"child_process":42,"fs":42,"os":65,"path":42}],50:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],51:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],52:[function(require,module,exports){ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +module.exports = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +} + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} + +},{}],53:[function(require,module,exports){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +},{}],54:[function(require,module,exports){ +(function (global){ +/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ +;(function () { + // Detect the `define` function exposed by asynchronous module loaders. The + // strict `define` check is necessary for compatibility with `r.js`. + var isLoader = false; + + // A set of types used to distinguish objects from primitives. + var objectTypes = { + "function": true, + "object": true + }; + + // Detect the `exports` object exposed by CommonJS implementations. + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + // Use the `global` object exposed by Node (including Browserify via + // `insert-module-globals`), Narwhal, and Ringo as the default context, + // and the `window` object in browsers. Rhino exports a `global` function + // instead. + var root = objectTypes[typeof window] && window || this, + freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global; + + if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) { + root = freeGlobal; + } + + // Public: Initializes JSON 3 using the given `context` object, attaching the + // `stringify` and `parse` functions to the specified `exports` object. + function runInContext(context, exports) { + context || (context = root["Object"]()); + exports || (exports = root["Object"]()); + + // Native constructor aliases. + var Number = context["Number"] || root["Number"], + String = context["String"] || root["String"], + Object = context["Object"] || root["Object"], + Date = context["Date"] || root["Date"], + SyntaxError = context["SyntaxError"] || root["SyntaxError"], + TypeError = context["TypeError"] || root["TypeError"], + Math = context["Math"] || root["Math"], + nativeJSON = context["JSON"] || root["JSON"]; + + // Delegate to the native `stringify` and `parse` implementations. + if (typeof nativeJSON == "object" && nativeJSON) { + exports.stringify = nativeJSON.stringify; + exports.parse = nativeJSON.parse; + } + + // Convenience aliases. + var objectProto = Object.prototype, + getClass = objectProto.toString, + isProperty, forEach, undef; + + // Test the `Date#getUTC*` methods. Based on work by @Yaffle. + var isExtended = new Date(-3509827334573292); + try { + // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical + // results for certain dates in Opera >= 10.53. + isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && + // Safari < 2.0.2 stores the internal millisecond time value correctly, + // but clips the values returned by the date methods to the range of + // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). + isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; + } catch (exception) {} + + // Internal: Determines whether the native `JSON.stringify` and `parse` + // implementations are spec-compliant. Based on work by Ken Snyder. + function has(name) { + if (has[name] !== undef) { + // Return cached feature test result. + return has[name]; + } + var isSupported; + if (name == "bug-string-char-index") { + // IE <= 7 doesn't support accessing string characters using square + // bracket notation. IE 8 only supports this for primitives. + isSupported = "a"[0] != "a"; + } else if (name == "json") { + // Indicates whether both `JSON.stringify` and `JSON.parse` are + // supported. + isSupported = has("json-stringify") && has("json-parse"); + } else { + var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; + // Test `JSON.stringify`. + if (name == "json-stringify") { + var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; + if (stringifySupported) { + // A test function object with a custom `toJSON` method. + (value = function () { + return 1; + }).toJSON = value; + try { + stringifySupported = + // Firefox 3.1b1 and b2 serialize string, number, and boolean + // primitives as object literals. + stringify(0) === "0" && + // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object + // literals. + stringify(new Number()) === "0" && + stringify(new String()) == '""' && + // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or + // does not define a canonical JSON representation (this applies to + // objects with `toJSON` properties as well, *unless* they are nested + // within an object or array). + stringify(getClass) === undef && + // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and + // FF 3.1b3 pass this test. + stringify(undef) === undef && + // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, + // respectively, if the value is omitted entirely. + stringify() === undef && + // FF 3.1b1, 2 throw an error if the given value is not a number, + // string, array, object, Boolean, or `null` literal. This applies to + // objects with custom `toJSON` methods as well, unless they are nested + // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` + // methods entirely. + stringify(value) === "1" && + stringify([value]) == "[1]" && + // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of + // `"[null]"`. + stringify([undef]) == "[null]" && + // YUI 3.0.0b1 fails to serialize `null` literals. + stringify(null) == "null" && + // FF 3.1b1, 2 halts serialization if an array contains a function: + // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 + // elides non-JSON values from objects and arrays, unless they + // define custom `toJSON` methods. + stringify([undef, getClass, null]) == "[null,null,null]" && + // Simple serialization test. FF 3.1b1 uses Unicode escape sequences + // where character escape codes are expected (e.g., `\b` => `\u0008`). + stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && + // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. + stringify(null, value) === "1" && + stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && + // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly + // serialize extended years. + stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && + // The milliseconds are optional in ES 5, but required in 5.1. + stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && + // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative + // four-digit years instead of six-digit years. Credits: @Yaffle. + stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && + // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond + // values less than 1000. Credits: @Yaffle. + stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; + } catch (exception) { + stringifySupported = false; + } + } + isSupported = stringifySupported; + } + // Test `JSON.parse`. + if (name == "json-parse") { + var parse = exports.parse; + if (typeof parse == "function") { + try { + // FF 3.1b1, b2 will throw an exception if a bare literal is provided. + // Conforming implementations should also coerce the initial argument to + // a string prior to parsing. + if (parse("0") === 0 && !parse(false)) { + // Simple parsing test. + value = parse(serialized); + var parseSupported = value["a"].length == 5 && value["a"][0] === 1; + if (parseSupported) { + try { + // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. + parseSupported = !parse('"\t"'); + } catch (exception) {} + if (parseSupported) { + try { + // FF 4.0 and 4.0.1 allow leading `+` signs and leading + // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow + // certain octal literals. + parseSupported = parse("01") !== 1; + } catch (exception) {} + } + if (parseSupported) { + try { + // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal + // points. These environments, along with FF 3.1b1 and 2, + // also allow trailing commas in JSON objects and arrays. + parseSupported = parse("1.") !== 1; + } catch (exception) {} + } + } + } + } catch (exception) { + parseSupported = false; + } + } + isSupported = parseSupported; + } + } + return has[name] = !!isSupported; + } + + if (!has("json")) { + // Common `[[Class]]` name aliases. + var functionClass = "[object Function]", + dateClass = "[object Date]", + numberClass = "[object Number]", + stringClass = "[object String]", + arrayClass = "[object Array]", + booleanClass = "[object Boolean]"; + + // Detect incomplete support for accessing string characters by index. + var charIndexBuggy = has("bug-string-char-index"); + + // Define additional utility methods if the `Date` methods are buggy. + if (!isExtended) { + var floor = Math.floor; + // A mapping between the months of the year and the number of days between + // January 1st and the first of the respective month. + var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; + // Internal: Calculates the number of days between the Unix epoch and the + // first day of the given month. + var getDay = function (year, month) { + return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); + }; + } + + // Internal: Determines if a property is a direct property of the given + // object. Delegates to the native `Object#hasOwnProperty` method. + if (!(isProperty = objectProto.hasOwnProperty)) { + isProperty = function (property) { + var members = {}, constructor; + if ((members.__proto__ = null, members.__proto__ = { + // The *proto* property cannot be set multiple times in recent + // versions of Firefox and SeaMonkey. + "toString": 1 + }, members).toString != getClass) { + // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but + // supports the mutable *proto* property. + isProperty = function (property) { + // Capture and break the object's prototype chain (see section 8.6.2 + // of the ES 5.1 spec). The parenthesized expression prevents an + // unsafe transformation by the Closure Compiler. + var original = this.__proto__, result = property in (this.__proto__ = null, this); + // Restore the original prototype chain. + this.__proto__ = original; + return result; + }; + } else { + // Capture a reference to the top-level `Object` constructor. + constructor = members.constructor; + // Use the `constructor` property to simulate `Object#hasOwnProperty` in + // other environments. + isProperty = function (property) { + var parent = (this.constructor || constructor).prototype; + return property in this && !(property in parent && this[property] === parent[property]); + }; + } + members = null; + return isProperty.call(this, property); + }; + } + + // Internal: Normalizes the `for...in` iteration algorithm across + // environments. Each enumerated key is yielded to a `callback` function. + forEach = function (object, callback) { + var size = 0, Properties, members, property; + + // Tests for bugs in the current environment's `for...in` algorithm. The + // `valueOf` property inherits the non-enumerable flag from + // `Object.prototype` in older versions of IE, Netscape, and Mozilla. + (Properties = function () { + this.valueOf = 0; + }).prototype.valueOf = 0; + + // Iterate over a new instance of the `Properties` class. + members = new Properties(); + for (property in members) { + // Ignore all properties inherited from `Object.prototype`. + if (isProperty.call(members, property)) { + size++; + } + } + Properties = members = null; + + // Normalize the iteration algorithm. + if (!size) { + // A list of non-enumerable properties inherited from `Object.prototype`. + members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; + // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable + // properties. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, length; + var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty; + for (property in object) { + // Gecko <= 1.0 enumerates the `prototype` property of functions under + // certain conditions; IE does not. + if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { + callback(property); + } + } + // Manually invoke the callback for each non-enumerable property. + for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); + }; + } else if (size == 2) { + // Safari <= 2.0.4 enumerates shadowed properties twice. + forEach = function (object, callback) { + // Create a set of iterated properties. + var members = {}, isFunction = getClass.call(object) == functionClass, property; + for (property in object) { + // Store each property name to prevent double enumeration. The + // `prototype` property of functions is not enumerated due to cross- + // environment inconsistencies. + if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { + callback(property); + } + } + }; + } else { + // No bugs detected; use the standard `for...in` algorithm. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, isConstructor; + for (property in object) { + if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { + callback(property); + } + } + // Manually invoke the callback for the `constructor` property due to + // cross-environment inconsistencies. + if (isConstructor || isProperty.call(object, (property = "constructor"))) { + callback(property); + } + }; + } + return forEach(object, callback); + }; + + // Public: Serializes a JavaScript `value` as a JSON string. The optional + // `filter` argument may specify either a function that alters how object and + // array members are serialized, or an array of strings and numbers that + // indicates which properties should be serialized. The optional `width` + // argument may be either a string or number that specifies the indentation + // level of the output. + if (!has("json-stringify")) { + // Internal: A map of control characters and their escaped equivalents. + var Escapes = { + 92: "\\\\", + 34: '\\"', + 8: "\\b", + 12: "\\f", + 10: "\\n", + 13: "\\r", + 9: "\\t" + }; + + // Internal: Converts `value` into a zero-padded string such that its + // length is at least equal to `width`. The `width` must be <= 6. + var leadingZeroes = "000000"; + var toPaddedString = function (width, value) { + // The `|| 0` expression is necessary to work around a bug in + // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. + return (leadingZeroes + (value || 0)).slice(-width); + }; + + // Internal: Double-quotes a string `value`, replacing all ASCII control + // characters (characters with code unit values between 0 and 31) with + // their escaped equivalents. This is an implementation of the + // `Quote(value)` operation defined in ES 5.1 section 15.12.3. + var unicodePrefix = "\\u00"; + var quote = function (value) { + var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; + var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value); + for (; index < length; index++) { + var charCode = value.charCodeAt(index); + // If the character is a control character, append its Unicode or + // shorthand escape sequence; otherwise, append the character as-is. + switch (charCode) { + case 8: case 9: case 10: case 12: case 13: case 34: case 92: + result += Escapes[charCode]; + break; + default: + if (charCode < 32) { + result += unicodePrefix + toPaddedString(2, charCode.toString(16)); + break; + } + result += useCharIndex ? symbols[index] : value.charAt(index); + } + } + return result + '"'; + }; + + // Internal: Recursively serializes an object. Implements the + // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. + var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { + var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; + try { + // Necessary for host object support. + value = object[property]; + } catch (exception) {} + if (typeof value == "object" && value) { + className = getClass.call(value); + if (className == dateClass && !isProperty.call(value, "toJSON")) { + if (value > -1 / 0 && value < 1 / 0) { + // Dates are serialized according to the `Date#toJSON` method + // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 + // for the ISO 8601 date time string format. + if (getDay) { + // Manually compute the year, month, date, hours, minutes, + // seconds, and milliseconds if the `getUTC*` methods are + // buggy. Adapted from @Yaffle's `date-shim` project. + date = floor(value / 864e5); + for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); + for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); + date = 1 + date - getDay(year, month); + // The `time` value specifies the time within the day (see ES + // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used + // to compute `A modulo B`, as the `%` operator does not + // correspond to the `modulo` operation for negative numbers. + time = (value % 864e5 + 864e5) % 864e5; + // The hours, minutes, seconds, and milliseconds are obtained by + // decomposing the time within the day. See section 15.9.1.10. + hours = floor(time / 36e5) % 24; + minutes = floor(time / 6e4) % 60; + seconds = floor(time / 1e3) % 60; + milliseconds = time % 1e3; + } else { + year = value.getUTCFullYear(); + month = value.getUTCMonth(); + date = value.getUTCDate(); + hours = value.getUTCHours(); + minutes = value.getUTCMinutes(); + seconds = value.getUTCSeconds(); + milliseconds = value.getUTCMilliseconds(); + } + // Serialize extended years correctly. + value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + + "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + + // Months, dates, hours, minutes, and seconds should have two + // digits; milliseconds should have three. + "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + + // Milliseconds are optional in ES 5.0, but required in 5.1. + "." + toPaddedString(3, milliseconds) + "Z"; + } else { + value = null; + } + } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { + // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the + // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 + // ignores all `toJSON` methods on these objects unless they are + // defined directly on an instance. + value = value.toJSON(property); + } + } + if (callback) { + // If a replacement function was provided, call it to obtain the value + // for serialization. + value = callback.call(object, property, value); + } + if (value === null) { + return "null"; + } + className = getClass.call(value); + if (className == booleanClass) { + // Booleans are represented literally. + return "" + value; + } else if (className == numberClass) { + // JSON numbers must be finite. `Infinity` and `NaN` are serialized as + // `"null"`. + return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; + } else if (className == stringClass) { + // Strings are double-quoted and escaped. + return quote("" + value); + } + // Recursively serialize objects and arrays. + if (typeof value == "object") { + // Check for cyclic structures. This is a linear search; performance + // is inversely proportional to the number of unique nested objects. + for (length = stack.length; length--;) { + if (stack[length] === value) { + // Cyclic structures cannot be serialized by `JSON.stringify`. + throw TypeError(); + } + } + // Add the object to the stack of traversed objects. + stack.push(value); + results = []; + // Save the current indentation level and indent one additional level. + prefix = indentation; + indentation += whitespace; + if (className == arrayClass) { + // Recursively serialize array elements. + for (index = 0, length = value.length; index < length; index++) { + element = serialize(index, value, callback, properties, whitespace, indentation, stack); + results.push(element === undef ? "null" : element); + } + result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; + } else { + // Recursively serialize object members. Members are selected from + // either a user-specified list of property names, or the object + // itself. + forEach(properties || value, function (property) { + var element = serialize(property, value, callback, properties, whitespace, indentation, stack); + if (element !== undef) { + // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} + // is not the empty string, let `member` {quote(property) + ":"} + // be the concatenation of `member` and the `space` character." + // The "`space` character" refers to the literal space + // character, not the `space` {width} argument provided to + // `JSON.stringify`. + results.push(quote(property) + ":" + (whitespace ? " " : "") + element); + } + }); + result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; + } + // Remove the object from the traversed object stack. + stack.pop(); + return result; + } + }; + + // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. + exports.stringify = function (source, filter, width) { + var whitespace, callback, properties, className; + if (objectTypes[typeof filter] && filter) { + if ((className = getClass.call(filter)) == functionClass) { + callback = filter; + } else if (className == arrayClass) { + // Convert the property names array into a makeshift set. + properties = {}; + for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); + } + } + if (width) { + if ((className = getClass.call(width)) == numberClass) { + // Convert the `width` to an integer and create a string containing + // `width` number of space characters. + if ((width -= width % 1) > 0) { + for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); + } + } else if (className == stringClass) { + whitespace = width.length <= 10 ? width : width.slice(0, 10); + } + } + // Opera <= 7.54u2 discards the values associated with empty string keys + // (`""`) only if they are used directly within an object member list + // (e.g., `!("" in { "": 1})`). + return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); + }; + } + + // Public: Parses a JSON source string. + if (!has("json-parse")) { + var fromCharCode = String.fromCharCode; + + // Internal: A map of escaped control characters and their unescaped + // equivalents. + var Unescapes = { + 92: "\\", + 34: '"', + 47: "/", + 98: "\b", + 116: "\t", + 110: "\n", + 102: "\f", + 114: "\r" + }; + + // Internal: Stores the parser state. + var Index, Source; + + // Internal: Resets the parser state and throws a `SyntaxError`. + var abort = function () { + Index = Source = null; + throw SyntaxError(); + }; + + // Internal: Returns the next token, or `"$"` if the parser has reached + // the end of the source string. A token may be a string, number, `null` + // literal, or Boolean literal. + var lex = function () { + var source = Source, length = source.length, value, begin, position, isSigned, charCode; + while (Index < length) { + charCode = source.charCodeAt(Index); + switch (charCode) { + case 9: case 10: case 13: case 32: + // Skip whitespace tokens, including tabs, carriage returns, line + // feeds, and space characters. + Index++; + break; + case 123: case 125: case 91: case 93: case 58: case 44: + // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at + // the current position. + value = charIndexBuggy ? source.charAt(Index) : source[Index]; + Index++; + return value; + case 34: + // `"` delimits a JSON string; advance to the next character and + // begin parsing the string. String tokens are prefixed with the + // sentinel `@` character to distinguish them from punctuators and + // end-of-string tokens. + for (value = "@", Index++; Index < length;) { + charCode = source.charCodeAt(Index); + if (charCode < 32) { + // Unescaped ASCII control characters (those with a code unit + // less than the space character) are not permitted. + abort(); + } else if (charCode == 92) { + // A reverse solidus (`\`) marks the beginning of an escaped + // control character (including `"`, `\`, and `/`) or Unicode + // escape sequence. + charCode = source.charCodeAt(++Index); + switch (charCode) { + case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: + // Revive escaped control characters. + value += Unescapes[charCode]; + Index++; + break; + case 117: + // `\u` marks the beginning of a Unicode escape sequence. + // Advance to the first character and validate the + // four-digit code point. + begin = ++Index; + for (position = Index + 4; Index < position; Index++) { + charCode = source.charCodeAt(Index); + // A valid sequence comprises four hexdigits (case- + // insensitive) that form a single hexadecimal value. + if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { + // Invalid Unicode escape sequence. + abort(); + } + } + // Revive the escaped character. + value += fromCharCode("0x" + source.slice(begin, Index)); + break; + default: + // Invalid escape sequence. + abort(); + } + } else { + if (charCode == 34) { + // An unescaped double-quote character marks the end of the + // string. + break; + } + charCode = source.charCodeAt(Index); + begin = Index; + // Optimize for the common case where a string is valid. + while (charCode >= 32 && charCode != 92 && charCode != 34) { + charCode = source.charCodeAt(++Index); + } + // Append the string as-is. + value += source.slice(begin, Index); + } + } + if (source.charCodeAt(Index) == 34) { + // Advance to the next character and return the revived string. + Index++; + return value; + } + // Unterminated string. + abort(); + default: + // Parse numbers and literals. + begin = Index; + // Advance past the negative sign, if one is specified. + if (charCode == 45) { + isSigned = true; + charCode = source.charCodeAt(++Index); + } + // Parse an integer or floating-point value. + if (charCode >= 48 && charCode <= 57) { + // Leading zeroes are interpreted as octal literals. + if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { + // Illegal octal literal. + abort(); + } + isSigned = false; + // Parse the integer component. + for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); + // Floats cannot contain a leading decimal point; however, this + // case is already accounted for by the parser. + if (source.charCodeAt(Index) == 46) { + position = ++Index; + // Parse the decimal component. + for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + // Illegal trailing decimal. + abort(); + } + Index = position; + } + // Parse exponents. The `e` denoting the exponent is + // case-insensitive. + charCode = source.charCodeAt(Index); + if (charCode == 101 || charCode == 69) { + charCode = source.charCodeAt(++Index); + // Skip past the sign following the exponent, if one is + // specified. + if (charCode == 43 || charCode == 45) { + Index++; + } + // Parse the exponential component. + for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + // Illegal empty exponent. + abort(); + } + Index = position; + } + // Coerce the parsed value to a JavaScript number. + return +source.slice(begin, Index); + } + // A negative sign may only precede numbers. + if (isSigned) { + abort(); + } + // `true`, `false`, and `null` literals. + if (source.slice(Index, Index + 4) == "true") { + Index += 4; + return true; + } else if (source.slice(Index, Index + 5) == "false") { + Index += 5; + return false; + } else if (source.slice(Index, Index + 4) == "null") { + Index += 4; + return null; + } + // Unrecognized token. + abort(); + } + } + // Return the sentinel `$` character if the parser has reached the end + // of the source string. + return "$"; + }; + + // Internal: Parses a JSON `value` token. + var get = function (value) { + var results, hasMembers; + if (value == "$") { + // Unexpected end of input. + abort(); + } + if (typeof value == "string") { + if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { + // Remove the sentinel `@` character. + return value.slice(1); + } + // Parse object and array literals. + if (value == "[") { + // Parses a JSON array, returning a new JavaScript array. + results = []; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + // A closing square bracket marks the end of the array literal. + if (value == "]") { + break; + } + // If the array literal contains elements, the current token + // should be a comma separating the previous element from the + // next. + if (hasMembers) { + if (value == ",") { + value = lex(); + if (value == "]") { + // Unexpected trailing `,` in array literal. + abort(); + } + } else { + // A `,` must separate each array element. + abort(); + } + } + // Elisions and leading commas are not permitted. + if (value == ",") { + abort(); + } + results.push(get(value)); + } + return results; + } else if (value == "{") { + // Parses a JSON object, returning a new JavaScript object. + results = {}; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + // A closing curly brace marks the end of the object literal. + if (value == "}") { + break; + } + // If the object literal contains members, the current token + // should be a comma separator. + if (hasMembers) { + if (value == ",") { + value = lex(); + if (value == "}") { + // Unexpected trailing `,` in object literal. + abort(); + } + } else { + // A `,` must separate each object member. + abort(); + } + } + // Leading commas are not permitted, object property names must be + // double-quoted strings, and a `:` must separate each property + // name and value. + if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { + abort(); + } + results[value.slice(1)] = get(lex()); + } + return results; + } + // Unexpected token encountered. + abort(); + } + return value; + }; + + // Internal: Updates a traversed object member. + var update = function (source, property, callback) { + var element = walk(source, property, callback); + if (element === undef) { + delete source[property]; + } else { + source[property] = element; + } + }; + + // Internal: Recursively traverses a parsed JSON object, invoking the + // `callback` function for each value. This is an implementation of the + // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. + var walk = function (source, property, callback) { + var value = source[property], length; + if (typeof value == "object" && value) { + // `forEach` can't be used to traverse an array in Opera <= 8.54 + // because its `Object#hasOwnProperty` implementation returns `false` + // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). + if (getClass.call(value) == arrayClass) { + for (length = value.length; length--;) { + update(value, length, callback); + } + } else { + forEach(value, function (property) { + update(value, property, callback); + }); + } + } + return callback.call(source, property, value); + }; + + // Public: `JSON.parse`. See ES 5.1 section 15.12.2. + exports.parse = function (source, callback) { + var result, value; + Index = 0; + Source = "" + source; + result = get(lex()); + // If a JSON string contains multiple tokens, it is invalid. + if (lex() != "$") { + abort(); + } + // Reset the parser state. + Index = Source = null; + return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; + }; + } + } + + exports["runInContext"] = runInContext; + return exports; + } + + if (freeExports && !isLoader) { + // Export for CommonJS environments. + runInContext(root, freeExports); + } else { + // Export for web browsers and JavaScript engines. + var nativeJSON = root.JSON, + previousJSON = root["JSON3"], + isRestored = false; + + var JSON3 = runInContext(root, (root["JSON3"] = { + // Public: Restores the original value of the global `JSON` object and + // returns a reference to the `JSON3` object. + "noConflict": function () { + if (!isRestored) { + isRestored = true; + root.JSON = nativeJSON; + root["JSON3"] = previousJSON; + nativeJSON = previousJSON = null; + } + return JSON3; + } + })); + + root.JSON = { + "parse": JSON3.parse, + "stringify": JSON3.stringify + }; + } + + // Export for asynchronous module loaders. + if (isLoader) { + define(function () { + return JSON3; + }); + } +}).call(this); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],55:[function(require,module,exports){ +/** + * lodash 3.2.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCopy = require('lodash._basecopy'), + keys = require('lodash.keys'); + +/** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); +} + +module.exports = baseAssign; + +},{"lodash._basecopy":56,"lodash.keys":63}],56:[function(require,module,exports){ +/** + * lodash 3.0.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; +} + +module.exports = baseCopy; + +},{}],57:[function(require,module,exports){ +/** + * lodash 3.0.3 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; +}()); + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = baseCreate; + +},{}],58:[function(require,module,exports){ +/** + * lodash 3.9.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var funcTag = '[object Function]'; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = getNative; + +},{}],59:[function(require,module,exports){ +/** + * lodash 3.0.9 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +/** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isIterateeCall; + +},{}],60:[function(require,module,exports){ +/** + * lodash 3.1.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseAssign = require('lodash._baseassign'), + baseCreate = require('lodash._basecreate'), + isIterateeCall = require('lodash._isiterateecall'); + +/** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; + +},{"lodash._baseassign":55,"lodash._basecreate":57,"lodash._isiterateecall":59}],61:[function(require,module,exports){ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isArguments; + +},{}],62:[function(require,module,exports){ +/** + * lodash 3.0.4 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var arrayTag = '[object Array]', + funcTag = '[object Function]'; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsArray = getNative(Array, 'isArray'); + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ +var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; +}; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = isArray; + +},{}],63:[function(require,module,exports){ +/** + * lodash 3.1.2 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var getNative = require('lodash._getnative'), + isArguments = require('lodash.isarguments'), + isArray = require('lodash.isarray'); + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = getNative(Object, 'keys'); + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keys; + +},{"lodash._getnative":58,"lodash.isarguments":61,"lodash.isarray":62}],64:[function(require,module,exports){ +(function (process){ +var path = require('path'); +var fs = require('fs'); +var _0777 = parseInt('0777', 8); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} + +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + p = path.resolve(p); + + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } + + return made; +}; + +}).call(this,require('_process')) +},{"_process":67,"fs":42,"path":42}],65:[function(require,module,exports){ +exports.endianness = function () { return 'LE' }; + +exports.hostname = function () { + if (typeof location !== 'undefined') { + return location.hostname + } + else return ''; +}; + +exports.loadavg = function () { return [] }; + +exports.uptime = function () { return 0 }; + +exports.freemem = function () { + return Number.MAX_VALUE; +}; + +exports.totalmem = function () { + return Number.MAX_VALUE; +}; + +exports.cpus = function () { return [] }; + +exports.type = function () { return 'Browser' }; + +exports.release = function () { + if (typeof navigator !== 'undefined') { + return navigator.appVersion; + } + return ''; +}; + +exports.networkInterfaces += exports.getNetworkInterfaces += function () { return {} }; + +exports.arch = function () { return 'javascript' }; + +exports.platform = function () { return 'browser' }; + +exports.tmpdir = exports.tmpDir = function () { + return '/tmp'; +}; + +exports.EOL = '\n'; + +},{}],66:[function(require,module,exports){ +(function (process){ +'use strict'; + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = nextTick; +} else { + module.exports = process.nextTick; +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + +}).call(this,require('_process')) +},{"_process":67}],67:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],68:[function(require,module,exports){ +module.exports = require("./lib/_stream_duplex.js") + +},{"./lib/_stream_duplex.js":69}],69:[function(require,module,exports){ +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +'use strict'; + +/**/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +module.exports = Duplex; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} +},{"./_stream_readable":71,"./_stream_writable":73,"core-util-is":45,"inherits":51,"process-nextick-args":66}],70:[function(require,module,exports){ +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +'use strict'; + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); +}; +},{"./_stream_transform":72,"core-util-is":45,"inherits":51}],71:[function(require,module,exports){ +(function (process){ +'use strict'; + +module.exports = Readable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var isArray = require('isarray'); +/**/ + +Readable.ReadableState = ReadableState; + +/**/ +var EE = require('events').EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var debugUtil = require('util'); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var BufferList = require('./internal/streams/BufferList'); +var StringDecoder; + +util.inherits(Readable, Stream); + +function prependListener(emitter, event, fn) { + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; + } +} + +var Duplex; +function ReadableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +var Duplex; +function Readable(options) { + Duplex = Duplex || require('./_stream_duplex'); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options && typeof options.read === 'function') this._read = options.read; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + + if (!state.objectMode && typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = bufferShim.from(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var _e = new Error('stream.unshift() after end event'); + stream.emit('error', _e); + } else { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } + + if (!addToFront) state.reading = false; + + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + processNextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var _i = 0; _i < len; _i++) { + dests[_i].emit('unpipe', this); + }return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + processNextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function (ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = bufferShim.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +}).call(this,require('_process')) +},{"./_stream_duplex":69,"./internal/streams/BufferList":74,"_process":67,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":48,"inherits":51,"isarray":53,"process-nextick-args":66,"string_decoder/":80,"util":40}],72:[function(require,module,exports){ +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +'use strict'; + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) stream.push(data); + + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er) { + done(stream, er); + });else done(stream); + }); +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('Not implemented'); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +function done(stream, er) { + if (er) return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) throw new Error('Calling transform done when ws.length != 0'); + + if (ts.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); +} +},{"./_stream_duplex":69,"core-util-is":45,"inherits":51}],73:[function(require,module,exports){ +(function (process){ +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + +'use strict'; + +module.exports = Writable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var internalUtil = { + deprecate: require('util-deprecate') +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +util.inherits(Writable, Stream); + +function nop() {} + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +var Duplex; +function WritableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); +} + +WritableState.prototype.getBuffer = function writableStateGetBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') + }); + } catch (_) {} +})(); + +var Duplex; +function Writable(options) { + Duplex = Duplex || require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; + } + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe, not readable')); +}; + +function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + processNextTick(cb, er); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + var er = false; + // Always throw error if a null is written + // if we are not in object mode then throw + // if it is not a buffer, string, or undefined. + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + processNextTick(cb, er); + valid = false; + } + return valid; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } +}; + +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; + return this; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = bufferShim.from(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + + if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) processNextTick(cb, er);else cb(er); + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /**/ + asyncWrite(afterWrite, stream, state, finished, cb); + /**/ + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + while (entry) { + buffer[count] = entry; + entry = entry.next; + count += 1; + } + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequestCount = 0; + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else { + prefinish(stream, state); + } + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) processNextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; + } else { + state.corkedRequestsFree = _this; + } + }; +} +}).call(this,require('_process')) +},{"./_stream_duplex":69,"_process":67,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":48,"inherits":51,"process-nextick-args":66,"util-deprecate":81}],74:[function(require,module,exports){ +'use strict'; + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +module.exports = BufferList; + +function BufferList() { + this.head = null; + this.tail = null; + this.length = 0; +} + +BufferList.prototype.push = function (v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; +}; + +BufferList.prototype.unshift = function (v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; +}; + +BufferList.prototype.shift = function () { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; +}; + +BufferList.prototype.clear = function () { + this.head = this.tail = null; + this.length = 0; +}; + +BufferList.prototype.join = function (s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; +}; + +BufferList.prototype.concat = function (n) { + if (this.length === 0) return bufferShim.alloc(0); + if (this.length === 1) return this.head.data; + var ret = bufferShim.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + p.data.copy(ret, i); + i += p.data.length; + p = p.next; + } + return ret; +}; +},{"buffer":44,"buffer-shims":43}],75:[function(require,module,exports){ +module.exports = require("./lib/_stream_passthrough.js") + +},{"./lib/_stream_passthrough.js":70}],76:[function(require,module,exports){ +(function (process){ +var Stream = (function (){ + try { + return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify + } catch(_){} +}()); +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = Stream || exports; +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); + +if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream; +} + +}).call(this,require('_process')) +},{"./lib/_stream_duplex.js":69,"./lib/_stream_passthrough.js":70,"./lib/_stream_readable.js":71,"./lib/_stream_transform.js":72,"./lib/_stream_writable.js":73,"_process":67}],77:[function(require,module,exports){ +module.exports = require("./lib/_stream_transform.js") + +},{"./lib/_stream_transform.js":72}],78:[function(require,module,exports){ +module.exports = require("./lib/_stream_writable.js") + +},{"./lib/_stream_writable.js":73}],79:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Stream; + +var EE = require('events').EventEmitter; +var inherits = require('inherits'); + +inherits(Stream, EE); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +},{"events":48,"inherits":51,"readable-stream/duplex.js":68,"readable-stream/passthrough.js":75,"readable-stream/readable.js":76,"readable-stream/transform.js":77,"readable-stream/writable.js":78}],80:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} + +},{"buffer":44}],81:[function(require,module,exports){ +(function (global){ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],82:[function(require,module,exports){ +arguments[4][51][0].apply(exports,arguments) +},{"dup":51}],83:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],84:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":83,"_process":67,"inherits":82}]},{},[1]); diff --git a/support/client/lib/vwf/view/mocha/package.json b/support/client/lib/vwf/view/mocha/package.json new file mode 100644 index 000000000..ab9767049 --- /dev/null +++ b/support/client/lib/vwf/view/mocha/package.json @@ -0,0 +1,1417 @@ +{ + "_args": [ + [ + { + "raw": "mocha@^3.2.0", + "scope": null, + "escapedName": "mocha", + "name": "mocha", + "rawSpec": "^3.2.0", + "spec": ">=3.2.0 <4.0.0", + "type": "range" + }, + "D:\\Dev\\vwf-itdg\\public\\itdg" + ] + ], + "_from": "mocha@>=3.2.0 <4.0.0", + "_id": "mocha@3.2.0", + "_inCache": true, + "_location": "/mocha", + "_nodeVersion": "7.2.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/mocha-3.2.0.tgz_1480031903482_0.1920817163772881" + }, + "_npmUser": { + "name": "boneskull", + "email": "boneskull@boneskull.com" + }, + "_npmVersion": "3.10.9", + "_phantomChildren": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + }, + "_requested": { + "raw": "mocha@^3.2.0", + "scope": null, + "escapedName": "mocha", + "name": "mocha", + "rawSpec": "^3.2.0", + "spec": ">=3.2.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/mocha/-/mocha-3.2.0.tgz", + "_shasum": "7dc4f45e5088075171a68896814e6ae9eb7a85e3", + "_shrinkwrap": null, + "_spec": "mocha@^3.2.0", + "_where": "D:\\Dev\\vwf-itdg\\public\\itdg", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "bin": { + "mocha": "./bin/mocha", + "_mocha": "./bin/_mocha" + }, + "browser": { + "debug": "./lib/browser/debug.js", + "events": "./lib/browser/events.js", + "tty": "./lib/browser/tty.js", + "./index.js": "./browser-entry.js", + "fs": false, + "glob": false, + "path": false, + "supports-color": false + }, + "bugs": { + "url": "https://github.com/mochajs/mocha/issues" + }, + "contributors": [ + { + "name": "aaroncrows", + "url": "https://github.com/aaroncrows" + }, + { + "name": "Aaron Hamid", + "email": "aaron@incsw.com", + "url": "https://github.com/ahamid" + }, + { + "name": "Aaron Heckmann", + "email": "aaron.heckmann+github@gmail.com", + "url": "https://github.com/aheckmann" + }, + { + "name": "Adam Crabtree", + "url": "CrabDude's alias" + }, + { + "name": "Adam Gruber", + "url": "https://github.com/adamgruber" + }, + { + "name": "Adrian Ludwig", + "url": "https://github.com/adrian-ludwig" + }, + { + "name": "Ainthe Kitchen", + "email": "a.in.the.k@gmail.com", + "url": "https://github.com/ainthek" + }, + { + "name": "ajaykodali", + "url": "https://github.com/ajaykodali" + }, + { + "name": "Alex Early", + "url": "https://github.com/aearly" + }, + { + "name": "Alex Pham", + "email": "thedark1337@thedark1337.com", + "url": "https://github.com/thedark1337" + }, + { + "name": "amsul", + "url": "https://github.com/amsul" + }, + { + "name": "Andreas Brekken", + "email": "andreas@brekken.com", + "url": "https://github.com/abrkn" + }, + { + "name": "Andreas Lind", + "email": "andreas@one.com", + "url": "https://github.com/papandreou" + }, + { + "name": "Andrew Miller", + "email": "vnikitin@live.com", + "url": "https://github.com/vnikiti" + }, + { + "name": "Andrew Nesbitt", + "email": "andrewnez@gmail.com", + "url": "https://github.com/andrew" + }, + { + "name": "Andrey Popp", + "email": "8mayday@gmail.com", + "url": "https://github.com/andreypopp" + }, + { + "name": "Andrii Shumada", + "email": "eagleeyes91@gmail.com", + "url": "https://github.com/eagleeye" + }, + { + "name": "Anis Safine", + "url": "https://github.com/anis" + }, + { + "name": "Arian Stolwijk", + "email": "stolwijk.arian@gmail.com", + "url": "https://github.com/arian" + }, + { + "name": "Ariel Mashraki", + "email": "ariel@mashraki.co.il", + "url": "https://github.com/a8m" + }, + { + "name": "Arnaud Brousseau", + "url": "https://github.com/ArnaudBrousseau" + }, + { + "name": "Atsuya Takagi", + "email": "atsuya.takagi@gmail.com", + "url": "https://github.com/atsuya" + }, + { + "name": "Attila Domokos", + "url": "https://github.com/adomokos" + }, + { + "name": "Austin Birch", + "url": "https://github.com/austinbirch" + }, + { + "name": "Avi Vahl", + "url": "https://github.com/AviVahl" + }, + { + "name": "Ben Bradley", + "url": "https://github.com/ben-bradley" + }, + { + "name": "beneidel", + "url": "https://github.com/beneidel" + }, + { + "name": "Benjie Gillam", + "url": "https://github.com/benjie" + }, + { + "name": "Ben Noordhuis", + "email": "info@bnoordhuis.nl", + "url": "https://github.com/bnoordhuis" + }, + { + "name": "Benoit Larroque", + "url": "https://github.com/zetaben" + }, + { + "name": "Benoît Zugmeyer", + "url": "https://github.com/BenoitZugmeyer" + }, + { + "name": "Ben Vinegar", + "url": "https://github.com/benvinegar" + }, + { + "name": "Berker Peksag", + "email": "berker.peksag@gmail.com", + "url": "https://github.com/berkerpeksag" + }, + { + "name": "Bjørge Næss", + "url": "https://github.com/bjoerge" + }, + { + "name": "Brendan Nee", + "email": "brendan@blinktag.com", + "url": "https://github.com/brendannee" + }, + { + "name": "Brian Beck", + "email": "exogen@gmail.com", + "url": "https://github.com/exogen" + }, + { + "name": "Brian C", + "email": "brian.m.carlson@gmail.com", + "url": "https://github.com/brianc" + }, + { + "name": "Brian Lalor", + "email": "blalor@bravo5.org", + "url": "https://github.com/blalor" + }, + { + "name": "Brian Moore", + "url": "https://github.com/bionicbrian" + }, + { + "name": "Bryan Donovan", + "url": "https://github.com/BryanDonovan" + }, + { + "name": "Buck Doyle", + "url": "https://github.com/backspace" + }, + { + "name": "C. Scott Ananian", + "email": "cscott@cscott.net", + "url": "https://github.com/cscott" + }, + { + "name": "Casey Foster", + "url": "https://github.com/caseywebdev" + }, + { + "name": "Charles Lowell", + "email": "cowboyd@frontside.io", + "url": "https://github.com/cowboyd" + }, + { + "name": "Chris Buckley", + "email": "chris@cmbuckley.co.uk", + "url": "https://github.com/cmbuckley" + }, + { + "name": "Christopher Hiller", + "email": "boneskull@boneskull.com", + "url": "https://github.com/boneskull" + }, + { + "name": "Chris Wren", + "email": "chriswrendev@gmail.com", + "url": "https://github.com/ChrisWren" + }, + { + "name": "Clemens Stolle", + "url": "https://github.com/klaemo" + }, + { + "name": "Connor Dunn", + "url": "https://github.com/Connorhd" + }, + { + "name": "Corey Butler", + "url": "https://github.com/coreybutler" + }, + { + "name": "Cory Thomas", + "url": "https://github.com/dump247" + }, + { + "name": "cybertk", + "url": "https://github.com/cybertk" + }, + { + "name": "Daniel Ericsson", + "url": "https://github.com/monowerker" + }, + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com", + "url": "https://github.com/danielstjules" + }, + { + "name": "Daniel Stockman", + "email": "daniel.stockman@gmail.com", + "url": "https://github.com/evocateur" + }, + { + "name": "Dave McKenna", + "email": "davemckenna01@gmail.com", + "url": "https://github.com/davemckenna01" + }, + { + "name": "David da Silva", + "email": "yo@dasilvacont.in", + "url": "https://github.com/dasilvacontin" + }, + { + "name": "David Henderson", + "url": "https://github.com/dhendo" + }, + { + "name": "Denis Bardadym", + "email": "bardadymchik@gmail.com", + "url": "https://github.com/btd" + }, + { + "name": "Devin Weaver", + "email": "suki@tritarget.org", + "url": "https://github.com/sukima" + }, + { + "name": "Diogo Monteiro", + "email": "diogo.gmt@gmail.com", + "url": "https://github.com/diogogmt" + }, + { + "name": "Dmitry Shirokov", + "email": "deadrunk@gmail.com", + "url": "https://github.com/runk" + }, + { + "name": "Domenic Denicola", + "email": "d@domenic.me", + "url": "https://github.com/domenic" + }, + { + "name": "Dominic Barnes", + "email": "dominic@dbarnes.info", + "url": "https://github.com/dominicbarnes" + }, + { + "name": "domq", + "url": "https://github.com/domq" + }, + { + "name": "Douglas Wilson", + "email": "doug@somethingdoug.com", + "url": "https://github.com/dougwilson" + }, + { + "name": "Duncan Beevers", + "email": "duncan@dweebd.com", + "url": "https://github.com/duncanbeevers" + }, + { + "name": "Duncan Wong", + "url": "https://github.com/badunk" + }, + { + "name": "eiji.ienaga", + "url": "https://github.com/haru01" + }, + { + "name": "Fabio Crisci", + "email": "piuccio@gmail.com", + "url": "https://github.com/piuccio" + }, + { + "name": "Fede Ramirez", + "email": "i@2fd.me", + "url": "https://github.com/2fd" + }, + { + "name": "Fedor Indutny", + "email": "fedor@indutny.com", + "url": "https://github.com/indutny" + }, + { + "name": "fengmk2", + "email": "m@fengmk2.com", + "url": "https://github.com/fengmk2" + }, + { + "name": "Florian Margaine", + "email": "florian@margaine.com", + "url": "https://github.com/ralt" + }, + { + "name": "Forbes Lindesay", + "url": "https://github.com/ForbesLindesay" + }, + { + "name": "Frederico Silva", + "url": "https://github.com/fredericosilva" + }, + { + "name": "Fredrik Enestad", + "email": "fredrik.enestad@soundtrackyourbrand.com", + "url": "https://github.com/fredr" + }, + { + "name": "Fredrik Lindin", + "url": "https://github.com/Cowboy-coder" + }, + { + "name": "Gabriel Silk", + "url": "https://github.com/gsilk" + }, + { + "name": "Gareth Aye", + "email": "gareth.aye@gmail.com", + "url": "https://github.com/gaye" + }, + { + "name": "Gavin Mogan", + "email": "gavin@gavinmogan.com", + "url": "https://github.com/halkeye" + }, + { + "name": "gigadude", + "url": "https://github.com/gigadude" + }, + { + "name": "Giovanni Bassi", + "url": "https://github.com/giggio" + }, + { + "name": "Glen Huang", + "email": "curvedmark@gmail.com", + "url": "https://github.com/curvedmark" + }, + { + "name": "Glen Mailer", + "email": "glen@stainlessed.co.uk", + "url": "https://github.com/glenjamin" + }, + { + "name": "Greg Perkins", + "email": "gregperkins@alum.mit.edu", + "url": "https://github.com/gregrperkins" + }, + { + "name": "Guillermo Rauch", + "email": "rauchg@gmail.com", + "url": "https://github.com/rauchg" + }, + { + "name": "Guy Arye", + "url": "https://github.com/aryeguy" + }, + { + "name": "Gyandeep Singh", + "email": "gyandeeps@gmail.com", + "url": "https://github.com/gyandeeps" + }, + { + "name": "Harish", + "email": "hyeluri@gmail.com", + "url": "https://github.com/hyeluri" + }, + { + "name": "Harry Brundage", + "email": "harry.brundage@gmail.com", + "url": "https://github.com/airhorns" + }, + { + "name": "Ian Remmel", + "email": "design@ianwremmel.com", + "url": "https://github.com/ianwremmel" + }, + { + "name": "Ian Storm Taylor", + "url": "https://github.com/ianstormtaylor" + }, + { + "name": "Ian Young", + "email": "ian@iangreenleaf.com", + "url": "https://github.com/iangreenleaf" + }, + { + "name": "Ivan", + "url": "https://github.com/ivanstoyanov" + }, + { + "name": "Jaakko Salonen", + "url": "https://github.com/jsalonen" + }, + { + "name": "Jacob Wejendorp", + "email": "jacob@wejendorp.dk", + "url": "https://github.com/wejendorp" + }, + { + "name": "Jake Craige", + "url": "https://github.com/jakecraige" + }, + { + "name": "Jake Marsh", + "url": "https://github.com/jakemmarsh" + }, + { + "name": "Jake Mc", + "email": "jake.mc@icloud.com", + "url": "https://github.com/startswithaj" + }, + { + "name": "Jake Verbaten", + "email": "raynos2@gmail.com", + "url": "https://github.com/Raynos" + }, + { + "name": "Jakub Nešetřil", + "email": "jakub@apiary.io", + "url": "https://github.com/zzen" + }, + { + "name": "James Bowes", + "url": "https://github.com/jbowes" + }, + { + "name": "James Carr", + "email": "james.r.carr@gmail.com", + "url": "https://github.com/jamescarr" + }, + { + "name": "James G. Kim", + "email": "jgkim@jayg.org", + "url": "https://github.com/jgkim" + }, + { + "name": "James Lal", + "email": "james@lightsofapollo.com", + "url": "https://github.com/lightsofapollo" + }, + { + "name": "James Nylen", + "email": "jnylen@gmail.com", + "url": "https://github.com/nylen" + }, + { + "name": "Jason", + "url": "https://github.com/jlai" + }, + { + "name": "Jason Barry", + "email": "jay@jcbarry.com", + "url": "https://github.com/JCBarry" + }, + { + "name": "Javier Aranda", + "email": "javier.aranda.varo@gmail.com", + "url": "https://github.com/javierav" + }, + { + "name": "jcreamer898", + "url": "https://github.com/jcreamer898" + }, + { + "name": "Jean Ponchon", + "url": "https://github.com/nopnop" + }, + { + "name": "Jeff Kunkle", + "url": "https://github.com/kunklejr" + }, + { + "name": "Jeff Schilling", + "email": "jeff@manicwave.com", + "url": "https://github.com/jschilli" + }, + { + "name": "JeongHoon Byun", + "email": "outsideris@gmail.com", + "url": "aka Outsider" + }, + { + "name": "Jeremy Martin", + "url": "https://github.com/jmar777" + }, + { + "name": "jimenglish81", + "url": "https://github.com/jimenglish81" + }, + { + "name": "Jimmy Cuadra", + "url": "https://github.com/jimmycuadra" + }, + { + "name": "jldailey", + "url": "https://github.com/jldailey" + }, + { + "name": "jleyba", + "url": "https://github.com/jleyba" + }, + { + "name": "Joey Cozza", + "email": "joeycozza@gmail.com", + "url": "https://github.com/joeycozza" + }, + { + "name": "Johnathon Sanders", + "url": "https://github.com/outdooricon" + }, + { + "name": "John Doty", + "email": "jrhdoty@gmail.com", + "url": "https://github.com/jrhdoty" + }, + { + "name": "John Firebaugh", + "email": "john.firebaugh@gmail.com", + "url": "https://github.com/jfirebaugh" + }, + { + "name": "John Reeves", + "url": "https://github.com/jonnyreeves" + }, + { + "name": "Jo Liss", + "email": "joliss42@gmail.com", + "url": "https://github.com/joliss" + }, + { + "name": "Jonas Dohse", + "url": "https://github.com/dohse" + }, + { + "name": "Jonathan Kim", + "email": "hello@jkimbo.co.uk", + "url": "https://github.com/jkimbo" + }, + { + "name": "Jonathan Park", + "email": "jonathan.daniel.park@gmail.com", + "url": "https://github.com/park9140" + }, + { + "name": "jongleberry", + "email": "me@jongleberry.com", + "url": "https://github.com/jonathanong" + }, + { + "name": "Jordan Sexton", + "email": "jordan@jordansexton.com", + "url": "https://github.com/jordansexton" + }, + { + "name": "Joseph Spencer", + "url": "https://github.com/jsdevel" + }, + { + "name": "Josh Lory", + "url": "https://github.com/joshlory" + }, + { + "name": "Joshua Appelman", + "email": "joshua@jbna.nl", + "url": "https://github.com/jbnicolai" + }, + { + "name": "Joshua Krall", + "email": "joshuakrall@pobox.com", + "url": "https://github.com/jkrall" + }, + { + "name": "João Moreno", + "url": "https://github.com/joaomoreno" + }, + { + "name": "João Paulo Bochi", + "email": "jpbochi@gmail.com", + "url": "https://github.com/jpbochi" + }, + { + "name": "jugglinmike", + "url": "https://github.com/jugglinmike" + }, + { + "name": "Julien Wajsberg", + "url": "https://github.com/julienw" + }, + { + "name": "Jussi Virtanen", + "email": "contact@jvirtanen.org", + "url": "https://github.com/jvirtanen" + }, + { + "name": "Justin DuJardin", + "url": "https://github.com/justindujardin" + }, + { + "name": "Juzer Ali", + "email": "juzerali@live.com", + "url": "https://github.com/juzerali" + }, + { + "name": "Jérémie Astori", + "url": "https://github.com/astorije" + }, + { + "name": "Katie Gengler", + "url": "https://github.com/kategengler" + }, + { + "name": "Kazuhito Hokamura", + "url": "https://github.com/hokaccha" + }, + { + "name": "Keith Cirkel", + "url": "https://github.com/keithamus" + }, + { + "name": "Kent C. Dodds", + "email": "kent+github@doddsfamily.us", + "url": "https://github.com/kentcdodds" + }, + { + "name": "Kevin Burke", + "email": "kev@inburke.com", + "url": "https://github.com/kevinburke" + }, + { + "name": "Kevin Conway", + "email": "kevinjacobconway@gmail.com", + "url": "https://github.com/kevinconway" + }, + { + "name": "Kevin Kirsche", + "email": "Kev.Kirsche@gmail.com", + "url": "https://github.com/kkirsche" + }, + { + "name": "Kirill Korolyov", + "email": "kirill.korolyov@gmail.com", + "url": "https://github.com/Dremora" + }, + { + "name": "Koen Punt", + "email": "mail@koen.pt", + "url": "https://github.com/koenpunt" + }, + { + "name": "Konstantin Käfer", + "email": "mail@kkaefer.com", + "url": "https://github.com/kkaefer" + }, + { + "name": "Kris Rasmussen", + "url": "https://github.com/krisr" + }, + { + "name": "Kyle Mitchell", + "email": "kyle@kemitchell.com", + "url": "https://github.com/kemitchell" + }, + { + "name": "lakmeer", + "url": "https://github.com/lakmeer" + }, + { + "name": "Liam Newman", + "email": "bitwiseman@gmail.com", + "url": "https://github.com/bitwiseman" + }, + { + "name": "Linus Unnebäck", + "email": "linus@folkdatorn.se", + "url": "https://github.com/LinusU" + }, + { + "name": "Long Ho", + "email": "holevietlong@gmail.com", + "url": "https://github.com/longlho" + }, + { + "name": "László Bácsi", + "email": "lackac@lackac.hu", + "url": "https://github.com/lackac" + }, + { + "name": "Maciej Małecki", + "email": "me@mmalecki.com", + "url": "https://github.com/mmalecki" + }, + { + "name": "Mal Graty", + "url": "https://github.com/mal" + }, + { + "name": "Marcello Bastéa-Forte", + "email": "marcello@cellosoft.com", + "url": "https://github.com/marcello3d" + }, + { + "name": "Marc Kuo", + "email": "marc@routific.com", + "url": "https://github.com/mck-" + }, + { + "name": "Mark Banner", + "url": "https://github.com/Standard8" + }, + { + "name": "Matija Marohnić", + "email": "matija.marohnic@gmail.com", + "url": "https://github.com/silvenon" + }, + { + "name": "Matthew Shanley", + "email": "matthewshanley@littlesecretsrecords.com", + "url": "https://github.com/arkadyan" + }, + { + "name": "mattias-lw", + "url": "https://github.com/mattias-lw" + }, + { + "name": "Matt Robenolt", + "email": "m@robenolt.com", + "url": "https://github.com/mattrobenolt" + }, + { + "name": "Matt Smith", + "email": "matt@twobitfool.com", + "url": "https://github.com/twobitfool" + }, + { + "name": "Max Goodman", + "email": "c@chromako.de", + "url": "https://github.com/chromakode" + }, + { + "name": "Maximilian Antoni", + "email": "mail@maxantoni.de", + "url": "https://github.com/mantoni" + }, + { + "name": "Merrick Christensen", + "email": "merrick.christensen@gmail.com", + "url": "https://github.com/iammerrick" + }, + { + "name": "michael-adsk", + "url": "https://github.com/michael-adsk" + }, + { + "name": "Michael Demmer", + "url": "https://github.com/demmer" + }, + { + "name": "Michael Jackson", + "email": "mjijackson@gmail.com", + "url": "https://github.com/mjackson" + }, + { + "name": "Michael Schoonmaker", + "email": "michael.r.schoonmaker@gmail.com", + "url": "https://github.com/Schoonology" + }, + { + "name": "Michal Charemza", + "url": "https://github.com/michalc" + }, + { + "name": "Mike Olson", + "url": "https://github.com/mwolson" + }, + { + "name": "Mislav Marohnić", + "email": "mislav.marohnic@gmail.com", + "url": "https://github.com/mislav" + }, + { + "name": "mrShturman", + "url": "https://github.com/mrShturman" + }, + { + "name": "Nathan Alderson", + "email": "nathan@nathanalderson.com", + "url": "https://github.com/nathanalderson" + }, + { + "name": "Nathan Black", + "email": "nathan@nathanblack.org", + "url": "https://github.com/nathanboktae" + }, + { + "name": "Nathan Bowser", + "email": "nbowser@gmail.com", + "url": "https://github.com/nathanbowser" + }, + { + "name": "Nathan Houle", + "email": "nathan+github@nathanhoule.com", + "url": "https://github.com/ndhoule" + }, + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net", + "url": "https://github.com/TooTallNate" + }, + { + "name": "Nick Fitzgerald", + "url": "https://github.com/fitzgen" + }, + { + "name": "noirlab", + "url": "https://github.com/noirlab" + }, + { + "name": "Noshir Patel", + "email": "nosh@blackpiano.com", + "url": "https://github.com/noshir-patel" + }, + { + "name": "OlegTsyba", + "email": "oleg.tsyba.ua@gmail.com", + "url": "https://github.com/OlegTsyba" + }, + { + "name": "omar", + "url": "https://github.com/omardelarosa" + }, + { + "name": "Panu Horsmalahti", + "email": "panu.horsmalahti@iki.fi", + "url": "https://github.com/panuhorsmalahti" + }, + { + "name": "Parker Moore", + "email": "email@byparker.com", + "url": "https://github.com/parkr" + }, + { + "name": "Paul Armstrong", + "url": "https://github.com/paularmstrong" + }, + { + "name": "Paul Miller", + "email": "paul+gh@paulmillr.com", + "url": "https://github.com/paulmillr" + }, + { + "name": "Pavel Zubkou", + "url": "https://github.com/irnc" + }, + { + "name": "Pete Hawkins", + "url": "https://github.com/phawk" + }, + { + "name": "Phil Sung", + "email": "philbert@gmail.com", + "url": "https://github.com/psung" + }, + { + "name": "Prayag Verma", + "email": "prayag.verma@gmail.com", + "url": "https://github.com/pra85" + }, + { + "name": "qiu zuhui", + "email": "qiuzuhui@gmail.com", + "url": "https://github.com/qiuzuhui" + }, + { + "name": "Quang Van", + "email": "quang@boldapps.io", + "url": "https://github.com/quangv" + }, + { + "name": "Rauno", + "url": "https://github.com/Rauno56" + }, + { + "name": "Refael Ackermann", + "email": "me@refack.com", + "url": "https://github.com/refack" + }, + { + "name": "Richard Dingwall", + "email": "rdingwall@gmail.com", + "url": "https://github.com/rdingwall" + }, + { + "name": "Richard Knop", + "url": "https://github.com/RichardKnop" + }, + { + "name": "Rico Sta. Cruz", + "email": "hi@ricostacruz.com", + "url": "https://github.com/rstacruz" + }, + { + "name": "Robert Rossmann", + "url": "https://github.com/Alaneor" + }, + { + "name": "Rob Wu", + "email": "rob@robwu.nl", + "url": "https://github.com/Rob--W" + }, + { + "name": "Romain", + "url": "https://github.com/rprieto" + }, + { + "name": "Roman Neuhauser", + "email": "rneuhauser@sigpipe.cz", + "url": "https://github.com/roman-neuhauser" + }, + { + "name": "Roman Shtylman", + "url": "https://github.com/defunctzombie" + }, + { + "name": "Russ Bradberry", + "email": "devdazed@me.com", + "url": "https://github.com/devdazed" + }, + { + "name": "Russell Munson", + "url": "https://github.com/rmunson" + }, + { + "name": "Ryan", + "email": "ryan.shaw@min.vc", + "url": "https://github.com/ryan-shaw" + }, + { + "name": "Ryan Hubbard", + "url": "https://github.com/ryedog" + }, + { + "name": "Ryunosuke Sato", + "email": "tricknotes.rs@gmail.com", + "url": "https://github.com/tricknotes" + }, + { + "name": "ryym", + "url": "https://github.com/ryym" + }, + { + "name": "Salehen Shovon Rahman", + "email": "sal@linux.com", + "url": "https://github.com/shovon" + }, + { + "name": "Salvador de la Puente González", + "email": "salva@unoyunodiez.com", + "url": "https://github.com/delapuente" + }, + { + "name": "Sam Mussell", + "url": "https://github.com/smussell" + }, + { + "name": "Samuel Goldszmidt", + "email": "samuel.goldszmidt@gmail.com", + "url": "https://github.com/ouhouhsami" + }, + { + "name": "Sasha Koss", + "email": "kossnocorp@gmail.com", + "url": "https://github.com/kossnocorp" + }, + { + "name": "Scott Santucci", + "email": "ScottFreeCode@gmail.com", + "url": "https://github.com/ScottFreeCode" + }, + { + "name": "Sean Lang", + "email": "slang800@gmail.com", + "url": "https://github.com/slang800" + }, + { + "name": "seb vincent", + "email": "seb.vincent@gmail.com", + "url": "https://github.com/sebv" + }, + { + "name": "Seiya Konno", + "email": "nulltask@gmail.com", + "url": "https://github.com/nulltask" + }, + { + "name": "Sergey Simonchik", + "url": "https://github.com/segrey" + }, + { + "name": "Sergio Santoro", + "url": "https://github.com/taueres" + }, + { + "name": "Shahar Soel", + "url": "https://github.com/bd82" + }, + { + "name": "Shaine Hatch", + "url": "https://github.com/shaine" + }, + { + "name": "Shiwei Wang", + "url": "https://github.com/wsw0108" + }, + { + "name": "Simon Gaeremynck", + "url": "https://github.com/simong" + }, + { + "name": "Simon Goumaz", + "url": "https://github.com/sgoumaz" + }, + { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "https://github.com/sindresorhus" + }, + { + "name": "slientcloud", + "email": "rjmuqiang@gmail.com", + "url": "https://github.com/silentcloud" + }, + { + "name": "Sorin Iclanzan", + "url": "https://github.com/iclanzan" + }, + { + "name": "Standa Opichal", + "email": "opichals@gmail.com", + "url": "https://github.com/opichals" + }, + { + "name": "Stephen Mathieson", + "email": "me@stephenmathieson.com", + "url": "https://github.com/stephenmathieson" + }, + { + "name": "Steve Mason", + "url": "https://github.com/spmason" + }, + { + "name": "Stewart Taylor", + "email": "stewart@taylore.net", + "url": "https://github.com/Stewart-Taylor" + }, + { + "name": "Sune Simonsen", + "email": "sune@we-knowhow.dk", + "url": "https://github.com/sunesimonsen" + }, + { + "name": "Sylvain Faucherand", + "url": "https://github.com/slyg" + }, + { + "name": "Takuya Nishigori", + "email": "nishigori.tak@gmail.com", + "url": "https://github.com/nishigori" + }, + { + "name": "Taylor Gautier", + "url": "https://github.com/tsgautier" + }, + { + "name": "Teddy Zeenny", + "url": "https://github.com/teddyzeenny" + }, + { + "name": "Thomas Grainger", + "email": "https//@graingert.co.uk", + "url": "https://github.com/graingert" + }, + { + "name": "Tim Ehat", + "url": "https://github.com/timehat" + }, + { + "name": "Timothy Gu", + "email": "timothygu99@gmail.com", + "url": "https://github.com/TimothyGu" + }, + { + "name": "Timo Tijhof", + "email": "krinklemail@gmail.com", + "url": "https://github.com/Krinkle" + }, + { + "name": "Tingan Ho", + "email": "tingan87@gmail.com", + "url": "https://github.com/tinganho" + }, + { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca", + "url": "https://github.com/tj" + }, + { + "name": "Tobias Bieniek", + "email": "tobias.bieniek@gmail.com", + "url": "https://github.com/Turbo87" + }, + { + "name": "Toby Ho", + "email": "airportyh@gmail.com", + "url": "https://github.com/airportyh" + }, + { + "name": "Todd Agulnick", + "url": "https://github.com/tawdle" + }, + { + "name": "Tom Hughes", + "url": "https://github.com/tomhughes" + }, + { + "name": "Tommy Montgomery", + "url": "https://github.com/tmont" + }, + { + "name": "traleig1", + "url": "https://github.com/traleig1" + }, + { + "name": "Travis Jeffery", + "email": "tj@travisjeffery.com", + "url": "https://github.com/travisjeffery" + }, + { + "name": "Tyson Tate", + "email": "tyson@tysontate.com", + "url": "https://github.com/tysontate" + }, + { + "name": "Valentin Agachi", + "url": "https://github.com/avaly" + }, + { + "name": "Victor Costan", + "email": "victor@costan.us", + "url": "https://github.com/pwnall" + }, + { + "name": "Vladimir Chernis", + "url": "https://github.com/vlazzle" + }, + { + "name": "Vlad Magdalin", + "email": "vlad@webflow.com", + "url": "https://github.com/callmevlad" + }, + { + "name": "Will Langstroth", + "url": "https://github.com/wlangstroth" + }, + { + "name": "Wil Moore III", + "email": "wil.moore@wilmoore.com", + "url": "https://github.com/wilmoore" + }, + { + "name": "Xavier Antoviaque", + "email": "xavier@opencraft.com", + "url": "https://github.com/antoviaque" + }, + { + "name": "Xavier Damman", + "email": "xdamman@gmail.com", + "url": "https://github.com/xdamman" + }, + { + "name": "Yanis Wang", + "email": "yanis.wang@gmail.com", + "url": "https://github.com/yaniswang" + }, + { + "name": "yuitest", + "email": "developer.yuitest+github@cjhat.net", + "url": "https://github.com/yuitest" + }, + { + "name": "Zhiye Li", + "email": "github@zhiye.li", + "url": "https://github.com/zhiyelee" + }, + { + "name": "Zhouxuan Yang", + "email": "fool2fish@gmail.com", + "url": "https://github.com/fool2fish" + }, + { + "name": "Zsolt Takács", + "email": "firstname at lastname dot cc", + "url": "https://github.com/oker1" + } + ], + "dependencies": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.5", + "glob": "7.0.5", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "description": "simple, flexible, fun test framework", + "devDependencies": { + "assert": "^1.4.1", + "browserify": "^13.0.0", + "coffee-script": "^1.10.0", + "eslint": "^2.13.1", + "eslint-config-semistandard": "^6.0.2", + "eslint-config-standard": "^5.0.0", + "eslint-plugin-promise": "^2.0.1", + "eslint-plugin-standard": "1.3.2", + "expect.js": "^0.3.1", + "karma": "^1.1.0", + "karma-browserify": "^5.0.5", + "karma-chrome-launcher": "^2.0.0", + "karma-expect": "^1.1.2", + "karma-mocha": "^1.3.0", + "karma-phantomjs-launcher": "^0.2.3", + "karma-sauce-launcher": "^1.0.0", + "karma-spec-reporter": "0.0.26", + "os-name": "^2.0.1", + "phantomjs": "1.9.8", + "rimraf": "^2.5.2", + "should": "^9.0.2", + "through2": "^2.0.1", + "watchify": "^3.7.0" + }, + "directories": {}, + "dist": { + "shasum": "7dc4f45e5088075171a68896814e6ae9eb7a85e3", + "tarball": "https://registry.npmjs.org/mocha/-/mocha-3.2.0.tgz" + }, + "engines": { + "node": ">= 0.10.x", + "npm": ">= 1.4.x" + }, + "files": [ + "bin", + "images", + "lib", + "index.js", + "mocha.css", + "mocha.js", + "browser-entry.js", + "LICENSE", + "bower.json" + ], + "gitHead": "b51e36014d9c6db07aee3057579c35315ec4efd7", + "homepage": "https://mochajs.org", + "keywords": [ + "mocha", + "test", + "bdd", + "tdd", + "tap" + ], + "license": "MIT", + "logo": "https://cldup.com/S9uQ-cOLYz.svg", + "maintainers": [ + { + "name": "boneskull", + "email": "boneskull@boneskull.com" + }, + { + "name": "dasilvacontin", + "email": "dasilvacontin@gmail.com" + } + ], + "name": "mocha", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mochajs/mocha.git" + }, + "scripts": { + "test": "make test" + }, + "version": "3.2.0" +} diff --git a/support/lobby/.eslintignore b/support/lobby/.eslintignore new file mode 100644 index 000000000..796699b60 --- /dev/null +++ b/support/lobby/.eslintignore @@ -0,0 +1,4 @@ +node_modules/ +doc/ +test/ +*.bundle.* diff --git a/support/lobby/.eslintrc.json b/support/lobby/.eslintrc.json new file mode 100644 index 000000000..e49643ce3 --- /dev/null +++ b/support/lobby/.eslintrc.json @@ -0,0 +1,27 @@ +{ + "env": { + "es6": true, + "browser": true + }, + "parser": + "babel-eslint", + "parserOptions": { + "sourceType": + "module", + "ecmaFeatures": { + "jsx": true + } + }, + "plugins": [ + "react" + ], + "extends": [ + "eslint:recommended", + "plugin:react/recommended" + ], + "rules": { + "no-console": "warn", + "no-unused-vars": [ "warn", { "args": "none" } ], + "react/prop-types": "warn" + } +} diff --git a/support/lobby/.gitignore b/support/lobby/.gitignore new file mode 100644 index 000000000..0b059813a --- /dev/null +++ b/support/lobby/.gitignore @@ -0,0 +1,3 @@ +/node_modules/ +/doc/ +*.bundle.* diff --git a/support/lobby/.jsdoc.json b/support/lobby/.jsdoc.json new file mode 100644 index 000000000..078380709 --- /dev/null +++ b/support/lobby/.jsdoc.json @@ -0,0 +1,21 @@ +{ + "source": { + "include": + ".", + "exclude": [ + "node_modules", + "doc", + "test" + ], + "excludePattern": + "\\.bundle(\\.min)?\\.js" + }, + "opts": { + "destination": "doc", + "recurse": true + }, + "plugins": [ + "plugins/commentConvert", + "plugins/markdown" + ] +} diff --git a/support/lobby/.webpack.base.js b/support/lobby/.webpack.base.js new file mode 100644 index 000000000..86d53f6f7 --- /dev/null +++ b/support/lobby/.webpack.base.js @@ -0,0 +1,40 @@ +"use strict"; + +const path = require( "path" ), + ExtractText = require( "extract-text-webpack-plugin" ); + +module.exports = { + context: + path.resolve( __dirname ), + entry: { + index: [ "./index.js", "./index.css" ], + login: [ "./login.js", "./login.css" ], + }, + output: { + path: path.resolve( __dirname ), + filename: "[name].bundle.js", + }, + devtool: + "source-map", + module: { + rules: [ { + test: + /\.js$/, + exclude: + /node_modules/, + loader: + "babel-loader", + options: { + presets: [ "env", "react", "stage-2" ], + }, + }, { + test: + /\.css$/, + use: + ExtractText.extract( { fallback: "style-loader", use: "css-loader" } ), + } ] + }, + plugins: [ + new ExtractText( { filename: "[name].bundle.css" } ), + ] +}; diff --git a/support/lobby/.webpack.dev.js b/support/lobby/.webpack.dev.js new file mode 100644 index 000000000..27f23d29a --- /dev/null +++ b/support/lobby/.webpack.dev.js @@ -0,0 +1,8 @@ +"use strict"; + +const webpack = require( "webpack" ), + merge = require( "webpack-merge" ); + +const base = require( "./.webpack.base.js" ); + +module.exports = merge( base, {} ); diff --git a/support/lobby/.webpack.prod.js b/support/lobby/.webpack.prod.js new file mode 100644 index 000000000..779079dd5 --- /dev/null +++ b/support/lobby/.webpack.prod.js @@ -0,0 +1,17 @@ +"use strict"; + +const webpack = require( "webpack" ), + uglify = require( "uglifyjs-webpack-plugin" ), + merge = require( "webpack-merge" ); + +const base = require( "./.webpack.base.js" ); + +module.exports = merge( base, { + output: { + filename: "[name].bundle.min.js", + }, + plugins: [ + new webpack.DefinePlugin( { "process.env.NODE_ENV": JSON.stringify( "production" ) } ), + new uglify( { sourceMap: true } ), + ], +} ); diff --git a/support/lobby/ONR_Logo.jpg b/support/lobby/ONR_Logo.jpg new file mode 100644 index 000000000..97f9c4efc Binary files /dev/null and b/support/lobby/ONR_Logo.jpg differ diff --git a/support/lobby/index.css b/support/lobby/index.css new file mode 100644 index 000000000..a59b69b93 --- /dev/null +++ b/support/lobby/index.css @@ -0,0 +1,2 @@ +@import url('node_modules/react-table/react-table.css'); +@import url('lib/layout.css'); diff --git a/support/lobby/index.html b/support/lobby/index.html new file mode 100644 index 000000000..1b9b73e7e --- /dev/null +++ b/support/lobby/index.html @@ -0,0 +1,21 @@ + + + + + + + + + Virtual World Framework lobby + + + + + + + +
      + + + + diff --git a/support/lobby/index.js b/support/lobby/index.js new file mode 100644 index 000000000..5301a4b98 --- /dev/null +++ b/support/lobby/index.js @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom"; + +import Layout from "./lib/Layout"; + +ReactDOM.render( + , + document.getElementById( "root" ) +); diff --git a/support/lobby/lib/ActiveSessions.js b/support/lobby/lib/ActiveSessions.js new file mode 100644 index 000000000..75a648db4 --- /dev/null +++ b/support/lobby/lib/ActiveSessions.js @@ -0,0 +1,155 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Button } from "react-bootstrap"; +import ReactTable from "react-table"; + +export default function ActiveSessions( props ) { + return ( + { + return row[ filter.id ] !== undefined ? + String( row[ filter.id ] ).toLowerCase().indexOf( filter.value.toLowerCase() ) >= 0 : true + } } /> + ); +} + +ActiveSessions.propTypes = { + records: + PropTypes.arrayOf( PropTypes.object ).isRequired, +}; + +const columns = [ { + Header: + "Scenario", + id: + "session.state.scenarioTitle", + accessor: + session => session, + Cell: + function Cell( props ) { return }, + filterMethod: + function( filter, row, column ) { + return row[ filter.id ] !== undefined ? + String( row[ filter.id ].state.scenarioTitle ).toLowerCase().indexOf( filter.value.toLowerCase() ) >= 0 : true; + }, + Filter: + function Filter( props ) { return }, +}, { + Header: + "Company", + accessor: + "state.classroom.company", +}, { + Header: + "Platoon", + accessor: + "state.classroom.platoon", +}, { + Header: + "Unit", + accessor: + "state.classroom.unit", +}, { + Header: + "", + id: + "blank", + accessor: + session => "", + sortable: + false, + filterable: + false, +}, { + Header: + "", + id: + "action", + accessor: + session => session, + Cell: + function Cell( props ) { return }, + sortable: + false, + filterable: + false, +} ]; + +class ScenarioFilter extends React.Component { + + static propTypes = { + filter: + PropTypes.object, + onChange: + PropTypes.func.isRequired, + }; + + render() { + return this.props.onChange( event.target.value ) } />; + } + +} + +class ScenarioCell extends React.Component { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + return + { this.props.value.state.scenarioTitle } +
      + { instructorStudentsLabel( this.props.value ) } +
      ; + } + +} + +class ActionCell extends React.Component { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + return ; + } + +} + +// Generate the Instructor/Students annotation for a session. + +function instructorStudentsLabel( session ) { + + var instanceCounts = session.completion.instance || { instructors: 0, students: 0 }, + label = ""; + + if ( instanceCounts.instructors > 0 || instanceCounts.students > 0 ) { + + if ( instanceCounts.instructors > 0 ) { + label += "Instructor, "; + } + + if ( instanceCounts.students === 1 ) { + label += instanceCounts.students + " student"; + } else { + label += instanceCounts.students + " students"; + } + + } + + return label; + +} diff --git a/support/lobby/lib/Layout.js b/support/lobby/lib/Layout.js new file mode 100644 index 000000000..cc7b5524b --- /dev/null +++ b/support/lobby/lib/Layout.js @@ -0,0 +1,179 @@ +import React from "react"; +import { TabContainer, Navbar, Image, Nav, NavItem, TabContent, TabPane, Button } from "react-bootstrap"; +import _ from "lodash"; + +import "./LobbyTR"; +import Scenarios from "./Scenarios"; +import ActiveSessions from "./ActiveSessions"; +import PreviousSessions from "./PreviousSessions"; +import { get } from "./utils"; + +export default class Layout extends React.Component { + + state = { + version: null, + user: null, + manifest: null, + }; + + render() { + if ( this.state.version && this.state.user && this.state.manifest ) { + return type + "-" + key } + > +
      + + + + + + + + { this.state.version.title } + + + + + + + + + + { + ( this.state.user.last_name || "" ) + ( this.state.user.last_name && ( this.state.user.first_name || this.state.user.middle_initial ) ? ", " : "" ) + + ( this.state.user.first_name || "" ) + ( this.state.user.first_name && this.state.user.middle_initial ? " " : "" ) + + ( this.state.user.middle_initial || "" ) + ( this.state.user.middle_initial ? "." : "" ) + } + + + + + { this.state.user.instructor && + + } + { true && + + + + } + { this.state.user.instructor && + + } + +
      +
      ; + } else { + return null; + } + } + + + componentDidMount() { + this.handleVersion(); + this.handleUser(); + this.handleManifest(); + } + + handleVersion = () => { + get( "version" ). + then( version => + this.setState( { version: version || {} } ) ). + catch( error => + console.log( error.message ) ); /* eslint no-console: "off" */ + } + + handleUser = () => { + get( "user" ). + then( user => + this.setState( { user: user || {} } ) ). + catch( error => + console.log( error.message ) ); /* eslint no-console: "off" */ + } + + handleManifest = () => { + get( "manifest" ). + then( manifest => + this.setState( { manifest: manifest || {} } ) ). + catch( error => + console.log( error.message ) ); /* eslint no-console: "off" */ + } + + scenarioRecords() { + const scenarios = this.state.manifest[ "/ITDG/index.vwf" ] || {}; + const sortedScenariosArray = + _.map( _.sortBy( _.toPairs( scenarios ), function( [ name, scenario ] ) { + return name.toLowerCase(); + } ), 1 ); + return sortedScenariosArray.filter( function( scenario ) { + return scenario.scenario.document; + } ); + } + + activeSessionRecords() { + return this.scenarioRecords().reduce( function( allActiveSessions, scenario ) { + var activeSessions = ( scenario.sessions || [] ).filter( function( session ) { + return session.instance && !session.completion.instance.isReview; + } ).sort( sessionComparator ); + return allActiveSessions.concat( activeSessions ); + }, [] ); + } + + previousSessionRecords() { + return this.scenarioRecords().reduce( function( allPreviousSessions, scenario ) { + var previousSessions = ( scenario.sessions || [] ).filter( function( session ) { + return !session.instance; + } ); + return allPreviousSessions.concat( previousSessions ); + }, [] ).sort( function( a, b ) { + return b.document.timestamp - a.document.timestamp; + } ); + } + +} + +/// `Array#sort` comparison function to sort sessions by company, then platoon, then unit. + +function sessionComparator( sessionA, sessionB ) { + + var stateA = sessionA.state || {}, + classroomA = stateA.classroom || {}, + companyA = ( classroomA.company || "" ).toLowerCase(), + platoonA = Number( classroomA.platoon ), + unitA = Number( classroomA.unit ); + + var stateB = sessionB.state || {}, + classroomB = stateB.classroom || {}, + companyB = ( classroomB.company || "" ).toLowerCase(), + platoonB = Number( classroomB.platoon ), + unitB = Number( classroomB.unit ); + + if ( companyA < companyB ) { + return -1; + } else if ( companyA > companyB ) { + return 1; + } + + if ( platoonA < platoonB ) { + return -1; + } else if ( platoonA > platoonB ) { + return 1; + } + + if ( unitA < unitB ) { + return -1; + } else if ( unitA > unitB ) { + return 1; + } + + return 0; + +} diff --git a/support/lobby/lib/LobbyTR.js b/support/lobby/lib/LobbyTR.js new file mode 100644 index 000000000..8654f15c9 --- /dev/null +++ b/support/lobby/lib/LobbyTR.js @@ -0,0 +1,61 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { ReactTableDefaults } from "react-table"; +import _ from "lodash"; + +let BaseTR = ReactTableDefaults.TrComponent; + +class LobbyTR extends React.Component { + + static propTypes = { + fields: + PropTypes.arrayOf( PropTypes.string ).isRequired, + readers: + PropTypes.objectOf( PropTypes.func ).isRequired, + writers: + PropTypes.objectOf( PropTypes.func ).isRequired, + }; + + static defaultProps = { + fields: [], + readers: {}, + writers: {}, + }; + + state = { + values: + _.zipObject( this.props.fields, this.props.fields.map( field => "" ) ) + }; + + static childContextTypes = { + values: + PropTypes.objectOf( PropTypes.string ).isRequired, + readers: + PropTypes.objectOf( PropTypes.func ).isRequired, + writers: + PropTypes.objectOf( PropTypes.func ).isRequired, + }; + + getChildContext() { + return { + values: + this.state.values, + readers: + _.mapValues( this.props.readers, reader => + () => reader( this.state.values ) ), + writers: + _.mapValues( this.props.writers, writer => + ( ...args ) => { + let values = writer( ...args ); + this.setState( prevState => ( { values: _.assign( prevState.values, values ) } ) ) + } ), + }; + } + + render() { + return ; + } + +} + +ReactTableDefaults.TrComponent = LobbyTR; diff --git a/support/lobby/lib/Login.js b/support/lobby/lib/Login.js new file mode 100644 index 000000000..6dde0bf64 --- /dev/null +++ b/support/lobby/lib/Login.js @@ -0,0 +1,217 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Modal, Form, FormGroup, FormControl, Checkbox, ControlLabel, Image, Row, Fade, Alert } from "react-bootstrap"; + +import { get } from "./utils"; + +const navy = '#000080'; +const medBlue = '#0000CD'; + +export default class Login extends React.Component { + + constructor(props) { + super(props); + this.state = { + lastName: "", + firstName: "", + middleInitial: "", + instructor: false, + version: null, + instructorBtn:false, + studentBtn: false, + password: false, + firstColor: navy, + secondColor: navy, + }; + this.changeColor = this.changeColor.bind(this); + } + + static propTypes = { + flash: + PropTypes.arrayOf( PropTypes.object ).isRequired, + }; + + static defaultProps = { + flash: [] + }; + +//Changes the color of the button + +changeColor(isStudent){ + if(isStudent){ + this.setState({secondColor: medBlue}); + this.setState({firstColor: navy}); + } + else{ + this.setState({secondColor: navy}); + this.setState({firstColor: medBlue}); + } +} + + instructorClick(){ + + this.setInstructor(true); + this.changeColor(false); + } + + +setInstructor(isInstructor){ + if(isInstructor){ + this.setState({studentBtn: false}); + this.setState({instructorBtn: true}); + this.setState( { instructor: true} ); + + + } + +} + + + studentClick(){ + this.setStudent(true); + this.changeColor(true); + } + + +setStudent(isStudent){ + if(isStudent){ + this.setState({instructorBtn: false}); + this.setState({instructor: false}); + this.setState({studentBtn: true}); + + } +} + + + + render() { + if ( this.state.version ) { + return +
      + + + +

      { this.state.version.title }

      +
      + + + +
      +
      + + + {/*Row 1*/} + + {/*Instructor*/} + + + + {/*Student*/} + + + + + + {/*Row 2*/} + + + {/*Textfield appears when either instructor or student btn is clicked*/} + + +
      + + Last name + + + + First name + + + + M. I. + + +
      +
      +
      + +
      + + + {/*Row 3*/} + + {/*Password textfield appears once instructor btn is clicked*/} + + + + Password + + + + + + + + +   + + + Instructor + + + + + + +
      + + + + + + + +
      +
      ; + + + }else { + return null; + } + +} + //Checks the value in the textfields + + componentDidMount() { + this.handleVersion(); + } + + handleLastName = event => { + this.setState( { lastName: event.target.value } ); + } + + handleFirstName = event => { + this.setState( { firstName: event.target.value } ); + } + + handleMiddleInitial = event => { + this.setState( { middleInitial: event.target.value } ); + } + + handleInstructor = event => { + this.setState( { instructor: true} ); + } + + + handleVersion = () => { + get( "version" ). + then( version => + this.setState( { version: version || {} } ) ). + catch( error => + console.log( "Not working" ) ); /* eslint no-console: "off" */ + } + +} + +/// Convert an Express flash `type` to a Bootstrap alert style. + diff --git a/support/lobby/lib/PreviousSessions.js b/support/lobby/lib/PreviousSessions.js new file mode 100644 index 000000000..46afa2977 --- /dev/null +++ b/support/lobby/lib/PreviousSessions.js @@ -0,0 +1,195 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Button } from "react-bootstrap"; +import ReactTable from "react-table"; +import dateFormat from "dateformat"; + +export default function PreviousSessions( props ) { + return { + return row[ filter.id ] !== undefined ? + String( row[ filter.id ] ).toLowerCase().indexOf( filter.value.toLowerCase() ) >= 0 : true + } } + />; +} + +PreviousSessions.propTypes = { + records: + PropTypes.arrayOf( PropTypes.object ).isRequired, +}; + +const columns = [ { + Header: + "Scenario", + accessor: + "state.scenarioTitle", + Cell: + function Cell( props ) { return + }, + Filter: + function Filter( props ) { return + }, +}, { + Header: + "Company", + accessor: + "state.classroom.company", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "Platoon", + accessor: + "state.classroom.platoon", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "Unit", + accessor: + "state.classroom.unit", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "Date", + accessor: + "document.timestamp", + Cell: + function Cell( props ) { return + }, + filterable: + false, + width: + 190, +}, { + Header: + "", + id: + "action", + accessor: + session => session, + Cell: + function Cell( props ) { return + }, + sortable: + false, + filterable: + false, +}, { + Header: + "", + id: + "action", + accessor: + session => session, + Cell: + function Cell( props ) { return + }, + sortable: + false, + filterable: + false, +} ]; + +const buttonContainerStyle = { + width: "100%", + textAlign: "center" +} + +class ScenarioFilter extends React.Component { + + static propTypes = { + filter: + PropTypes.object, + onChange: + PropTypes.func.isRequired, + }; + + render() { + return this.props.onChange( event.target.value ) } />; + } + +} + +class TextCell extends React.Component { + + static propTypes = { + value: + PropTypes.string.isRequired, + }; + + render() { + return ( +
      + { this.props.value } +
      + ); + } + +} + +class DateCell extends React.Component { + + static propTypes = { + value: + PropTypes.string.isRequired, + }; + + render() { + return ; + } + +} + +class ReviewCell extends React.Component { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + const url = + ( this.props.value.instance || this.props.value.document.uri ) + "?isReview=true"; + return ( +
      + +
      + ); + } + +} + +class ResumeCell extends React.Component { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + return ( +
      + +
      + ); + } + +} \ No newline at end of file diff --git a/support/lobby/lib/Scenarios.js b/support/lobby/lib/Scenarios.js new file mode 100644 index 000000000..ca93c1aea --- /dev/null +++ b/support/lobby/lib/Scenarios.js @@ -0,0 +1,427 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Table, FormControl, Button, ControlLabel, Checkbox } from "react-bootstrap"; +import ReactTable from "react-table"; + +import { post } from "./utils"; + +let COMPANY_LENGTH = 8; +let PLATOON_MIN = 1; +let PLATOON_MAX = 9; +let UNIT_MIN = 1; +let UNIT_MAX = 9; + +export default function Scenarios( props ) { + return + + + + +
      + ( { + fields: + [ "company", "platoon", "unit" ], + readers: { + filled: + values => values.company.length > 0 && values.platoon.length > 0 && values.unit.length > 0 }, + writers: { + company: + event => ( { company: event.target.value } ), + platoon: + event => ( { platoon: event.target.value } ), + unit: + event => ( { unit: event.target.value } ) }, + } ) } + getTdProps={ () => ( { + onServerChange: props.onServerChange + } ) } + defaultFilterMethod={ ( filter, row, column ) => { + return row[ filter.id ] !== undefined ? + String( row[ filter.id ] ).toLowerCase().indexOf( filter.value.toLowerCase() ) >= 0 : true + } } + /> +
      ; +} + + +Scenarios.propTypes = { + records: + PropTypes.arrayOf( PropTypes.object ).isRequired, + onServerChange: + PropTypes.func, +}; + +class Application extends React.Component { + + static TITLE_PLACEHOLDER = "New Scenario Title"; + + static propTypes = { + onServerChange: + PropTypes.func, + }; + + state = { + title: "", + isClicked : false, + buttonOn: true, + }; + + //Function called when Create Scenario button is clicked + createScenario(){ + this.isCreating(true); + } + + isCreating(value){ + if(value){ + this.setState({isClicked: true}); + this.setState({buttonOn: false}); + } + } + + + render() { + return + + + {/*Click on button to make create info pop up*/} + + + {/*will not appear until create button is clicked*/} + + + + + + + + + + + + + Import + + + + {/*X out button to cancel out if you do not want to create scenario*/} + + + + + ; + + } + + handleTitle = event => { + this.setState( { title: event.target.value } ); + } + + //closes create info upon clicking 'create' button and leads to new page + handleSubmit = event => { + + this.setState({isClicked: false}); + this.setState({buttonOn: true}); + let properties = { + name: this.name(), + title: this.state.title }; + let newTab = window.open("", "_blank"); + newTab.document.write("Loading..."); + post( "scenarios", properties ). + then( result => { + newTab.location.href = result.document.uri + "/"; + this.props.onServerChange && this.props.onServerChange() } ). + catch( error => { + console.log( error.message ) } ); /* eslint no-console: "off" */ + this.setState( { title: "" } ); + event.preventDefault(); + + } + + + removeScenario(){ + this.notCreating(true); + } + + notCreating(value){ + if(value){ + this.setState({isClicked: false}); + this.setState({buttonOn: true}); + this.setState({title: ""}); + + } + } + + + + handleKeyPress = event => { + if ( event.key === "Enter" ) { + this.handleSubmit( event ); + } + } + + handleImport = event => { + let file = event.target.files && + event.target.files[0]; + if ( file ) { + let formData = new FormData(); + formData.append( "file", file ); + post( "/import-scenarios", formData ). + then( result => { + this.props.onServerChange && this.props.onServerChange() } ). + catch( error => { + alert( "Uh oh ... we were unable to upload that file for import.\n" + error.message ) } ); + } + } + + name() { + return this.state.title.trim().replace( /[^0-9A-Za-z]+/g, "-" ); + } + + filled() { + return this.state.title.length > 0; + } + + + + +} + +const columns = [ + { + Header: + "Scenario", + accessor: + "scenario.state.scenarioTitle", + Filter: + function Filter( props ) { return + }, +}, + + +{ + Header: + "Company", + id: + "company", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "Platoon", + id: + "platoon", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "Unit", + id: + "unit", + Cell: + function Cell( props ) { return + }, +}, { + Header: + "", + accessor: + "scenario.state.scenarioName", + Cell: + function Cell( props ) { return + }, + sortable: + false, + filterable: + false, +}, { + Header: + "", + id: + "action", + accessor: + "scenario", + Cell: + function Cell( props ) { return + }, + sortable: + false, + filterable: + false, +},{ + Header: + "", + id: + "export", + accessor: + "scenario", + Cell: + function Cell( props ) { return + }, + sortable: + false, + filterable: + false, +} ]; + +class ScenarioFilter extends React.Component { + + static propTypes = { + filter: + PropTypes.object, + onChange: + PropTypes.func.isRequired, + }; + + render() { + return this.props.onChange( event.target.value ) } />; + } + +} + + + + +class LobbyCell extends React.Component { + static contextTypes = { + values: + PropTypes.objectOf( PropTypes.string ).isRequired, + readers: + PropTypes.objectOf( PropTypes.func ).isRequired, + writers: + PropTypes.objectOf( PropTypes.func ).isRequired, + }; +} + +class CompanyCell extends LobbyCell { + render() { + return ; + } +} + +class PlatoonCell extends LobbyCell { + render() { + return ; + } +} + +class UnitCell extends LobbyCell { + render() { + return ; + } +} + +class ActionCell extends LobbyCell { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + return + + + + ; + } + + handleSubmit = event => { + let properties = { + name: this.props.value.state.scenarioName, + company: this.context.values.company, + platoon: this.context.values.platoon, + unit: this.context.values.unit }; + let newTab = window.open( "", "_blank" ); + newTab.document.write( "Loading..." ); + post( "sessions", properties ). + then( result => { + newTab.location.href = result.document.uri + "/"; + this.props.tdProps.rest.onServerChange && this.props.tdProps.rest.onServerChange() } ). + catch( error => { + console.log( error.message ) } ); /* eslint no-console: "off" */ + event.preventDefault(); + } + +} + +//class DeleteCell extends React.Component{ +// +// static propTypes = { +// value: +// PropTypes.object.isRequired, +// }; +// state = { +// check: false, +// } +// +// render() { +// return +// +// +// ; +// } +// +// handleChange = event => { +// this.setState({check: event.target.checked}); +// } +// +// +//} + + + + + +class HiddenCell extends React.Component { + + static propTypes = { + value: + PropTypes.string.isRequired, + }; + + render() { + return ; + } + +} + +class ExportCell extends React.Component { + + static propTypes = { + value: + PropTypes.object.isRequired, + }; + + render() { + return ; + } + +} diff --git a/support/lobby/lib/layout.css b/support/lobby/lib/layout.css new file mode 100644 index 000000000..1667f6ceb --- /dev/null +++ b/support/lobby/lib/layout.css @@ -0,0 +1,36 @@ +body { + padding-top: 20px; + padding-bottom: 20px; +} + +.navbar { + margin-bottom: 20px; +} + +table { + width: 100%; + max-width: 100%; + table-layout: auto; +} + + +tbody { + display: table-row-group; + height: 100%; + overflow-y: auto; + table-layout: auto; +} + +tr { display: table-row; table-layout: auto;} +td { display: table-cell;} + +.logo_img { + width: 100%; + height: auto; +} + +.logo_img_small { + width: 60px; + height: auto; +} + diff --git a/support/lobby/lib/utils.js b/support/lobby/lib/utils.js new file mode 100644 index 000000000..637d77bf2 --- /dev/null +++ b/support/lobby/lib/utils.js @@ -0,0 +1,38 @@ +export function get( resource ) { + return fetch( resource, getOptions() ). + then( responseBody ); +} + +export function post( resource, body ) { + return fetch( resource, postOptions( body ) ). + then( responseBody ); +} + +function getOptions() { + return { + credentials: "same-origin", + }; +} + +function postOptions( body ) { + let json = ( typeof body === "object" ) && ( body !== null ) && + ( body instanceof FormData === false ); + + return { + method: "POST", + body: json ? JSON.stringify( body ) : body, + headers: json ? { "Content-Type": "application/json" } : undefined, + credentials: "same-origin", + }; +} + +function responseBody( response ) { + + if ( !response.ok ){ + throw Error( response.statusText ); + } + let contentType = response.headers.get( "Content-Type" ) || "", + json = contentType.includes( "application/json" ); + + return json ? response.json() : response.text(); +} diff --git a/support/lobby/login.css b/support/lobby/login.css new file mode 100644 index 000000000..405298589 --- /dev/null +++ b/support/lobby/login.css @@ -0,0 +1 @@ +@import url('lib/layout.css'); diff --git a/support/lobby/login.html b/support/lobby/login.html new file mode 100644 index 000000000..5a188df81 --- /dev/null +++ b/support/lobby/login.html @@ -0,0 +1,91 @@ + + + + + + + + + + + + + Virtual World Framework lobby + + + + + + + + + +
      + + + + diff --git a/support/lobby/login.js b/support/lobby/login.js new file mode 100644 index 000000000..3452e9581 --- /dev/null +++ b/support/lobby/login.js @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom"; + +import Login from "./lib/Login"; + +ReactDOM.render( + , + document.getElementById( "root" ) +); diff --git a/support/lobby/npm-shrinkwrap.json b/support/lobby/npm-shrinkwrap.json new file mode 100644 index 000000000..93c41e32e --- /dev/null +++ b/support/lobby/npm-shrinkwrap.json @@ -0,0 +1,6751 @@ +{ + "name": "vwf-lobby", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz", + "integrity": "sha512-sW77BFwJ48YvQp3Gzz5xtAUiXuYOL2aMJKDwiaY3OcvdqBFurtYfOpSa4QrNyDxmOGRFSYzUpabU2m9QrlWE7w==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.36.tgz", + "integrity": "sha512-/SGPOyifPf20iTrMN+WdlY2MbKa7/o4j7B/4IAsdOusASp2icT+Wcdjf4tjJHaXNX8Pe9bpgVxLNxhRvcf8E5w==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.36", + "@babel/template": "7.0.0-beta.36", + "@babel/types": "7.0.0-beta.36" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.36.tgz", + "integrity": "sha512-vPPcx2vsSoDbcyWr9S3nd0FM3B4hEXnt0p1oKpwa08GwK0fSRxa98MyaRGf8suk8frdQlG1P3mDrz5p/Rr3pbA==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.36" + } + }, + "@babel/template": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.36.tgz", + "integrity": "sha512-mUBi90WRyZ9iVvlWLEdeo8gn/tROyJdjKNC4W5xJTSZL+9MS89rTJSqiaJKXIkxk/YRDL/g/8snrG/O0xl33uA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.36", + "@babel/types": "7.0.0-beta.36", + "babylon": "7.0.0-beta.36", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.36.tgz", + "integrity": "sha512-rw4YdadGwajAMMRl6a5swhQ0JCOOFyaYCfJ0AsmNBD8uBD/r4J8mux7wBaqavvFKqUKQYWOzA1Speams4YDzsQ==", + "dev": true + } + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.36.tgz", + "integrity": "sha512-OTUb6iSKVR/98dGThRJ1BiyfwbuX10BVnkz89IpaerjTPRhDfMBfLsqmzxz5MiywUOW4M0Clta0o7rSxkfcuzw==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.36", + "@babel/helper-function-name": "7.0.0-beta.36", + "@babel/types": "7.0.0-beta.36", + "babylon": "7.0.0-beta.36", + "debug": "3.1.0", + "globals": "11.1.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.36.tgz", + "integrity": "sha512-rw4YdadGwajAMMRl6a5swhQ0JCOOFyaYCfJ0AsmNBD8uBD/r4J8mux7wBaqavvFKqUKQYWOzA1Speams4YDzsQ==", + "dev": true + }, + "globals": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.36.tgz", + "integrity": "sha512-PyAORDO9um9tfnrddXgmWN9e6Sq9qxraQIt5ynqBOSXKA5qvK1kUr+Q3nSzKFdzorsiK+oqcUnAFvEoKxv9D+Q==", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", + "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "2.3.11", + "normalize-path": "2.1.1" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1.js": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", + "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000778", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.0", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "babel-eslint": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.1.tgz", + "integrity": "sha512-RzdVOyWKQRUnLXhwLk+eKb4oyW+BykZSkpYwFhM4tnfzAG5OWfvG0w/uyzMp5XKEU0jN82+JefHr39bG2+KhRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.36", + "@babel/traverse": "7.0.0-beta.36", + "@babel/types": "7.0.0-beta.36", + "babylon": "7.0.0-beta.36", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "1.0.0" + }, + "dependencies": { + "babylon": { + "version": "7.0.0-beta.36", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.36.tgz", + "integrity": "sha512-rw4YdadGwajAMMRl6a5swhQ0JCOOFyaYCfJ0AsmNBD8uBD/r4J8mux7wBaqavvFKqUKQYWOzA1Speams4YDzsQ==", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.4", + "source-map": "0.5.7", + "trim-right": "1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + } + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "esutils": "2.0.2" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz", + "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==", + "dev": true, + "requires": { + "find-cache-dir": "1.0.0", + "loader-utils": "1.1.0", + "mkdirp": "0.5.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-generators": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-plugin-syntax-class-properties": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "6.24.1", + "babel-plugin-syntax-decorators": "6.13.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + } + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "dev": true, + "requires": { + "babel-helper-builder-react-jsx": "6.26.0", + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "0.10.1" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "2.9.1", + "invariant": "2.2.2", + "semver": "5.4.1" + }, + "dependencies": { + "browserslist": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.9.1.tgz", + "integrity": "sha512-3n3nPdbUqn3nWmsy4PeSQthz2ja1ndpoXta+dwFFNhveGjMg6FXpWYe12vsTpNoXJbzx3j7GZXdtoVIdvh3JbA==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000778", + "electron-to-chromium": "1.3.28" + } + } + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "6.22.0" + } + }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "6.18.0", + "babel-plugin-transform-react-display-name": "6.25.0", + "babel-plugin-transform-react-jsx": "6.24.1", + "babel-plugin-transform-react-jsx-self": "6.22.0", + "babel-plugin-transform-react-jsx-source": "6.22.0", + "babel-preset-flow": "6.23.0" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-decorators": "6.24.1", + "babel-preset-stage-3": "6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-generator-functions": "6.24.1", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-object-rest-spread": "6.26.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "core-js": "2.5.1", + "home-or-tmp": "2.0.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + } + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "7.0.0-beta.19", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz", + "integrity": "sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "bootstrap": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz", + "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E=" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify-aes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.1.1", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000778", + "electron-to-chromium": "1.3.28" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8", + "isarray": "1.0.0" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000778", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + } + }, + "caniuse-db": { + "version": "1.0.30000778", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000778.tgz", + "integrity": "sha1-Fnxg6VQqKqYFN8RG+ziB2FOjByo=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000778", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000778.tgz", + "integrity": "sha1-8efLixOx9nREAikddfC81MMWA2k=", + "dev": true + }, + "catharsis": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz", + "integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=", + "dev": true, + "requires": { + "underscore-contrib": "0.3.0" + } + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.5" + } + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.1.3", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, + "requires": { + "chalk": "1.1.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + } + } + }, + "clone": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, + "requires": { + "q": "1.5.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "requires": { + "clone": "1.0.3", + "color-convert": "1.9.1", + "color-string": "0.3.0" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, + "requires": { + "color": "0.11.4", + "css-color-names": "0.0.4", + "has": "1.0.1" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5", + "randomfill": "1.0.3" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-loader": { + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz", + "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "css-selector-tokenizer": "0.7.0", + "cssnano": "3.10.0", + "icss-utils": "2.1.0", + "loader-utils": "1.1.0", + "lodash.camelcase": "4.3.0", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0", + "postcss-value-parser": "3.3.0", + "source-list-map": "2.0.0" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + } + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "decamelize": "1.2.0", + "defined": "1.0.0", + "has": "1.0.1", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-calc": "5.3.1", + "postcss-colormin": "2.2.2", + "postcss-convert-values": "2.6.1", + "postcss-discard-comments": "2.0.4", + "postcss-discard-duplicates": "2.1.0", + "postcss-discard-empty": "2.1.0", + "postcss-discard-overridden": "0.1.1", + "postcss-discard-unused": "2.2.3", + "postcss-filter-plugins": "2.0.2", + "postcss-merge-idents": "2.1.7", + "postcss-merge-longhand": "2.0.2", + "postcss-merge-rules": "2.1.2", + "postcss-minify-font-values": "1.0.5", + "postcss-minify-gradients": "1.0.5", + "postcss-minify-params": "1.2.2", + "postcss-minify-selectors": "2.1.1", + "postcss-normalize-charset": "1.1.1", + "postcss-normalize-url": "3.0.8", + "postcss-ordered-values": "2.2.3", + "postcss-reduce-idents": "2.4.0", + "postcss-reduce-initial": "1.0.1", + "postcss-reduce-transforms": "1.0.4", + "postcss-svgo": "2.1.6", + "postcss-unique-selectors": "2.0.2", + "postcss-value-parser": "3.3.0", + "postcss-zindex": "2.2.0" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "1.2.3", + "source-map": "0.5.7" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.37" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.5" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.5" + } + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "dom-helpers": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz", + "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=" + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.28", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz", + "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.19" + } + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + } + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true, + "requires": { + "prr": "0.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.12.1.tgz", + "integrity": "sha512-28hOYej+NZ/R5H1yMvyKa1+bPlu+fnsIAQffK6hxXgvmXnImos2bA5XfCn5dYv2k2mrKj+/U/Z4L5ICWxC7TQw==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "babel-code-frame": "6.26.0", + "chalk": "2.3.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.2", + "eslint-scope": "3.7.1", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.0.1", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + } + }, + "eslint-plugin-react": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz", + "integrity": "sha512-YGSjB9Qu6QbVTroUZi66pYky3DfoIPLdHQ/wmrBGyBRnwxQsBXAov9j2rpXt/55i8nyMv6IRWJv2s4d4YnduzQ==", + "dev": true, + "requires": { + "doctrine": "2.0.2", + "has": "1.0.1", + "jsx-ast-utils": "2.0.1", + "prop-types": "15.6.0" + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "extract-text-webpack-plugin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", + "dev": true, + "requires": { + "async": "2.6.0", + "loader-utils": "1.1.0", + "schema-utils": "0.3.0", + "webpack-sources": "1.1.0" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.17" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + } + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "make-dir": "1.1.0", + "pkg-dir": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.8.0", + "node-pre-gyp": "0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.2.9" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "extend": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.15" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.1" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.1.1", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.0", + "sshpk": "1.13.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.2", + "hawk": "3.1.3", + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.0", + "rc": "1.2.1", + "request": "2.81.0", + "rimraf": "2.6.1", + "semver": "5.3.0", + "tar": "2.2.1", + "tar-pack": "3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.0", + "osenv": "0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.1", + "util-deprecate": "1.0.2" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.15", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.0.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.0.1" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jodid25519": "1.0.2", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.8", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.2.9", + "rimraf": "2.6.1", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.0.1.tgz", + "integrity": "sha1-Eqh7sBDlFUOWrMU14eQ/x1Ow5eg=", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + } + }, + "js-base64": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz", + "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA==", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "js2xmlparser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz", + "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=", + "dev": true, + "requires": { + "xmlcreate": "1.0.2" + } + }, + "jsdoc": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz", + "integrity": "sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg==", + "dev": true, + "requires": { + "babylon": "7.0.0-beta.19", + "bluebird": "3.5.1", + "catharsis": "0.8.9", + "escape-string-regexp": "1.0.5", + "js2xmlparser": "3.0.0", + "klaw": "2.0.0", + "marked": "0.3.7", + "mkdirp": "0.5.1", + "requizzle": "0.2.1", + "strip-json-comments": "2.0.1", + "taffydb": "2.6.2", + "underscore": "1.8.3" + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "3.0.3" + } + }, + "keycode": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.1.9.tgz", + "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "klaw": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz", + "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "macaddress": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", + "dev": true + }, + "make-dir": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", + "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", + "dev": true, + "requires": { + "pify": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "marked": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.7.tgz", + "integrity": "sha512-zBEP4qO1YQp5aXHt8S5wTiOv9i2X74V/LQL0zhUNvVaklt6Ywa6lChxIvS+ibYlCGgADwKwZFhjC3+XfpsvQvQ==", + "dev": true + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.3", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "1.0.3", + "timers-browserify": "2.0.4", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "prepend-http": "1.0.4", + "query-string": "4.3.4", + "sort-keys": "1.1.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.2", + "browserify-aes": "1.1.1", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "2.1.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "js-base64": "2.4.0", + "source-map": "0.5.7", + "supports-color": "3.2.3" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, + "requires": { + "colormin": "1.1.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-filter-plugins": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "uniqid": "4.1.1" + } + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-api": "1.6.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3", + "vendors": "1.0.1" + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "uniqs": "2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3" + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "dev": true, + "requires": { + "postcss": "6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.14" + }, + "dependencies": { + "postcss": { + "version": "6.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz", + "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "source-map": "0.6.1", + "supports-color": "4.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, + "requires": { + "is-absolute-url": "2.1.0", + "normalize-url": "1.9.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "requires": { + "is-svg": "2.1.0", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "svgo": "0.7.2" + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, + "requires": { + "has": "1.0.1", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "prop-types-extra": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.0.1.tgz", + "integrity": "sha1-pXvUgQ6C0no/9DF+zBtK0AX3moI=", + "requires": { + "warning": "3.0.0" + } + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "randomfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", + "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "dev": true, + "requires": { + "randombytes": "2.0.5", + "safe-buffer": "5.1.1" + } + }, + "react": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.2.0.tgz", + "integrity": "sha512-ZmIomM7EE1DvPEnSFAHZn9Vs9zJl5A9H7el0EGTE6ZbW9FKe/14IYAlPbC8iH25YarEQxZL+E8VW7Mi7kfQrDQ==", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-bootstrap": { + "version": "0.31.5", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.31.5.tgz", + "integrity": "sha512-xgDihgX4QvYHmHzL87faDBMDnGfYyqcrqV0TEbWY+JizePOG1vfb8M3xJN+6MJ3kUYqDtQSZ7v/Q6Y5YDrkMdA==", + "requires": { + "babel-runtime": "6.26.0", + "classnames": "2.2.5", + "dom-helpers": "3.2.1", + "invariant": "2.2.2", + "keycode": "2.1.9", + "prop-types": "15.6.0", + "prop-types-extra": "1.0.1", + "react-overlays": "0.7.4", + "uncontrollable": "4.1.0", + "warning": "3.0.0" + } + }, + "react-dom": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.2.0.tgz", + "integrity": "sha512-zpGAdwHVn9K0091d+hr+R0qrjoJ84cIBFL2uU60KvWBPfZ7LPSrfqviTxGHWN0sjPZb2hxWzMexwrvJdKePvjg==", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-overlays": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.7.4.tgz", + "integrity": "sha512-7vsooMx3siLAuEfTs8FYeP/lAORWWFXTO8PON3KgX0Htq1Oa+po6ioSjGyO0/GO5CVSMNhpWt6V2opeexHgBuQ==", + "requires": { + "classnames": "2.2.5", + "dom-helpers": "3.2.1", + "prop-types": "15.6.0", + "prop-types-extra": "1.0.1", + "warning": "3.0.0" + } + }, + "react-table": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.7.6.tgz", + "integrity": "sha1-P547MIMozrBO+TpHur76uiYZyQU=", + "requires": { + "classnames": "2.2.5" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.3", + "set-immediate-shim": "1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "math-expression-evaluator": "1.2.17", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "1.3.3", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "0.5.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "requizzle": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz", + "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=", + "dev": true, + "requires": { + "underscore": "1.6.0" + }, + "dependencies": { + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + } + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.5.1" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "style-loader": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz", + "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==", + "dev": true, + "requires": { + "loader-utils": "1.1.0", + "schema-utils": "0.3.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, + "requires": { + "coa": "1.0.4", + "colors": "1.1.2", + "csso": "2.3.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "sax": "1.2.4", + "whet.extend": "0.9.9" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "2.7.3" + } + } + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "type-detect": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", + "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } + }, + "uncontrollable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-4.1.0.tgz", + "integrity": "sha1-4DWCkSUuGGUiLZCTmxny9J+Bwak=", + "requires": { + "invariant": "2.2.2" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "underscore-contrib": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/underscore-contrib/-/underscore-contrib-0.3.0.tgz", + "integrity": "sha1-ZltmwkeD+PorGMn4y7Dix9SMJsc=", + "dev": true, + "requires": { + "underscore": "1.6.0" + }, + "dependencies": { + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=", + "dev": true + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqid": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "dev": true, + "requires": { + "macaddress": "0.2.8" + } + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "vendors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "dev": true + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "1.3.1" + } + }, + "watchpack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", + "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", + "dev": true, + "requires": { + "async": "2.6.0", + "chokidar": "1.7.0", + "graceful-fs": "4.1.11" + } + }, + "webpack": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", + "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-dynamic-import": "2.0.2", + "ajv": "5.5.1", + "ajv-keywords": "2.1.1", + "async": "2.6.0", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.4.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" + }, + "dependencies": { + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "webpack-merge": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.1.tgz", + "integrity": "sha512-geQsZ86YkXOVOjvPC5yv3JSNnL6/X3Kzh935AQ/gJNEYXEfJDQFu/sdFuktS9OW2JcH/SJec8TGfRdrpHshH7A==", + "dev": true, + "requires": { + "lodash": "4.17.4" + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "xmlcreate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz", + "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + } + } +} diff --git a/support/lobby/package.json b/support/lobby/package.json new file mode 100644 index 000000000..e342ec5c4 --- /dev/null +++ b/support/lobby/package.json @@ -0,0 +1,59 @@ +{ + "name": "vwf-lobby", + "version": "0.0.0", + "description": "Virtual World Framework lobby", + "directories": { + "doc": "doc", + "lib": "lib", + "test": "test" + }, + "files": [ + "index.html", + "index.js", + "index.css", + "doc/", + "lib/" + ], + "scripts": { + "prepublish": "npm run build && npm run test", + "build": "npm run build:webpack && npm run build:jsdoc", + "build:webpack": "npm run build:webpack:prod && npm run build:webpack:dev", + "build:webpack:prod": "webpack --config .webpack.prod.js", + "build:webpack:dev": "webpack --config .webpack.dev.js", + "build:jsdoc": "jsdoc --configure .jsdoc.json", + "test": "npm run test:eslint && npm run test:mocha", + "test:eslint": "eslint .", + "test:mocha": "mocha" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/interactive-tactical-decision-games/vwf.git" + }, + "license": "Apache-2.0", + "dependencies": { + "bootstrap": "^3.3.7", + "prop-types": "^15.6.0", + "react": "^16.2.0", + "react-bootstrap": "^0.31.5", + "react-dom": "^16.2.0", + "react-table": "^6.7.6" + }, + "devDependencies": { + "babel-core": "^6.26.0", + "babel-eslint": "^8.2.1", + "babel-loader": "^7.1.2", + "babel-preset-env": "^1.6.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "chai": "^4.1.2", + "css-loader": "^0.28.7", + "eslint": "^4.12.1", + "eslint-plugin-react": "^7.5.1", + "extract-text-webpack-plugin": "^3.0.2", + "jsdoc": "^3.5.5", + "mocha": "^4.0.1", + "style-loader": "^0.19.0", + "webpack": "^3.10.0", + "webpack-merge": "^4.1.1" + } +} diff --git a/support/lobby/test/index.js b/support/lobby/test/index.js new file mode 100644 index 000000000..936e6ad41 --- /dev/null +++ b/support/lobby/test/index.js @@ -0,0 +1,9 @@ +"use strict"; + +var assert = require( "chai" ).assert; + +describe( "Test", function() { + specify( "condition", function() { + assert( true, "description" ); + } ); +} ); diff --git a/support/lobby/test/mocha.opts b/support/lobby/test/mocha.opts new file mode 100644 index 000000000..e69de29bb diff --git a/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml index a6a136e5d..251e15d91 100644 --- a/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml @@ -4,3 +4,5 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/canvas.vwf.yaml b/support/proxy/vwf.example.com/kinetic/canvas.vwf.yaml index df01e52d2..0ed29aec8 100644 --- a/support/proxy/vwf.example.com/kinetic/canvas.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/canvas.vwf.yaml @@ -5,4 +5,4 @@ extends: http://vwf.example.com/node.vwf properties: width: height: - pixelRatio: + pixelRatio: 1.0 diff --git a/support/proxy/vwf.example.com/kinetic/container.js b/support/proxy/vwf.example.com/kinetic/container.js index 34deba615..9149cf307 100644 --- a/support/proxy/vwf.example.com/kinetic/container.js +++ b/support/proxy/vwf.example.com/kinetic/container.js @@ -8,4 +8,4 @@ this.deleteChildNode = function( id ) { if ( child ) { this.children.delete( child ); } -} //@ sourceURL=kinetic_container.js \ No newline at end of file +} //# sourceURL=kinetic_container.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 938402359..ab019ee0a 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -1,593 +1,24 @@ -this.initialize = function() { - this.drawing_private = {}; - this.future(0).clientWatch(); -}; - -this.clientWatch = function() { - - var clients = this.find( "doc('http://vwf.example.com/clients.vwf')" )[0]; - - if ( clients !== undefined ) { - - clients.children.added = clients.events.add( function( index, child ) { - this.clientJoin( this.moniker ); - }, this ); - - clients.children.removed = clients.events.add( function( index, child ) { - this.clientLeave( this.moniker ); - }, this ); - - } - -}; - -this.isValid = function( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); -}; - -this.clientJoin = function( moniker ) { - - // mirrors the initial state of the toolbar - if ( !this.isValid( this.drawing_clients ) ) { - this.drawing_clients = {}; - } - if ( this.drawing_clients[ moniker ] === undefined ) { - this.drawing_clients[ moniker ] = { - "drawing_mode": 'none', - "drawing_visible": 'inherit', - "drawing_color": 'black', - "drawing_width": 4, - "drawing_parentPath": '/', - "drawing_opacity": 1.0, - "nameIndex": 1, - "fontSize": 16, - "angle": 30 - }; - } - this.drawing_clients = this.drawing_clients; - -}; - -this.clientLeave = function( moniker ) { - if ( this.drawing_clients[ moniker ] !== undefined ) { - delete this.drawing_clients[ moniker ]; - this.drawing_clients = this.drawing_clients; - } - if ( this.drawing_private[ moniker ] !== undefined ) { - delete this.drawing_private[ moniker ]; - } -}; - -this.setUpPrivate = function( moniker ) { - - if ( this.drawing_private === undefined ) { - this.drawing_private = {}; - } - if ( this.drawing_private[ moniker ] === undefined ) { - this.drawing_private[ moniker ] = { - "drawingObject": null, - "initialDownPoint": [ -1, -1 ], - "previousPoint": [ -1, -1 ], - "mouseDown": false - }; - } - -}; - -this.setClientUIState = function( stateObj ) { - - //console.info( "setClientUIState " + JSON.stringify( stateObj ) ); - if ( stateObj !== undefined ) { - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { - this.clientJoin( this.client ); - } - var clients = this.drawing_clients; - var userState = clients[ this.client ]; - for ( var property in stateObj ) { - userState[ property ] = stateObj[ property ]; - } - this.drawing_clients = clients; - } -}; - -this.down = function( eventData, nodeData, touch ) { - - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { - this.clientJoin( this.client ); - } - if ( !this.isValid( this.drawing_private ) || - !this.isValid( this.drawing_private[ this.client ] ) ) { - this.setUpPrivate( this.client ); - } - - var userState = this.drawing_clients[ this.client ]; - var privateState = this.drawing_private[ this.client ]; - var drawingMode = userState.drawing_mode; - - if ( privateState.drawingObject !== null ) { - return; - } - - var compExtends = undefined; - var groupExtends = undefined; - var section = "/shapes"; - - if ( drawingMode === "freeDraw" ) { - section = "/lines"; - } - - switch ( drawingMode ) { - - case "arc": - case "circle": - case "ellipse": - case "regularPolygon": - case "rect": - case "ring": - case "star": - case "wedge": - compExtends = [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join(''); - break; - - case "sprite": - case "text": - case "image": - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "border": "http://vwf.example.com/kinetic/line.vwf", - "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') - }; - break; - - case "arrow": - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "line": "http://vwf.example.com/kinetic/line.vwf", - "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" - }; - break; - - case "thickArrow": - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "line": "http://vwf.example.com/kinetic/line.vwf", - "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" - }; - break; - - case "borderRect": - case "line": - case "freeDraw": - compExtends = "http://vwf.example.com/kinetic/line.vwf"; - break; - - case 'none': - default: - break; - - } - - var getDefaultProperties = function( drawingMode, groupParent, eventPoint ) { - var retObj = { - "visible": 'inherit', - "opacity": userState.drawing_opacity, - "z-index": 4 - }; - - switch( drawingMode ) { - case "sprite": - //case "text": - case "image": - retObj.opacity = 1.0; - retObj.scaleOnLoad = true; - break; - - default: - retObj.fill = userState.drawing_color; - break; - } - - if ( groupParent ) { - retObj.x = 0; - retObj.y = 0; - retObj.position = [ 0, 0 ]; - } else { - retObj.x = eventPoint[ 0 ]; - retObj.y = eventPoint[ 1 ]; - retObj.position = eventPoint; - } - - return retObj; - }; - - var eventPointDown = eventData.stageRelative; - if ( groupExtends !== undefined ) { - - privateState.initialDownPoint = eventPointDown; - var parentPath = userState.drawing_parentPath + section ; - var parents = this.find( parentPath ); - - // find was failing 9/2/14, and the code below - // was a backup, going to leave this in until we feel good - // about the issues we saw are no longer a problem - if ( parents === undefined ) { - parents = [ this.findChild( this, parentPath.split( '/' ) ) ]; - } - - var parent = parents.length > 0 ? parents[ 0 ] : this; - var groupDef = { - "extends": groupExtends, - "properties": { - "visible": false, - "position": eventPointDown - }, - "children": {} - }; - - for ( var def in compExtends ) { - groupDef.children[ def ] = { - "extends": compExtends[ def ], - "properties": getDefaultProperties( drawingMode, true, eventPointDown ) - } - } - - var self = this; - var selfMoniker = this.client; - var name = drawingMode + this.drawing_index; - this.drawing_index = this.drawing_index + 1; - parent.children.create( name, groupDef, function( child ) { - self.drawing_private[ selfMoniker ].drawingObject = child; - } ); - - } else if ( compExtends !== undefined ) { - - privateState.initialDownPoint = eventPointDown; - var parentPath = userState.drawing_parentPath + section; - var parents = this.find( parentPath ); - - // find was failing 9/2/14, and the code below - // was a backup, going to leave this in until we feel good - // about the issues we saw are no longer a problem - if ( parents === undefined ) { - parents = [ this.findChild( this, parentPath.split( '/' ) ) ]; - } - - var parent = parents.length > 0 ? parents[ 0 ] : this; - var shapeDef = { - "extends": compExtends, - "properties": getDefaultProperties( drawingMode, false, eventPointDown ) - }; - - var self = this; - var selfMoniker = this.client; - var name = drawingMode + this.drawing_index; - this.drawing_index = this.drawing_index + 1; - parent.children.create( name, shapeDef, function( child ) { - self.drawing_private[ selfMoniker ].drawingObject = child; - } ); - - } -}; +// Deprecated: This component exists only for backward compatibility +// It was deprecated in v2.6.5 -this.move = function( eventData, nodeData, touch ) { +this.clientJoin = function() { + console.warn( "drawing.clientJoin:", + "This function is deprecated. Please resave scenario to remove the event handler." ); - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { - this.clientJoin( this.client ); - } - if ( this.drawing_private === undefined || - this.drawing_private[ this.client ] === undefined ) { - this.setUpPrivate( this.client ); - } + // Remove all event handlers from this object + var clients = this.find( "doc('http://vwf.example.com/clients.vwf')" )[ 0 ]; + clients.children.added = clients.events.flush( this ); + clients.children.removed = clients.events.flush( this ); - this.update( eventData, nodeData, false ); + //# sourceURL=drawing.clientJoin }; -this.up = function( eventData, nodeData, touch ) { +this.clientLeave = function() { + console.warn( "drawing.clientLeave:", + "This function is deprecated. Please resave scenario to remove the event handler." ); - if ( this.drawing_private[ this.client ] !== undefined && - this.drawing_private[ this.client ].drawingObject !== null ) { - var drawingObject = this.drawing_private[ this.client ].drawingObject; - this.update( eventData, nodeData, true ); - - this.drawingObjectCreated( drawingObject.id ); - - var userState = this.drawing_clients[ this.client ]; - if ( this.moniker === this.client ) { - - switch( userState.drawing_mode ) { - - case "text": - this.textCreated( drawingObject.content.id ); - break; - - case "sprite": - case "image": - this.imageCreated( drawingObject.content.id ); - break; - - } - } - - switch( userState.drawing_mode ) { - - case "text": - case "sprite": - case "image": - drawingObject.border.visible = false; - break; - - } - - this.drawing_private[ this.client ].drawingObject = null; - } -}; - -this.update = function( eventData, nodeData, upEvent ) { - - if ( this.drawing_private === undefined || - this.drawing_private[ this.client ] === undefined || - !this.isValid( this.drawing_clients ) ) { - return; - } - - if ( this.drawing_private[ this.client ].drawingObject !== null ) { - - var eventPoint = eventData.stageRelative; - var userState = this.drawing_clients[ this.client ]; - var privateState = this.drawing_private[ this.client ]; - var drawingObject = privateState.drawingObject; - var pointAccepted = true; - - if ( drawingObject.visible !== userState.drawing_visible ) { - drawingObject.visible = userState.drawing_visible; - } - var diffX = eventPoint[ 0 ] - privateState.initialDownPoint[ 0 ]; - var diffY = eventPoint[ 1 ] - privateState.initialDownPoint[ 1 ]; - var pos = [ privateState.initialDownPoint[ 0 ], privateState.initialDownPoint[ 1 ] ]; - var width = diffX; - var height = diffY; - var dist = Math.sqrt( ( diffX * diffX ) + ( diffY * diffY ) ); - - //console.info( "== "+userState.drawing_mode +" ==" ); - //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); - - // this keeps the pos as the top left corner for the - // rectangular objects - switch ( userState.drawing_mode ) { - - case "line": - case "arrow": - case "thickArrow": - case "freeDraw": - break; - - default: - if ( diffX < 0 ) { - pos[ 0 ] += diffX; - width = Math.abs( diffX ); - } - if ( diffY < 0 ) { - pos[ 1 ] += diffY; - height = Math.abs( diffY ); - } - drawingObject.position = pos; - drawingObject.width = width; - drawingObject.height = height; - break; - } - - //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); - - switch ( userState.drawing_mode ) { - - case "arc": - drawingObject.angle = userState.angle ? userState.angle : 30; - if ( dist > this.drawing_width ) { - drawingObject.innerRadius = dist - this.drawing_width; - drawingObject.outerRadius = dist; - } - break; - - case "ellipse": - drawingObject.radius = { "x": width * 0.5, "y": height * 0.5 }; - break; - - case "circle": - drawingObject.radius = dist; - break; - - case "line": - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - drawingObject.points = [ 0, 0, diffX, diffY ]; - break; - - case "freeDraw": - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - - var isFirstStrokeOfNewLine = ( drawingObject.points.length === 0 ); - var posX = eventPoint[ 0 ] - drawingObject.x; - var posY = eventPoint[ 1 ] - drawingObject.y; - - if ( isFirstStrokeOfNewLine ) { - if ( Math.abs( posX ) + Math.abs( posY ) > 0 ) { - drawingObject.points = [ 0, 0, posX, posY ]; - } else { - pointAccepted = false; - } - } else { - var dragDiff = [ - posX - privateState.previousPoint[ 0 ], - posY - privateState.previousPoint[ 1 ] - ]; - - if ( Math.abs( dragDiff[0] ) + Math.abs( dragDiff[1] ) > 0 ) { - drawingObject.points.push( posX ); - drawingObject.points.push( posY ); - } else { - pointAccepted = false; - } - } - break; - - case "regularPolygon": - // needs defining - break; - - case "ring": - if ( dist > userState.drawing_width ) { - drawingObject.innerRadius = dist - userState.drawing_width; - drawingObject.outerRadius = dist; - } - break; - - case "star": - drawingObject.points = 5; - drawingObject.innerRadius = dist * 80; - drawingObject.outerRadius = dist; - break; - - case "wedge": - // needs defining - drawingObject.angle = userState.angle ? userState.angle : 30; - drawingObject.radius = dist; - drawingObject.clockwise = false; - break; - - case "borderRect": - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - drawingObject.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; - break; - - case "arrow": - drawingObject.x = drawingObject.position[ 0 ]; - drawingObject.y = drawingObject.position[ 1 ]; - - drawingObject.line.stroke = userState.drawing_color; - drawingObject.line.strokeWidth = userState.drawing_width; - drawingObject.line.position = [ 0, 0 ]; - - drawingObject.head.sides = 3; - drawingObject.head.radius = userState.drawing_width * 3; - - var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); - var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; - var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; - var headOffset = ( userState.drawing_width * 3 ) * Math.sin( Math.PI / 6 ); - var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); - var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); - goog.vec.Vec2.normalize( dir, dir ); - - drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; - goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 3 ), endPoint ); - drawingObject.head.position = [ endPoint[0], endPoint[1] ]; - goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 3 ) + headOffset ), endPoint ); - drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; - break; - - case "thickArrow": - drawingObject.x = drawingObject.position[ 0 ]; - drawingObject.y = drawingObject.position[ 1 ]; - - drawingObject.line.stroke = userState.drawing_color; - drawingObject.line.strokeWidth = userState.drawing_width * 8; - drawingObject.line.position = [ 0, 0 ]; - - drawingObject.head.sides = 3; - drawingObject.head.radius = userState.drawing_width * 8; - - var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); - var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; - var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; - var headOffset = ( userState.drawing_width * 8 ) * Math.sin( Math.PI / 6 ); - var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); - var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); - goog.vec.Vec2.normalize( dir, dir ); - - drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; - goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 8 ), endPoint ); - drawingObject.head.position = [ endPoint[0], endPoint[1] ]; - goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 8 ) + headOffset ), endPoint ); - drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; - break; - - case "sprite": - case "image": - drawingObject.border.stroke = userState.drawing_color; - drawingObject.border.strokeWidth = 4; - drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; - drawingObject.content.width = width; - drawingObject.content.height = height; - break; - - case "text": - drawingObject.border.stroke = userState.drawing_color; - drawingObject.border.strokeWidth = 4; - drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; - drawingObject.content.fontSize = userState.fontSize ? userState.fontSize : 16; - break; - - case "rect": - default: - break; - - } - - if ( pointAccepted ) { - privateState.previousPoint = eventPoint; - } - - } -}; - -this.pointerDown = function( eventData, nodeData ) { - this.down( eventData, nodeData, false ); -}; - -this.pointerMove = function( eventData, nodeData ) { - this.move( eventData, nodeData, false ); -}; - -this.pointerUp = function( eventData, nodeData ) { - this.up( eventData, nodeData, false ); -}; - -this.touchStart = function( eventData, nodeData ) { - this.down( eventData, nodeData, true ); -}; - -this.touchMove = function( eventData, nodeData ) { - this.move( eventData, nodeData, true ); + // Remove all event handlers from this object + var clients = this.find( "doc('http://vwf.example.com/clients.vwf')" )[ 0 ]; + clients.children.added = clients.events.flush( this ); + clients.children.removed = clients.events.flush( this ); }; - -this.touchEnd = function( eventData, nodeData ) { - this.up( eventData, nodeData, true ); -}; - -this.findChild = function( parent, names ) { - if ( names.length > 0 ) { - var childName = names.shift(); - while ( childName === "" ) { - childName = names.shift(); - } - if ( parent.children[ childName ] ) { - if ( names.length === 0 ) { - return parent.children[ childName ]; - } else { - return this.findChild( parent.children[ childName ], names ); - } - } - else { - return undefined; - } - } - return undefined; -} - -//@ sourceURL=kinetic_drawing.js diff --git a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml index 5919fc277..baddd8783 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml @@ -1,31 +1,9 @@ --- -extends: - http://vwf.example.com/kinetic/stage.vwf -properties: - drawing_clients: - drawing_index: 1 +# Deprecated: This component has been left only for backward compatibility. +# It was deprecated in v2.6.5 +extends: http://vwf.example.com/node.vwf methods: - update: - down: - move: - up: - clientWatch: clientJoin: clientLeave: - setUpPrivate: - setClientUIState: - isValid: - getStageRelativePoint: -events: - pointerDown: - pointerMove: - pointerUp: - touchStart: - touchMove: - touchEnd: - drawingObjectCreated: - textCreated: - imageCreated: - findChild: scripts: -- source: "http://vwf.example.com/kinetic/drawing.js" +- source: http://vwf.example.com/kinetic/drawing.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml index 0c0d31322..3919bef8e 100644 --- a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml @@ -1,4 +1,6 @@ # http://kineticjs.com/docs/Kinetic.Group.html --- -extends: http://vwf.example.com/kinetic/group.vwf \ No newline at end of file +extends: http://vwf.example.com/kinetic/group.vwf +properties: + supportMouseAndTouchEvents: true diff --git a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml index e0e54ad73..1d050bdbd 100644 --- a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml @@ -4,3 +4,5 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/group.vwf.yaml b/support/proxy/vwf.example.com/kinetic/group.vwf.yaml index 27847bf7b..301a131ad 100644 --- a/support/proxy/vwf.example.com/kinetic/group.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/group.vwf.yaml @@ -1,4 +1,6 @@ # http://kineticjs.com/docs/Kinetic.Group.html --- -extends: http://vwf.example.com/kinetic/container.vwf \ No newline at end of file +extends: http://vwf.example.com/kinetic/container.vwf +properties: + supportMouseAndTouchEvents: false diff --git a/support/proxy/vwf.example.com/kinetic/image.vwf.yaml b/support/proxy/vwf.example.com/kinetic/image.vwf.yaml index 6d7f20172..e72c893f6 100644 --- a/support/proxy/vwf.example.com/kinetic/image.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/image.vwf.yaml @@ -3,9 +3,10 @@ --- extends: http://vwf.example.com/kinetic/shape.vwf properties: - image: + image: crop: - scaleOnLoad: false + scaleOnLoad: true + strokeEnabled: false events: imageLoaded: imageLoadError: diff --git a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml index 19a8bd98c..6b22eed9c 100644 --- a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml @@ -4,3 +4,5 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/node.js b/support/proxy/vwf.example.com/kinetic/node.js index 078556749..6adc1ca97 100644 --- a/support/proxy/vwf.example.com/kinetic/node.js +++ b/support/proxy/vwf.example.com/kinetic/node.js @@ -1,5 +1,15 @@ this.initialize = function() { this.previousVisible = undefined; + this.previousListening = undefined; + + // If the value of supportMouseAndTouchEvents is true, this code ensures that the view receives + // an initializedProperty or satProperty call for it. + // This is needed for the view to set up mouse and touch event handlers. + // We do this here to avoid making the view issue a getProperty to the reflector for every + // node in order to know its property value. + if ( this.supportMouseAndTouchEvents ) { + this.supportMouseAndTouchEvents = true; + } } this.toggleVisibility = function() { @@ -23,4 +33,25 @@ this.toggleVisibility = function() { } -//@ sourceURL=kinetic_node.js \ No newline at end of file +this.toggleListening = function() { + + // isListening will take care of 'inherit', and + // trace up through the scene graph to determine + // if the current state is listening or not + if ( this.isListening ) { + this.listening = this.previousListening ? this.previousListening : false; + } else { + this.listening = this.previousListening ? this.previousListening : true; + } + + var listen = this.listening; + + if ( listen === 'inherit' ) { + this.previousListening = 'inherit'; + } else { + this.previousListening = undefined; + } + +} + +//# sourceURL=kinetic_node.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 80cf9dde9..e8ebc3942 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -10,9 +10,11 @@ properties: visible: isVisible: listening: + isListening: id: name: opacity: + disableScaleAndRotationForSpeed: true scale: scaleX: scaleY: @@ -30,26 +32,22 @@ properties: absoluteTransform: absoluteOpacity: absoluteZIndex: - uniqueInView: - dragProperty: "position" + modelX: + modelY: + supportMouseAndTouchEvents: false + hasMouseAndTouchEvents: false + attributes: + hitGraphFromCache: false + minCachePixelSizeThreshold: 0 methods: toggleVisibility: + toggleListening: events: pointerMove: - pointerOut: - pointerEnter: - pointerLeave: pointerDown: pointerUp: pointerClick: - pointerDoubleClick: - touchStart: - touchMove: - touchEnd: - tap: doubleTap: - dragStart: - dragMove: dragEnd: draggingFromView: scripts: diff --git a/support/proxy/vwf.example.com/kinetic/rect.vwf.yaml b/support/proxy/vwf.example.com/kinetic/rect.vwf.yaml index 9496c9485..6ac104e89 100644 --- a/support/proxy/vwf.example.com/kinetic/rect.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/rect.vwf.yaml @@ -4,3 +4,8 @@ extends: http://vwf.example.com/kinetic/shape.vwf properties: cornerRadius: + shadowColor: 'rgba( 1, 1, 1, 0.5 )' + shadowBlur: 10 + shadowOffsetX: 8 + shadowOffsetY: 8 + shadowEnabled: true diff --git a/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml b/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml index 1c500544f..f23b6611a 100644 --- a/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml @@ -4,10 +4,6 @@ extends: http://vwf.example.com/kinetic/node.vwf properties: fill: - fillRed: - fillGreen: - fillBlue: - fillAlpha: fillPatternImage: fillPatternX: fillPatternY: @@ -38,20 +34,12 @@ properties: fillEnabled: fillPriority: stroke: - strokeRed: - strokeGreen: - strokeBlue: - strokeAlpha: strokeWidth: strokeScaleEnabled: strokeEnabled: lineJoin: lineCap: shadowColor: - shadowRed: - shadowGreen: - shadowBlue: - shadowAlpha: shadowBlur: shadowOffset: shadowOffsetX: @@ -61,4 +49,5 @@ properties: dash: dashEnabled: x: 0 - y: 0 \ No newline at end of file + y: 0 + supportMouseAndTouchEvents: true diff --git a/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml b/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml index cb57aac51..baa9f0fc1 100644 --- a/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml @@ -4,7 +4,8 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: container: - enableEvents: + disableScaleAndRotationForSpeed: false + supportMouseAndTouchEvents: true events: pointerDown: pointerMove: diff --git a/support/proxy/vwf.example.com/mil-sym/missionGfx.js b/support/proxy/vwf.example.com/mil-sym/missionGfx.js new file mode 100644 index 000000000..ca8296a14 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/missionGfx.js @@ -0,0 +1,3 @@ +this.initialize = function() { + this.future( 0 ).render(); +} \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/missionGfx.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/missionGfx.vwf.yaml new file mode 100644 index 000000000..e35a0c3e4 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/missionGfx.vwf.yaml @@ -0,0 +1,32 @@ +--- +extends: http://vwf.example.com/kinetic/image.vwf +properties: + affiliation: + fullName: + tagName: + description: + symbolID: + symbolType: + controlPts: [] + scaleOnLoad: false + disableScaleAndRotationForSpeed: false + isDraggable: false + bounds: [] + hitGraphFromCache: true + minCachePixelSizeThreshold: 60 + + image: + set: | + if ( value !== undefined ) { + this.image = value; + this.imageChanged( value ); + } + +methods: + render: + +events: + imageChanged: + +scripts: +- source: "missionGfx.js" \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml new file mode 100755 index 000000000..38bdb6861 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml @@ -0,0 +1,41 @@ +--- +extends: http://vwf.example.com/node.vwf +properties: + pixelSize: 35 + icon: true + keepUnitRatio: + symbologyStandard: + echelon: + quantity: + additionalInfo1: + additionalInfo2: + additionalInfo3: + altitudeDepth: + combatEffectiveness: + directionOfMovement: + DTG1: + DTG2: + evaluationRating: + higherFormation: + hostile: + iffSif: + location: + reinforcedReduced: + signatureEquip: + staffComments: + equipType: + uniqueDesignation1: + uniqueDesignation2: + speed: + validModifiers: + distance: + azimuth: + length: + width: + angle: + fillColor: + lineColor: +scripts: +- | + this.initialize = function() { + } //# sourceURL=modifier.vwf \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unit.js b/support/proxy/vwf.example.com/mil-sym/unit.js new file mode 100755 index 000000000..de8b51c02 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unit.js @@ -0,0 +1,5 @@ +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + this.parent && this.parent.handleRender( img, iconSize, symbolCenter, symbolBounds ); + + //# sourceURL=unit.handleRender +} \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml new file mode 100755 index 000000000..0c8dec24d --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml @@ -0,0 +1,76 @@ +--- +extends: http://vwf.example.com/node2.vwf +properties: + + echelon: + set: | + if ( this.echelon !== value ) { + this.echelon = value; + this.echelonChanged( value ); + } + + affiliation: + set: | + if ( this.affiliation !== value ) { + this.affiliation = value; + this.affiliationChanged( value ); + } + + fullName: + + tagName: + + description: + + symbolID: + set: | + if ( this.symbolID !== value ) { + this.symbolID = value; + this.symbolIDChanged( value ); + } + + image: + + unitStatus: + set: | + if ( this.unitStatus !== value ) { + this.unitStatus = value; + this.unitStatusChanged( value ); + } + + mobility: + set: | + if ( this.mobility !== value ) { + this.mobility = value; + this.mobilityChanged( value ); + } + + taskForce: + set: | + if ( this.taskForce !== value ) { + this.taskForce = value; + this.taskForceChanged( value ); + } + + installation: + set: | + if ( this.installation !== value ) { + this.installation = value; + this.installationChanged( value ); + } + +methods: + handleRender: + +events: + imageRendered: + echelonChanged: + affiliationChanged: + symbolIDChanged: + unitStatusChanged: + mobilityChanged: + taskForceChanged: + installationChanged: + +scripts: +- source: "unit.js" \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.js b/support/proxy/vwf.example.com/mil-sym/unitGroup.js new file mode 100755 index 000000000..2f90b2b2b --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.js @@ -0,0 +1,181 @@ +this.initialize = function() { + + if ( !!this.threatArea ) { + if ( !this.threatArea.fill && !!this.threatArea.attributes && !!this.threatArea.attributes.fill ) { + this.threatArea.fill = this.threatArea.attributes.fill; + } + + this.threatArea.draggable = false; + } + + if ( this.icon !== undefined && this.icon.imageGenerator !== undefined ) { + + this.icon.imageGenerator.affiliationChanged = this.events.add( function( affiliation ) { + + if ( this.threatArea ) { + switch ( affiliation ) { + case "hostile": + this.threatArea.fill = 'red'; + break; + case "neutral": + this.threatArea.fill = 'lime'; + break; + case "friendly": + this.threatArea.fill = 'cyan'; + break; + default: + this.threatArea.fill = 'yellow'; + break; + } + } + + }, this ); + + this.icon.imageGenerator.imageRendered = this.events.add( function( img, iconSize, symbolCenter, symbolBounds ) { + + if ( this.threatArea ) { + this.threatArea.position = this.icon.symbolCenter; + } + + }, this ); + + } + + // Now that unitGroup is complete, show it + this.visible = "inherit"; +} + +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + + this.zIndex = 20; + + if ( this.threatArea ) { + this.threatArea.position = this.icon.symbolCenter; + } +} + +this.updateThreatShape = function() { + + var visible = false; + if ( this.threatArea ) { + visible = this.threatArea.visible; + this.children.delete( this.threatArea ); + } + + var newShape = undefined; + var color = 'yellow'; + + if ( this.icon && this.icon.imageGenerator ) { + switch ( this.icon.imageGenerator.affiliation ) { + case "hostile": + color = 'red'; + break; + case "neutral": + color = 'lime'; + break; + case "friendly": + color = 'cyan'; + break; + }; + } + + switch ( this.threatShape ) { + + case "rect": + newShape = { + "extends": "http://vwf.example.com/kinetic/rect.vwf", + "properties": { + "x": 20, + "y": 20, + "visible": visible, + "listening": false, + "width": 40, + "height": 40, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + case "circle": + newShape = { + "extends": "http://vwf.example.com/kinetic/circle.vwf", + "properties": { + "x": 16, + "y": 16, + "visible": visible, + "listening": false, + "radius": 32, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + case "wedge": + newShape = { + "extends": "http://vwf.example.com/kinetic/wedge.vwf", + "properties": { + "x": 16, + "y": 16, + "visible": visible, + "listening": false, + "width": 40, + "height": 40, + "angle": 40, + "radius": 32, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + default: + this.logger.info( "Unknown threat shape: " + this.threatShape ); + break; + + } + + if ( newShape ) { + this.children.create( "threatArea", newShape ); + this.threatShapeChanged( this.threatShape ); + } + +} + +this.setPositionFromMapPosition = function() { + var symbolCenter = ( this.icon || {} ).symbolCenter || { + x: 0, + y: 0 + } + this.position = { + x: this.mapPosition.x - this.scaleX * symbolCenter.x, + y: this.mapPosition.y - this.scaleY * symbolCenter.y + }; + + //# sourceURL=unitGroup.setPositionFromMapPosition +} + +this.setMapPositionFromPosition = function( konvaObjectPosition, scale ) { + var symbolCenter = ( this.icon || {} ).symbolCenter || { + x: 0, + y: 0 + }; + this.mapPosition = { + x: konvaObjectPosition.x + scale * symbolCenter.x, + y: konvaObjectPosition.y + scale * symbolCenter.y, + } + + //# sourceURL=unitGroup.setMapPositionFromPosition +} + +//# sourceURL=unitGroup.js diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml new file mode 100755 index 000000000..d8cfef6c8 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -0,0 +1,47 @@ +--- +extends: http://vwf.example.com/kinetic/group.vwf +properties: + supportMouseAndTouchEvents: true + disableScaleAndRotationForSpeed: false + index: 8 + zIndex: 8 + dragToTop: true + mapPosition: + set: | + if ( value !== undefined ) { + this.mapPosition = value; + this.setPositionFromMapPosition(); + } + value: { "x": 0, "y": 0 } + + threatShape: + set: | + if ( this.threatShape !== value ) { + this.threatShape = value; + this.updateThreatShape(); + } + value: "circle" + + showThreat: + set: | + if ( this.threatArea !== undefined ) { + this.threatArea.visible = value; + } + get: | + if ( this.threatArea !== undefined ) { + return this.threatArea.visible; + } + return false; + value: false + + mirrorAll: false +methods: + updateThreatShape: + handleRender: + setPositionFromMapPosition: + setMapPositionFromPosition: +events: + threatShapeChanged: + unitGroupDragged: +scripts: +- source: "unitGroup.js" diff --git a/support/proxy/vwf.example.com/mil-sym/unitIcon.js b/support/proxy/vwf.example.com/mil-sym/unitIcon.js new file mode 100755 index 000000000..64597bee6 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitIcon.js @@ -0,0 +1,37 @@ +this.initialize = function() { + + if ( this.imageGenerator !== undefined ) { + this.imageGenerator.imageRendered = this.events.add( function( img, iconSize, symbolCenter, symbolBounds ) { + this.updateIcon( img, iconSize, symbolCenter ); + }, this ); + } + +} + +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + + this.updateIcon( img, iconSize, symbolCenter ); + + if ( this.parent !== undefined ) { + this.parent.handleRender( img, iconSize, symbolCenter, symbolBounds ); + } + + //# sourceURL=unitIcon.handleRender +} + +this.updateIcon = function( img, iconSize, symbolCenter ) { + + // Update the image to the one that has just been rendered + this.image = img; + this.size = iconSize; + this.width = iconSize.width; + this.height = iconSize.height; + this.symbolCenter = symbolCenter; + + // Since the size of the icon might have changed, + // reset the unit group's "position" (upper left point) + // to keep its center on "mapPosition" + this.parent.setPositionFromMapPosition(); + + //# sourceURL=unitIcon.updateIcon +} diff --git a/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml new file mode 100755 index 000000000..dd9c7c963 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml @@ -0,0 +1,50 @@ +--- +extends: http://vwf.example.com/kinetic/image.vwf +properties: + + image: + set: | + if ( value !== undefined ) { + this.image = value; + this.imageChanged( value ); + } + + iconSize: + set: | + if ( value !== undefined ) { + this.iconSize = value; + this.iconSizeChanged( value ); + } + value: { "width": 32, "height": 32 } + + symbolCenter: + set: | + if ( value !== undefined ) { + this.symbolCenter = value; + this.symbolCenterChanged( value ); + } + value: { "x": 16, "y": 16 } + + strokeEnabled: false + transformsEnabled: "position" + zIndex: 20 + shadowColor: "rgba( 1, 1, 1, 0.5 )" + shadowBlur: 10 + shadowOffsetX: 8 + shadowOffsetY: 8 + shadowEnabled: false + +methods: + handleRender: + updateIcon: + +events: + + imageChanged: + + iconSizeChanged: + + symbolCenterChanged: + +scripts: +- source: "unitIcon.js" diff --git a/support/proxy/vwf.example.com/mil-sym/unitSimData.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitSimData.vwf.yaml new file mode 100644 index 000000000..f9ee88409 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitSimData.vwf.yaml @@ -0,0 +1,6 @@ +--- +extends: http://vwf.example.com/node.vwf + +# Support for this component has been removed. +# It is left in for backward compatibility with scenarios that have a unitSimData object in them. +# It was used to support SoarTech's TXS simulation, which is no longer supported.