mission = 
{
    ["trig"] = 
    {
        ["actions"] = 
        {
            [1] = "a_do_script(\"dcsCommon = {}\\\
dcsCommon.version = \\\"2.5.9\\\"\\\
--[[-- VERSION HISTORY\\\
 2.2.6 - compassPositionOfARelativeToB\\\
       - clockPositionOfARelativeToB\\\
 2.2.7 - isTroopCarrier \\\
       - distFlat\\\
 2.2.8 - fixed event2text \\\
 2.2.9 - getUnitAGL\\\
       - getUnitAlt\\\
       - getUnitSpeed \\\
       - getUnitHeading\\\
       - getUnitHeadingDegrees\\\
       - mag\\\
       - clockPositionOfARelativeToB with own heading \\\
 2.3.0 - unitIsInfantry\\\
 2.3.1 - bool2YesNo\\\
       - bool2Text\\\
 2.3.2 - getGroupAvgSpeed\\\
       - getGroupMaxSpeed\\\
 2.3.3 - getSizeOfTable\\\
 2.3.4 - isSceneryObject\\\
         coalition2county\\\
 2.3.5 - smallRandom\\\
         pickRandom uses smallRandom\\\
         airfield handling, parking \\\
         flight waypoint handling\\\
         landing waypoint creation\\\
         take-off waypoint creation\\\
 2.3.6 - createOverheadAirdromeRoutPintData(aerodrome)\\\
 2.3.7 - coalition2county - warning when creating UN \\\
 2.3.8 - improved headingOfBInDegrees, new getClockDirection\\\
 2.3.9 - getClosingVelocity\\\
       - dot product \\\
       - magSquare\\\
       - vMag\\\
 2.4.0 - libCheck\\\
 2.4.1 - grid/square/rect formation \\\
       - arrangeGroupInNColumns formation \\\
       - 2Columns formation deep and wide formation\\\
 2.4.2 - getAirbasesInRangeOfPoint\\\
 2.4.3 - lerp \\\
 2.4.4 - getClosestAirbaseTo\\\
       - fixed bug in containsString when strings equal\\\
 2.4.5 - added cargo and mass options to createStaticObjectData\\\
 2.4.6 - fixed randompercent \\\
 2.4.7 - smokeColor2Num(smokeColor)\\\
 2.4.8 - linkStaticDataToUnit()\\\
 2.4.9 - trim functions \\\
       - createGroundUnitData uses trim function to remove leading/trailing blanks\\\
         so now we can use blanks after comma to separate types \\\
       - dcsCommon.trimArray(\\\
       - createStaticObjectData uses trim for type \\\
       - getEnemyCoalitionFor understands strings, still returns number\\\
       - coalition2county also undertsands 'red' and 'blue'\\\
 2.5.0 - \\\"Line\\\" formation with one unit places unit at center     \\\
 2.5.1 - vNorm(a)  \\\
 2.5.1 - added SA-18 Igla manpad to unitIsInfantry()\\\
 2.5.2 - added copyArray method\\\
       - corrected heading in createStaticObjectData\\\
 2.5.3 - corrected rotateGroupData bug for cz \\\
       - removed forced error in failed pickRandom\\\
 2.5.4 - rotateUnitData()\\\
       - randomBetween()\\\
 2.5.5 - stringStartsWithDigit()\\\
       - stringStartsWithLetter()\\\
       - stringIsPositiveNumber()\\\
 2.5.6 - corrected stringEndsWith() bug with str\\\
 2.5.7 - point2text(p) \\\
 2.5.8 - string2GroupCat()\\\
 2.5.9 - string2ObjectCat()\\\
       \\\
--]]--\\\
\\\
    -- dcsCommon is a library of common lua functions \\\
    -- for easy access and simple mission programming\\\
    -- (c) 2021, 2022 by Chritian Franz and cf/x AG\\\
\\\
    dcsCommon.verbose = false -- set to true to see debug messages. Lots of them\\\
    dcsCommon.uuidStr = \\\"uuid-\\\"\\\
\\\
    -- globals\\\
    dcsCommon.cbID = 0 -- callback id for simple callback scheduling\\\
    dcsCommon.troopCarriers = {\\\"Mi-8MT\\\", \\\"UH-1H\\\", \\\"Mi-24P\\\"} -- Ka-50 and Gazelle can't carry troops\\\
\\\
    -- verify that a module is loaded. obviously not required\\\
    -- for dcsCommon, but all higher-order modules\\\
    function dcsCommon.libCheck(testingFor, requiredLibs)\\\
        local canRun = true \\\
        for idx, libName in pairs(requiredLibs) do \\\
            if not _G[libName] then \\\
                trigger.action.outText(\\\"*** \\\" .. testingFor .. \\\" requires \\\" .. libName, 30)\\\
                canRun = false \\\
            end\\\
        end\\\
        return canRun\\\
    end\\\
\\\
    -- returns only positive values, lo must be >0 and <= hi \\\
    function dcsCommon.randomBetween(loBound, hiBound)\\\
        if not loBound then loBound = 1 end \\\
        if not hiBound then hiBound = 1 end \\\
        if loBound == hiBound then return loBound end \\\
\\\
        local delayMin = loBound\\\
        local delayMax = hiBound \\\
        local delay = delayMax \\\
    \\\
        if delayMin ~= delayMax then \\\
            -- pick random in range , say 3-7 --> 5 s!\\\
            local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\\\
            delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\\\
            delay = delay + delayMin \\\
            if delay > delayMax then delay = delayMax end \\\
            if delay < 1 then delay = 1 end \\\
        \\\
            if dcsCommon.verbose then \\\
                trigger.action.outText(\\\"+++dcsC: delay range \\\" .. delayMin .. \\\"-\\\" .. delayMax .. \\\": selected \\\" .. delay, 30)\\\
            end\\\
        end\\\
        \\\
        return delay\\\
    end\\\
    \\\
\\\
    -- taken inspiration from mist, as dcs lua has issues with\\\
    -- random numbers smaller than 50. Given a range of x numbers 1..x, it is \\\
    -- repeated a number of times until it fills an array of at least \\\
    -- 50 items (usually some more), and only then one itemis picked from \\\
    -- that array with a random number that is from a greater range (0..50+)\\\
    function dcsCommon.smallRandom(theNum) -- adapted from mist, only support ints\\\
        if theNum >= 50 then return math.random(theNum) end\\\
        \\\
        -- for small randoms (<50) \\\
        local lowNum, highNum\\\
        highNum = theNum\\\
        lowNum = 1\\\
        local total = 1\\\
        if math.abs(highNum - lowNum + 1) < 50 then -- if total values is less than 50\\\
            total = math.modf(50/math.abs(highNum - lowNum + 1)) -- number of times to repeat whole range to get above 50. e.g. 11 would be 5 times 1 .. 11, giving us 55 items total \\\
        end\\\
        local choices = {}\\\
        for i = 1, total do -- iterate required number of times\\\
            for x = lowNum, highNum do -- iterate between the range\\\
                choices[#choices +1] = x -- add each entry to a table\\\
            end\\\
        end\\\
        local rtnVal; -- = math.random(#choices) -- will now do a math.random of at least 50 choices\\\
        for i = 1, 15 do\\\
            rtnVal = math.random(#choices) -- iterate 15 times for randomization\\\
        end\\\
        return choices[rtnVal] -- return indexed\\\
    end\\\
    \\\
\\\
    function dcsCommon.getSizeOfTable(theTable)\\\
        local count = 0\\\
        for _ in pairs(theTable) do count = count + 1 end\\\
        return count\\\
    end\\\
\\\
    function dcsCommon.findAndRemoveFromTable(theTable, theElement) -- assumes array \\\
        if not theElement then return false end \\\
        if not theTable then return false end \\\
        for i=1, #theTable do \\\
            if theTable[i] == theElement then \\\
                -- this element found. remove from table \\\
                table.remove(theTable, i)\\\
                return true \\\
            end\\\
        end\\\
    end\\\
\\\
    function dcsCommon.pickRandom(theTable)\\\
        if not theTable then \\\
            trigger.action.outText(\\\"*** warning: nil table in pick random\\\", 30)\\\
        end\\\
        \\\
        if #theTable < 1 then \\\
            trigger.action.outText(\\\"*** warning: zero choice in pick random\\\", 30)\\\
            --local k = i.ll \\\
            return nil\\\
        end\\\
        if #theTable == 1 then return theTable[1] end\\\
        r = dcsCommon.smallRandom(#theTable) --r = math.random(#theTable)\\\
        return theTable[r]\\\
    end\\\
\\\
    -- enumerateTable - make an array out of a table for indexed access\\\
    function dcsCommon.enumerateTable(theTable)\\\
        if not theTable then theTable = {} end\\\
        local array = {}\\\
        for key, value in pairs(theTable) do \\\
            table.insert(array, value)\\\
        end\\\
        return array\\\
    end\\\
\\\
-- \\\
-- A I R F I E L D S  A N D  F A R P S  \\\
--\\\
\\\
    -- airfield management \\\
    function dcsCommon.getAirbaseCat(aBase)\\\
        if not aBase then return nil end \\\
        \\\
        local airDesc = aBase:getDesc()\\\
        if not airDesc then return nil end \\\
        \\\
        local airCat = airDesc.category\\\
        return airCat \\\
    end\\\
\\\
    -- get free parking slot. optional parkingType can be used to \\\
    -- filter for a scpecific type, e.g. 104 = open field\\\
    function dcsCommon.getFirstFreeParkingSlot(aerodrome, parkingType) \\\
        if not aerodrome then return nil end \\\
        local freeSlots = aerodrome:getParking(true)\\\
        \\\
        for idx, theSlot in pairs(freeSlots) do \\\
            if not parkingType then \\\
                -- simply return the first we come across\\\
                return theSlot\\\
            end        \\\
            \\\
            if theSlot.Term_Type == parkingType then \\\
                return theSlot \\\
            end\\\
        end\\\
        \\\
        return nil \\\
    end\\\
\\\
    -- getAirbasesInRangeOfPoint: get airbases that are in range of point \\\
    function dcsCommon.getAirbasesInRangeOfPoint(center, range, filterCat, filterCoalition)\\\
        if not center then return {} end \\\
        if not range then range = 500 end -- 500m default \\\
        local basesInRange = {}\\\
        \\\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition)\\\
        for idx, aBase in pairs(allAB) do             \\\
            local delta = dcsCommon.dist(center, aBase:getPoint())\\\
            if delta <= range then \\\
                table.insert(basesInRange, aBase)\\\
            end\\\
        end\\\
        return basesInRange\\\
    end\\\
\\\
    -- getAirbasesInRangeOfAirbase returns all airbases that \\\
    -- are in range of the given airbase \\\
    function dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeCenter, range, filterCat, filterCoalition)\\\
        if not airbase then return {} end\\\
        if not range then range = 150000 end \\\
        local center = airbase:getPoint() \\\
        local centerName = airbase:getName() \\\
        \\\
        local ABinRange = {}\\\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition)\\\
        \\\
        for idx, aBase in pairs(allAB) do \\\
            if aBase:getName() ~= centerName then \\\
                local delta = dcsCommon.dist(center, aBase:getPoint())\\\
                if delta <= range then \\\
                    table.insert(ABinRange, aBase)\\\
                end\\\
            end        \\\
        end\\\
        \\\
        if includeCenter then \\\
            table.insert(ABinRange, airbase)\\\
        end\\\
        \\\
        return ABinRange\\\
    end\\\
\\\
    function dcsCommon.getAirbasesInRangeOfAirbaseList(theCenterList, includeList, range, filterCat, filterCoalition)\\\
        local collectorDict = {}\\\
        for idx, aCenter in pairs(theCenterList) do \\\
            -- get all surrounding airbases. returns list of airfields \\\
            local surroundingAB = dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeList, range, filterCat, filterCoalition)\\\
            \\\
            for idx2, theAirField in pairs (surroundingAB) do \\\
                collectorDict[airField] = theAirField \\\
            end\\\
        end\\\
        \\\
        -- make result an array\\\
        local theABList = dcsCommon.enumerateTable(collectorDict)\\\
        return theABList\\\
    end\\\
\\\
    -- getAirbasesWhoseNameContains - get all airbases containing \\\
    -- a name. filterCat is optional and can be aerodrome (0), farp (1), ship (2)\\\
    -- filterCoalition is optional and can be 0 (neutral), 1 (red), 2 (blue) \\\
    -- if no name given or aName = \\\"*\\\", then all bases are returned prior to filtering \\\
    function dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\\\
        --trigger.action.outText(\\\"getAB(name): enter with \\\" .. aName, 30)\\\
        if not aName then aName = \\\"*\\\" end \\\
        local allYourBase = world.getAirbases() -- get em all \\\
        local areBelongToUs = {}\\\
        -- now iterate all bases\\\
        for idx, aBase in pairs(allYourBase) do\\\
            local airBaseName = aBase:getName() -- get display name\\\
            if aName == \\\"*\\\" or dcsCommon.containsString(airBaseName, aName) then \\\
                -- containsString is case insesitive unless told otherwise\\\
                --if aName ~= \\\"*\\\" then \\\
                --    trigger.action.outText(\\\"getAB(name): matched \\\" .. airBaseName, 30)\\\
                --end \\\
                local doAdd = true \\\
                if filterCat then \\\
                    -- make sure the airbase is of that category \\\
                    local airCat = dcsCommon.getAirbaseCat(aBase)\\\
                    doAdd = doAdd and airCat == filterCat \\\
                end\\\
                \\\
                if filterCoalition then \\\
                    doAdd = doAdd and filterCoalition == aBase:getCoalition()\\\
                end\\\
                \\\
                if doAdd then \\\
                    -- all good, add to table\\\
                    table.insert(areBelongToUs, aBase)\\\
                end            \\\
            end\\\
        end\\\
        return areBelongToUs\\\
    end\\\
\\\
    function dcsCommon.getFirstAirbaseWhoseNameContains(aName, filterCat, filterCoalition)\\\
        local allBases = dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\\\
        for idx, aBase in pairs (allBases) do \\\
            -- simply return first \\\
            return aBase\\\
        end\\\
        return nil \\\
    end    \\\
\\\
    function dcsCommon.getClosestAirbaseTo(thePoint, filterCat, filterCoalition)\\\
        local delta = math.huge\\\
        local allYourBase = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition) -- get em all and filter\\\
        local closestBase = nil \\\
        for idx, aBase in pairs(allYourBase) do\\\
            -- iterate them all \\\
            local abPoint = aBase:getPoint()\\\
            newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\\\
            if newDelta < delta then \\\
                delta = newDelta\\\
                closestBase = aBase\\\
            end\\\
        end\\\
        return closestBase, delta \\\
    end\\\
\\\
-- \\\
-- U N I T S   M A N A G E M E N T \\\
--\\\
\\\
    -- number of living units in group\\\
    function dcsCommon.livingUnitsInGroup(group)\\\
        local living = 0\\\
        local allUnits = group:getUnits()\\\
        for key, aUnit in pairs(allUnits) do \\\
            if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                living = living + 1\\\
            end\\\
        end\\\
        return living\\\
    end\\\
\\\
    -- closest living unit in group to a point\\\
    function dcsCommon.getClosestLivingUnitToPoint(group, p)\\\
        if not p then return nil end\\\
        if not group then return nil end\\\
        local closestUnit = nil\\\
        local closestDist = math.huge\\\
        local allUnits = group:getUnits()\\\
        for key, aUnit in pairs(allUnits) do \\\
            if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                local thisDist = dcsCommon.dist(p, aUnit:getPoint())\\\
                if thisDist < closestDist then \\\
                    closestDist = thisDist\\\
                    closestUnit = aUnit \\\
                end\\\
            end\\\
        end\\\
        return closestUnit, closestDist\\\
    end\\\
    \\\
    -- closest living group to a point - cat can be nil or one of Group.Category = { AIRPLANE = 0, HELICOPTER = 1, GROUND = 2, SHIP = 3, TRAIN = 4}\\\
    function dcsCommon.getClosestLivingGroupToPoint(p, coal, cat) \\\
        if not cat then cat = 2 end -- ground is default \\\
        local closestGroup = nil;\\\
        local closestGroupDist = math.huge\\\
        local allGroups =  coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \\\
        for key, grp in pairs(allGroups) do\\\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\\\
            if closestUnit then \\\
                if dist < closestGroupDist then \\\
                    closestGroup = grp\\\
                    closestGroupDist = dist\\\
                end\\\
            end            \\\
        end\\\
        return closestGroup, closestGroupDist\\\
    end\\\
\\\
    function dcsCommon.getLivingGroupsAndDistInRangeToPoint(p, range, coal, cat) \\\
        if not cat then cat = 2 end -- ground is default \\\
        local groupsInRange = {};\\\
        local allGroups = coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \\\
        for key, grp in pairs(allGroups) do\\\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\\\
            if closestUnit then \\\
                if dist < range then \\\
                    table.insert(groupsInRange, {group = grp, dist = dist}) -- array\\\
                end\\\
            end            \\\
        end\\\
        -- sort the groups by distance\\\
        table.sort(groupsInRange, function (left, right) return left.dist < right.dist end )\\\
        return groupsInRange\\\
    end\\\
\\\
    -- distFlat ignores y, input must be xyz points, NOT xy points  \\\
    function dcsCommon.distFlat(p1, p2) \\\
        local point1 = {x = p1.x, y = 0, z=p1.z}\\\
        local point2 = {x = p2.x, y = 0, z=p2.z}\\\
        return dcsCommon.dist(point1, point2)\\\
    end\\\
    \\\
    -- distance between points\\\
    function dcsCommon.dist(point1, point2)     -- returns distance between two points\\\
      -- supports xyz and xy notations\\\
      if not point1 then \\\
        trigger.action.outText(\\\"+++ warning: nil point1 in common:dist\\\", 30)\\\
        point1 = {x=0, y=0, z=0}\\\
      end\\\
\\\
      if not point2 then \\\
        trigger.action.outText(\\\"+++ warning: nil point2 in common:dist\\\", 30)\\\
        point2 = {x=0, y=0, z=0}\\\
        stop.here.now = 1\\\
      end\\\
      \\\
      local p1 = {x = point1.x, y = point1.y}\\\
      if not point1.z then \\\
        p1.z = p1.y\\\
        p1.y = 0\\\
      else \\\
        p1.z = point1.z\\\
      end\\\
      \\\
      local p2 = {x = point2.x, y = point2.y}\\\
      if not point2.z then \\\
        p2.z = p2.y\\\
        p2.y = 0\\\
      else \\\
        p2.z = point2.z\\\
      end\\\
      \\\
      local x = p1.x - p2.x\\\
      local y = p1.y - p2.y \\\
      local z = p1.z - p2.z\\\
      \\\
      return (x*x + y*y + z*z)^0.5\\\
    end\\\
\\\
    function dcsCommon.delta(name1, name2) -- returns distance (in meters) of two named objects\\\
      local n1Pos = Unit.getByName(name1):getPosition().p\\\
      local n2Pos = Unit.getByName(name2):getPosition().p\\\
      return dcsCommon.dist(n1Pos, n2Pos)\\\
    end\\\
\\\
    -- lerp between a and b, x being 0..1 (percentage), clipped to [0..1]\\\
    function dcsCommon.lerp(a, b, x) \\\
        if not a then return 0 end\\\
        if not b then return 0 end\\\
        if not x then return a end\\\
        if x < 0 then x = 0 end \\\
        if x > 1 then x = 1 end \\\
        return a + (b - a ) * x\\\
    end\\\
\\\
    function dcsCommon.bearingFromAtoB(A, B) -- coords in x, z \\\
        dx = B.x - A.x\\\
        dz = B.z - A.z\\\
        bearing = math.atan2(dz, dx) -- in radiants\\\
        return bearing\\\
    end\\\
\\\
    function dcsCommon.bearingInDegreesFromAtoB(A, B)\\\
        local bearing = dcsCommon.bearingFromAtoB(A, B) -- in rads \\\
        bearing = math.floor(bearing / math.pi * 180)\\\
        if bearing < 0 then bearing = bearing + 360 end\\\
        if bearing > 360 then bearing = bearing - 360 end\\\
        return bearing\\\
    end\\\
    \\\
    function dcsCommon.compassPositionOfARelativeToB(A, B)\\\
        -- warning: is REVERSE in order for bearing, returns a string like 'Sorth', 'Southwest'\\\
        if not A then return \\\"***error:A***\\\" end\\\
        if not B then return \\\"***error:B***\\\" end\\\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\\\
        if bearing < 23 then return \\\"North\\\" end \\\
        if bearing < 68 then return \\\"NE\\\" end\\\
        if bearing < 112 then return \\\"East\\\" end \\\
        if bearing < 158 then return \\\"SE\\\" end \\\
        if bearing < 202 then return \\\"South\\\" end \\\
        if bearing < 248 then return \\\"SW\\\" end \\\
        if bearing < 292 then return \\\"West\\\" end\\\
        if bearing < 338 then return \\\"NW\\\" end \\\
        return \\\"North\\\"\\\
    end\\\
    \\\
    function dcsCommon.clockPositionOfARelativeToB(A, B, headingOfBInDegrees)\\\
        -- o'clock notation \\\
        if not A then return \\\"***error:A***\\\" end\\\
        if not B then return \\\"***error:B***\\\" end\\\
        if not headingOfBInDegrees then headingOfBInDegrees = 0 end \\\
        \\\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\\\
--        trigger.action.outText(\\\"+++comm: oclock - bearing = \\\" .. bearing .. \\\" and inHeading = \\\" .. headingOfBInDegrees, 30) \\\
        bearing = bearing - headingOfBInDegrees\\\
        return dcsCommon.getClockDirection(bearing)\\\
        \\\
    end \\\
    \\\
    -- given a heading, return clock with 0 being 12, 180 being 6 etc.\\\
    function dcsCommon.getClockDirection(direction) -- inspired by cws, improvements my own\\\
        if not direction then return 0 end\\\
        direction = math.fmod (direction, 360)\\\
        while direction < 0 do \\\
            direction = direction + 360\\\
        end\\\
        \\\
        if direction < 15 then -- special case 12 o'clock past 12 o'clock\\\
            return 12\\\
        end\\\
    \\\
        direction = direction + 15 -- add offset so we get all other times correct\\\
        return math.floor(direction/30)\\\
    \\\
    end\\\
\\\
    \\\
    function dcsCommon.randomDegrees()\\\
        local degrees = math.random(360) * 3.14152 / 180\\\
        return degrees\\\
    end\\\
\\\
    function dcsCommon.randomPercent()\\\
        local percent = math.random(100)/100\\\
        return percent\\\
    end\\\
\\\
    function dcsCommon.randomPointOnPerimeter(sourceRadius, x, z) \\\
        return dcsCommon.randomPointInCircle(sourceRadius, sourceRadius-1, x, z)\\\
    end\\\
\\\
    function dcsCommon.randomPointInCircle(sourceRadius, innerRadius, x, z)\\\
        if not x then x = 0 end\\\
        --local y = 0\\\
        if not innerRadius then innerRadius = 0 end        \\\
        if innerRadius < 0 then innerRadius = 0 end\\\
        \\\
        local percent = dcsCommon.randomPercent() -- 1 / math.random(100)\\\
        -- now lets get a random degree\\\
        local degrees = dcsCommon.randomDegrees() -- math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \\\
        local r = (sourceRadius-innerRadius) * percent \\\
        local x = x + (innerRadius + r) * math.cos(degrees)\\\
        local z = z + (innerRadius + r) * math.sin(degrees)\\\
    \\\
        local thePoint = {}\\\
        thePoint.x = x\\\
        thePoint.y = 0\\\
        thePoint.z = z \\\
        \\\
        return thePoint, degrees\\\
    end\\\
\\\
    -- get group location: get the group's location by \\\
    -- accessing the fist existing, alive member of the group that it finds\\\
    function dcsCommon.getGroupLocation(group)\\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                return theUnit:getPosition().p \\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        --trigger.action.outText(\\\"+++cmn: A group has no live units. returning nil\\\", 10)\\\
        return nil \\\
        \\\
    end\\\
\\\
    -- get the group's first Unit that exists and is \\\
    -- alive \\\
    function dcsCommon.getGroupUnit(group)\\\
        if not group then return nil  end\\\
        \\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        if not group:isExist() then return nil end \\\
        \\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                return theUnit\\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        --trigger.action.outText(\\\"+++cmn A group has no live units. returning nil\\\", 10)\\\
        return nil \\\
        \\\
    end\\\
\\\
    -- and here the alias\\\
    function dcsCommon.getFirstLivingUnit(group)\\\
        return dcsCommon.getGroupUnit(group)\\\
    end\\\
    \\\
    -- isGroupAlive returns true if there is at least one unit in the group that isn't dead\\\
    function dcsCommon.isGroupAlive(group)\\\
        return (dcsCommon.getGroupUnit(group) ~= nil) \\\
    end\\\
\\\
    function dcsCommon.getLiveGroupUnits(group)\\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        local liveUnits = {}\\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                table.insert(liveUnits, theUnit) \\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        return liveUnits\\\
    end\\\
\\\
    function dcsCommon.getGroupTypeString(group) -- convert into comma separated types \\\
        if not group then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypeString: nil group\\\", 30)\\\
            return \\\"\\\" \\\
        end\\\
        if not dcsCommon.isGroupAlive(group) then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypeString: dead group\\\", 30)\\\
            return \\\"\\\" \\\
        end \\\
        local theTypes = \\\"\\\"\\\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\\\
        for i=1, #liveUnits do \\\
            if i > 1 then theTypes = theTypes .. \\\",\\\" end\\\
            theTypes = theTypes .. liveUnits[i]:getTypeName()\\\
        end\\\
        return theTypes\\\
    end\\\
\\\
    function dcsCommon.getGroupTypes(group) \\\
        if not group then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypes: nil group\\\", 30)\\\
            return {}\\\
        end\\\
        if not dcsCommon.isGroupAlive(group) then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypes: dead group\\\", 30)\\\
            return {}\\\
        end \\\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\\\
        local unitTypes = {}\\\
        for i=1, #liveUnits do \\\
            table.insert(unitTypes, liveUnits[i]:getTypeName())\\\
        end\\\
        return unitTypes\\\
    end\\\
\\\
    function dcsCommon.getEnemyCoalitionFor(aCoalition)\\\
        if aCoalition == 1 then return 2 end\\\
        if aCoalition == 2 then return 1 end\\\
        if type(aCoalition) == \\\"string\\\" then \\\
            aCoalition = aCoalition:lower()\\\
            if aCoalition == \\\"red\\\" then return 2 end\\\
            if aCoalition == \\\"blue\\\" then return 1 end\\\
        end\\\
        return nil\\\
    end\\\
\\\
    function dcsCommon.getACountryForCoalition(aCoalition)\\\
        -- scan the table of countries and get the first country that is part of aCoalition\\\
        -- this is useful if you want to create troops for a coalition but don't know the\\\
        -- coalition's countries \\\
        -- we start with id=0 (Russia), go to id=85 (Slovenia), but skip id = 14\\\
        local i = 0\\\
        while i < 86 do \\\
            if i ~= 14 then \\\
                if (coalition.getCountryCoalition(i) == aCoalition) then return i end\\\
            end\\\
            i = i + 1\\\
        end\\\
        \\\
        return nil\\\
    end\\\
--\\\
--\\\
-- C A L L B A C K   H A N D L E R \\\
--\\\
--\\\
\\\
    -- installing callbacks\\\
    -- based on mist, with optional additional hooks for pre- and post-\\\
    -- processing of the event\\\
    -- when filtering occurs in pre, an alternative 'rejected' handler can be called \\\
    function dcsCommon.addEventHandler(f, pre, post, rejected) -- returns ID \\\
        local handler = {} -- build a wrapper and connect the onEvent\\\
        --dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\\\
        handler.id = dcsCommon.uuid(\\\"eventHandler\\\")\\\
        handler.f = f -- the callback itself\\\
        if (rejected) then handler.rejected = rejected end\\\
        -- now set up pre- and post-processors. defaults are set in place\\\
        -- so pre and post are optional. If pre returns false, the callback will\\\
        -- not be invoked\\\
        if (pre) then handler.pre = pre else handler.pre = dcsCommon.preCall end\\\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\\\
        function handler:onEvent(event)\\\
            if not self.pre(event) then \\\
                if dcsCommon.verbose then\\\
--                    trigger.action.outText(\\\"event \\\" .. event.id .. \\\" discarded by pre-processor\\\", 10)\\\
                end\\\
                if (self.rejected) then self.rejected(event) end \\\
                return\\\
            end\\\
            self.f(event) -- call the handler\\\
            self.post(event) -- do post-processing\\\
        end\\\
        world.addEventHandler(handler)\\\
        return handler.id\\\
    end\\\
\\\
    function dcsCommon.preCall(e)\\\
        -- we can filter here\\\
        -- if we return false, the call is abortet\\\
        if dcsCommon.verbose then\\\
            trigger.action.outText(\\\"event \\\" .. e.id .. \\\" received: PRE-PROCESSING\\\", 10)\\\
        end\\\
        return true;\\\
    end;\\\
\\\
    function dcsCommon.postCall(e)\\\
        -- we do pos proccing here \\\
        if dcsCommon.verbose then\\\
            trigger.action.outText(\\\"event \\\" .. e.id .. \\\" received: post proc\\\", 10)\\\
        end\\\
    end\\\
    \\\
    -- highly specific eventhandler for one event only\\\
    -- based on above, with direct filtering built in; skips pre\\\
    -- but does post\\\
    function dcsCommon.addEventHandlerForEventTypes(f, evTypes, post, rejected) -- returns ID \\\
        local handler = {} -- build a wrapper and connect the onEvent\\\
        dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\\\
        handler.id = dcsCommon.cbID\\\
        handler.what = evTypes\\\
        if (rejected) then handler.rejected = rejected end \\\
        \\\
        handler.f = f -- set the callback itself\\\
        -- now set up post-processor. pre is hard-coded to match evType\\\
        -- post is optional. If event.id is not in evTypes, the callback will\\\
        -- not be invoked\\\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\\\
        function handler:onEvent(event)\\\
            hasMatch = false;\\\
            for key, evType in pairs(self.what) do\\\
                if evType == event.id then\\\
                    hasMatch = true;\\\
                    break;\\\
                end;\\\
            end;\\\
            if not hasMatch then \\\
                if dcsCommon.verbose then\\\
                    trigger.action.outText(\\\"event \\\" .. e.id .. \\\" discarded - not in whitelist evTypes\\\", 10)\\\
                end\\\
                if (self.rejected) then self.rejected(event) end \\\
                return;\\\
            end;\\\
            \\\
            self.f(event) -- call the actual handler as passed to us\\\
            self.post(event) -- do post-processing \\\
        end\\\
        world.addEventHandler(handler) -- add to event handlers\\\
        return handler.id\\\
    end\\\
    \\\
    \\\
    \\\
    -- remove event handler / callback, identical to Mist \\\
    -- note we don't call world.removeEventHandler, but rather directly \\\
    -- access world.eventHandlers directly and remove kvp directly.\\\
    function dcsCommon.removeEventHandler(id)\\\
        for key, handler in pairs(world.eventHandlers) do\\\
            if handler.id and handler.id == id then\\\
                world.eventHandlers[key] = nil\\\
                return true\\\
            end\\\
        end\\\
        return false\\\
    end\\\
\\\
--\\\
--\\\
-- C L O N I N G \\\
--\\\
--\\\
    -- topClone is a shallow clone of orig, only top level is iterated,\\\
    -- all values are ref-copied\\\
    function dcsCommon.topClone(orig)\\\
        local orig_type = type(orig)\\\
        local copy\\\
        if orig_type == 'table' then\\\
            copy = {}\\\
            for orig_key, orig_value in pairs(orig) do\\\
                copy[orig_key] = orig_value\\\
            end\\\
        else -- number, string, boolean, etc\\\
            copy = orig\\\
        end\\\
        return copy\\\
    end\\\
\\\
    -- clone is a recursive clone which will also clone\\\
    -- deeper levels, as used in units \\\
    function dcsCommon.clone(orig)\\\
        local orig_type = type(orig)\\\
        local copy\\\
        if orig_type == 'table' then\\\
            copy = {}\\\
            for orig_key, orig_value in next, orig, nil do\\\
                copy[dcsCommon.clone(orig_key)] = dcsCommon.clone(orig_value)\\\
            end\\\
            setmetatable(copy, dcsCommon.clone(getmetatable(orig)))\\\
        else -- number, string, boolean, etc\\\
            copy = orig\\\
        end\\\
        return copy\\\
    end\\\
\\\
    function dcsCommon.copyArray(inArray)\\\
        -- warning: this is a ref copy!\\\
        local theCopy = {}\\\
        for idx, element in pairs(inArray) do \\\
            table.insert(theCopy, element)\\\
        end\\\
        return theCopy \\\
    end\\\
--\\\
-- \\\
-- S P A W N I N G \\\
-- \\\
-- \\\
\\\
    function dcsCommon.createEmptyGroundGroupData (name)\\\
        local theGroup = {} -- empty group\\\
        theGroup.visible = false\\\
        theGroup.taskSelected = true\\\
        -- theGroup.route = {}\\\
        -- theGroup.groupId = id\\\
        theGroup.tasks = {}\\\
        -- theGroup.hidden = false -- hidden on f10?\\\
\\\
        theGroup.units = { } -- insert units here! -- use addUnitToGroupData\\\
\\\
        theGroup.x = 0\\\
        theGroup.y = 0\\\
        theGroup.name = name\\\
        -- theGroup.start_time = 0\\\
        theGroup.task = \\\"Ground Nothing\\\"\\\
        \\\
        return theGroup\\\
    end;\\\
\\\
    function dcsCommon.createEmptyAircraftGroupData (name)\\\
        local theGroup = dcsCommon.createEmptyGroundGroupData(name)--{} -- empty group\\\
\\\
        theGroup.task = \\\"Nothing\\\" -- can be others, like Transport, CAS, etc\\\
        -- returns with empty route\\\
        theGroup.route = dcsCommon.createEmptyAircraftRouteData() -- we can add points here \\\
        return theGroup\\\
    end;\\\
\\\
    function dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\\\
        local rp = {}\\\
        rp.x = x\\\
        rp.y = z\\\
        rp.action = \\\"Turning Point\\\"\\\
        rp.type = \\\"Turning Point\\\"\\\
        if action then rp.action = action; rp.type = action end -- warning: may not be correct, need to verify later\\\
        rp.alt = altitudeInFeet * 0.3048\\\
        rp.speed = knots * 0.514444 -- we use \\\
        rp.alt_type = \\\"BARO\\\"\\\
        if (altType) then rp.alt_type = altType end \\\
        return rp\\\
    end\\\
\\\
    function dcsCommon.addRoutePointDataToRouteData(inRoute, x, z, altitudeInFeet, knots, altType, action)\\\
        local p = dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\\\
        local thePoints = inRoute.points \\\
        table.insert(thePoints, p)\\\
    end\\\
    \\\
    function dcsCommon.addRoutePointDataToGroupData(group, x, z, altitudeInFeet, knots, altType, action)\\\
        if not group.route then group.route = dcsCommon.createEmptyAircraftRouteData() end\\\
        local theRoute = group.route \\\
        dcsCommon.addRoutePointDataToRouteData(theRoute, x, z, altitudeInFeet, knots, altType, action)\\\
    end\\\
\\\
    function dcsCommon.addRoutePointForGroupData(theGroup, theRP)\\\
        if not theGroup then return end \\\
        if not theGroup.route then theGroup.route = dcsCommon.createEmptyAircraftRouteData() end\\\
        \\\
        local theRoute = theGroup.route \\\
        local thePoints = theRoute.points \\\
        table.insert(thePoints, theRP)\\\
    end\\\
    \\\
    function dcsCommon.createEmptyAircraftRouteData()\\\
        local route = {}\\\
        route.points = {}\\\
        return route\\\
    end\\\
\\\
    function dcsCommon.createTakeOffFromParkingRoutePointData(aerodrome)\\\
        if not aerodrome then return nil end \\\
            \\\
        local rp = {}    \\\
        local freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome, 104) -- get big slot first \\\
        if not freeParkingSlot then \\\
            freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome) -- try any size\\\
        end\\\
            \\\
        if not freeParkingSlot then \\\
            trigger.action.outText(\\\"civA: no free parking at \\\" .. aerodrome:getName(), 30)\\\
            return nil \\\
        end\\\
            \\\
        local p = freeParkingSlot.vTerminalPos\\\
            \\\
        rp.airdromeId = aerodrome:getID() \\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y \\\
        rp.action = \\\"From Parking Area\\\"\\\
        rp.type = \\\"TakeOffParking\\\"\\\
            \\\
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
\\\
    function dcsCommon.createOverheadAirdromeRoutPintData(aerodrome)\\\
        if not aerodrome then return nil end \\\
        local rp = {}            \\\
        local p = aerodrome:getPoint()\\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y + 2000 -- 6000 ft overhead\\\
        rp.action = \\\"Turning Point\\\"\\\
        rp.type = \\\"Turning Point\\\"\\\
            \\\
        rp.speed = 133; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
    \\\
\\\
    function dcsCommon.createLandAtAerodromeRoutePointData(aerodrome)\\\
        if not aerodrome then return nil end \\\
            \\\
        local rp = {}            \\\
        local p = aerodrome:getPoint()\\\
        rp.airdromeId = aerodrome:getID() \\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y \\\
        rp.action = \\\"Landing\\\"\\\
        rp.type = \\\"Land\\\"\\\
            \\\
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
\\\
    \\\
    function dcsCommon.createRPFormationData(findex) -- must be added as \\\"task\\\" to an RP. use 4 for Echelon right\\\
        local task = {}\\\
        task.id = \\\"ComboTask\\\"\\\
        local params = {}\\\
        task.params = params\\\
        local tasks = {}\\\
        params.tasks = tasks\\\
        local t1 = {}\\\
        tasks[1] = t1\\\
        t1.number = 1\\\
        t1.auto = false \\\
        t1.id = \\\"WrappedAction\\\"\\\
        t1.enabled = true\\\
        local t1p = {}\\\
        t1.params = t1p\\\
        local action = {}\\\
        t1p.action = action \\\
        action.id = \\\"Option\\\"\\\
        local ap = {}\\\
        action.params = ap\\\
        ap.variantIndex = 3\\\
        ap.name = 5 -- AI.Option.Air.ID 5 = Formation \\\
        ap.formationIndex = findex -- 4 is echelon_right\\\
        ap.value = 262147\\\
        \\\
        return task \\\
    end\\\
\\\
    function dcsCommon.addTaskDataToRP(theTask, theGroup, rpIndex)\\\
        local theRoute = theGroup.route\\\
        local thePoints = theRoute.points\\\
        local rp = thePoints[rpIndex]\\\
        rp.task = theTask\\\
    end\\\
    \\\
    -- create a minimal payload table that is compatible with creating \\\
    -- a unit. you may need to alter this before adding the unit to\\\
    -- the mission. all params optional \\\
    function dcsCommon.createPayload(fuel, flare, chaff, gun) \\\
        local payload = {}\\\
        payload.pylons = {}\\\
        if not fuel then fuel = 1000 end -- in kg. check against fuelMassMax in type desc\\\
        if not flare then flare = 0 end\\\
        if not chaff then chaff = 0 end\\\
        if not gun then gun = 0 end\\\
        return payload \\\
        \\\
    end\\\
\\\
    function dcsCommon.createCallsign(cs) \\\
        local callsign = {}\\\
        callsign[1] = 1\\\
        callsign[2] = 1\\\
        callsign[3] = 1\\\
        if not cs then cs = \\\"Enfield11\\\" end\\\
        callsign.name = cs\\\
        return callsign\\\
    end\\\
    \\\
\\\
    -- create the data table required to spawn a unit.\\\
    -- unit types are defined in https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\\\
    function dcsCommon.createGroundUnitData(name, unitType, transportable)\\\
        local theUnit = {}\\\
        unitType = dcsCommon.trim(unitType)\\\
        theUnit.type = unitType -- e.g. \\\"LAV-25\\\",\\\
        if not transportable then transportable = false end -- elaborate, not requried code\\\
        theUnit.transportable = {[\\\"randomTransportable\\\"] = transportable} \\\
        -- theUnit.unitId = id \\\
        theUnit.skill = \\\"Average\\\" -- always average \\\
        theUnit.x = 0 -- make it zero, zero!\\\
        theUnit.y = 0\\\
        theUnit.name = name\\\
        theUnit.playerCanDrive = false\\\
        theUnit.heading = 0\\\
        return theUnit\\\
    end \\\
\\\
    function dcsCommon.createAircraftUnitData(name, unitType, transportable, altitude, speed, heading)\\\
        local theAirUnit = dcsCommon.createGroundUnitData(name, unitType, transportable)\\\
        theAirUnit.alt = 100 -- make it 100m\\\
        if altitude then theAirUnit.alt = altitude end \\\
        theAirUnit.alt_type = \\\"RADIO\\\" -- AGL\\\
        theAirUnit.speed = 77 -- m/s --> 150 knots\\\
        if speed then theAirUnit.speed = speed end \\\
        if heading then theAirUnit.heading = heading end \\\
        theAirUnit.payload = dcsCommon.createPayload()\\\
        theAirUnit.callsign = dcsCommon.createCallsign()\\\
        return theAirUnit\\\
    end\\\
    \\\
\\\
    function dcsCommon.addUnitToGroupData(theUnit, theGroup, dx, dy, heading)\\\
        -- add a unit to a group, and place it at dx, dy of group's position,\\\
        -- taking into account unit's own current location\\\
        if not dx then dx = 0 end\\\
        if not dy then dy = 0 end\\\
        if not heading then heading = 0 end\\\
        theUnit.x = theUnit.x + dx + theGroup.x\\\
        theUnit.y = theUnit.y + dy + theGroup.y \\\
        theUnit.heading = heading\\\
        table.insert(theGroup.units, theUnit)\\\
    end;\\\
\\\
    function dcsCommon.createSingleUnitGroup(name, theUnitType, x, z, heading) \\\
        -- create the container \\\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\\\
        local aUnit = {}\\\
        aUnit = dcsCommon.createGroundUnitData(name .. \\\"-1\\\", theUnitType, false)\\\
--        trigger.action.outText(\\\"dcsCommon - unit name retval \\\" .. aUnit.name, 30)\\\
        dcsCommon.addUnitToGroupData(aUnit, theNewGroup, x, z, heading)\\\
        return theNewGroup\\\
    end\\\
    \\\
\\\
    function dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\\\
        -- formations:\\\
        --    (default) \\\"line\\\" (left to right along x) -- that is Y direction\\\
        --    \\\"line_v\\\" a line top to bottom -- that is X direction\\\
        --    \\\"chevron\\\" - left to right middle too top\\\
        --    \\\"scattered\\\", \\\"random\\\" -- random, innerRadius used to clear area in center\\\
        --       \\\"circle\\\", \\\"circle_forward\\\" -- circle, forward facing\\\
        --    \\\"circle_in\\\" -- circle, inwarf facing\\\
        --    \\\"circle_out\\\" -- circle, outward facing\\\
        --    \\\"grid\\\", \\\"square\\\", \\\"rect\\\" -- optimal rectangle\\\
        --    \\\"2cols\\\", \\\"2deep\\\" -- 2 columns, n deep \\\
        --    \\\"2wide\\\" -- 2 columns wide, 2 deep \\\
\\\
        local num = #theNewGroup.units \\\
        \\\
        -- now do the formation stuff\\\
        -- make sure that they keep minimum  distance \\\
--        trigger.action.outText(\\\"dcsCommon - processing formation \\\" .. formation .. \\\" with radius = \\\" .. radius, 30)\\\
        if formation == \\\"LINE_V\\\" then \\\
            -- top to bottom in zone (heding 0). -- will run through x-coordinate \\\
            -- use entire radius top to bottom \\\
            local currX = -radius\\\
            local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            for i=1, num do\\\
            \\\
                local u = theNewGroup.units[i]\\\
--                trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currX, 30)\\\
                u.x = currX\\\
                currX = currX + increment\\\
            end\\\
        \\\
        elseif formation == \\\"LINE\\\" then \\\
            -- left to right in zone. runs through Y\\\
            -- left and right are y because at heading 0, forward is x (not y as expected)\\\
            -- if only one, place in middle of circle and be done \\\
            if num == 1 then \\\
                -- nothing. just stay in the middle \\\
            else \\\
                local currY = -radius\\\
                local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
                for i=1, num do\\\
                    local u = theNewGroup.units[i]\\\
--                    trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currY, 30)\\\
                    u.y = currY\\\
                    currY = currY + increment\\\
                end    \\\
            end \\\
            \\\
        elseif formation == \\\"CHEVRON\\\" then \\\
            -- left to right in zone. runs through Y\\\
            -- left and right are y because at heading 0, forward is x (not y as expected)\\\
            local currY = -radius\\\
            local currX = 0\\\
            local incrementY = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            local incrementX = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            for i=1, num do\\\
                local u = theNewGroup.units[i]\\\
--                trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currX .. \\\" currY = \\\" .. currY, 30)\\\
                u.x = currX\\\
                u.y = currY\\\
                -- calc coords for NEXT iteration\\\
                currY = currY + incrementY -- march left to right\\\
                if i < num / 2 then -- march up\\\
                    currX = currX + incrementX \\\
                elseif i == num / 2 then -- even number, keep height\\\
                    currX = currX + 0 \\\
                else \\\
                    currX = currX - incrementX -- march down \\\
                end \\\
                -- note: when unit number even, the wedge is sloped. may need an odd/even test for better looks\\\
            end    \\\
\\\
        elseif formation == \\\"SCATTERED\\\" or formation == \\\"RANDOM\\\" then \\\
            -- use randomPointInCircle and tehn iterate over all vehicles for mindelta\\\
            processedUnits = {}\\\
            for i=1, num do\\\
                local emergencyBreak = 1 -- prevent endless loop\\\
                local lowDist = 10000\\\
                local uPoint = {}\\\
                local thePoint = {}\\\
                repeat     -- get random point intil mindistance to all is kept or emergencybreak\\\
                    for idx, rUnit in pairs(processedUnits) do -- get min dist to all positioned units\\\
                        thePoint = dcsCommon.randomPointInCircle(radius, innerRadius) -- returns x, 0, z\\\
                        uPoint.x = rUnit.x\\\
                        uPoint.y = 0\\\
                        uPoint.z = rUnit.y \\\
                        local dist = dcsCommon.dist(thePoint, uPoint) -- measure distance to unit\\\
                        if (dist < lowDist) then lowDist = dist end\\\
                    end\\\
                    emergencyBreak = emergencyBreak + 1\\\
                until (emergencyBreak > 20) or (lowDist > minDist)\\\
                -- we have random x, y \\\
                local u = theNewGroup.units[i] -- get unit to position\\\
                u.x = thePoint.x\\\
                u.y = thePoint.z -- z --> y mapping! \\\
                -- now add the unit to the 'processed' set \\\
                table.insert(processedUnits, u)\\\
            end    \\\
\\\
        elseif dcsCommon.stringStartsWith(formation, \\\"CIRCLE\\\") then\\\
            -- units are arranged on perimeter of circle defined by radius \\\
--            trigger.action.outText(\\\"formation circle detected\\\", 30)\\\
            local currAngle = 0\\\
            local angleInc = 2 * 3.14157 / num -- increase per spoke \\\
            for i=1, num do\\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = radius * math.cos(currAngle)\\\
                u.y = radius * math.sin(currAngle)\\\
                \\\
                -- now baldower out heading \\\
                -- circle, circle_forward no modifier of heading\\\
                if dcsCommon.stringStartsWith(formation, \\\"CIRCLE_IN\\\") then \\\
                    -- make the heading inward faceing - that's angle + pi\\\
                    u.heading = u.heading + currAngle + 3.14157\\\
                elseif dcsCommon.stringStartsWith(formation, \\\"CIRCLE_OUT\\\") then \\\
                    u.heading = u.heading + currAngle + 0\\\
                end\\\
\\\
                currAngle = currAngle + angleInc\\\
            end\\\
        elseif formation == \\\"GRID\\\" or formation == \\\"SQUARE\\\" or formation == \\\"RECT\\\" then \\\
            if num < 2 then return end \\\
            -- arrange units in an w x h grid\\\
            -- e-g- 12 units = 4 x 3. \\\
            -- calculate w \\\
            local w = math.floor(num^(0.5) + 0.5)\\\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
            --[[--\\\
            local h = math.floor(num / w)\\\
            --trigger.action.outText(\\\"AdcsC: num=\\\" .. num .. \\\" w=\\\" .. w .. \\\"h=\\\" .. h .. \\\" -- num%w=\\\" .. num%w, 30)\\\
            if (num % w) > 0 then \\\
                h = h + 1\\\
            end\\\
            \\\
            --trigger.action.outText(\\\"BdcsC: num=\\\" .. num .. \\\" w=\\\" .. w .. \\\"h=\\\" .. h, 30)\\\
            \\\
            -- now w * h always >= num and num items fir in that grid\\\
            -- w is width, h is height, of course :) \\\
            -- now calculat xInc and yInc\\\
            local i = 1\\\
            local xInc = 0 \\\
            if w > 1 then xInc = 2 * radius / (w-1) end\\\
            local yInc = 0\\\
            if h > 1 then yInc = 2 * radius / (h-1) end \\\
            local currY = radius \\\
            if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\\\
            while h > 0 do \\\
                local currX = radius \\\
                local wCnt = w \\\
                while wCnt > 0 and (i <= num) do \\\
                    local u = theNewGroup.units[i] -- get unit \\\
                    u.x = currX\\\
                    u.y = currY\\\
                    currX = currX - xInc\\\
                    wCnt = wCnt - 1\\\
                    i = i + 1\\\
                end\\\
                currY = currY - yInc \\\
                h = h - 1\\\
            end\\\
            --]]--\\\
        elseif formation == \\\"2DEEP\\\" or formation == \\\"2COLS\\\" then\\\
            if num < 2 then return end \\\
            -- arrange units in an 2 x h grid\\\
            local w = 2\\\
            dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\\\
\\\
        elseif formation == \\\"2WIDE\\\" then\\\
            if num < 2 then return end \\\
            -- arrange units in an 2 x h grid\\\
            local w = 2\\\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
        else \\\
            trigger.action.outText(\\\"dcsCommon - unknown formation: \\\" .. formation, 30)\\\
        end\\\
    \\\
    end\\\
    \\\
    function dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
        local num = #theNewGroup.units\\\
        local h = math.floor(num / w)\\\
        if (num % w) > 0 then \\\
            h = h + 1\\\
        end\\\
        local i = 1\\\
        local xInc = 0 \\\
        if w > 1 then xInc = 2 * radius / (w-1) end\\\
        local yInc = 0\\\
        if h > 1 then yInc = 2 * radius / (h-1) end \\\
        local currY = radius \\\
        if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\\\
        while h > 0 do \\\
            local currX = radius \\\
            local wCnt = w \\\
            while wCnt > 0 and (i <= num) do \\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = currX\\\
                u.y = currY\\\
                currX = currX - xInc\\\
                wCnt = wCnt - 1\\\
                i = i + 1\\\
            end\\\
            currY = currY - yInc \\\
            h = h - 1\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\\\
        local num = #theNewGroup.units\\\
        local h = math.floor(num / w)\\\
        if (num % w) > 0 then \\\
            h = h + 1\\\
        end\\\
        local i = 1\\\
        local yInc = 0 \\\
        if w > 1 then yInc = 2 * radius / (w-1) end\\\
        local xInc = 0\\\
        if h > 1 then xInc = 2 * radius / (h-1) end \\\
        local currX = radius \\\
        if h < 2 then currX = 0 end -- special:_ place in Y middle if only one row)\\\
        while h > 0 do \\\
            local currY = radius \\\
            local wCnt = w \\\
            while wCnt > 0 and (i <= num) do \\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = currX\\\
                u.y = currY\\\
                currY = currY - yInc\\\
                wCnt = wCnt - 1\\\
                i = i + 1\\\
            end\\\
            currX = currX - xInc \\\
            h = h - 1\\\
        end\\\
    end\\\
    \\\
    \\\
    function dcsCommon.createGroundGroupWithUnits(name, theUnitTypes, radius, minDist, formation, innerRadius)\\\
        if not minDist then mindist = 4 end -- meters\\\
        if not formation then formation = \\\"line\\\" end \\\
        if not radius then radius = 30 end -- meters \\\
        if not innerRadius then innerRadius = 0 end\\\
        formation = formation:upper()\\\
        -- theUnitTypes can be either a single string or a table of strings\\\
        -- see here for TypeName https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\\\
        -- formation defines how the units are going to be arranged in the\\\
        -- formation specified. \\\
        -- formations:\\\
        --    (default) \\\"line\\\" (left to right along x) -- that is Y direction\\\
        --    \\\"line_V\\\" a line top to bottom -- that is X direction\\\
        --    \\\"chevron\\\" - left to right middle too top\\\
        --    \\\"scattered\\\", \\\"random\\\" -- random, innerRadius used to clear area in center\\\
        --       \\\"circle\\\", \\\"circle_forward\\\" -- circle, forward facing\\\
        --    \\\"circle_in\\\" -- circle, inwarf facing\\\
        --    \\\"circle_out\\\" -- circle, outward facing\\\
\\\
        -- first, we create a group\\\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\\\
        \\\
        -- now add a single unit or multiple units\\\
        if type(theUnitTypes) ~= \\\"table\\\" then \\\
--            trigger.action.outText(\\\"dcsCommon - i am here\\\", 30)\\\
--            trigger.action.outText(\\\"dcsCommon - name \\\" .. name, 30)\\\
--            trigger.action.outText(\\\"dcsCommon - unit type \\\" .. theUnitTypes, 30)\\\
            \\\
            local aUnit = {}\\\
            aUnit = dcsCommon.createGroundUnitData(name .. \\\"-1\\\", theUnitTypes, false)\\\
--            trigger.action.outText(\\\"dcsCommon - unit name retval \\\" .. aUnit.name, 30)\\\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0) -- create with data at location (0,0)\\\
            return theNewGroup\\\
        end \\\
\\\
        -- if we get here, theUnitTypes is a table\\\
        -- now loop and create a unit for each table\\\
        local num = 1\\\
        for key, theType in pairs(theUnitTypes) do \\\
            -- trigger.action.outText(\\\"+++dcsC: creating unit \\\" .. name .. \\\"-\\\" .. num .. \\\": \\\" .. theType, 30)\\\
            local aUnit = dcsCommon.createGroundUnitData(name .. \\\"-\\\"..num, theType, false)\\\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0)\\\
            num = num + 1\\\
        end\\\
        \\\
        dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\\\
        return theNewGroup\\\
\\\
    \\\
    end\\\
\\\
-- create a new group, based on group in mission. Groups coords are 0,0 for group and all\\\
-- x,y and heading\\\
    function dcsCommon.createGroupDataFromLiveGroup(name, newName) \\\
        if not newName then newName = dcsCommon.uuid(\\\"uniqName\\\") end\\\
        -- get access to the group\\\
        local liveGroup = Group.getByName(name)\\\
        if not liveGroup then return nil end\\\
        -- get the categorty\\\
        local cat = liveGroup:getCategory()\\\
        local theNewGroup = {}\\\
        \\\
        -- create a new empty group at (0,0) \\\
        if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \\\
            theNewGroup = dcsCommon.createEmptyAircraftGroupData(newName)\\\
        elseif cat == Group.Category.GROUND then\\\
            theNewGroup = dcsCommon.createEmptyGroudGroupData(newName)\\\
        else \\\
            trigger.action.outText(\\\"dcsCommon - unknown category: \\\" .. cat, 30)\\\
            return nil\\\
        end\\\
        \\\
\\\
        -- now get all units from live group and create data units\\\
        -- note that unit data for group has x=0, y=0\\\
        liveUnits = liveGroup:getUnits()\\\
        \\\
        for index, theUnit in pairs(liveUnits) do \\\
            -- for each unit we get the desc \\\
            local desc = theUnit:getDesc() -- of interest is only typename \\\
            local newUnit = dcsCommon.createGroundUnitData(dcsCommon.uuid(newName),\\\
                                                           desc.typeName,\\\
                                                           false)\\\
            -- we now basically have a ground unit at (0,0) \\\
            -- add mandatory fields by type\\\
            if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \\\
                newUnit.alt = 100 -- make it 100m\\\
                newUnit.alt_type = \\\"RADIO\\\" -- AGL\\\
                newUnit.speed = 77 -- m/s --> 150 knots\\\
                newUnit.payload = dcsCommon.createPayload() -- empty payload\\\
                newUnit.callsign = dcsCommon.createCallsign() -- 'enfield11'\\\
                \\\
            elseif cat == Group.Category.GROUND then\\\
                -- we got all we need\\\
            else \\\
                -- trigger.action.outText(\\\"dcsCommon - unknown category: \\\" .. cat, 30)\\\
                -- return nil\\\
                -- we also got all we need\\\
            end            \\\
            \\\
        end\\\
    \\\
    end;\\\
    \\\
\\\
    function dcsCommon.rotatePointAroundOrigin(inX, inY, angle) -- angle in degrees\\\
        local degrees =  3.14152 / 180 -- ok, it's actually radiants. \\\
        angle = angle * degrees -- turns into rads\\\
        local c = math.cos(angle)\\\
        local s = math.sin(angle)\\\
        local px\\\
        local py \\\
        px = inX * c - inY * s\\\
        py = inX * s + inY * c\\\
        return px, py        \\\
    end\\\
\\\
    function dcsCommon.rotateUnitData(theUnit, degrees, cx, cy)\\\
        if not cx then cx = 0 end\\\
        if not cz then cz = 0 end\\\
        local cy = cz \\\
        --trigger.action.outText(\\\"+++dcsC:rotGrp cy,cy = \\\"..cx .. \\\",\\\" .. cy, 30)\\\
        \\\
        local rads = degrees *  3.14152 / 180\\\
        do\\\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\\\
            theUnit.y = theUnit.y - cy                 \\\
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\\\
            theUnit.x = theUnit.x + cx -- MOVE BACK \\\
            theUnit.y = theUnit.y + cy                 \\\
\\\
            -- may also want to increase heading by degreess\\\
            theUnit.heading = theUnit.heading + rads \\\
        end\\\
    end\\\
    \\\
\\\
    function dcsCommon.rotateGroupData(theGroup, degrees, cx, cz)\\\
        if not cx then cx = 0 end\\\
        if not cz then cz = 0 end\\\
        local cy = cz \\\
        --trigger.action.outText(\\\"+++dcsC:rotGrp cy,cy = \\\"..cx .. \\\",\\\" .. cy, 30)\\\
        \\\
        local rads = degrees *  3.14152 / 180\\\
        -- turns all units in group around the group's center by degrees.\\\
        -- may also need to turn individual units by same amount\\\
        for i, theUnit in pairs (theGroup.units) do\\\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\\\
            theUnit.y = theUnit.y - cy                 \\\
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\\\
            theUnit.x = theUnit.x + cx -- MOVE BACK \\\
            theUnit.y = theUnit.y + cy                 \\\
\\\
            -- may also want to increase heading by degreess\\\
            theUnit.heading = theUnit.heading + rads \\\
        end\\\
    end\\\
\\\
    function dcsCommon.offsetGroupData(theGroup, dx, dy)\\\
        -- add dx and dy to group's and all unit's coords\\\
        for i, theUnit in pairs (theGroup.units) do \\\
            theUnit.x = theUnit.x + dx\\\
            theUnit.y = theUnit.y + dy\\\
        end\\\
        \\\
        theGroup.x = theGroup.x + dx\\\
        theGroup.y = theGroup.y + dy \\\
    end\\\
    \\\
    function dcsCommon.moveGroupDataTo(theGroup, xAbs, yAbs)\\\
        local dx = xAbs-theGroup.x\\\
        local dy = yAbs-theGroup.y\\\
        dcsCommon.offsetGroupData(theGroup, dx, dy)\\\
    end\\\
    \\\
    -- static objectr shapes and types are defined here\\\
    -- https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB/Statics\\\
    \\\
    function dcsCommon.createStaticObjectData(name, objType, heading, dead, cargo, mass)\\\
        local staticObj = {}\\\
        if not heading then heading = 0 end \\\
        if not dead then dead = false end \\\
        if not cargo then cargo = false end \\\
        objType = dcsCommon.trim(objType) \\\
        \\\
        staticObj.heading = heading\\\
        -- staticObj.groupId = 0\\\
        -- staticObj.shape_name = shape -- e.g. H-Windsock_RW\\\
        staticObj.type = objType  -- e.g. Windsock\\\
        -- [\\\"unitId\\\"] = 3,\\\
        staticObj.rate = 1 -- score when killed\\\
        staticObj.name = name\\\
        -- staticObj.category = \\\"Fortifications\\\",\\\
        staticObj.y = 0\\\
        staticObj.x = 0\\\
        staticObj.dead = dead\\\
        staticObj.canCargo = cargo -- to cargo\\\
        if cargo then \\\
            if not mass then mass = 1234 end \\\
            staticObj.mass = mass -- to cargo\\\
        end\\\
        return staticObj\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\\\
        local theData = dcsCommon.createStaticObjectData(name, objType, heading, dead)\\\
        theData.x = loc.x\\\
        theData.y = loc.z \\\
        return theData\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectForCoalitionAtLocation(theCoalition, loc, name, objType, heading, dead) \\\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\\\
        local theData = dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\\\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\\\
        return theStatic\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectForCoalitionInRandomRing(theCoalition, objType, x, z, innerRadius, outerRadius, heading, alive) \\\
        if not outerRadius then outerRadius = innerRadius end\\\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\\\
        local dead = not alive\\\
        local p = dcsCommon.randomPointInCircle(outerRadius, innerRadius, x, z)\\\
        local theData = dcsCommon.createStaticObjectData(dcsCommon.uuid(\\\"static\\\"), objType, heading, dead)\\\
        theData.x = p.x\\\
        theData.y = p.z \\\
        \\\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\\\
        return theStatic\\\
    end\\\
    \\\
    \\\
    \\\
    function dcsCommon.linkStaticDataToUnit(theStatic, theUnit, dx, dy, heading)\\\
        if not theStatic then \\\
            trigger.action.OutText(\\\"+++dcsC: NIL theStatic on linkStatic!\\\", 30)\\\
            return \\\
        end\\\
        -- NOTE: we may get current heading and subtract/add \\\
        -- to original heading \\\
        local rotX, rotY = dcsCommon.rotatePointAroundOrigin(dx, dy, -heading)\\\
        \\\
        if not theUnit then return end\\\
        if not theUnit:isExist() then return end \\\
        theStatic.linkOffset = true \\\
        theStatic.linkUnit = theUnit:getID()\\\
        local unitPos = theUnit:getPoint()\\\
        local offsets = {}\\\
        offsets.x = rotX  \\\
        offsets.y = rotY \\\
        offsets.angle = 0\\\
        theStatic.offsets = offsets\\\
    end\\\
    \\\
    function dcsCommon.offsetStaticData(theStatic, dx, dy)\\\
        theStatic.x = theStatic.x + dx\\\
        theStatic.y = theStatic.y + dy\\\
        -- now check if thre is a route (for linked objects)\\\
        if theStatic.route then \\\
            -- access points[1] x and y and copy from main\\\
            theStatic.route.points[1].x = theStatic.x\\\
            theStatic.route.points[1].y = theStatic.y\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.moveStaticDataTo(theStatic, x, y)\\\
        theStatic.x = x\\\
        theStatic.y = y\\\
        -- now check if thre is a route (for linked objects)\\\
        if theStatic.route then \\\
            -- access points[1] x and y and copy from main\\\
            theStatic.route.points[1].x = theStatic.x\\\
            theStatic.route.points[1].y = theStatic.y\\\
        end\\\
\\\
    end\\\
    \\\
--\\\
--\\\
-- M I S C   M E T H O D S \\\
--\\\
--\\\
\\\
    function dcsCommon.arrayContainsString(theArray, theString) \\\
        if not theArray then return false end\\\
        if not theString then return false end\\\
        for i = 1, #theArray do \\\
            if theArray[i] == theString then return true end \\\
        end\\\
        return false \\\
    end\\\
    \\\
    function dcsCommon.splitString(inputstr, sep) \\\
        if sep == nil then\\\
            sep = \\\"%s\\\"\\\
        end\\\
        if inputstr == nil then \\\
            inputstr = \\\"\\\"\\\
        end\\\
        \\\
        local t={}\\\
        for str in string.gmatch(inputstr, \\\"([^\\\"..sep..\\\"]+)\\\") do\\\
            table.insert(t, str)\\\
        end\\\
        return t\\\
    \\\
    end\\\
    \\\
    function dcsCommon.trimFront(inputstr) \\\
        if not inputstr then return nil end \\\
        local s = inputstr\\\
        while string.len(s) > 1 and string.sub(s, 1, 1) == \\\" \\\" do \\\
            local snew = string.sub(s, 2) -- all except first\\\
            s = snew\\\
        end\\\
        return s\\\
    end\\\
    \\\
    function dcsCommon.trimBack(inputstr)\\\
        if not inputstr then return nil end \\\
        local s = inputstr\\\
        while string.len(s) > 1 and string.sub(s, -1) == \\\" \\\" do \\\
            local snew = string.sub(s, 1, -2) -- all except last\\\
            s = snew\\\
        end\\\
        return s\\\
    end\\\
    \\\
    function dcsCommon.trim(inputstr) \\\
        local t1 = dcsCommon.trimFront(inputstr)\\\
        local t2 = dcsCommon.trimBack(t1)\\\
        return t2\\\
    end\\\
    \\\
    function dcsCommon.trimArray(theArray)\\\
        local trimmedArray = {}\\\
        for idx, element in pairs(theArray) do \\\
            local tel = dcsCommon.trim(element)\\\
            table.insert(trimmedArray, tel)\\\
        end\\\
        return trimmedArray\\\
    end\\\
    \\\
    function dcsCommon.stringIsPositiveNumber(theString)\\\
        -- only full integer positive numbers supported \\\
        if not theString then return false end \\\
--        if theString == \\\"\\\" then return false end \\\
        for i = 1, #theString do \\\
            local c = theString:sub(i,i)\\\
            if c < \\\"0\\\" or c > \\\"9\\\" then return false end \\\
        end\\\
        return true \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWithDigit(theString)\\\
        if #theString < 1 then return false end \\\
        local c = string.sub(theString, 1, 1) \\\
        return c >= \\\"0\\\" and c <= \\\"9\\\" \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWithLetter(theString)\\\
        if #theString < 1 then return false end \\\
        local c = string.sub(theString, 1, 1)\\\
        if c >= \\\"a\\\" and c <= \\\"z\\\" then return true end  \\\
        if c >= \\\"A\\\" and c <= \\\"Z\\\" then return true end \\\
        return false \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWith(theString, thePrefix)\\\
        return theString:find(thePrefix) == 1\\\
    end\\\
    \\\
    function dcsCommon.removePrefix(theString, thePrefix)\\\
        if not dcsCommon.stringStartsWith(theString, thePrefix) then \\\
            return theString\\\
        end;\\\
        return theString:sub(1 + #thePrefix)\\\
    end\\\
    \\\
    function dcsCommon.stringEndsWith(theString, theEnding)\\\
        return theEnding == \\\"\\\" or theString:sub(-#theEnding) == theEnding\\\
    end\\\
    \\\
    function dcsCommon.removeEnding(theString, theEnding) \\\
        if not dcsCommon.stringEndsWith(theString, theEnding) then \\\
            return theString\\\
        end\\\
        return theString:sub(1, #theString - #theEnding)\\\
    end\\\
    \\\
    function dcsCommon.containsString(inString, what, caseSensitive)\\\
        if (not caseSensitive) then \\\
            inString = string.upper(inString)\\\
            what = string.upper(what)\\\
        end\\\
        if inString == what then return true end -- when entire match \\\
        return string.find(inString, what)\\\
    end\\\
    \\\
    function dcsCommon.bool2Text(theBool) \\\
        if not theBool then theBool = false end \\\
        if theBool then return \\\"true\\\" end \\\
        return \\\"false\\\"\\\
    end\\\
    \\\
    function dcsCommon.bool2YesNo(theBool)\\\
        if not theBool then theBool = false end \\\
        if theBool then return \\\"yes\\\" end \\\
        return \\\"no\\\"\\\
    end\\\
\\\
    function dcsCommon.point2text(p) \\\
        if not p then return \\\"<!NIL!>\\\" end \\\
        local t = \\\"[x=\\\"\\\
        if p.x then t = t .. p.x .. \\\", \\\" else t = t .. \\\"<nil>, \\\" end \\\
        if p.y then t = t .. p.y .. \\\", \\\" else t = t .. \\\"<nil>, \\\" end \\\
        if p.z then t = t .. p.z .. \\\"]\\\" else t = t .. \\\"<nil>]\\\" end \\\
        return t \\\
    end\\\
\\\
    function dcsCommon.string2GroupCat(inString)\\\
\\\
        if not inString then return 2 end -- default ground \\\
        inString = inString:lower()\\\
        inString = dcsCommon.trim(inString)\\\
\\\
        local catNum = tonumber(inString)\\\
        if catNum then \\\
            if catNum < 0 then catNum = 0 end \\\
            if catNum > 4 then catNum = 4 end \\\
            return catNum \\\
        end\\\
    \\\
        catNum = 2 -- ground default \\\
        if dcsCommon.stringStartsWith(inString, \\\"grou\\\") then catNum = 2 end \\\
        if dcsCommon.stringStartsWith(inString, \\\"air\\\") then catNum = 0 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"hel\\\") then catNum = 1 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"shi\\\") then catNum = 3 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"trai\\\") then catNum = 4 end\\\
\\\
        return catNum\\\
    end\\\
\\\
    function dcsCommon.string2ObjectCat(inString)\\\
\\\
        if not inString then return 3 end -- default static \\\
        inString = inString:lower()\\\
        inString = dcsCommon.trim(inString)\\\
\\\
        local catNum = tonumber(inString)\\\
        if catNum then \\\
            if catNum < 0 then catNum = 0 end \\\
            if catNum > 6 then catNum = 6 end \\\
            return catNum \\\
        end\\\
    \\\
        catNum = 3 -- static default \\\
        if dcsCommon.stringStartsWith(inString, \\\"uni\\\") then catNum = 1 end \\\
        if dcsCommon.stringStartsWith(inString, \\\"wea\\\") then catNum = 2 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"bas\\\") then catNum = 4 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"sce\\\") then catNum = 5 end\\\
        if dcsCommon.stringStartsWith(inString, \\\"car\\\") then catNum = 6 end\\\
\\\
        return catNum\\\
    end\\\
\\\
    -- recursively show the contents of a variable\\\
    function dcsCommon.dumpVar(key, value, prefix, inrecursion)\\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            env.info(\\\"*** dcsCommon vardump START\\\")\\\
        end\\\
        if not value then value = \\\"nil\\\" end\\\
        if not prefix then prefix = \\\"\\\" end\\\
        prefix = \\\" \\\" .. prefix\\\
        if type(value) == \\\"table\\\" then \\\
            env.info(prefix .. key .. \\\": [ \\\")\\\
            -- iterate through all kvp\\\
            for k,v in pairs (value) do\\\
                dcsCommon.dumpVar(k, v, prefix, true)\\\
            end\\\
            env.info(prefix .. \\\" ] - end \\\" .. key)\\\
            \\\
        elseif type(value) == \\\"boolean\\\" then \\\
            local b = \\\"false\\\"\\\
            if value then b = \\\"true\\\" end\\\
            env.info(prefix .. key .. \\\": \\\" .. b)\\\
            \\\
        else -- simple var, show contents, ends recursion\\\
            env.info(prefix .. key .. \\\": \\\" .. value)\\\
        end\\\
        \\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"=== dcsCommon vardump END\\\", 30)\\\
            env.info(\\\"=== dcsCommon vardump END\\\")\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.dumpVar2Str(key, value, prefix, inrecursion)\\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"*** dcsCommon vardump START\\\",30)\\\
        end\\\
        if not value then value = \\\"nil\\\" end\\\
        if not prefix then prefix = \\\"\\\" end\\\
        prefix = \\\" \\\" .. prefix\\\
        if type(value) == \\\"table\\\" then \\\
            trigger.action.outText(prefix .. key .. \\\": [ \\\", 30)\\\
            -- iterate through all kvp\\\
            for k,v in pairs (value) do\\\
                dcsCommon.dumpVar2Str(k, v, prefix, true)\\\
            end\\\
            trigger.action.outText(prefix .. \\\" ] - end \\\" .. key, 30)\\\
            \\\
        elseif type(value) == \\\"boolean\\\" then \\\
            local b = \\\"false\\\"\\\
            if value then b = \\\"true\\\" end\\\
            trigger.action.outText(prefix .. key .. \\\": \\\" .. b, 30)\\\
            \\\
        else -- simple var, show contents, ends recursion\\\
            trigger.action.outText(prefix .. key .. \\\": \\\" .. value, 30)\\\
        end\\\
        \\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"=== dcsCommon vardump END\\\", 30)\\\
            --env.info(\\\"=== dcsCommon vardump END\\\")\\\
        end\\\
    end\\\
    \\\
\\\
    dcsCommon.simpleUUID = 76543 -- a number to start. as good as any\\\
    function dcsCommon.numberUUID()\\\
        dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1\\\
        return dcsCommon.simpleUUID\\\
    end\\\
\\\
    function dcsCommon.uuid(prefix)\\\
        dcsCommon.uuIdent = dcsCommon.uuIdent + 1\\\
        if not prefix then prefix = dcsCommon.uuidStr end\\\
        return prefix .. \\\"-\\\" .. dcsCommon.uuIdent\\\
    end\\\
    \\\
    function dcsCommon.event2text(id) \\\
        if not id then return \\\"error\\\" end\\\
        if id == 0 then return \\\"invalid\\\" end\\\
        -- translate the event id to text\\\
        local events = {\\\"shot\\\", \\\"hit\\\", \\\"takeoff\\\", \\\"land\\\",\\\
                        \\\"crash\\\", \\\"eject\\\", \\\"refuel\\\", \\\"dead\\\",\\\
                        \\\"pilot dead\\\", \\\"base captured\\\", \\\"mission start\\\", \\\"mission end\\\", -- 12\\\
                        \\\"took control\\\", \\\"refuel stop\\\", \\\"birth\\\", \\\"human failure\\\", \\\
                        \\\"det. failure\\\", \\\"engine start\\\", \\\"engine stop\\\", \\\"player enter unit\\\",\\\
                        \\\"player leave unit\\\", \\\"player comment\\\", \\\"start shoot\\\", \\\"end shoot\\\",\\\
                        \\\"mark add\\\", \\\"mark changed\\\", \\\"makr removed\\\", \\\"kill\\\", \\\
                        \\\"score\\\", \\\"unit lost\\\", \\\"land after eject\\\", \\\"Paratrooper land\\\", \\\
                        \\\"chair discard after eject\\\", \\\"weapon add\\\", \\\"trigger zone\\\", \\\"landing quality mark\\\",\\\
                        \\\"BDA\\\", \\\"max\\\"}\\\
        if id > #events then return \\\"Unknown (ID=\\\" .. id .. \\\")\\\" end\\\
        return events[id]\\\
    end\\\
\\\
    function dcsCommon.smokeColor2Text(smokeColor)\\\
        if (smokeColor == 0) then return \\\"Green\\\" end\\\
        if (smokeColor == 1) then return \\\"Red\\\" end\\\
        if (smokeColor == 2) then return \\\"White\\\" end\\\
        if (smokeColor == 3) then return \\\"Orange\\\" end\\\
        if (smokeColor == 4) then return \\\"Blue\\\" end\\\
        \\\
        return (\\\"unknown: \\\" .. smokeColor)\\\
    end\\\
    \\\
    function dcsCommon.smokeColor2Num(smokeColor)\\\
        if not smokeColor then smokeColor = \\\"green\\\" end \\\
        if type(smokeColor) ~= \\\"string\\\" then return 0 end \\\
        smokeColor = smokeColor:lower()\\\
        if (smokeColor == \\\"green\\\") then return 0 end \\\
        if (smokeColor == \\\"red\\\") then return 1 end \\\
        if (smokeColor == \\\"white\\\") then return 2 end \\\
        if (smokeColor == \\\"orange\\\") then return 3 end \\\
        if (smokeColor == \\\"blue\\\") then return 4 end \\\
        return 0\\\
    end\\\
    \\\
    function dcsCommon.markPointWithSmoke(p, smokeColor)\\\
        local x = p.x \\\
        local z = p.z -- do NOT change the point directly\\\
        -- height-correct\\\
        local y = land.getHeight({x = x, y = z})\\\
        local newPoint= {x = x, y = y + 2, z = z}\\\
        trigger.action.smoke(newPoint, smokeColor)\\\
    end\\\
\\\
--\\\
--\\\
-- V E C T O R   M A T H \\\
--\\\
--\\\
function dcsCommon.vAdd(a, b) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    r.x = a.x + b.x \\\
    r.y = a.y + b.y \\\
    r.z = a.z + b.z \\\
    return r \\\
end\\\
\\\
function dcsCommon.vSub(a, b) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    r.x = a.x - b.x \\\
    r.y = a.y - b.y \\\
    r.z = a.z - b.z \\\
    return r \\\
end\\\
\\\
function dcsCommon.vMultScalar(a, f) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not f then f = 0 end\\\
    r.x = a.x * f \\\
    r.y = a.y * f \\\
    r.z = a.z * f \\\
    return r \\\
end\\\
\\\
function dcsCommon.vLerp (a, b, t)\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    \\\
    local d = dcsCommon.vSub(b, a)\\\
    local dt = dcsCommon.vMultScalar(d, t)\\\
    local r = dcsCommon.vAdd(a, dt)\\\
    return r\\\
end\\\
\\\
function dcsCommon.mag(x, y, z) \\\
    if not x then x = 0 end\\\
    if not y then y = 0 end \\\
    if not z then z = 0 end \\\
    \\\
    return (x * x + y * y + z * z)^0.5\\\
end\\\
\\\
function dcsCommon.vMag(a) \\\
    if not a then return 0 end \\\
    if not a.x then a.x = 0 end \\\
    if not a.y then a.y = 0 end \\\
    if not a.z then a.z = 0 end\\\
    return dcsCommon.mag(a.x, a.y, a.z) \\\
end\\\
\\\
function dcsCommon.magSquare(x, y, z) \\\
    if not x then x = 0 end\\\
    if not y then y = 0 end \\\
    if not z then z = 0 end \\\
    \\\
    return (x * x + y * y + z * z)\\\
end\\\
\\\
function dcsCommon.vNorm(a) \\\
    if not a then return {x = 0, y = 0, z = 0} end \\\
    m = dcsCommon.vMag(a)\\\
    if m <= 0 then return {x = 0, y = 0, z = 0} end \\\
    local r = {}\\\
    r.x = a.x / m \\\
    r.y = a.y / m \\\
    r.z = a.z / m\\\
    return r \\\
end\\\
\\\
function dcsCommon.dot (a, b) \\\
    if not a then a = {} end \\\
    if not a.x then a.x = 0 end \\\
    if not a.y then a.y = 0 end \\\
    if not a.z then a.z = 0 end\\\
    if not b then b = {} end \\\
    if not b.x then b.x = 0 end \\\
    if not b.y then b.y = 0 end \\\
    if not b.z then b.z = 0 end \\\
    \\\
    return a.x * b.x + a.y * b.y + a.z * b.z \\\
end\\\
--\\\
-- UNIT MISC\\\
-- \\\
function dcsCommon.isSceneryObject(theUnit)\\\
    if not theUnit then return false end\\\
    return theUnit.getCoalition == nil -- scenery objects do not return a coalition \\\
end\\\
\\\
function dcsCommon.isTroopCarrier(theUnit)\\\
    -- return true if conf can carry troups\\\
    if not theUnit then return false end \\\
    local uType = theUnit:getTypeName()\\\
    if dcsCommon.arrayContainsString(dcsCommon.troopCarriers, uType) then \\\
        -- may add additional tests before returning true\\\
        return true\\\
    end\\\
    return false\\\
end\\\
\\\
function dcsCommon.getUnitAlt(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local p = theUnit:getPoint()\\\
    return p.y \\\
end\\\
\\\
function dcsCommon.getUnitAGL(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local p = theUnit:getPoint()\\\
    local alt = p.y \\\
    local loc = {x = p.x, y = p.z}\\\
    local landElev = land.getHeight(loc)\\\
    return alt - landElev\\\
end \\\
\\\
function dcsCommon.getUnitSpeed(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local v = theUnit:getVelocity()\\\
    return dcsCommon.mag(v.x, v.y, v.z)\\\
end\\\
\\\
-- closing velocity of u1 and u2, seen from u1\\\
function dcsCommon.getClosingVelocity(u1, u2)\\\
    if not u1 then return 0 end \\\
    if not u2 then return 0 end \\\
    if not u1:isExist() then return 0 end \\\
    if not u2:isExist() then return 0 end \\\
    local v1 = u1:getVelocity()\\\
    local v2 = u2:getVelocity()\\\
    local dV = dcsCommon.vSub(v1,v2)\\\
    local a = u1:getPoint()\\\
    local b = u2:getPoint() \\\
    local aMinusB = dcsCommon.vSub(a,b) -- vector from u2 to u1\\\
    local abMag = dcsCommon.vMag(aMinusB) -- distance u1 to u2 \\\
    if abMag < .0001 then return 0 end \\\
    -- project deltaV onto vector from u2 to u1 \\\
    local vClose = dcsCommon.dot(dV, aMinusB) / abMag \\\
    return vClose \\\
end\\\
\\\
function dcsCommon.getGroupAvgSpeed(theGroup)\\\
    if not theGroup then return 0 end \\\
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \\\
    local totalSpeed = 0\\\
    local cnt = 0 \\\
    local livingUnits = theGroup:getUnits()\\\
    for idx, theUnit in pairs(livingUnits) do \\\
        cnt = cnt + 1\\\
        totalSpeed = totalSpeed + dcsCommon.getUnitSpeed(theUnit)\\\
    end \\\
    if cnt == 0 then return 0 end \\\
    return totalSpeed / cnt \\\
end\\\
 \\\
function dcsCommon.getGroupMaxSpeed(theGroup)\\\
    if not theGroup then return 0 end \\\
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \\\
    local maxSpeed = 0\\\
    local livingUnits = theGroup:getUnits()\\\
    for idx, theUnit in pairs(livingUnits) do \\\
        currSpeed = dcsCommon.getUnitSpeed(theUnit)\\\
        if currSpeed > maxSpeed then maxSpeed = currSpeed end \\\
    end \\\
    return maxSpeed\\\
end \\\
\\\
function dcsCommon.getUnitHeading(theUnit)\\\
    if not theUnit then return 0 end \\\
    if not theUnit:isExist() then return 0 end \\\
    local pos = theUnit:getPosition() -- returns three vectors, p is location\\\
\\\
    local heading = math.atan2(pos.x.z, pos.x.x)\\\
    -- make sure positive only, add 260 degrees\\\
    if heading < 0 then\\\
        heading = heading + 2 * math.pi    -- put heading in range of 0 to 2*pi\\\
    end\\\
    return heading \\\
end\\\
\\\
function dcsCommon.getUnitHeadingDegrees(theUnit)\\\
    local heading = dcsCommon.getUnitHeading(theUnit)\\\
    return heading * 57.2958 -- 180 / math.pi \\\
end\\\
\\\
function dcsCommon.unitIsInfantry(theUnit)\\\
    if not theUnit then return false end \\\
    if not theUnit:isExist() then return end\\\
    local theType = theUnit:getTypeName()\\\
    local isInfantry =  \\\
                dcsCommon.containsString(theType, \\\"infantry\\\", false) or \\\
                dcsCommon.containsString(theType, \\\"paratrooper\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"stinger\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"manpad\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"soldier\\\", false) or \\\
                dcsCommon.containsString(theType, \\\"SA-18 Igla\\\", false)\\\
    return isInfantry\\\
end\\\
\\\
function dcsCommon.coalition2county(inCoalition)\\\
    -- simply return UN troops for 0 neutral,\\\
    -- joint red for 1  red\\\
    -- joint blue for 2 blue \\\
    if inCoalition == 1 then return 81 end -- cjtf red\\\
    if inCoalition == 2 then return 80 end -- blue \\\
    if type(inCoalition) == \\\"string\\\" then \\\
            inCoalition = inCoalition:lower()\\\
            if inCoalition == \\\"red\\\" then return 81 end\\\
            if inCoalition == \\\"blue\\\" then return 80 end\\\
    end\\\
        \\\
    trigger.action.outText(\\\"+++dcsC: coalition2county in (\\\" .. inCoalition .. \\\") converts to UN (82)!\\\", 30)\\\
    return 82 -- UN \\\
    \\\
end\\\
\\\
--\\\
--\\\
-- INIT\\\
--\\\
--\\\
    -- init any variables the lib requires internally\\\
    function dcsCommon.init()\\\
        cbID = 0\\\
        dcsCommon.uuIdent = 0\\\
        if (dcsCommon.verbose) or true then\\\
          trigger.action.outText(\\\"dcsCommon v\\\" .. dcsCommon.version .. \\\" loaded\\\", 10)\\\
        end\\\
    end\\\
\\\
    \\\
-- do init. \\\
dcsCommon.init()\\\
\\\
--[[--\\\
\\\
to do: \\\
- formation 2Column\\\
- formation 3Column\\\
\\\
-]]--\\\
\");a_do_script(\"-- cf/x zone management module\\\
-- reads dcs zones and makes them accessible and mutable \\\
-- by scripting.\\\
--\\\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\\\
--\\\
\\\
cfxZones = {}\\\
cfxZones.version = \\\"2.7.0\\\"\\\
--[[-- VERSION HISTORY\\\
 - 2.2.4 - getCoalitionFromZoneProperty\\\
         - getStringFromZoneProperty\\\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \\\
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\\\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \\\
 - 2.2.8 - getBoolFromZoneProperty supports default \\\
         - cfxZones.hasProperty\\\
 - 2.3.0 - property names are case insensitive \\\
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\\\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \\\
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \\\
         - markZoneWithSmoke raised by 3 meters\\\
 - 2.4.2 - getClosestZone also returns delta \\\
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \\\
           createUniqueZoneName()\\\
           getStringFromZoneProperty returns default if property value = \\\"\\\"\\\
           corrected bug in addZoneToManagedZones\\\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\\\
         - linkUnit can use \\\"useOffset\\\" property to keep relative position\\\
 - 2.4.5 - updated various methods to support getPoint when referencing \\\
           zone.point  \\\
 - 2.4.6 - corrected spelling in markZoneWithSmoke\\\
 - 2.4.7 - copy reference to dcs zone into cfx zone \\\
 - 2.4.8 - getAllZoneProperties\\\
 - 2.4.9 - createSimpleZone no longer requires location \\\
         - parse dcs adds empty .properties = {} if none tehre \\\
         - createCircleZone adds empty properties \\\
         - createPolyZone adds empty properties \\\
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\\\
          - getBoolFromZoneProperty also recognizes 0, 1\\\
          - removed autostart\\\
 - 2.4.11 - removed typo in get closest zone \\\
 - 2.4.12 - getStringFromZoneProperty\\\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\\\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \\\
 - 2.5.2  - getPoint also writes through to zone itself for optimization\\\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
 - 2.5.3  - new getAllGroupsInZone()\\\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \\\
          - extractPropertyFromDCS trims key and property \\\
 - 2.5.5  - pollFlag() centralized for banging \\\
          - allStaticsInZone\\\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \\\
          - pollFlag supports theZone as final parameter\\\
          - randomDelayFromPositiveRange\\\
          - isMEFlag\\\
 - 2.5.7  - pollFlag supports dml flags\\\
 - 2.5.8  - flagArrayFromString\\\
          - getFlagNumber invokes tonumber() before returning result \\\
 - 2.5.9  - removed pass-back flag in getPoint() \\\
 - 2.6.0  - testZoneFlag() method based flag testing\\\
 - 2.6.1  - Watchflag parsing of zone condition for number-named flags\\\
          - case insensitive\\\
          - verbose for zone-local accepted (but not acted upon)\\\
          - hasProperty now offers active information when looking for '*?' and '*!'\\\
 - 2.7.0  - doPollFlag - fully support multiple flags per bang!\\\
 - 2.7.1  - setFlagValueMult()\\\
 \\\
--]]--\\\
cfxZones.verbose = false\\\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \\\
cfxZones.ups = 1 -- updates per second. updates moving zones\\\
\\\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\\\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\\\
\\\
-- a zone has the following attributes\\\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\\\
-- radius (zero if quad zone)\\\
-- isCircle (true if quad zone)\\\
-- poly the quad coords are in the poly attribute and are a \\\
-- 1..n, wound counter-clockwise as (currently) in DCS:\\\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \\\
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \\\
--          for both circle and poly, all (x, 0, z)\\\
\\\
-- zones can carry information in their names that can get processed into attributes\\\
-- use \\\
-- zones can also carry information in their 'properties' tag that ME allows to \\\
-- edit. cfxZones provides an easy method to access these properties \\\
--  - getZoneProperty (returns as string)\\\
--  - getMinMaxFromZoneProperty\\\
--  - getBoolFromZoneProperty\\\
--  - getNumberFromZoneProperty\\\
\\\
\\\
-- SUPPORTED PROPERTIES\\\
-- - \\\"linkedUnit\\\" - zone moves with unit of that name. must be exact match\\\
--   can be combined with other attributes that extend (e.g. scar manager and\\\
--   limited pilots/airframes \\\
--\\\
\\\
--\\\
-- readZonesFromDCS is executed exactly once at the beginning\\\
-- from then on, use only the cfxZones.zones table \\\
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \\\
-- indexed by upper case. If you have two zones with same name but \\\
-- different case, one will be replaced\\\
--\\\
\\\
function cfxZones.readFromDCS(clearfirst)\\\
    if (clearfirst) then\\\
        cfxZones.zones = {}\\\
    end\\\
    -- not all missions have triggers or zones\\\
    if not env.mission.triggers then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no env.triggers defined\\\", 10)\\\
        end\\\
        return\\\
    end\\\
    \\\
    if not env.mission.triggers.zones then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no zones defined\\\", 10)\\\
        end\\\
        return;\\\
    end\\\
\\\
    -- we only retrieve the data we need. At this point it is name, location and radius\\\
    -- and put this in our own little  structure. we also convert to all upper case name for index\\\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\\\
    -- so we can quickly create other sets from this\\\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\\\
    --   name - name in upper case\\\
    --   isCircle - true if circular zone \\\
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \\\
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\\\
    --   radius - number, zero when quad\\\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\\\
    --   poly - array 1..n of poly points, wound counter-clockwise \\\
    \\\
    for i, dcsZone in pairs(env.mission.triggers.zones) do\\\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\\\
                                         -- dcs data is like a box of chocolates...\\\
            local newZone = {}\\\
            -- name, converted to upper is used only for indexing\\\
            -- the original name remains untouched\\\
            newZone.dcsZone = dcsZone\\\
            newZone.name = dcsZone.name\\\
            newZone.isCircle = false\\\
            newZone.isPoly = false\\\
            newZone.radius = 0\\\
            newZone.poly = {}\\\
            newZone.bounds = {}\\\
            newZone.properties = {} -- dcs has this too, copy if present\\\
            if dcsZone.properties then \\\
                newZone.properties = dcsZone.properties \\\
            else\\\
                newZone.properties = {}\\\
            end -- WARNING: REF COPY. May need to clone \\\
            \\\
            local upperName = newZone.name:upper()\\\
            \\\
            -- location as 'point'\\\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\\\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\\\
            --          altitude (they are an infinite cylinder) this works. Remember to \\\
            --          drop y from zone calculations to see if inside. \\\
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\\\
\\\
\\\
            -- start type processing. if zone.type exists, we have a mission \\\
            -- created with 2.7 or above, else earlier \\\
            local zoneType = 0\\\
            if (dcsZone.type) then \\\
                zoneType = dcsZone.type \\\
            end\\\
            \\\
            if zoneType == 0 then \\\
                -- circular zone \\\
                newZone.isCircle = true \\\
                newZone.radius = dcsZone.radius\\\
    \\\
            elseif zoneType == 2 then\\\
                -- polyZone\\\
                newZone.isPoly = true \\\
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\\\
                -- now transfer all point in the poly\\\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\\\
                -- correct vor this \\\
                local verts = {}\\\
                if dcsZone.verticies then verts = dcsZone.verticies \\\
                else \\\
                    -- in later versions, this was corrected\\\
                    verts = dcsZone.vertices -- see if this is ever called\\\
                end\\\
                \\\
                for v=1, #verts do\\\
                    local dcsPoint = verts[v]\\\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\\\
                    newZone.poly[v] = polyPoint\\\
                end\\\
            else \\\
                \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" unknown type \\\" .. zoneType, 10)\\\
            end\\\
            \\\
\\\
            -- calculate bounds\\\
            cfxZones.calculateZoneBounds(newZone) \\\
\\\
            -- add to my table\\\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\\\
            --trigger.action.outText(\\\"znd: procced \\\" .. newZone.name .. \\\" with radius \\\" .. newZone.radius, 30)\\\
        else\\\
            if cfxZones.verbose then \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" dropped\\\", 10)\\\
            end\\\
        end -- else var not a table\\\
        \\\
    end -- for all zones kvp\\\
end -- readFromDCS\\\
\\\
function cfxZones.calculateZoneBounds(theZone)\\\
    if not (theZone) then return \\\
    end\\\
    \\\
    local bounds = theZone.bounds -- copy ref!\\\
    \\\
    if theZone.isCircle then \\\
        -- aabb are easy: center +/- radius \\\
        local center = theZone.point\\\
        local radius = theZone.radius \\\
        -- dcs uses z+ is down on map\\\
        -- upper left is center - radius \\\
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\\\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\\\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\\\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\\\
        \\\
    elseif theZone.isPoly then\\\
        local poly = theZone.poly -- ref copy!\\\
        -- create the four points\\\
        local ll = cfxZones.createPointFromPoint(poly[1])\\\
        local lr = cfxZones.createPointFromPoint(poly[1])\\\
        local ul = cfxZones.createPointFromPoint(poly[1])\\\
        local ur = cfxZones.createPointFromPoint(poly[1])\\\
\\\
        -- now iterate through all points and adjust bounds accordingly \\\
        for v=2, #poly do \\\
             local vertex = poly[v]\\\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \\\
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \\\
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\\\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \\\
            \\\
        end\\\
        \\\
        -- now keep the new point references\\\
        -- and store them in the zone's bounds\\\
        bounds.ll = ll\\\
        bounds.lr = lr\\\
        bounds.ul = ul\\\
        bounds.ur = ur \\\
    else \\\
        -- huston, we have a problem\\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: calc bounds: zone \\\" .. theZone.name .. \\\" has unknown type\\\", 30)\\\
        end\\\
    end\\\
    \\\
end\\\
\\\
function cfxZones.createPoint(x, y, z)\\\
    local newPoint = {}\\\
    newPoint.x = x\\\
    newPoint.y = y\\\
    newPoint.z = z \\\
    return newPoint\\\
end\\\
\\\
function cfxZones.copyPoint(inPoint) \\\
    local newPoint = {}\\\
    newPoint.x = inPoint.x\\\
    newPoint.y = inPoint.y\\\
    newPoint.z = inPoint.z \\\
    return newPoint    \\\
end\\\
\\\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\\\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\\\
    return cP\\\
end\\\
\\\
function cfxZones.getHeightCorrectedZonePoint(theZone)\\\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\\\
end\\\
\\\
function cfxZones.createPointFromPoint(inPoint)\\\
    return cfxZones.copyPoint(inPoint)\\\
end\\\
\\\
function cfxZones.createPointFromDCSPoint(inPoint) \\\
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\\\
end\\\
\\\
\\\
function cfxZones.createRandomPointInsideBounds(bounds)\\\
    local x = math.random(bounds.ll.x, ur.x)\\\
    local z = math.random(bounds.ll.z, ur.z)\\\
    return cfxZones.createPoint(x, 0, z)\\\
end\\\
\\\
function cfxZones.addZoneToManagedZones(theZone)\\\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\\\
    cfxZones.zones[upperName] = theZone\\\
end\\\
\\\
function cfxZones.createUniqueZoneName(inName, searchSet)\\\
    if not inName then return nil end \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    inName = inName:upper()\\\
    while searchSet[inName] ~= nil do \\\
        inName = inName .. \\\"X\\\"\\\
    end\\\
    return inName\\\
end\\\
\\\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\\\
    if not radius then radius = 10 end\\\
    if not addToManaged then addToManaged = false end \\\
    if not location then \\\
        location = {}\\\
    end\\\
    if not location.x then location.x = 0 end \\\
    if not location.z then location.z = 0 end \\\
    \\\
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\\\
    \\\
    if addToManaged then \\\
        cfxZones.addZoneToManagedZones(newZone)\\\
    end\\\
    return newZone\\\
end\\\
\\\
function cfxZones.createCircleZone(name, x, z, radius) \\\
    local newZone = {}\\\
    newZone.isCircle = true\\\
    newZone.isPoly = false\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = radius\\\
    newZone.point = cfxZones.createPoint(x, 0, z)\\\
 \\\
    -- props \\\
    newZone.properties = {}\\\
    \\\
    -- calculate my bounds\\\
    cfxZones.calculateZoneBounds(newZone)\\\
    \\\
    return newZone\\\
end\\\
\\\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\\\
local newZone = {}\\\
    newZone.isCircle = false\\\
    newZone.isPoly = true\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = 0\\\
    -- copy poly\\\
    for v=1, #poly do \\\
        local theVertex = poly[v] \\\
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \\\
    end\\\
    \\\
    -- properties \\\
    newZone.properties = {}\\\
    \\\
    cfxZones.calculateZoneBounds(newZone)\\\
end\\\
\\\
\\\
\\\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\\\
    -- create a new circular zone with center placed inside inZone\\\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\\\
    -- inZone.\\\
    \\\
--    trigger.action.outText(\\\"Zones: creating rZiZ with tr = \\\" .. targetRadius .. \\\" for \\\" .. inZone.name .. \\\" that as r = \\\" .. inZone.radius, 10)\\\
    \\\
    if inZone.isCircle then \\\
        local sourceRadius = inZone.radius\\\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\\\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\\\
    \\\
        -- ok, let's first create a random percentage value for the new radius\\\
        local percent = 1 / math.random(100)\\\
        -- now lets get a random degree\\\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \\\
        local r = sourceRadius * percent \\\
        local x = inZone.point.x + r * math.cos(degrees)\\\
        local z = inZone.point.z + r * math.sin(degrees)\\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\\\
        return newZone\\\
    \\\
    elseif inZone.isPoly then \\\
        -- we have a poly zone. the way we do this is simple:\\\
        -- generate random x, z with ranges of the bounding box \\\
        -- until the point falls within the polygon.\\\
        local newPoint = {}\\\
        local emergencyBrake = 0\\\
        repeat\\\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\\\
            emergencyBrake = emergencyBrake + 1\\\
            if (emergencyBrake > 100) then \\\
                newPoint = cfxZones.copyPoint(inZone.Point)\\\
                trigger.action.outText(\\\"CreateZoneInZone: mergency brake for inZone\\\" .. inZone.name,  10)\\\
                break\\\
            end\\\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\\\
        \\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\\\
        return newZone\\\
        \\\
    else \\\
        -- zone type unknown\\\
        trigger.action.outText(\\\"CreateZoneInZone: unknown zone type for inZone =\\\" .. inZone.name ,  10)\\\
        return nil \\\
    end\\\
end\\\
\\\
-- polygon inside zone calculations\\\
\\\
\\\
-- isleft returns true if point P is to the left of line AB \\\
-- by determining the sign (up or down) of the normal vector of \\\
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\\\
-- left as being > 0, so right is <= 0. As long as we always use the \\\
-- same comparison, it does not matter what up or down mean.\\\
-- this is important because we don't know if dcs always winds quads\\\
-- the same way, we must simply assume that they are wound as a polygon \\\
function cfxZones.isLeftXZ(A, B, P)\\\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\\\
end\\\
\\\
-- returns true/false for inside\\\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \\\
    -- Inside test (only convex polygons): \\\
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\\\
    -- how do we find out which side a point lies on? via the cross product\\\
    -- see isLeft below\\\
    \\\
    -- so all we need to do is make sure all results of isLeft for all\\\
    -- four sides are the same\\\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\\\
                                       -- they just must be the same side.\\\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\\\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \\\
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\\\
    return true\\\
end\\\
\\\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\\\
function cfxZones.isPointInsidePoly(thePoint, poly)\\\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\\\
    for v=2, #poly-1 do \\\
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\\\
    end\\\
    -- final test\\\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\\\
    \\\
    return true\\\
end;\\\
\\\
function cfxZones.isPointInsideZone(thePoint, theZone)\\\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\\\
    if (theZone.isCircle) then \\\
        local zp = cfxZones.getPoint(theZone)\\\
        local d = dcsCommon.dist(p, theZone.point)\\\
        return d < theZone.radius\\\
    end \\\
    \\\
    if (theZone.isPoly) then \\\
        --trigger.action.outText(\\\"zne: isPointInside: \\\" .. theZone.name .. \\\" is Polyzone!\\\", 30)\\\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\\\
    end\\\
\\\
    trigger.action.outText(\\\"isPointInsideZone: Unknown zone type for \\\" .. outerZone.name, 10)\\\
end\\\
\\\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\\\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \\\
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\\\
\\\
    \\\
end\\\
\\\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containerZones = {}\\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            table.insert(containerZones, tData)\\\
        end\\\
    end\\\
\\\
    return containerZones\\\
end\\\
\\\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            return tData\\\
        end\\\
    end\\\
\\\
    return nil\\\
end\\\
\\\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containedZones = {}\\\
    for zName, zData in pairs(testZones) do\\\
        if cfxZones.isZoneInsideZone(zData, superZone) then \\\
            if zData ~= superZone then \\\
                -- we filter superzone because superzone usually resides \\\
                -- inside itself \\\
                table.insert(containedZones, zData)\\\
            end\\\
        end\\\
    end\\\
    return containedZones \\\
end\\\
\\\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\\\
    if not testZones then testZones = cfxZones.zones end \\\
    local attributZones = {}\\\
    for aName,aZone in pairs(testZones) do\\\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\\\
        if attr then \\\
            -- this zone has the requested attribute\\\
            table.insert(attributZones, aZone)\\\
        end\\\
    end\\\
    return attributZones\\\
end\\\
\\\
--\\\
-- units / groups in zone\\\
--\\\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    --trigger.action.outText(\\\"Zone \\\" .. theZone.name .. \\\" radius \\\" .. theZone.radius, 30)\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allGroups = coalition.getGroups(coa, categ)\\\
        for key, group in pairs(allGroups) do -- iterate all groups\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(inZones, group)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allStats = coalition.getStaticObjects(coa)\\\
        for key, statO in pairs(allStats) do -- iterate all groups\\\
            local oP = statO:getPoint()\\\
            if cfxZones.pointInZone(oP, theZone) then\\\
                table.insert(inZones, statO)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\\\
    local groupsInZone = {}\\\
    local allGroups = coalition.getGroups(coal, categ)\\\
    for key, group in pairs(allGroups) do -- iterate all groups\\\
        if group:isExist() then\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(groupsInZone, group)            \\\
            end\\\
        end\\\
    end\\\
    return groupsInZone\\\
end\\\
\\\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
        \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then         \\\
            local p = aUnit:getPoint()\\\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\\\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \\\
                --trigger.action.outText(\\\"zne: YAY <\\\" .. aUnit:getName() .. \\\"> IS IN \\\" .. aZone.name, 30) \\\
                return true\\\
            end \\\
            --trigger.action.outText(\\\"zne: <\\\" .. aUnit:getName() .. \\\"> not in \\\" .. aZone.name .. \\\", dist = \\\" .. dist .. \\\", rad = \\\", aZone.radius, 30) \\\
        end\\\
    end\\\
    return false\\\
end\\\
\\\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then \\\
            local p = aUnit:getPoint()\\\
            if not cfxZones.isPointInsideZone(p, aZone) then \\\
                return false\\\
            end\\\
        end\\\
    end\\\
    return true\\\
end\\\
\\\
\\\
--\\\
-- Zone Manipulation\\\
--\\\
\\\
function cfxZones.offsetZone(theZone, dx, dz)\\\
    -- first, update center \\\
    theZone.point.x = theZone.point.x + dx\\\
    theZone.point.z = theZone.point.z + dz \\\
    \\\
    -- now process all polygon points - it's empty for circular, so don't worry\\\
    for v=1, #theZone.poly do \\\
        theZone.poly[v].x = theZone.poly[v].x + dx\\\
        theZone.poly[v].z = theZone.poly[v].z + dz \\\
    end\\\
end\\\
\\\
function cfxZones.moveZoneTo(theZone, x, z)\\\
    local dx = x - theZone.point.x\\\
    local dz = z - theZone.point.z \\\
    cfxZones.offsetZone(theZone, dx, dz)\\\
end;\\\
\\\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \\\
    local thePoint = theUnit:getPoint()\\\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\\\
end\\\
\\\
\\\
--[[\\\
-- no longer makes sense with poly zones\\\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\\\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\\\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\\\
    local reducedR = outerZone.radius - innerZone.radius\\\
    return d < reducedR\\\
end;\\\
--]]\\\
\\\
function cfxZones.dumpZones(zoneTable)\\\
    if not zoneTable then zoneTable = cfxZones.zones end \\\
    \\\
    trigger.action.outText(\\\"Zones START\\\", 10)\\\
    for i, zone in pairs(zoneTable) do \\\
        local myType = \\\"unknown\\\"\\\
        if zone.isCircle then myType = \\\"Circle\\\" end\\\
        if zone.isPoly then myType = \\\"Poly\\\" end \\\
        \\\
        trigger.action.outText(\\\"#\\\".. i .. \\\": \\\" .. zone.name .. \\\" of type \\\" .. myType, 10)\\\
    end\\\
    trigger.action.outText(\\\"Zones END\\\", 10)\\\
end\\\
\\\
function cfxZones.stringStartsWith(theString, thePrefix)\\\
    return theString:find(thePrefix) == 1\\\
end\\\
\\\
function cfxZones.keysForTable(theTable)\\\
    local keyset={}\\\
    local n=0\\\
\\\
    for k,v in pairs(tab) do\\\
        n=n+1\\\
        keyset[n]=k\\\
    end\\\
    return keyset\\\
end\\\
\\\
\\\
--\\\
-- return all zones that have a specific named property\\\
--\\\
function cfxZones.zonesWithProperty(propertyName, searchSet)\\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    local theZones = {}\\\
    for k, aZone in pairs(searchSet) do \\\
        if not aZone then \\\
            trigger.action.outText(\\\"+++zone: nil aZone for \\\" .. k, 30)\\\
        else \\\
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\\\
            if lU then \\\
                table.insert(theZones, aZone)\\\
            end\\\
        end\\\
    end    \\\
    return theZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with string prefix\\\
--\\\
function cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    \\\
--    trigger.action.outText(\\\"Enter: zonesStartingWithName for \\\" .. prefix , 30)\\\
    local prefixZones = {}\\\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\\\
    for name, zone in pairs(searchSet) do\\\
--        trigger.action.outText(\\\"testing \\\" .. name:upper() .. \\\" starts with \\\" .. prefix , 30)\\\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\\\
            prefixZones[name] = zone -- note: ref copy!\\\
            --trigger.action.outText(\\\"zone with prefix <\\\" .. prefix .. \\\"> found: \\\" .. name, 10)\\\
        end\\\
    end\\\
    \\\
    return prefixZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \\\
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\\\
-- with '+' and return only those. Use during debugging to force finding a specific zone\\\
--\\\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\\\
    -- you can force zones by having their name start with \\\"+\\\"\\\
    -- which will force them to return immediately if debugging is true for this call\\\
\\\
    if (debugging) then \\\
        local debugZones = cfxZones.zonesStartingWithName(\\\"+\\\", searchSet)\\\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \\\
            --trigger.action.outText(\\\"returning zones with prefix <\\\" .. prefix .. \\\">\\\", 10)\\\
            return debugZones \\\
        end \\\
    end\\\
    \\\
    --trigger.action.outText(\\\"#debugZones is  <\\\" .. #debugZones .. \\\">\\\", 10)\\\
\\\
    if (type(prefix) == \\\"string\\\") then \\\
        return cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    end\\\
    \\\
    local allZones = {}\\\
    for i=1, #prefix do \\\
        -- iterate through all names in prefix set\\\
        local theName = prefix[i]\\\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\\\
        -- add them all to current table\\\
        for zName, zInfo in pairs(newZones) do \\\
            allZones[zName] = zInfo -- will also replace doublets\\\
        end\\\
    end\\\
    \\\
    return allZones\\\
end\\\
\\\
function cfxZones.getZoneByName(aName, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    aName = aName:upper()\\\
    return searchSet[aName] -- the joys of key value pairs\\\
end\\\
\\\
function cfxZones.getZonesContainingString(aString, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end\\\
    aString = string.upper(aString)\\\
    resultSet = {}\\\
    for zName, zData in pairs(searchSet) do \\\
        if aString == string.upper(zData.name) then \\\
            resultSet[zName] = zData\\\
        end\\\
    end\\\
    \\\
end;\\\
\\\
-- filter zones by range to a point. returns indexed set\\\
function cfxZones.getZonesInRange(point, range, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    \\\
    local inRangeSet = {}\\\
    for zName, zData in pairs (theZones) do \\\
        if dcsCommon.dist(point, zData.point) < range then \\\
            table.insert(inRangeSet, zData)\\\
        end\\\
    end\\\
    return inRangeSet \\\
end\\\
\\\
-- get closest zone returns the zone that is closest to point \\\
function cfxZones.getClosestZone(point, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    local currDelta = math.huge \\\
    local closestZone = nil\\\
    for zName, zData in pairs(theZones) do \\\
        local zPoint = cfxZones.getPoint(zData)\\\
        local delta = dcsCommon.dist(point, zPoint)\\\
        if (delta < currDelta) then \\\
            currDelta = delta\\\
            closestZone = zData\\\
        end\\\
    end\\\
    return closestZone, currDelta \\\
end\\\
\\\
-- return a random zone from the table passed in zones\\\
function cfxZones.pickRandomZoneFrom(zones)\\\
    if not zones then zones = cfxZones.zones end\\\
    local indexedZones = dcsCommon.enumerateTable(zones)\\\
    local r = math.random(#indexedZones)\\\
    return indexedZones[r]\\\
end\\\
\\\
-- return an zone element by index \\\
function cfxZones.getZoneByIndex(theZones, theIndex) \\\
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\\\
    if (theIndex > #enumeratedZones) then\\\
        trigger.action.outText(\\\"WARNING: zone index \\\" .. theIndex .. \\\" out of bounds - max = \\\" .. #enumeratedZones, 30)\\\
        return nil end\\\
    if (theIndex < 1) then return nil end\\\
    \\\
    return enumeratedZones[theIndex]\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by dx, dy \\\
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
    if not alt then alt = 5 end \\\
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\\\
    point.x = point.x + dx -- getpoint updates and returns copy \\\
    point.z = point.z + dz \\\
    -- get height at point \\\
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\\\
    -- height-correct\\\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\\\
    trigger.action.smoke(point, smokeColor)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and degrees \\\
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\\\
    local rads = degrees * math.pi / 180\\\
    local dx = radius * math.sin(rads)\\\
    local dz = radius * math.cos(rads)\\\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \\\
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\\\
    local degrees = math.random(360)\\\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\\\
end\\\
\\\
\\\
-- unitInZone returns true if theUnit is inside the zone \\\
-- the second value returned is the percentage of distance\\\
-- from center to rim, with 100% being entirely in center, 0 = outside\\\
-- the third value returned is the distance to center\\\
function cfxZones.pointInZone(thePoint, theZone)\\\
\\\
    if not (theZone) then return false, 0, 0 end\\\
        \\\
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\\\
    \\\
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \\\
    local ppoint = thePoint -- xyz\\\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\\\
    local dist = dcsCommon.dist(zpoint, pflat)\\\
    \\\
    if theZone.isCircle then \\\
        if theZone.radius <= 0 then \\\
            return false, 0, 0\\\
        end\\\
\\\
        local success = dist < theZone.radius\\\
        local percentage = 0\\\
        if (success) then \\\
            percentage = 1 - dist / theZone.radius \\\
        end\\\
        return success, percentage, dist \\\
    \\\
    elseif theZone.isPoly then\\\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\\\
        return success, 0, dist\\\
    else \\\
        trigger.action.outText(\\\"pointInZone: Unknown zone type for \\\" .. theZone.name, 10)\\\
    end\\\
\\\
    return false\\\
end\\\
\\\
function cfxZones.unitInZone(theUnit, theZone)\\\
    if not (theUnit) then return false, 0, 0 end\\\
    if not (theUnit:isExist()) then return false, 0, 0 end\\\
    -- force zone update if it is linked to another zone \\\
    -- pointInZone does update\\\
    local thePoint = theUnit:getPoint()\\\
    return cfxZones.pointInZone(thePoint, theZone)\\\
    \\\
end\\\
\\\
-- returns all units of the input set that are inside the zone \\\
function cfxZones.unitsInZone(theUnits, theZone)\\\
    if not theUnits then return {} end\\\
    if not theZone then return {} end\\\
    \\\
    local zoneUnits = {}\\\
    for index, aUnit in pairs(theUnits) do \\\
        if cfxZones.unitInZone(aUnit, theZone) then \\\
            table.insert( zoneUnits, aUnit)\\\
        end\\\
    end\\\
    return zoneUnits\\\
end\\\
\\\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\\\
    -- does not care if they really are in zone. call unitsInZone first\\\
    -- if you need to have them filtered\\\
    -- theUnits MUST BE ARRAY\\\
    if not theUnits then return nil end\\\
    if #theUnits == 0 then return nil end\\\
    local closestUnit = theUnits[1]\\\
    for i=2, #theUnits do\\\
        local aUnit = theUnits[i]\\\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \\\
            closestUnit = aUnit\\\
        end\\\
    end\\\
    return closestUnit\\\
end\\\
\\\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\\\
        local playerUnit = pinfo.unit\\\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \\\
            return true, playerUnit\\\
        end\\\
    end -- for all players \\\
    return false, nil\\\
end\\\
\\\
\\\
-- grow zone\\\
function cfxZones.growZone()\\\
    -- circular zones simply increase radius\\\
    -- poly zones: not defined \\\
    \\\
end\\\
\\\
\\\
-- creating units in a zone\\\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \\\
    -- theUnits can be string or table of string \\\
    if not groupName then groupName = \\\"G_\\\"..theZone.name end \\\
    -- group name will be taken from zone name and prependend with \\\"G_\\\"\\\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\\\
    \\\
    -- turn the entire formation to heading\\\
    if (not heading) then heading = 0 end\\\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\\\
    \\\
    \\\
    -- now move the group to center of theZone\\\
    dcsCommon.moveGroupDataTo(theGroup, \\\
                          theZone.point.x, \\\
                          theZone.point.z) -- watchit: Z!!!\\\
\\\
\\\
    -- create the group in the world and return it\\\
    -- first we need to translate the coalition to a legal \\\
    -- country. we use UN for neutral, cjtf for red and blue \\\
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\\\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\\\
\\\
end\\\
\\\
-- parsing zone names. The first part of the name until the first blank \\\" \\\" \\\
-- is the prefix and is dropped unless keepPrefix is true. \\\
-- all others are regarded as key:value pairs and are then added \\\
-- to the zone \\\
-- separated by equal sign \\\"=\\\" AND MUST NOT CONTAIN BLANKS\\\
--\\\
-- example usage \\\"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\\\
--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
-- \\\
--[[--\\\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\\\
--    trigger.action.outText(\\\"Parsing zone:  \\\".. theZone.name, 30)\\\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\\\
    -- now split the name into space-separated strings\\\
    local attributes = dcsCommon.splitString(theZone.name, \\\" \\\")\\\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\\\
\\\
    -- now parse all substrings and add them as attributes to theZone\\\
    for i=1, #attributes do \\\
        local a = attributes[i]\\\
        local kvp = dcsCommon.splitString(a, \\\"=\\\")\\\
        if #kvp == 2 then \\\
            -- we have key value pair\\\
            local theKey = kvp[1]\\\
            local theValue = kvp[2]\\\
            theZone[theKey] = theValue \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\" parsed: Key = \\\" .. theKey .. \\\", Value = \\\" .. theValue, 30)\\\
        else \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\": dropped attribute \\\" .. a, 30)\\\
        end\\\
    end \\\
end\\\
--]]--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
--[[--\\\
function cfxZones.processCraterZones ()\\\
    local craters = cfxZones.zonesStartingWith(\\\"crater\\\")\\\
\\\
    \\\
\\\
    -- all these zones need to be processed and their name infor placed into attributes\\\
    for cName, cZone in pairs(craters) do\\\
        cfxZones.parseZoneNameIntoAttributes(cZone)\\\
        \\\
        -- blow stuff up at the location of the zone \\\
        local cPoint = cZone.point\\\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\\\
        trigger.action.explosion(cPoint, 900)\\\
         \\\
        -- now interpret and act on the crater info \\\
        -- to destroy and place fire. \\\
        \\\
        -- fire has small, medium, large \\\
        -- eg. fire=large\\\
        \\\
    end\\\
end\\\
--]]--\\\
--\\\
-- Flag Pulling \\\
--\\\
function cfxZones.pollFlag(theFlag, method, theZone) \\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zones: polling flag \\\" .. theFlag .. \\\" with \\\" .. method, 30)\\\
    end \\\
    \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++zones: nil theZone on pollFlag\\\", 30)\\\
    end\\\
    \\\
    method = method:lower()\\\
    --trigger.action.outText(\\\"+++zones: polling \\\" .. theZone.name .. \\\" method \\\" .. method .. \\\" flag \\\" .. theFlag, 30)\\\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\\\
    if method == \\\"inc\\\" or method == \\\"f+1\\\" then \\\
        --trigger.action.setUserFlag(theFlag, currVal + 1)\\\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\\\
        \\\
    elseif method == \\\"dec\\\" or method == \\\"f-1\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\\\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\\\
\\\
    elseif method == \\\"off\\\" or method == \\\"f=0\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, 0)\\\
        cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
    elseif method == \\\"flip\\\" or method == \\\"xor\\\" then \\\
        if currVal ~= 0 then \\\
--            trigger.action.setUserFlag(theFlag, 0)\\\
            cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
        else \\\
            --trigger.action.setUserFlag(theFlag, 1)\\\
            cfxZones.setFlagValue(theFlag, 1, theZone)\\\
        end\\\
        \\\
    else \\\
        if method ~= \\\"on\\\" and method ~= \\\"f=1\\\" then \\\
            trigger.action.outText(\\\"+++zones: unknown method <\\\" .. method .. \\\"> - using 'on'\\\", 30)\\\
        end\\\
        -- default: on.\\\
--        trigger.action.setUserFlag(theFlag, 1)\\\
        cfxZones.setFlagValue(theFlag, 1, theZone)\\\
\\\
    end\\\
    \\\
    if cfxZones.verbose then\\\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\\\
        trigger.action.outText(\\\"+++zones: flag <\\\" .. theFlag .. \\\"> changed from \\\" .. currVal .. \\\" to \\\" .. newVal, 30)\\\
    end \\\
end\\\
\\\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on setFlagValue\\\")\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight set, ME flag \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
        theFlag = zoneName .. theFlag\\\
    end\\\
    trigger.action.setUserFlag(theFlag, theValue)\\\
end \\\
\\\
function cfxZones.getFlagValue(theFlag, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on getFlagValue\\\", 30)\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight get, ME flag \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
            theFlag = zoneName .. theFlag\\\
    end\\\
    return tonumber(trigger.misc.getUserFlag(theFlag))\\\
end\\\
\\\
function cfxZones.isMEFlag(inFlag)\\\
    -- do NOT use me\\\
    trigger.action.outText(\\\"+++zne: warning: deprecated isMEFlag\\\", 30)\\\
    return true \\\
    -- returns true if inFlag is a pure positive number\\\
--    inFlag = dcsCommon.trim(inFlag)\\\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\\\
end\\\
\\\
-- method-based flag testing \\\
function cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\\\
    -- return true/false based on theMethod's contraints \\\
    -- simple constraints\\\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \\\
    local lMethod = string.lower(theMethod)\\\
    if lMethod == \\\"#\\\" or lMethod == \\\"change\\\" then \\\
        -- check if currVal different from lastVal\\\
        return currVal ~= lastVal  \\\
    end\\\
    \\\
    if lMethod == \\\"0\\\" or lMethod == \\\"no\\\" or lMethod == \\\"false\\\" \\\
       or lMethod == \\\"off\\\" then \\\
        -- WARNING: ONLY RETURNS TRUE IF FALSE AND lastval not zero!\\\
        return currVal == 0 and currVal ~= lastVal  \\\
    end\\\
    \\\
    if lMethod == \\\"1\\\" or lMethod == \\\"yes\\\" or lMethod == \\\"true\\\" \\\
       or lMethod == \\\"on\\\" then \\\
        -- WARNING: only returns true if lastval was false!!!!\\\
        return (currVal ~= 0 and lastVal == 0)  \\\
    end\\\
    \\\
    if lMethod == \\\"inc\\\" or lMethod == \\\"+1\\\" then \\\
        return currVal == lastVal+1\\\
    end\\\
    \\\
    if lMethod == \\\"dec\\\" or lMethod == \\\"-1\\\" then \\\
        return currVal == lastVal-1\\\
    end \\\
    \\\
    -- number constraints\\\
    -- or flag constraints \\\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \\\
    local op = string.sub(theMethod, 1, 1) \\\
    local remainder = string.sub(theMethod, 2)\\\
    remainder = dcsCommon.trim(remainder) -- remove all leading and trailing spaces\\\
    local rNum = tonumber(remainder)\\\
    if not rNum then \\\
        -- we use remainder as name for flag \\\
        -- PROCESS ESCAPE SEQUENCES\\\
        local esc = string.sub(remainder, 1, 1)\\\
        local last = string.sub(remainder, -1)\\\
        if esc == \\\"@\\\" then \\\
            remainder = string.sub(remainder, 2)\\\
            remainder = dcsCommon.trim(remainder)\\\
        end\\\
        \\\
        if esc == \\\"(\\\" and last == \\\")\\\" and string.len(remainder) > 2 then \\\
            -- note: iisues with startswith(\\\"(\\\") ???\\\
            remainder = string.sub(remainder, 2, -2)\\\
            remainder = dcsCommon.trim(remainder)        \\\
        end\\\
        if esc == \\\"\\\\\\\"\\\" and last == \\\"\\\\\\\"\\\" and string.len(remainder) > 2 then \\\
            remainder = string.sub(remainder, 2, -2)\\\
            remainder = dcsCommon.trim(remainder)        \\\
        end\\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++zne: accessing flag <\\\" .. remainder .. \\\">\\\", 30)\\\
        end \\\
        rNum = cfxZones.getFlagValue(remainder, theZone)\\\
    end \\\
    if rNum then \\\
        -- we have a comparison = \\\">\\\", \\\"=\\\", \\\"<\\\" followed by a number \\\
        -- THEY TRIGGER EACH TIME lastVal <> currVal AND condition IS MET  \\\
        if op == \\\"=\\\" then \\\
            return currVal == rNum and lastVal ~= currVal\\\
        end\\\
        \\\
        if op == \\\"#\\\" or op == \\\"~\\\" then \\\
            return currVal ~= rNum and lastVal ~= currVal \\\
        end \\\
        \\\
        if op == \\\"<\\\" then \\\
            return currVal < rNum and lastVal ~= currVal\\\
        end\\\
        \\\
        if op == \\\">\\\" then \\\
            return currVal > rNum and lastVal ~= currVal\\\
        end\\\
    end\\\
    \\\
    -- if we get here, we have an error \\\
    local zoneName = \\\"<NIL>\\\"\\\
    if theZone then zoneName = theZone.name end \\\
    trigger.action.outText(\\\"+++Zne: illegal method constraints |\\\" .. theMethod .. \\\"| for zone \\\" .. zoneName, 30 )\\\
    return false \\\
end\\\
\\\
function cfxZones.testZoneFlag(theZone, theFlagName, theMethod, latchName)\\\
    -- returns true if method contraints are met for flag theFlagName\\\
    -- as defined by theMethod \\\
    if not theMethod then \\\
        theMethod = \\\"change\\\"\\\
    end \\\
    \\\
    -- will read and update theZone[latchName] as appropriate \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone for testZoneFlag\\\", 30)\\\
        return\\\
    end \\\
    if not theFlagName then \\\
        -- this is common, no error, only on verbose \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++Zne: no flagName for zone \\\" .. theZone.name .. \\\" for testZoneFlag\\\", 30)\\\
        end \\\
        return\\\
    end\\\
    if not latchName then \\\
        trigger.action.outText(\\\"+++Zne: no latchName for zone \\\" .. theZone.name .. \\\" for testZoneFlag\\\", 30)\\\
        return    \\\
    end\\\
    -- get current value \\\
    local currVal = cfxZones.getFlagValue(theFlagName, theZone)\\\
    \\\
    -- get last value from latch\\\
    local lastVal = theZone[latchName]\\\
    if not lastVal then \\\
        trigger.action.outText(\\\"+++Zne: latch <\\\" .. latchName .. \\\"> not valid for zone \\\" .. theZone.name, 30)\\\
        return \\\
    end\\\
    \\\
    -- now, test by method \\\
    -- we should only test if currVal <> lastVal \\\
    if currVal == lastVal then\\\
        return false \\\
    end \\\
    \\\
    --trigger.action.outText(\\\"+++Zne: about to test: c = \\\" .. currVal .. \\\", l = \\\" .. lastVal, 30)\\\
    local testResult = cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\\\
\\\
    -- update latch by method\\\
    theZone[latchName] = currVal \\\
\\\
    -- return result\\\
    return testResult\\\
end\\\
\\\
\\\
\\\
function cfxZones.flagArrayFromString(inString)\\\
-- original code from RND flag\\\
    if string.len(inString) < 1 then \\\
        trigger.action.outText(\\\"+++zne: empty flags\\\", 30)\\\
        return {} \\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: processing <\\\" .. inString .. \\\">\\\", 30)\\\
    end \\\
    \\\
    local flags = {}\\\
    local rawElements = dcsCommon.splitString(inString, \\\",\\\")\\\
    -- go over all elements \\\
    for idx, anElement in pairs(rawElements) do \\\
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \\\"-\\\") then \\\
            -- interpret this as a range\\\
            local theRange = dcsCommon.splitString(anElement, \\\"-\\\")\\\
            local lowerBound = theRange[1]\\\
            lowerBound = tonumber(lowerBound)\\\
            local upperBound = theRange[2]\\\
            upperBound = tonumber(upperBound)\\\
            if lowerBound and upperBound then\\\
                -- swap if wrong order\\\
                if lowerBound > upperBound then \\\
                    local temp = upperBound\\\
                    upperBound = lowerBound\\\
                    lowerBound = temp \\\
                end\\\
                -- now add add numbers to flags\\\
                for f=lowerBound, upperBound do \\\
                    table.insert(flags, tostring(f))\\\
                end\\\
            else\\\
                -- bounds illegal\\\
                trigger.action.outText(\\\"+++zne: ignored range <\\\" .. anElement .. \\\"> (range)\\\", 30)\\\
            end\\\
        else\\\
            -- single number\\\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\\\
            if f then \\\
                table.insert(flags, f)\\\
\\\
            else \\\
                trigger.action.outText(\\\"+++zne: ignored element <\\\" .. anElement .. \\\"> (single)\\\", 30)\\\
            end\\\
        end\\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: <\\\" .. #flags .. \\\"> flags total\\\", 30)\\\
    end \\\
    return flags\\\
end\\\
\\\
--\\\
-- PROPERTY PROCESSING \\\
--\\\
\\\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \\\
    if not caseInsensitive then caseInsensitive = false end \\\
    if not theZone then return {} end \\\
    \\\
    local dcsProps = theZone.properties -- zone properties in dcs format \\\
    local props = {}\\\
    -- dcs has all properties as array with values .key and .value \\\
    -- so convert them into a dictionary \\\
    for i=1, #dcsProps do \\\
        local theProp = dcsProps[i]\\\
        local theKey = \\\"dummy\\\"\\\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \\\
        if caseInsensitive then theKey = theKey:upper() end \\\
        props[theKey] = theProp.value\\\
    end\\\
    return props \\\
end\\\
\\\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\\\
-- trim\\\
    theKey = dcsCommon.trim(theKey) \\\
--    make lower case conversion if not case sensitive\\\
    if not cfxZones.caseSensitiveProperties then \\\
        theKey = string.lower(theKey)\\\
    end\\\
\\\
-- iterate all keys and compare to what we are looking for     \\\
    for i=1, #theProperties do\\\
        local theP = theProperties[i]\\\
         \\\
        local existingKey = dcsCommon.trim(theP.key)  \\\
        if not cfxZones.caseSensitiveProperties then \\\
            existingKey = string.lower(existingKey)\\\
        end\\\
        if existingKey == theKey then \\\
            return theP.value\\\
        end\\\
    end\\\
    return nil \\\
end\\\
\\\
function cfxZones.getZoneProperty(cZone, theKey)\\\
    if not cZone then \\\
        trigger.action.outText(\\\"+++zone: no zone in getZoneProperty\\\", 30)\\\
        return nil\\\
    end \\\
    if not theKey then \\\
        trigger.action.outText(\\\"+++zone: no property key in getZoneProperty for zone \\\" .. cZone.name, 30)\\\
--        breakme.here = 1\\\
        return \\\
    end    \\\
\\\
    local props = cZone.properties\\\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\\\
    return theVal\\\
end\\\
\\\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    \\\
    if not default then default = \\\"\\\" end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end\\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"\\\" then p = default end \\\
        return p\\\
    end\\\
    return default -- warning. what if it was a number first?\\\
end\\\
\\\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    local theNumbers = dcsCommon.splitString(p, \\\" \\\")\\\
\\\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\\\
    \\\
end\\\
\\\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \\\
    if not maxVal then return minVal end \\\
    if not minVal then return maxVal end \\\
    local delay = maxVal\\\
    if minVal > 0 and minVal < delay then \\\
        -- we want a randomized from time from minTime .. delay\\\
        local varPart = delay - minVal + 1\\\
        varPart = dcsCommon.smallRandom(varPart) - 1\\\
        delay = minVal + varPart\\\
    end\\\
    return delay \\\
end\\\
\\\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
    -- reads property as string, and interprets as range 'a-b'. \\\
    -- if not a range but single number, returns both for upper and lower \\\
    --trigger.action.outText(\\\"***Zne: enter with <\\\" .. theZone.name .. \\\">: range for property <\\\" .. theProperty .. \\\">!\\\", 30)\\\
    if not default then default = 0 end \\\
    local lowerBound = default\\\
    local upperBound = default \\\
    \\\
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    if dcsCommon.containsString(rangeString, \\\"-\\\") then \\\
        local theRange = dcsCommon.splitString(rangeString, \\\"-\\\")\\\
        lowerBound = theRange[1]\\\
        lowerBound = tonumber(lowerBound)\\\
        upperBound = theRange[2]\\\
        upperBound = tonumber(upperBound)\\\
        if lowerBound and upperBound then\\\
            -- swap if wrong order\\\
            if lowerBound > upperBound then \\\
                local temp = upperBound\\\
                upperBound = lowerBound\\\
                lowerBound = temp \\\
            end\\\
--            if rndFlags.verbose then \\\
--            trigger.action.outText(\\\"+++Zne: detected range <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
--            end\\\
        else\\\
            -- bounds illegal\\\
            trigger.action.outText(\\\"+++Zne: illegal range  <\\\" .. rangeString .. \\\">, using \\\" .. default .. \\\"-\\\" .. default, 30)\\\
            lowerBound = default\\\
            upperBound = default \\\
        end\\\
    else \\\
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \\\
        lowerBound = upperBound\\\
    end\\\
--    trigger.action.outText(\\\"+++Zne: returning <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
    return lowerBound, upperBound\\\
end\\\
\\\
function cfxZones.hasProperty(theZone, theProperty) \\\
    return cfxZones.getZoneProperty(theZone, theProperty) ~= nil \\\
end\\\
\\\
\\\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\\\
    if not defaultVal then defaultVal = false end \\\
    if type(defaultVal) ~= \\\"boolean\\\" then \\\
        defaultVal = false \\\
    end\\\
\\\
    if not theZone then \\\
        trigger.action.outText(\\\"WARNING: NIL Zone in getBoolFromZoneProperty\\\", 30)\\\
        return defaultVal\\\
    end\\\
\\\
\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return defaultVal end\\\
\\\
    -- make sure we compare so default always works when \\\
    -- answer isn't exactly the opposite\\\
    p = p:lower() \\\
    if defaultVal == false then \\\
        -- only go true if exact match to yes or true \\\
        theBool = false \\\
        theBool = (p == 'true') or (p == 'yes') or p == \\\"1\\\"\\\
        return theBool\\\
    end\\\
    \\\
    local theBool = true \\\
    -- only go false if exactly no or false or \\\"0\\\"\\\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \\\"0\\\") \\\
    return theBool\\\
end\\\
\\\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end  \\\
    if type(p) == \\\"number\\\" then -- can't currently really happen\\\
        if p == 1 then return 1 end \\\
        if p == 2 then return 2 end \\\
        return 0\\\
    end\\\
    \\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"1\\\" then return 1 end \\\
        if p == \\\"2\\\" then return 2 end \\\
        if p == \\\"0\\\" then return 0 end \\\
        \\\
        p = p:lower()\\\
        \\\
        if p == \\\"red\\\" then return 1 end \\\
        if p == \\\"blue\\\" then return 2 end \\\
        if p == \\\"neutral\\\" then return 0 end\\\
        if p == \\\"all\\\" then return 0 end \\\
        return default \\\
    end\\\
    \\\
    return default \\\
end\\\
\\\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\\\
--TODO: trim string \\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    p = tonumber(p)\\\
    if not p then return default else return p end\\\
end\\\
\\\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\\\
    if not minDims then minDims = 0 end \\\
    if not defaultVal then defaultVal = 0 end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    local sVec = dcsCommon.splitString(s, \\\",\\\")\\\
    local nVec = {}\\\
    for idx, numString in pairs (sVec) do \\\
        local n = tonumber(numString)\\\
        if not n then n = defaultVal end\\\
        table.insert(nVec, n)\\\
    end\\\
    -- make sure vector contains at least minDims values \\\
    while #nVec < minDims do \\\
        table.insert(nVec, defaultVal)\\\
    end\\\
    \\\
    return nVec \\\
end\\\
\\\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\\\
    if not default then default = \\\"red\\\" end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    s = s:lower()\\\
    s = dcsCommon.trim(s)\\\
    -- check numbers \\\
    if (s == \\\"0\\\") then return \\\"green\\\" end\\\
    if (s == \\\"1\\\") then return \\\"red\\\" end\\\
    if (s == \\\"2\\\") then return \\\"white\\\" end\\\
    if (s == \\\"3\\\") then return \\\"orange\\\" end\\\
    if (s == \\\"4\\\") then return \\\"blue\\\" end\\\
    \\\
    if s == \\\"green\\\" or\\\
       s == \\\"red\\\" or\\\
       s == \\\"white\\\" or\\\
       s == \\\"orange\\\" or\\\
       s == \\\"blue\\\" then return s end\\\
\\\
    return default \\\
end\\\
\\\
--\\\
-- Moving Zones. They contain a link to their unit\\\
-- they are always located at an offset (x,z) or delta, phi \\\
-- to their master unit. delta phi allows adjustment for heading\\\
-- The cool thing about moving zones in cfx is that they do not\\\
-- require special handling, they are always updated \\\
-- and work with 'pointinzone' etc automatically\\\
\\\
-- Always works on cfx Zones, NEVER on DCS zones.\\\
--\\\
-- requires that readFromDCS has been done\\\
--\\\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \\\
    if aZone.linkedUnit then \\\
        local theUnit = aZone.linkedUnit\\\
        -- has a link. is link existing?\\\
        if theUnit:isExist() then \\\
            -- updates zone position \\\
            cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
        end\\\
    end\\\
    local thePos = {}\\\
    thePos.x = aZone.point.x\\\
    thePos.y = 0 -- aZone.y \\\
    thePos.z = aZone.point.z\\\
    -- update the zone as well -- that's stupid!\\\
    --[[-- aZone.point = thePos \\\
    local retPoint = {} -- create new copy to pass back \\\
    retPoint.x = thePos.x\\\
    retPoint.y = 0 \\\
    retPoint.z = thePos.z\\\
    --]]--\\\
    return thePos \\\
end\\\
\\\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\\\
    theZone.linkedUnit = theUnit\\\
    if not dx then dx = 0 end\\\
    if not dy then dy = 0 end \\\
    theZone.dx = dx\\\
    theZone.dy = dy \\\
end\\\
\\\
function cfxZones.updateMovingZones()\\\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\\\
    -- simply scan all cfx zones for the linkedUnit property and if there\\\
    -- update the zone's points\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        if aZone.linkedUnit then \\\
            local theUnit = aZone.linkedUnit\\\
            -- has a link. is link existing?\\\
            if theUnit:isExist() then \\\
                cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
                --trigger.action.outText(\\\"cf/x zones update \\\" .. aZone.name, 30)\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
function cfxZones.startMovingZones()\\\
    -- read all zoness, and look for a property called 'linkedUnit'\\\
    -- which will make them a linked zone if there is a unit that exists\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        local lU = cfxZones.getZoneProperty(aZone, \\\"linkedUnit\\\")\\\
        if lU then \\\
            -- this zone is linked to a unit\\\
            theUnit = Unit.getByName(lU)\\\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \\\"useOffset\\\", false)\\\
            if useOffset then aZone.useOffset = true end\\\
            if theUnit then\\\
                local dx = 0\\\
                local dz = 0\\\
                if useOffset then \\\
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \\\
                    dx = delta.x \\\
                    dz = delta.z\\\
                end\\\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\\\
                --trigger.action.outText(\\\"cf/x zones: linked \\\" .. aZone.name .. \\\" to \\\" .. theUnit:getName(), 30)\\\
                if useOffset then \\\
                    --trigger.action.outText(\\\"and dx = \\\" .. dx .. \\\" dz = \\\" .. dz, 30)\\\
                end\\\
            end\\\
        end\\\
        -- support for local verbose flag \\\
        aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, \\\"verbose\\\", false)\\\
    end\\\
end\\\
\\\
--\\\
-- init\\\
--\\\
\\\
function cfxZones.init()\\\
    -- read all zones into my own db\\\
    cfxZones.readFromDCS(true) -- true: erase old\\\
    \\\
    -- now, pre-read zone owner for all zones\\\
    -- note, all zones with this property are by definition owned zones.\\\
    -- and hence will be read anyway. this will merely ensure that the \\\
    -- ownership is established right away\\\
    -- unless owned zones module is missing, in which case \\\
    -- ownership is still established \\\
    local pZones = cfxZones.zonesWithProperty(\\\"owner\\\")\\\
    for n, aZone in pairs(pZones) do\\\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \\\"owner\\\", 0)\\\
    end\\\
        \\\
    \\\
    -- now initialize moving zones\\\
    cfxZones.startMovingZones()\\\
    cfxZones.updateMovingZones() -- will auto-repeat\\\
    \\\
    trigger.action.outText(\\\"cf/x Zones v\\\".. cfxZones.version .. \\\": loaded\\\", 10)\\\
end\\\
\\\
-- get everything rolling\\\
cfxZones.init()\\\
-- cf/x zone management module\\\
-- reads dcs zones and makes them accessible and mutable \\\
-- by scripting.\\\
--\\\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\\\
--\\\
\\\
cfxZones = {}\\\
cfxZones.version = \\\"2.6.1\\\"\\\
--[[-- VERSION HISTORY\\\
 - 2.2.4 - getCoalitionFromZoneProperty\\\
         - getStringFromZoneProperty\\\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \\\
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\\\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \\\
 - 2.2.8 - getBoolFromZoneProperty supports default \\\
         - cfxZones.hasProperty\\\
 - 2.3.0 - property names are case insensitive \\\
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\\\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \\\
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \\\
         - markZoneWithSmoke raised by 3 meters\\\
 - 2.4.2 - getClosestZone also returns delta \\\
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \\\
           createUniqueZoneName()\\\
           getStringFromZoneProperty returns default if property value = \\\"\\\"\\\
           corrected bug in addZoneToManagedZones\\\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\\\
         - linkUnit can use \\\"useOffset\\\" property to keep relative position\\\
 - 2.4.5 - updated various methods to support getPoint when referencing \\\
           zone.point  \\\
 - 2.4.6 - corrected spelling in markZoneWithSmoke\\\
 - 2.4.7 - copy reference to dcs zone into cfx zone \\\
 - 2.4.8 - getAllZoneProperties\\\
 - 2.4.9 - createSimpleZone no longer requires location \\\
         - parse dcs adds empty .properties = {} if none tehre \\\
         - createCircleZone adds empty properties \\\
         - createPolyZone adds empty properties \\\
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\\\
          - getBoolFromZoneProperty also recognizes 0, 1\\\
          - removed autostart\\\
 - 2.4.11 - removed typo in get closest zone \\\
 - 2.4.12 - getStringFromZoneProperty\\\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\\\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \\\
 - 2.5.2  - getPoint also writes through to zone itself for optimization\\\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
 - 2.5.3  - new getAllGroupsInZone()\\\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \\\
          - extractPropertyFromDCS trims key and property \\\
 - 2.5.5  - pollFlag() centralized for banging \\\
          - allStaticsInZone\\\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \\\
          - pollFlag supports theZone as final parameter\\\
          - randomDelayFromPositiveRange\\\
          - isMEFlag\\\
 - 2.5.7  - pollFlag supports dml flags\\\
 - 2.5.8  - flagArrayFromString\\\
          - getFlagNumber invokes tonumber() before returning result \\\
 - 2.5.9  - removed pass-back flag in getPoint() \\\
 - 2.6.0  - testZoneFlag() method based flag testing\\\
 - 2.6.1  - Watchflag parsing of zone condition for number-named flags\\\
          - case insensitive  \\\
 \\\
--]]--\\\
cfxZones.verbose = false\\\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \\\
cfxZones.ups = 1 -- updates per second. updates moving zones\\\
\\\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\\\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\\\
\\\
-- a zone has the following attributes\\\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\\\
-- radius (zero if quad zone)\\\
-- isCircle (true if quad zone)\\\
-- poly the quad coords are in the poly attribute and are a \\\
-- 1..n, wound counter-clockwise as (currently) in DCS:\\\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \\\
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \\\
--          for both circle and poly, all (x, 0, z)\\\
\\\
-- zones can carry information in their names that can get processed into attributes\\\
-- use \\\
-- zones can also carry information in their 'properties' tag that ME allows to \\\
-- edit. cfxZones provides an easy method to access these properties \\\
--  - getZoneProperty (returns as string)\\\
--  - getMinMaxFromZoneProperty\\\
--  - getBoolFromZoneProperty\\\
--  - getNumberFromZoneProperty\\\
\\\
\\\
-- SUPPORTED PROPERTIES\\\
-- - \\\"linkedUnit\\\" - zone moves with unit of that name. must be exact match\\\
--   can be combined with other attributes that extend (e.g. scar manager and\\\
--   limited pilots/airframes \\\
--\\\
\\\
--\\\
-- readZonesFromDCS is executed exactly once at the beginning\\\
-- from then on, use only the cfxZones.zones table \\\
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \\\
-- indexed by upper case. If you have two zones with same name but \\\
-- different case, one will be replaced\\\
--\\\
\\\
function cfxZones.readFromDCS(clearfirst)\\\
    if (clearfirst) then\\\
        cfxZones.zones = {}\\\
    end\\\
    -- not all missions have triggers or zones\\\
    if not env.mission.triggers then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no env.triggers defined\\\", 10)\\\
        end\\\
        return\\\
    end\\\
    \\\
    if not env.mission.triggers.zones then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no zones defined\\\", 10)\\\
        end\\\
        return;\\\
    end\\\
\\\
    -- we only retrieve the data we need. At this point it is name, location and radius\\\
    -- and put this in our own little  structure. we also convert to all upper case name for index\\\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\\\
    -- so we can quickly create other sets from this\\\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\\\
    --   name - name in upper case\\\
    --   isCircle - true if circular zone \\\
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \\\
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\\\
    --   radius - number, zero when quad\\\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\\\
    --   poly - array 1..n of poly points, wound counter-clockwise \\\
    \\\
    for i, dcsZone in pairs(env.mission.triggers.zones) do\\\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\\\
                                         -- dcs data is like a box of chocolates...\\\
            local newZone = {}\\\
            -- name, converted to upper is used only for indexing\\\
            -- the original name remains untouched\\\
            newZone.dcsZone = dcsZone\\\
            newZone.name = dcsZone.name\\\
            newZone.isCircle = false\\\
            newZone.isPoly = false\\\
            newZone.radius = 0\\\
            newZone.poly = {}\\\
            newZone.bounds = {}\\\
            newZone.properties = {} -- dcs has this too, copy if present\\\
            if dcsZone.properties then \\\
                newZone.properties = dcsZone.properties \\\
            else\\\
                newZone.properties = {}\\\
            end -- WARNING: REF COPY. May need to clone \\\
            \\\
            local upperName = newZone.name:upper()\\\
            \\\
            -- location as 'point'\\\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\\\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\\\
            --          altitude (they are an infinite cylinder) this works. Remember to \\\
            --          drop y from zone calculations to see if inside. \\\
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\\\
\\\
\\\
            -- start type processing. if zone.type exists, we have a mission \\\
            -- created with 2.7 or above, else earlier \\\
            local zoneType = 0\\\
            if (dcsZone.type) then \\\
                zoneType = dcsZone.type \\\
            end\\\
            \\\
            if zoneType == 0 then \\\
                -- circular zone \\\
                newZone.isCircle = true \\\
                newZone.radius = dcsZone.radius\\\
    \\\
            elseif zoneType == 2 then\\\
                -- polyZone\\\
                newZone.isPoly = true \\\
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\\\
                -- now transfer all point in the poly\\\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\\\
                -- correct vor this \\\
                local verts = {}\\\
                if dcsZone.verticies then verts = dcsZone.verticies \\\
                else \\\
                    -- in later versions, this was corrected\\\
                    verts = dcsZone.vertices -- see if this is ever called\\\
                end\\\
                \\\
                for v=1, #verts do\\\
                    local dcsPoint = verts[v]\\\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\\\
                    newZone.poly[v] = polyPoint\\\
                end\\\
            else \\\
                \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" unknown type \\\" .. zoneType, 10)\\\
            end\\\
            \\\
\\\
            -- calculate bounds\\\
            cfxZones.calculateZoneBounds(newZone) \\\
\\\
            -- add to my table\\\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\\\
            --trigger.action.outText(\\\"znd: procced \\\" .. newZone.name .. \\\" with radius \\\" .. newZone.radius, 30)\\\
        else\\\
            if cfxZones.verbose then \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" dropped\\\", 10)\\\
            end\\\
        end -- else var not a table\\\
        \\\
    end -- for all zones kvp\\\
end -- readFromDCS\\\
\\\
function cfxZones.calculateZoneBounds(theZone)\\\
    if not (theZone) then return \\\
    end\\\
    \\\
    local bounds = theZone.bounds -- copy ref!\\\
    \\\
    if theZone.isCircle then \\\
        -- aabb are easy: center +/- radius \\\
        local center = theZone.point\\\
        local radius = theZone.radius \\\
        -- dcs uses z+ is down on map\\\
        -- upper left is center - radius \\\
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\\\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\\\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\\\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\\\
        \\\
    elseif theZone.isPoly then\\\
        local poly = theZone.poly -- ref copy!\\\
        -- create the four points\\\
        local ll = cfxZones.createPointFromPoint(poly[1])\\\
        local lr = cfxZones.createPointFromPoint(poly[1])\\\
        local ul = cfxZones.createPointFromPoint(poly[1])\\\
        local ur = cfxZones.createPointFromPoint(poly[1])\\\
\\\
        -- now iterate through all points and adjust bounds accordingly \\\
        for v=2, #poly do \\\
             local vertex = poly[v]\\\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \\\
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \\\
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\\\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \\\
            \\\
        end\\\
        \\\
        -- now keep the new point references\\\
        -- and store them in the zone's bounds\\\
        bounds.ll = ll\\\
        bounds.lr = lr\\\
        bounds.ul = ul\\\
        bounds.ur = ur \\\
    else \\\
        -- huston, we have a problem\\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: calc bounds: zone \\\" .. theZone.name .. \\\" has unknown type\\\", 30)\\\
        end\\\
    end\\\
    \\\
end\\\
\\\
function cfxZones.createPoint(x, y, z)\\\
    local newPoint = {}\\\
    newPoint.x = x\\\
    newPoint.y = y\\\
    newPoint.z = z \\\
    return newPoint\\\
end\\\
\\\
function cfxZones.copyPoint(inPoint) \\\
    local newPoint = {}\\\
    newPoint.x = inPoint.x\\\
    newPoint.y = inPoint.y\\\
    newPoint.z = inPoint.z \\\
    return newPoint    \\\
end\\\
\\\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\\\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\\\
    return cP\\\
end\\\
\\\
function cfxZones.getHeightCorrectedZonePoint(theZone)\\\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\\\
end\\\
\\\
function cfxZones.createPointFromPoint(inPoint)\\\
    return cfxZones.copyPoint(inPoint)\\\
end\\\
\\\
function cfxZones.createPointFromDCSPoint(inPoint) \\\
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\\\
end\\\
\\\
\\\
function cfxZones.createRandomPointInsideBounds(bounds)\\\
    local x = math.random(bounds.ll.x, ur.x)\\\
    local z = math.random(bounds.ll.z, ur.z)\\\
    return cfxZones.createPoint(x, 0, z)\\\
end\\\
\\\
function cfxZones.addZoneToManagedZones(theZone)\\\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\\\
    cfxZones.zones[upperName] = theZone\\\
end\\\
\\\
function cfxZones.createUniqueZoneName(inName, searchSet)\\\
    if not inName then return nil end \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    inName = inName:upper()\\\
    while searchSet[inName] ~= nil do \\\
        inName = inName .. \\\"X\\\"\\\
    end\\\
    return inName\\\
end\\\
\\\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\\\
    if not radius then radius = 10 end\\\
    if not addToManaged then addToManaged = false end \\\
    if not location then \\\
        location = {}\\\
    end\\\
    if not location.x then location.x = 0 end \\\
    if not location.z then location.z = 0 end \\\
    \\\
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\\\
    \\\
    if addToManaged then \\\
        cfxZones.addZoneToManagedZones(newZone)\\\
    end\\\
    return newZone\\\
end\\\
\\\
function cfxZones.createCircleZone(name, x, z, radius) \\\
    local newZone = {}\\\
    newZone.isCircle = true\\\
    newZone.isPoly = false\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = radius\\\
    newZone.point = cfxZones.createPoint(x, 0, z)\\\
 \\\
    -- props \\\
    newZone.properties = {}\\\
    \\\
    -- calculate my bounds\\\
    cfxZones.calculateZoneBounds(newZone)\\\
    \\\
    return newZone\\\
end\\\
\\\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\\\
local newZone = {}\\\
    newZone.isCircle = false\\\
    newZone.isPoly = true\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = 0\\\
    -- copy poly\\\
    for v=1, #poly do \\\
        local theVertex = poly[v] \\\
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \\\
    end\\\
    \\\
    -- properties \\\
    newZone.properties = {}\\\
    \\\
    cfxZones.calculateZoneBounds(newZone)\\\
end\\\
\\\
\\\
\\\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\\\
    -- create a new circular zone with center placed inside inZone\\\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\\\
    -- inZone.\\\
    \\\
--    trigger.action.outText(\\\"Zones: creating rZiZ with tr = \\\" .. targetRadius .. \\\" for \\\" .. inZone.name .. \\\" that as r = \\\" .. inZone.radius, 10)\\\
    \\\
    if inZone.isCircle then \\\
        local sourceRadius = inZone.radius\\\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\\\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\\\
    \\\
        -- ok, let's first create a random percentage value for the new radius\\\
        local percent = 1 / math.random(100)\\\
        -- now lets get a random degree\\\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \\\
        local r = sourceRadius * percent \\\
        local x = inZone.point.x + r * math.cos(degrees)\\\
        local z = inZone.point.z + r * math.sin(degrees)\\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\\\
        return newZone\\\
    \\\
    elseif inZone.isPoly then \\\
        -- we have a poly zone. the way we do this is simple:\\\
        -- generate random x, z with ranges of the bounding box \\\
        -- until the point falls within the polygon.\\\
        local newPoint = {}\\\
        local emergencyBrake = 0\\\
        repeat\\\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\\\
            emergencyBrake = emergencyBrake + 1\\\
            if (emergencyBrake > 100) then \\\
                newPoint = cfxZones.copyPoint(inZone.Point)\\\
                trigger.action.outText(\\\"CreateZoneInZone: mergency brake for inZone\\\" .. inZone.name,  10)\\\
                break\\\
            end\\\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\\\
        \\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\\\
        return newZone\\\
        \\\
    else \\\
        -- zone type unknown\\\
        trigger.action.outText(\\\"CreateZoneInZone: unknown zone type for inZone =\\\" .. inZone.name ,  10)\\\
        return nil \\\
    end\\\
end\\\
\\\
-- polygon inside zone calculations\\\
\\\
\\\
-- isleft returns true if point P is to the left of line AB \\\
-- by determining the sign (up or down) of the normal vector of \\\
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\\\
-- left as being > 0, so right is <= 0. As long as we always use the \\\
-- same comparison, it does not matter what up or down mean.\\\
-- this is important because we don't know if dcs always winds quads\\\
-- the same way, we must simply assume that they are wound as a polygon \\\
function cfxZones.isLeftXZ(A, B, P)\\\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\\\
end\\\
\\\
-- returns true/false for inside\\\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \\\
    -- Inside test (only convex polygons): \\\
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\\\
    -- how do we find out which side a point lies on? via the cross product\\\
    -- see isLeft below\\\
    \\\
    -- so all we need to do is make sure all results of isLeft for all\\\
    -- four sides are the same\\\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\\\
                                       -- they just must be the same side.\\\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\\\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \\\
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\\\
    return true\\\
end\\\
\\\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\\\
function cfxZones.isPointInsidePoly(thePoint, poly)\\\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\\\
    for v=2, #poly-1 do \\\
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\\\
    end\\\
    -- final test\\\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\\\
    \\\
    return true\\\
end;\\\
\\\
function cfxZones.isPointInsideZone(thePoint, theZone)\\\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\\\
    if (theZone.isCircle) then \\\
        local zp = cfxZones.getPoint(theZone)\\\
        local d = dcsCommon.dist(p, theZone.point)\\\
        return d < theZone.radius\\\
    end \\\
    \\\
    if (theZone.isPoly) then \\\
        --trigger.action.outText(\\\"zne: isPointInside: \\\" .. theZone.name .. \\\" is Polyzone!\\\", 30)\\\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\\\
    end\\\
\\\
    trigger.action.outText(\\\"isPointInsideZone: Unknown zone type for \\\" .. outerZone.name, 10)\\\
end\\\
\\\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\\\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \\\
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\\\
\\\
    \\\
end\\\
\\\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containerZones = {}\\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            table.insert(containerZones, tData)\\\
        end\\\
    end\\\
\\\
    return containerZones\\\
end\\\
\\\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            return tData\\\
        end\\\
    end\\\
\\\
    return nil\\\
end\\\
\\\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containedZones = {}\\\
    for zName, zData in pairs(testZones) do\\\
        if cfxZones.isZoneInsideZone(zData, superZone) then \\\
            if zData ~= superZone then \\\
                -- we filter superzone because superzone usually resides \\\
                -- inside itself \\\
                table.insert(containedZones, zData)\\\
            end\\\
        end\\\
    end\\\
    return containedZones \\\
end\\\
\\\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\\\
    if not testZones then testZones = cfxZones.zones end \\\
    local attributZones = {}\\\
    for aName,aZone in pairs(testZones) do\\\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\\\
        if attr then \\\
            -- this zone has the requested attribute\\\
            table.insert(attributZones, aZone)\\\
        end\\\
    end\\\
    return attributZones\\\
end\\\
\\\
--\\\
-- units / groups in zone\\\
--\\\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    --trigger.action.outText(\\\"Zone \\\" .. theZone.name .. \\\" radius \\\" .. theZone.radius, 30)\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allGroups = coalition.getGroups(coa, categ)\\\
        for key, group in pairs(allGroups) do -- iterate all groups\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(inZones, group)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allStats = coalition.getStaticObjects(coa)\\\
        for key, statO in pairs(allStats) do -- iterate all groups\\\
            local oP = statO:getPoint()\\\
            if cfxZones.pointInZone(oP, theZone) then\\\
                table.insert(inZones, statO)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\\\
    local groupsInZone = {}\\\
    local allGroups = coalition.getGroups(coal, categ)\\\
    for key, group in pairs(allGroups) do -- iterate all groups\\\
        if group:isExist() then\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(groupsInZone, group)            \\\
            end\\\
        end\\\
    end\\\
    return groupsInZone\\\
end\\\
\\\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
        \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then         \\\
            local p = aUnit:getPoint()\\\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\\\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \\\
                --trigger.action.outText(\\\"zne: YAY <\\\" .. aUnit:getName() .. \\\"> IS IN \\\" .. aZone.name, 30) \\\
                return true\\\
            end \\\
            --trigger.action.outText(\\\"zne: <\\\" .. aUnit:getName() .. \\\"> not in \\\" .. aZone.name .. \\\", dist = \\\" .. dist .. \\\", rad = \\\", aZone.radius, 30) \\\
        end\\\
    end\\\
    return false\\\
end\\\
\\\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then \\\
            local p = aUnit:getPoint()\\\
            if not cfxZones.isPointInsideZone(p, aZone) then \\\
                return false\\\
            end\\\
        end\\\
    end\\\
    return true\\\
end\\\
\\\
\\\
--\\\
-- Zone Manipulation\\\
--\\\
\\\
function cfxZones.offsetZone(theZone, dx, dz)\\\
    -- first, update center \\\
    theZone.point.x = theZone.point.x + dx\\\
    theZone.point.z = theZone.point.z + dz \\\
    \\\
    -- now process all polygon points - it's empty for circular, so don't worry\\\
    for v=1, #theZone.poly do \\\
        theZone.poly[v].x = theZone.poly[v].x + dx\\\
        theZone.poly[v].z = theZone.poly[v].z + dz \\\
    end\\\
end\\\
\\\
function cfxZones.moveZoneTo(theZone, x, z)\\\
    local dx = x - theZone.point.x\\\
    local dz = z - theZone.point.z \\\
    cfxZones.offsetZone(theZone, dx, dz)\\\
end;\\\
\\\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \\\
    local thePoint = theUnit:getPoint()\\\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\\\
end\\\
\\\
\\\
--[[\\\
-- no longer makes sense with poly zones\\\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\\\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\\\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\\\
    local reducedR = outerZone.radius - innerZone.radius\\\
    return d < reducedR\\\
end;\\\
--]]\\\
\\\
function cfxZones.dumpZones(zoneTable)\\\
    if not zoneTable then zoneTable = cfxZones.zones end \\\
    \\\
    trigger.action.outText(\\\"Zones START\\\", 10)\\\
    for i, zone in pairs(zoneTable) do \\\
        local myType = \\\"unknown\\\"\\\
        if zone.isCircle then myType = \\\"Circle\\\" end\\\
        if zone.isPoly then myType = \\\"Poly\\\" end \\\
        \\\
        trigger.action.outText(\\\"#\\\".. i .. \\\": \\\" .. zone.name .. \\\" of type \\\" .. myType, 10)\\\
    end\\\
    trigger.action.outText(\\\"Zones END\\\", 10)\\\
end\\\
\\\
function cfxZones.stringStartsWith(theString, thePrefix)\\\
    return theString:find(thePrefix) == 1\\\
end\\\
\\\
function cfxZones.keysForTable(theTable)\\\
    local keyset={}\\\
    local n=0\\\
\\\
    for k,v in pairs(tab) do\\\
        n=n+1\\\
        keyset[n]=k\\\
    end\\\
    return keyset\\\
end\\\
\\\
\\\
--\\\
-- return all zones that have a specific named property\\\
--\\\
function cfxZones.zonesWithProperty(propertyName, searchSet)\\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    local theZones = {}\\\
    for k, aZone in pairs(searchSet) do \\\
        if not aZone then \\\
            trigger.action.outText(\\\"+++zone: nil aZone for \\\" .. k, 30)\\\
        else \\\
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\\\
            if lU then \\\
                table.insert(theZones, aZone)\\\
            end\\\
        end\\\
    end    \\\
    return theZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with string prefix\\\
--\\\
function cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    \\\
--    trigger.action.outText(\\\"Enter: zonesStartingWithName for \\\" .. prefix , 30)\\\
    local prefixZones = {}\\\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\\\
    for name, zone in pairs(searchSet) do\\\
--        trigger.action.outText(\\\"testing \\\" .. name:upper() .. \\\" starts with \\\" .. prefix , 30)\\\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\\\
            prefixZones[name] = zone -- note: ref copy!\\\
            --trigger.action.outText(\\\"zone with prefix <\\\" .. prefix .. \\\"> found: \\\" .. name, 10)\\\
        end\\\
    end\\\
    \\\
    return prefixZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \\\
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\\\
-- with '+' and return only those. Use during debugging to force finding a specific zone\\\
--\\\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\\\
    -- you can force zones by having their name start with \\\"+\\\"\\\
    -- which will force them to return immediately if debugging is true for this call\\\
\\\
    if (debugging) then \\\
        local debugZones = cfxZones.zonesStartingWithName(\\\"+\\\", searchSet)\\\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \\\
            --trigger.action.outText(\\\"returning zones with prefix <\\\" .. prefix .. \\\">\\\", 10)\\\
            return debugZones \\\
        end \\\
    end\\\
    \\\
    --trigger.action.outText(\\\"#debugZones is  <\\\" .. #debugZones .. \\\">\\\", 10)\\\
\\\
    if (type(prefix) == \\\"string\\\") then \\\
        return cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    end\\\
    \\\
    local allZones = {}\\\
    for i=1, #prefix do \\\
        -- iterate through all names in prefix set\\\
        local theName = prefix[i]\\\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\\\
        -- add them all to current table\\\
        for zName, zInfo in pairs(newZones) do \\\
            allZones[zName] = zInfo -- will also replace doublets\\\
        end\\\
    end\\\
    \\\
    return allZones\\\
end\\\
\\\
function cfxZones.getZoneByName(aName, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    aName = aName:upper()\\\
    return searchSet[aName] -- the joys of key value pairs\\\
end\\\
\\\
function cfxZones.getZonesContainingString(aString, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end\\\
    aString = string.upper(aString)\\\
    resultSet = {}\\\
    for zName, zData in pairs(searchSet) do \\\
        if aString == string.upper(zData.name) then \\\
            resultSet[zName] = zData\\\
        end\\\
    end\\\
    \\\
end;\\\
\\\
-- filter zones by range to a point. returns indexed set\\\
function cfxZones.getZonesInRange(point, range, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    \\\
    local inRangeSet = {}\\\
    for zName, zData in pairs (theZones) do \\\
        if dcsCommon.dist(point, zData.point) < range then \\\
            table.insert(inRangeSet, zData)\\\
        end\\\
    end\\\
    return inRangeSet \\\
end\\\
\\\
-- get closest zone returns the zone that is closest to point \\\
function cfxZones.getClosestZone(point, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    local currDelta = math.huge \\\
    local closestZone = nil\\\
    for zName, zData in pairs(theZones) do \\\
        local zPoint = cfxZones.getPoint(zData)\\\
        local delta = dcsCommon.dist(point, zPoint)\\\
        if (delta < currDelta) then \\\
            currDelta = delta\\\
            closestZone = zData\\\
        end\\\
    end\\\
    return closestZone, currDelta \\\
end\\\
\\\
-- return a random zone from the table passed in zones\\\
function cfxZones.pickRandomZoneFrom(zones)\\\
    if not zones then zones = cfxZones.zones end\\\
    local indexedZones = dcsCommon.enumerateTable(zones)\\\
    local r = math.random(#indexedZones)\\\
    return indexedZones[r]\\\
end\\\
\\\
-- return an zone element by index \\\
function cfxZones.getZoneByIndex(theZones, theIndex) \\\
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\\\
    if (theIndex > #enumeratedZones) then\\\
        trigger.action.outText(\\\"WARNING: zone index \\\" .. theIndex .. \\\" out of bounds - max = \\\" .. #enumeratedZones, 30)\\\
        return nil end\\\
    if (theIndex < 1) then return nil end\\\
    \\\
    return enumeratedZones[theIndex]\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by dx, dy \\\
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
    if not alt then alt = 5 end \\\
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\\\
    point.x = point.x + dx -- getpoint updates and returns copy \\\
    point.z = point.z + dz \\\
    -- get height at point \\\
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\\\
    -- height-correct\\\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\\\
    trigger.action.smoke(point, smokeColor)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and degrees \\\
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\\\
    local rads = degrees * math.pi / 180\\\
    local dx = radius * math.sin(rads)\\\
    local dz = radius * math.cos(rads)\\\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \\\
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\\\
    local degrees = math.random(360)\\\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\\\
end\\\
\\\
\\\
-- unitInZone returns true if theUnit is inside the zone \\\
-- the second value returned is the percentage of distance\\\
-- from center to rim, with 100% being entirely in center, 0 = outside\\\
-- the third value returned is the distance to center\\\
function cfxZones.pointInZone(thePoint, theZone)\\\
\\\
    if not (theZone) then return false, 0, 0 end\\\
        \\\
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\\\
    \\\
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \\\
    local ppoint = thePoint -- xyz\\\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\\\
    local dist = dcsCommon.dist(zpoint, pflat)\\\
    \\\
    if theZone.isCircle then \\\
        if theZone.radius <= 0 then \\\
            return false, 0, 0\\\
        end\\\
\\\
        local success = dist < theZone.radius\\\
        local percentage = 0\\\
        if (success) then \\\
            percentage = 1 - dist / theZone.radius \\\
        end\\\
        return success, percentage, dist \\\
    \\\
    elseif theZone.isPoly then\\\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\\\
        return success, 0, dist\\\
    else \\\
        trigger.action.outText(\\\"pointInZone: Unknown zone type for \\\" .. theZone.name, 10)\\\
    end\\\
\\\
    return false\\\
end\\\
\\\
function cfxZones.unitInZone(theUnit, theZone)\\\
    if not (theUnit) then return false, 0, 0 end\\\
    if not (theUnit:isExist()) then return false, 0, 0 end\\\
    -- force zone update if it is linked to another zone \\\
    -- pointInZone does update\\\
    local thePoint = theUnit:getPoint()\\\
    return cfxZones.pointInZone(thePoint, theZone)\\\
    \\\
end\\\
\\\
-- returns all units of the input set that are inside the zone \\\
function cfxZones.unitsInZone(theUnits, theZone)\\\
    if not theUnits then return {} end\\\
    if not theZone then return {} end\\\
    \\\
    local zoneUnits = {}\\\
    for index, aUnit in pairs(theUnits) do \\\
        if cfxZones.unitInZone(aUnit, theZone) then \\\
            table.insert( zoneUnits, aUnit)\\\
        end\\\
    end\\\
    return zoneUnits\\\
end\\\
\\\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\\\
    -- does not care if they really are in zone. call unitsInZone first\\\
    -- if you need to have them filtered\\\
    -- theUnits MUST BE ARRAY\\\
    if not theUnits then return nil end\\\
    if #theUnits == 0 then return nil end\\\
    local closestUnit = theUnits[1]\\\
    for i=2, #theUnits do\\\
        local aUnit = theUnits[i]\\\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \\\
            closestUnit = aUnit\\\
        end\\\
    end\\\
    return closestUnit\\\
end\\\
\\\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\\\
        local playerUnit = pinfo.unit\\\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \\\
            return true, playerUnit\\\
        end\\\
    end -- for all players \\\
    return false, nil\\\
end\\\
\\\
\\\
-- grow zone\\\
function cfxZones.growZone()\\\
    -- circular zones simply increase radius\\\
    -- poly zones: not defined \\\
    \\\
end\\\
\\\
\\\
-- creating units in a zone\\\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \\\
    -- theUnits can be string or table of string \\\
    if not groupName then groupName = \\\"G_\\\"..theZone.name end \\\
    -- group name will be taken from zone name and prependend with \\\"G_\\\"\\\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\\\
    \\\
    -- turn the entire formation to heading\\\
    if (not heading) then heading = 0 end\\\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\\\
    \\\
    \\\
    -- now move the group to center of theZone\\\
    dcsCommon.moveGroupDataTo(theGroup, \\\
                          theZone.point.x, \\\
                          theZone.point.z) -- watchit: Z!!!\\\
\\\
\\\
    -- create the group in the world and return it\\\
    -- first we need to translate the coalition to a legal \\\
    -- country. we use UN for neutral, cjtf for red and blue \\\
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\\\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\\\
\\\
end\\\
\\\
-- parsing zone names. The first part of the name until the first blank \\\" \\\" \\\
-- is the prefix and is dropped unless keepPrefix is true. \\\
-- all others are regarded as key:value pairs and are then added \\\
-- to the zone \\\
-- separated by equal sign \\\"=\\\" AND MUST NOT CONTAIN BLANKS\\\
--\\\
-- example usage \\\"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\\\
--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
-- \\\
--[[--\\\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\\\
--    trigger.action.outText(\\\"Parsing zone:  \\\".. theZone.name, 30)\\\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\\\
    -- now split the name into space-separated strings\\\
    local attributes = dcsCommon.splitString(theZone.name, \\\" \\\")\\\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\\\
\\\
    -- now parse all substrings and add them as attributes to theZone\\\
    for i=1, #attributes do \\\
        local a = attributes[i]\\\
        local kvp = dcsCommon.splitString(a, \\\"=\\\")\\\
        if #kvp == 2 then \\\
            -- we have key value pair\\\
            local theKey = kvp[1]\\\
            local theValue = kvp[2]\\\
            theZone[theKey] = theValue \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\" parsed: Key = \\\" .. theKey .. \\\", Value = \\\" .. theValue, 30)\\\
        else \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\": dropped attribute \\\" .. a, 30)\\\
        end\\\
    end \\\
end\\\
--]]--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
--[[--\\\
function cfxZones.processCraterZones ()\\\
    local craters = cfxZones.zonesStartingWith(\\\"crater\\\")\\\
\\\
    \\\
\\\
    -- all these zones need to be processed and their name infor placed into attributes\\\
    for cName, cZone in pairs(craters) do\\\
        cfxZones.parseZoneNameIntoAttributes(cZone)\\\
        \\\
        -- blow stuff up at the location of the zone \\\
        local cPoint = cZone.point\\\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\\\
        trigger.action.explosion(cPoint, 900)\\\
         \\\
        -- now interpret and act on the crater info \\\
        -- to destroy and place fire. \\\
        \\\
        -- fire has small, medium, large \\\
        -- eg. fire=large\\\
        \\\
    end\\\
end\\\
--]]--\\\
--\\\
-- Flag Pulling \\\
--\\\
function cfxZones.doPollFlag(theFlag, method, theZone)\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zones: polling flag \\\" .. theFlag .. \\\" with \\\" .. method, 30)\\\
    end \\\
    \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++zones: nil theZone on pollFlag\\\", 30)\\\
    end\\\
    \\\
    method = method:lower()\\\
    --trigger.action.outText(\\\"+++zones: polling \\\" .. theZone.name .. \\\" method \\\" .. method .. \\\" flag \\\" .. theFlag, 30)\\\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\\\
    if method == \\\"inc\\\" or method == \\\"f+1\\\" then \\\
        --trigger.action.setUserFlag(theFlag, currVal + 1)\\\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\\\
        \\\
    elseif method == \\\"dec\\\" or method == \\\"f-1\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\\\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\\\
\\\
    elseif method == \\\"off\\\" or method == \\\"f=0\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, 0)\\\
        cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
    elseif method == \\\"flip\\\" or method == \\\"xor\\\" then \\\
        if currVal ~= 0 then \\\
--            trigger.action.setUserFlag(theFlag, 0)\\\
            cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
        else \\\
            --trigger.action.setUserFlag(theFlag, 1)\\\
            cfxZones.setFlagValue(theFlag, 1, theZone)\\\
        end\\\
        \\\
    else \\\
        if method ~= \\\"on\\\" and method ~= \\\"f=1\\\" then \\\
            trigger.action.outText(\\\"+++zones: unknown method <\\\" .. method .. \\\"> - using 'on'\\\", 30)\\\
        end\\\
        -- default: on.\\\
--        trigger.action.setUserFlag(theFlag, 1)\\\
        cfxZones.setFlagValue(theFlag, 1, theZone)\\\
\\\
    end\\\
    \\\
    if cfxZones.verbose then\\\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\\\
        trigger.action.outText(\\\"+++zones: flag <\\\" .. theFlag .. \\\"> changed from \\\" .. currVal .. \\\" to \\\" .. newVal, 30)\\\
    end \\\
end\\\
\\\
function cfxZones.pollFlag(theFlag, method, theZone) \\\
    local allFlags = {}\\\
    if dcsCommon.containsString(theFlag, \\\",\\\") then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++zones: will poll flag set <\\\" .. theFlag .. \\\"> with \\\" .. method, 30)\\\
        end\\\
        allFlags = dcsCommon.splitString(theFlag, \\\",\\\")\\\
    else \\\
        table.insert(allFlags, theFlag)\\\
    end\\\
    \\\
    for idx, aFlag in pairs(allFlags) do \\\
        aFlag = dcsCommon.trim(aFlag)\\\
        -- note: mey require range preprocessing, but that's not\\\
        -- a priority \\\
        cfxZones.doPollFlag(aFlag, method, theZone)\\\
    end \\\
    \\\
end\\\
\\\
function cfxZones.setFlagValueMult(theFlag, theValue, theZone)\\\
    local allFlags = {}\\\
    if dcsCommon.containsString(theFlag, \\\",\\\") then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++zones: will multi-set flags <\\\" .. theFlag .. \\\"> to \\\" .. theValue, 30)\\\
        end\\\
        allFlags = dcsCommon.splitString(theFlag, \\\",\\\")\\\
    else \\\
        table.insert(allFlags, theFlag)\\\
    end\\\
    \\\
    for idx, aFlag in pairs(allFlags) do \\\
        aFlag = dcsCommon.trim(aFlag)\\\
        -- note: mey require range preprocessing, but that's not\\\
        -- a priority \\\
        cfxZones.setFlagValue(aFlag, theValue, theZone)\\\
    end \\\
end\\\
\\\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on setFlagValue\\\")\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight set, ME flag \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
        theFlag = zoneName .. theFlag\\\
    end\\\
    trigger.action.setUserFlag(theFlag, theValue)\\\
end \\\
\\\
function cfxZones.getFlagValue(theFlag, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on getFlagValue\\\", 30)\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight get, ME flag \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
            theFlag = zoneName .. theFlag\\\
    end\\\
    return tonumber(trigger.misc.getUserFlag(theFlag))\\\
end\\\
\\\
function cfxZones.isMEFlag(inFlag)\\\
    -- do NOT use me\\\
    trigger.action.outText(\\\"+++zne: warning: deprecated isMEFlag\\\", 30)\\\
    return true \\\
    -- returns true if inFlag is a pure positive number\\\
--    inFlag = dcsCommon.trim(inFlag)\\\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\\\
end\\\
\\\
-- method-based flag testing \\\
function cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\\\
    -- return true/false based on theMethod's contraints \\\
    -- simple constraints\\\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \\\
    local lMethod = string.lower(theMethod)\\\
    if lMethod == \\\"#\\\" or lMethod == \\\"change\\\" then \\\
        -- check if currVal different from lastVal\\\
        return currVal ~= lastVal  \\\
    end\\\
    \\\
    if lMethod == \\\"0\\\" or lMethod == \\\"no\\\" or lMethod == \\\"false\\\" \\\
       or lMethod == \\\"off\\\" then \\\
        -- WARNING: ONLY RETURNS TRUE IF FALSE AND lastval not zero!\\\
        return currVal == 0 and currVal ~= lastVal  \\\
    end\\\
    \\\
    if lMethod == \\\"1\\\" or lMethod == \\\"yes\\\" or lMethod == \\\"true\\\" \\\
       or lMethod == \\\"on\\\" then \\\
        -- WARNING: only returns true if lastval was false!!!!\\\
        return (currVal ~= 0 and lastVal == 0)  \\\
    end\\\
    \\\
    if lMethod == \\\"inc\\\" or lMethod == \\\"+1\\\" then \\\
        return currVal == lastVal+1\\\
    end\\\
    \\\
    if lMethod == \\\"dec\\\" or lMethod == \\\"-1\\\" then \\\
        return currVal == lastVal-1\\\
    end \\\
    \\\
    -- number constraints\\\
    -- or flag constraints \\\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \\\
    local op = string.sub(theMethod, 1, 1) \\\
    local remainder = string.sub(theMethod, 2)\\\
    remainder = dcsCommon.trim(remainder) -- remove all leading and trailing spaces\\\
    local rNum = tonumber(remainder)\\\
    if not rNum then \\\
        -- we use remainder as name for flag \\\
        -- PROCESS ESCAPE SEQUENCES\\\
        local esc = string.sub(remainder, 1, 1)\\\
        local last = string.sub(remainder, -1)\\\
        if esc == \\\"@\\\" then \\\
            remainder = string.sub(remainder, 2)\\\
            remainder = dcsCommon.trim(remainder)\\\
        end\\\
        \\\
        if esc == \\\"(\\\" and last == \\\")\\\" and string.len(remainder) > 2 then \\\
            -- note: iisues with startswith(\\\"(\\\") ???\\\
            remainder = string.sub(remainder, 2, -2)\\\
            remainder = dcsCommon.trim(remainder)        \\\
        end\\\
        if esc == \\\"\\\\\\\"\\\" and last == \\\"\\\\\\\"\\\" and string.len(remainder) > 2 then \\\
            remainder = string.sub(remainder, 2, -2)\\\
            remainder = dcsCommon.trim(remainder)        \\\
        end\\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++zne: accessing flag <\\\" .. remainder .. \\\">\\\", 30)\\\
        end \\\
        rNum = cfxZones.getFlagValue(remainder, theZone)\\\
    end \\\
    if rNum then \\\
        -- we have a comparison = \\\">\\\", \\\"=\\\", \\\"<\\\" followed by a number \\\
        -- THEY TRIGGER EACH TIME lastVal <> currVal AND condition IS MET  \\\
        if op == \\\"=\\\" then \\\
            return currVal == rNum and lastVal ~= currVal\\\
        end\\\
        \\\
        if op == \\\"#\\\" or op == \\\"~\\\" then \\\
            return currVal ~= rNum and lastVal ~= currVal \\\
        end \\\
        \\\
        if op == \\\"<\\\" then \\\
            return currVal < rNum and lastVal ~= currVal\\\
        end\\\
        \\\
        if op == \\\">\\\" then \\\
            return currVal > rNum and lastVal ~= currVal\\\
        end\\\
    end\\\
    \\\
    -- if we get here, we have an error \\\
    local zoneName = \\\"<NIL>\\\"\\\
    if theZone then zoneName = theZone.name end \\\
    trigger.action.outText(\\\"+++Zne: illegal method constraints |\\\" .. theMethod .. \\\"| for zone \\\" .. zoneName, 30 )\\\
    return false \\\
end\\\
\\\
function cfxZones.testZoneFlag(theZone, theFlagName, theMethod, latchName)\\\
    -- returns true if method constraints are met for flag theFlagName\\\
    -- as defined by theMethod \\\
    if not theMethod then \\\
        theMethod = \\\"change\\\"\\\
    end \\\
    \\\
    -- will read and update theZone[latchName] as appropriate \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone for testZoneFlag\\\", 30)\\\
        return\\\
    end \\\
    if not theFlagName then \\\
        -- this is common, no error, only on verbose \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"+++Zne: no flagName for zone \\\" .. theZone.name .. \\\" for testZoneFlag\\\", 30)\\\
        end \\\
        return\\\
    end\\\
    if not latchName then \\\
        trigger.action.outText(\\\"+++Zne: no latchName for zone \\\" .. theZone.name .. \\\" for testZoneFlag\\\", 30)\\\
        return    \\\
    end\\\
    -- get current value \\\
    local currVal = cfxZones.getFlagValue(theFlagName, theZone)\\\
    \\\
    -- get last value from latch\\\
    local lastVal = theZone[latchName]\\\
    if not lastVal then \\\
        trigger.action.outText(\\\"+++Zne: latch <\\\" .. latchName .. \\\"> not valid for zone \\\" .. theZone.name, 30)\\\
        return \\\
    end\\\
    \\\
    -- now, test by method \\\
    -- we should only test if currVal <> lastVal \\\
    if currVal == lastVal then\\\
        return false \\\
    end \\\
    \\\
    --trigger.action.outText(\\\"+++Zne: about to test: c = \\\" .. currVal .. \\\", l = \\\" .. lastVal, 30)\\\
    local testResult = cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\\\
\\\
    -- update latch by method\\\
    theZone[latchName] = currVal \\\
\\\
    -- return result\\\
    return testResult\\\
end\\\
\\\
\\\
\\\
function cfxZones.flagArrayFromString(inString)\\\
-- original code from RND flag\\\
    if string.len(inString) < 1 then \\\
        trigger.action.outText(\\\"+++zne: empty flags\\\", 30)\\\
        return {} \\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: processing <\\\" .. inString .. \\\">\\\", 30)\\\
    end \\\
    \\\
    local flags = {}\\\
    local rawElements = dcsCommon.splitString(inString, \\\",\\\")\\\
    -- go over all elements \\\
    for idx, anElement in pairs(rawElements) do \\\
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \\\"-\\\") then \\\
            -- interpret this as a range\\\
            local theRange = dcsCommon.splitString(anElement, \\\"-\\\")\\\
            local lowerBound = theRange[1]\\\
            lowerBound = tonumber(lowerBound)\\\
            local upperBound = theRange[2]\\\
            upperBound = tonumber(upperBound)\\\
            if lowerBound and upperBound then\\\
                -- swap if wrong order\\\
                if lowerBound > upperBound then \\\
                    local temp = upperBound\\\
                    upperBound = lowerBound\\\
                    lowerBound = temp \\\
                end\\\
                -- now add add numbers to flags\\\
                for f=lowerBound, upperBound do \\\
                    table.insert(flags, tostring(f))\\\
                end\\\
            else\\\
                -- bounds illegal\\\
                trigger.action.outText(\\\"+++zne: ignored range <\\\" .. anElement .. \\\"> (range)\\\", 30)\\\
            end\\\
        else\\\
            -- single number\\\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\\\
            if f then \\\
                table.insert(flags, f)\\\
\\\
            else \\\
                trigger.action.outText(\\\"+++zne: ignored element <\\\" .. anElement .. \\\"> (single)\\\", 30)\\\
            end\\\
        end\\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: <\\\" .. #flags .. \\\"> flags total\\\", 30)\\\
    end \\\
    return flags\\\
end\\\
\\\
--\\\
-- PROPERTY PROCESSING \\\
--\\\
\\\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \\\
    if not caseInsensitive then caseInsensitive = false end \\\
    if not theZone then return {} end \\\
    \\\
    local dcsProps = theZone.properties -- zone properties in dcs format \\\
    local props = {}\\\
    -- dcs has all properties as array with values .key and .value \\\
    -- so convert them into a dictionary \\\
    for i=1, #dcsProps do \\\
        local theProp = dcsProps[i]\\\
        local theKey = \\\"dummy\\\"\\\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \\\
        if caseInsensitive then theKey = theKey:upper() end \\\
        props[theKey] = theProp.value\\\
    end\\\
    return props \\\
end\\\
\\\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\\\
-- trim\\\
    theKey = dcsCommon.trim(theKey) \\\
--    make lower case conversion if not case sensitive\\\
    if not cfxZones.caseSensitiveProperties then \\\
        theKey = string.lower(theKey)\\\
    end\\\
\\\
-- iterate all keys and compare to what we are looking for     \\\
    for i=1, #theProperties do\\\
        local theP = theProperties[i]\\\
         \\\
        local existingKey = dcsCommon.trim(theP.key)  \\\
        if not cfxZones.caseSensitiveProperties then \\\
            existingKey = string.lower(existingKey)\\\
        end\\\
        if existingKey == theKey then \\\
            return theP.value\\\
        end\\\
    end\\\
    return nil \\\
end\\\
\\\
function cfxZones.getZoneProperty(cZone, theKey)\\\
    if not cZone then \\\
        trigger.action.outText(\\\"+++zone: no zone in getZoneProperty\\\", 30)\\\
        return nil\\\
    end \\\
    if not theKey then \\\
        trigger.action.outText(\\\"+++zone: no property key in getZoneProperty for zone \\\" .. cZone.name, 30)\\\
--        breakme.here = 1\\\
        return \\\
    end    \\\
\\\
    local props = cZone.properties\\\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\\\
    return theVal\\\
end\\\
\\\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    \\\
    if not default then default = \\\"\\\" end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end\\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"\\\" then p = default end \\\
        return p\\\
    end\\\
    return default -- warning. what if it was a number first?\\\
end\\\
\\\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    local theNumbers = dcsCommon.splitString(p, \\\" \\\")\\\
\\\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\\\
    \\\
end\\\
\\\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \\\
    if not maxVal then return minVal end \\\
    if not minVal then return maxVal end \\\
    local delay = maxVal\\\
    if minVal > 0 and minVal < delay then \\\
        -- we want a randomized from time from minTime .. delay\\\
        local varPart = delay - minVal + 1\\\
        varPart = dcsCommon.smallRandom(varPart) - 1\\\
        delay = minVal + varPart\\\
    end\\\
    return delay \\\
end\\\
\\\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
    -- reads property as string, and interprets as range 'a-b'. \\\
    -- if not a range but single number, returns both for upper and lower \\\
    --trigger.action.outText(\\\"***Zne: enter with <\\\" .. theZone.name .. \\\">: range for property <\\\" .. theProperty .. \\\">!\\\", 30)\\\
    if not default then default = 0 end \\\
    local lowerBound = default\\\
    local upperBound = default \\\
    \\\
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    if dcsCommon.containsString(rangeString, \\\"-\\\") then \\\
        local theRange = dcsCommon.splitString(rangeString, \\\"-\\\")\\\
        lowerBound = theRange[1]\\\
        lowerBound = tonumber(lowerBound)\\\
        upperBound = theRange[2]\\\
        upperBound = tonumber(upperBound)\\\
        if lowerBound and upperBound then\\\
            -- swap if wrong order\\\
            if lowerBound > upperBound then \\\
                local temp = upperBound\\\
                upperBound = lowerBound\\\
                lowerBound = temp \\\
            end\\\
--            if rndFlags.verbose then \\\
--            trigger.action.outText(\\\"+++Zne: detected range <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
--            end\\\
        else\\\
            -- bounds illegal\\\
            trigger.action.outText(\\\"+++Zne: illegal range  <\\\" .. rangeString .. \\\">, using \\\" .. default .. \\\"-\\\" .. default, 30)\\\
            lowerBound = default\\\
            upperBound = default \\\
        end\\\
    else \\\
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \\\
        lowerBound = upperBound\\\
    end\\\
--    trigger.action.outText(\\\"+++Zne: returning <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
    return lowerBound, upperBound\\\
end\\\
\\\
function cfxZones.hasProperty(theZone, theProperty) \\\
    local foundIt = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not foundIt then \\\
        if string.sub(theProperty, -1) == \\\"?\\\" then \\\
            local lessOp = theProperty:sub(1,-2)\\\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \\\
                trigger.action.outText(\\\"*** NOTE: \\\" .. theZone.name .. \\\"'s property <\\\" .. lessOp .. \\\"> may be missing a Query ('?') symbol\\\", 30)\\\
            end\\\
            return false \\\
        end\\\
        \\\
        if string.sub(theProperty, -1) == \\\"!\\\" then \\\
            local lessOp = theProperty:sub(1,-2)\\\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \\\
                trigger.action.outText(\\\"*** NOTE: \\\" .. theZone.name .. \\\"'s property <\\\" .. lessOp .. \\\"> may be missing a Bang! ('!') symbol\\\", 30)\\\
            end\\\
            return false \\\
        end\\\
        \\\
        if string.sub(theProperty, -1) == \\\":\\\" then \\\
            local lessOp = theProperty:sub(1,-2)\\\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \\\
                trigger.action.outText(\\\"*** NOTE: \\\" .. theZone.name .. \\\"'s property <\\\" .. lessOp .. \\\"> may be missing a colon (':') at end\\\", 30)\\\
            end\\\
            return false \\\
        end\\\
        \\\
        return false \\\
    end\\\
    return true \\\
--    return foundIt ~= nil \\\
end\\\
\\\
\\\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\\\
    if not defaultVal then defaultVal = false end \\\
    if type(defaultVal) ~= \\\"boolean\\\" then \\\
        defaultVal = false \\\
    end\\\
\\\
    if not theZone then \\\
        trigger.action.outText(\\\"WARNING: NIL Zone in getBoolFromZoneProperty\\\", 30) -- intentional bug\\\
        return defaultVal\\\
    end\\\
\\\
\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return defaultVal end\\\
\\\
    -- make sure we compare so default always works when \\\
    -- answer isn't exactly the opposite\\\
    p = p:lower() \\\
    if defaultVal == false then \\\
        -- only go true if exact match to yes or true \\\
        theBool = false \\\
        theBool = (p == 'true') or (p == 'yes') or p == \\\"1\\\"\\\
        return theBool\\\
    end\\\
    \\\
    local theBool = true \\\
    -- only go false if exactly no or false or \\\"0\\\"\\\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \\\"0\\\") \\\
    return theBool\\\
end\\\
\\\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end  \\\
    if type(p) == \\\"number\\\" then -- can't currently really happen\\\
        if p == 1 then return 1 end \\\
        if p == 2 then return 2 end \\\
        return 0\\\
    end\\\
    \\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"1\\\" then return 1 end \\\
        if p == \\\"2\\\" then return 2 end \\\
        if p == \\\"0\\\" then return 0 end \\\
        \\\
        p = p:lower()\\\
        \\\
        if p == \\\"red\\\" then return 1 end \\\
        if p == \\\"blue\\\" then return 2 end \\\
        if p == \\\"neutral\\\" then return 0 end\\\
        if p == \\\"all\\\" then return 0 end \\\
        return default \\\
    end\\\
    \\\
    return default \\\
end\\\
\\\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\\\
--TODO: trim string \\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    p = tonumber(p)\\\
    if not p then return default else return p end\\\
end\\\
\\\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\\\
    if not minDims then minDims = 0 end \\\
    if not defaultVal then defaultVal = 0 end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    local sVec = dcsCommon.splitString(s, \\\",\\\")\\\
    local nVec = {}\\\
    for idx, numString in pairs (sVec) do \\\
        local n = tonumber(numString)\\\
        if not n then n = defaultVal end\\\
        table.insert(nVec, n)\\\
    end\\\
    -- make sure vector contains at least minDims values \\\
    while #nVec < minDims do \\\
        table.insert(nVec, defaultVal)\\\
    end\\\
    \\\
    return nVec \\\
end\\\
\\\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\\\
    if not default then default = \\\"red\\\" end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    s = s:lower()\\\
    s = dcsCommon.trim(s)\\\
    -- check numbers \\\
    if (s == \\\"0\\\") then return \\\"green\\\" end\\\
    if (s == \\\"1\\\") then return \\\"red\\\" end\\\
    if (s == \\\"2\\\") then return \\\"white\\\" end\\\
    if (s == \\\"3\\\") then return \\\"orange\\\" end\\\
    if (s == \\\"4\\\") then return \\\"blue\\\" end\\\
    \\\
    if s == \\\"green\\\" or\\\
       s == \\\"red\\\" or\\\
       s == \\\"white\\\" or\\\
       s == \\\"orange\\\" or\\\
       s == \\\"blue\\\" then return s end\\\
\\\
    return default \\\
end\\\
\\\
--\\\
-- Moving Zones. They contain a link to their unit\\\
-- they are always located at an offset (x,z) or delta, phi \\\
-- to their master unit. delta phi allows adjustment for heading\\\
-- The cool thing about moving zones in cfx is that they do not\\\
-- require special handling, they are always updated \\\
-- and work with 'pointinzone' etc automatically\\\
\\\
-- Always works on cfx Zones, NEVER on DCS zones.\\\
--\\\
-- requires that readFromDCS has been done\\\
--\\\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \\\
    if aZone.linkedUnit then \\\
        local theUnit = aZone.linkedUnit\\\
        -- has a link. is link existing?\\\
        if theUnit:isExist() then \\\
            -- updates zone position \\\
            cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
        end\\\
    end\\\
    local thePos = {}\\\
    thePos.x = aZone.point.x\\\
    thePos.y = 0 -- aZone.y \\\
    thePos.z = aZone.point.z\\\
    -- update the zone as well -- that's stupid!\\\
    --[[-- aZone.point = thePos \\\
    local retPoint = {} -- create new copy to pass back \\\
    retPoint.x = thePos.x\\\
    retPoint.y = 0 \\\
    retPoint.z = thePos.z\\\
    --]]--\\\
    return thePos \\\
end\\\
\\\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\\\
    theZone.linkedUnit = theUnit\\\
    if not dx then dx = 0 end\\\
    if not dy then dy = 0 end \\\
    theZone.dx = dx\\\
    theZone.dy = dy \\\
end\\\
\\\
function cfxZones.updateMovingZones()\\\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\\\
    -- simply scan all cfx zones for the linkedUnit property and if there\\\
    -- update the zone's points\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        if aZone.linkedUnit then \\\
            local theUnit = aZone.linkedUnit\\\
            -- has a link. is link existing?\\\
            if theUnit:isExist() then \\\
                cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
                --trigger.action.outText(\\\"cf/x zones update \\\" .. aZone.name, 30)\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
function cfxZones.startMovingZones()\\\
    -- read all zoness, and look for a property called 'linkedUnit'\\\
    -- which will make them a linked zone if there is a unit that exists\\\
    -- also scans for 'verbose' flag.\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        local lU = cfxZones.getZoneProperty(aZone, \\\"linkedUnit\\\")\\\
        if lU then \\\
            -- this zone is linked to a unit\\\
            theUnit = Unit.getByName(lU)\\\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \\\"useOffset\\\", false)\\\
            if useOffset then aZone.useOffset = true end\\\
            if theUnit then\\\
                local dx = 0\\\
                local dz = 0\\\
                if useOffset then \\\
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \\\
                    dx = delta.x \\\
                    dz = delta.z\\\
                end\\\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\\\
                --trigger.action.outText(\\\"cf/x zones: linked \\\" .. aZone.name .. \\\" to \\\" .. theUnit:getName(), 30)\\\
                if useOffset then \\\
                    --trigger.action.outText(\\\"and dx = \\\" .. dx .. \\\" dz = \\\" .. dz, 30)\\\
                end\\\
            end\\\
        end\\\
        -- support for local verbose flag \\\
        aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, \\\"verbose\\\", false)\\\
    end\\\
end\\\
\\\
--\\\
-- init\\\
--\\\
\\\
function cfxZones.init()\\\
    -- read all zones into my own db\\\
    cfxZones.readFromDCS(true) -- true: erase old\\\
    \\\
    -- now, pre-read zone owner for all zones\\\
    -- note, all zones with this property are by definition owned zones.\\\
    -- and hence will be read anyway. this will merely ensure that the \\\
    -- ownership is established right away\\\
    -- unless owned zones module is missing, in which case \\\
    -- ownership is still established \\\
    local pZones = cfxZones.zonesWithProperty(\\\"owner\\\")\\\
    for n, aZone in pairs(pZones) do\\\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \\\"owner\\\", 0)\\\
    end\\\
        \\\
    \\\
    -- now initialize moving zones\\\
    cfxZones.startMovingZones()\\\
    cfxZones.updateMovingZones() -- will auto-repeat\\\
    \\\
    trigger.action.outText(\\\"cf/x Zones v\\\".. cfxZones.version .. \\\": loaded\\\", 10)\\\
end\\\
\\\
-- get everything rolling\\\
cfxZones.init()\\\
\");a_do_script(\"cfxSmokeZone = {}\\\
cfxSmokeZone.version = \\\"1.1.0\\\" \\\
cfxSmokeZone.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
--[[--\\\
    Version History\\\
 1.0.0 - initial version\\\
 1.0.1 - added removeSmokeZone\\\
 1.0.2 - added altitude\\\
 1.0.3 - added paused attribute \\\
       - added f? attribute --> onFlag \\\
       - broke out startSmoke \\\
 1.0.4 - startSmoke? synonym\\\
       - alphanum DML flag upgrade \\\
       - random color support \\\
 1.1.0 - Watchflag upgrade \\\
 \\\
    SMOKE ZONES *** EXTENDS ZONES ***\\\
    keeps 'eternal' smoke up for any zone that has the \\\
    'smoke' attribute \\\
    \\\
    USAGE\\\
    add a 'smoke' attribute to the zone. the value of the attribute \\\
    defines the color. Valid values are: red, green, blue, white, orange, 0 (results in green smoke), 1 (red smoke), 2 (white), 3 (orange), 4 (blue)\\\
    defaults to \\\"green\\\"\\\
    altiude is meters above ground height, defaults to 5m\\\
--]]--\\\
cfxSmokeZone.smokeZones = {}\\\
cfxSmokeZone.updateDelay = 5 * 60 -- every 5 minutes \\\
\\\
function cfxSmokeZone.processSmokeZone(aZone)\\\
    local rawVal = cfxZones.getStringFromZoneProperty(aZone, \\\"smoke\\\", \\\"green\\\")\\\
    rawVal = rawVal:lower()\\\
    local theColor = 0 \\\
    if rawVal == \\\"red\\\" or rawVal == \\\"1\\\" then theColor = 1 end \\\
    if rawVal == \\\"white\\\" or rawVal == \\\"2\\\" then theColor = 2 end \\\
    if rawVal == \\\"orange\\\" or rawVal == \\\"3\\\" then theColor = 3 end \\\
    if rawVal == \\\"blue\\\" or rawVal == \\\"4\\\" then theColor = 4 end \\\
    if rawVal == \\\"?\\\" or rawVal == \\\"random\\\" or rawVal == \\\"rnd\\\" then \\\
        theColor = dcsCommon.smallRandom(5) - 1\\\
    end\\\
\\\
    aZone.smokeColor = theColor\\\
    aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, \\\"altitude\\\", 1)\\\
    \\\
    -- paused \\\
    aZone.paused = cfxZones.getBoolFromZoneProperty(aZone, \\\"paused\\\", false)\\\
    \\\
    -- f? query flags \\\
    if cfxZones.hasProperty(aZone, \\\"f?\\\") then \\\
        aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, \\\"f?\\\", \\\"*<none>\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(aZone, \\\"startSmoke?\\\") then \\\
        aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, \\\"startSmoke?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if aZone.onFlag then \\\
        aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- save last value\\\
    end\\\
    \\\
    -- watchflags:\\\
    -- triggerMethod\\\
    aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, \\\"triggerMethod\\\", \\\"change\\\")\\\
\\\
    if cfxZones.hasProperty(aZone, \\\"smokeTriggerMethod\\\") then \\\
        aZone.delayTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, \\\"smokeTriggerMethod\\\", \\\"change\\\")\\\
    end\\\
    \\\
end\\\
\\\
function cfxSmokeZone.addSmokeZone(aZone)\\\
    table.insert(cfxSmokeZone.smokeZones, aZone)\\\
end\\\
\\\
function cfxSmokeZone.addSmokeZoneWithColor(aZone, aColor, anAltitude, paused, onFlag)\\\
    if not aColor then aColor = 0 end -- default green \\\
    if not anAltitude then anAltitude = 5 end \\\
    if not aZone then return end \\\
    if not paused then paused = false end \\\
    \\\
    aZone.smokeColor = aColor\\\
    aZone.smokeAlt = anAltitude\\\
    aZone.paused = paused \\\
    \\\
    if onFlag then \\\
        aZone.onFlag = onFlag \\\
        aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- trigger.misc.getUserFlag(onFlag)\\\
    end\\\
    \\\
    cfxSmokeZone.addSmokeZone(aZone) -- add to update loop\\\
    if not paused then \\\
        cfxSmokeZone.startSmoke(aZone)\\\
    end\\\
    \\\
end\\\
\\\
function cfxSmokeZone.startSmoke(aZone)\\\
    if type(aZone) == \\\"string\\\" then \\\
        aZone = cfxZones.getZoneByName(aZone) \\\
    end\\\
    if not aZone then return end \\\
    if not aZone.smokeColor then return end \\\
    aZone.paused = false \\\
    cfxZones.markZoneWithSmoke(aZone, 0, 0, aZone.smokeColor, aZone.smokeAlt)\\\
end\\\
\\\
function cfxSmokeZone.removeSmokeZone(aZone)\\\
    if type(aZone) == \\\"string\\\" then \\\
        aZone = cfxZones.getZoneByName(aZone) \\\
    end\\\
    if not aZone then return end \\\
    \\\
    -- now create new table \\\
    local filtered = {}\\\
    for idx, theZone in pairs(cfxSmokeZone.smokeZones) do \\\
        if theZone ~= aZone then \\\
            table.insert(filtered, theZone)\\\
        end \\\
    end\\\
    cfxSmokeZone.smokeZones = filtered \\\
end\\\
\\\
\\\
function cfxSmokeZone.update()\\\
    -- call me in a couple of minutes to 'rekindle'\\\
    timer.scheduleFunction(cfxSmokeZone.update, {}, timer.getTime() + cfxSmokeZone.updateDelay)\\\
    \\\
    -- re-smoke all zones after delay\\\
    for idx, aZone in pairs(cfxSmokeZone.smokeZones) do \\\
        if not aZone.paused and aZone.smokeColor then \\\
            cfxSmokeZone.startSmoke(aZone)\\\
        end\\\
    end\\\
end\\\
\\\
\\\
function cfxSmokeZone.checkFlags()\\\
    timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1) -- every second \\\
    for idx, aZone in pairs(cfxSmokeZone.smokeZones) do \\\
        \\\
        if aZone.paused and aZone.onFlagVal then \\\
            -- see if this changed \\\
            if cfxZones.testZoneFlag(aZone, aZone.onFlag, aZone.smokeTriggerMethod, \\\"onFlagVal\\\") then\\\
                cfxSmokeZone.startSmoke(aZone)\\\
            end \\\
--[[--            \\\
            -- old code \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- trigger.misc.getUserFlag(aZone.onFlag)\\\
            if currTriggerVal ~= aZone.onFlagVal then\\\
                -- yupp, trigger start \\\
                cfxSmokeZone.startSmoke(aZone)\\\
                aZone.onFlagVal = currTriggerVal\\\
            end    \\\
--]]--            \\\
        end\\\
    end\\\
end\\\
\\\
function cfxSmokeZone.start()\\\
    if not dcsCommon.libCheck(\\\"cfx Smoke Zones\\\", \\\
        cfxSmokeZone.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- collect all zones with 'smoke' attribute \\\
    -- collect all spawn zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"smoke\\\")\\\
    \\\
    -- now create a smoker for all, add them to updater,\\\
    -- smoke all that aren't paused \\\
    for k, aZone in pairs(attrZones) do \\\
        cfxSmokeZone.processSmokeZone(aZone) -- process attribute and add to zone\\\
        cfxSmokeZone.addSmokeZone(aZone) -- remember it so we can smoke it\\\
    end\\\
\\\
    -- start update loop\\\
    cfxSmokeZone.update() -- also starts all unpaused \\\
    \\\
    -- start check loop in one second \\\
    timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1)\\\
    \\\
    -- say hi\\\
    trigger.action.outText(\\\"cfx Smoke Zones v\\\" .. cfxSmokeZone.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go \\\
if not cfxSmokeZone.start() then \\\
    trigger.action.outText(\\\"cf/x Smoke Zones aborted: missing libraries\\\", 30)\\\
    cfxSmokeZone = nil \\\
end\");",
            [2] = "a_explosion_marker(333, 1, \"1\"); mission.trig.func[2]=nil;",
        }, -- end of ["actions"]
        ["events"] = 
        {
        }, -- end of ["events"]
        ["custom"] = 
        {
        }, -- end of ["custom"]
        ["func"] = 
        {
            [2] = "if mission.trig.conditions[2]() then mission.trig.actions[2]() end",
        }, -- end of ["func"]
        ["flag"] = 
        {
            [1] = true,
            [2] = true,
        }, -- end of ["flag"]
        ["conditions"] = 
        {
            [1] = "return(true)",
            [2] = "return(c_time_after(1) )",
        }, -- end of ["conditions"]
        ["customStartup"] = 
        {
        }, -- end of ["customStartup"]
        ["funcStartup"] = 
        {
            [1] = "if mission.trig.conditions[1]() then mission.trig.actions[1]() end",
        }, -- end of ["funcStartup"]
    }, -- end of ["trig"]
    ["requiredModules"] = 
    {
    }, -- end of ["requiredModules"]
    ["date"] = 
    {
        ["Day"] = 21,
        ["Year"] = 2016,
        ["Month"] = 6,
    }, -- end of ["date"]
    ["result"] = 
    {
        ["offline"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["offline"]
        ["total"] = 0,
        ["blue"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["blue"]
        ["red"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["red"]
    }, -- end of ["result"]
    ["groundControl"] = 
    {
        ["passwords"] = 
        {
            ["artillery_commander"] = 
            {
            }, -- end of ["artillery_commander"]
            ["instructor"] = 
            {
            }, -- end of ["instructor"]
            ["observer"] = 
            {
            }, -- end of ["observer"]
            ["forward_observer"] = 
            {
            }, -- end of ["forward_observer"]
        }, -- end of ["passwords"]
        ["roles"] = 
        {
            ["artillery_commander"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["artillery_commander"]
            ["instructor"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["instructor"]
            ["observer"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["observer"]
            ["forward_observer"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["forward_observer"]
        }, -- end of ["roles"]
        ["isPilotControlVehicles"] = false,
    }, -- end of ["groundControl"]
    ["maxDictId"] = 5,
    ["pictureFileNameN"] = 
    {
    }, -- end of ["pictureFileNameN"]
    ["goals"] = 
    {
    }, -- end of ["goals"]
    ["descriptionNeutralsTask"] = "DictKey_descriptionNeutralsTask_4",
    ["weather"] = 
    {
        ["atmosphere_type"] = 0,
        ["groundTurbulence"] = 0,
        ["enable_fog"] = false,
        ["wind"] = 
        {
            ["at8000"] = 
            {
                ["speed"] = 0,
                ["dir"] = 0,
            }, -- end of ["at8000"]
            ["atGround"] = 
            {
                ["speed"] = 0,
                ["dir"] = 0,
            }, -- end of ["atGround"]
            ["at2000"] = 
            {
                ["speed"] = 0,
                ["dir"] = 0,
            }, -- end of ["at2000"]
        }, -- end of ["wind"]
        ["visibility"] = 
        {
            ["distance"] = 80000,
        }, -- end of ["visibility"]
        ["season"] = 
        {
            ["temperature"] = 20,
        }, -- end of ["season"]
        ["type_weather"] = 0,
        ["qnh"] = 760,
        ["cyclones"] = 
        {
        }, -- end of ["cyclones"]
        ["name"] = "Winter, clean sky",
        ["dust_density"] = 0,
        ["fog"] = 
        {
            ["thickness"] = 0,
            ["visibility"] = 0,
        }, -- end of ["fog"]
        ["modifiedTime"] = false,
        ["enable_dust"] = false,
        ["clouds"] = 
        {
            ["thickness"] = 200,
            ["density"] = 0,
            ["preset"] = "Preset2",
            ["base"] = 2500,
            ["iprecptns"] = 0,
        }, -- end of ["clouds"]
    }, -- end of ["weather"]
    ["theatre"] = "Caucasus",
    ["triggers"] = 
    {
        ["zones"] = 
        {
            [1] = 
            {
                ["radius"] = 10,
                ["zoneId"] = 165,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "smoke",
                        ["value"] = "red",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = false,
                ["y"] = 646392.34120686,
                ["x"] = -281756.95968715,
                ["name"] = "Smoke em!",
                ["type"] = 0,
            }, -- end of [1]
            [2] = 
            {
                ["radius"] = 10,
                ["zoneId"] = 330,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "smoke",
                        ["value"] = "orange",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = false,
                ["y"] = 646592.08226299,
                ["x"] = -281772.33798569,
                ["name"] = "Smoke em!-1",
                ["type"] = 0,
            }, -- end of [2]
            [3] = 
            {
                ["radius"] = 10,
                ["zoneId"] = 331,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "smoke",
                        ["value"] = "green",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = false,
                ["y"] = 646791.29320437,
                ["x"] = -281788.37884419,
                ["name"] = "Smoke em!-2",
                ["type"] = 0,
            }, -- end of [3]
            [4] = 
            {
                ["radius"] = 10,
                ["zoneId"] = 332,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "smoke",
                        ["value"] = "blue",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = false,
                ["y"] = 646990.63409439,
                ["x"] = -281804.78385105,
                ["name"] = "Smoke em!-3",
                ["type"] = 0,
            }, -- end of [4]
            [5] = 
            {
                ["radius"] = 10,
                ["zoneId"] = 333,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                }, -- end of ["properties"]
                ["hidden"] = false,
                ["y"] = 646502.99189409,
                ["x"] = -281666.16615145,
                ["name"] = "ME Smoke",
                ["type"] = 0,
            }, -- end of [5]
        }, -- end of ["zones"]
    }, -- end of ["triggers"]
    ["map"] = 
    {
        ["centerY"] = 646811.40428241,
        ["zoom"] = 2974.9607010357,
        ["centerX"] = -281695.63790325,
    }, -- end of ["map"]
    ["coalitions"] = 
    {
        ["neutrals"] = 
        {
            [1] = 70,
            [2] = 83,
            [3] = 23,
            [4] = 65,
            [5] = 86,
            [6] = 64,
            [7] = 25,
            [8] = 63,
            [9] = 76,
            [10] = 84,
            [11] = 29,
            [12] = 62,
            [13] = 30,
            [14] = 78,
            [15] = 87,
            [16] = 31,
            [17] = 61,
            [18] = 32,
            [19] = 33,
            [20] = 60,
            [21] = 17,
            [22] = 35,
            [23] = 69,
            [24] = 36,
            [25] = 59,
            [26] = 71,
            [27] = 79,
            [28] = 58,
            [29] = 57,
            [30] = 56,
            [31] = 55,
            [32] = 88,
            [33] = 73,
            [34] = 39,
            [35] = 89,
            [36] = 54,
            [37] = 77,
            [38] = 72,
            [39] = 41,
            [40] = 42,
            [41] = 44,
            [42] = 85,
            [43] = 75,
            [44] = 53,
            [45] = 22,
            [46] = 52,
            [47] = 66,
            [48] = 51,
            [49] = 74,
            [50] = 82,
            [51] = 7,
            [52] = 68,
            [53] = 50,
            [54] = 49,
            [55] = 48,
            [56] = 67,
        }, -- end of ["neutrals"]
        ["blue"] = 
        {
            [1] = 21,
            [2] = 11,
            [3] = 8,
            [4] = 80,
            [5] = 28,
            [6] = 26,
            [7] = 13,
            [8] = 5,
            [9] = 16,
            [10] = 6,
            [11] = 15,
            [12] = 20,
            [13] = 12,
            [14] = 40,
            [15] = 45,
            [16] = 9,
            [17] = 46,
            [18] = 10,
            [19] = 3,
            [20] = 4,
            [21] = 1,
            [22] = 2,
        }, -- end of ["blue"]
        ["red"] = 
        {
            [1] = 18,
            [2] = 24,
            [3] = 27,
            [4] = 81,
            [5] = 34,
            [6] = 37,
            [7] = 38,
            [8] = 0,
            [9] = 43,
            [10] = 19,
            [11] = 47,
        }, -- end of ["red"]
    }, -- end of ["coalitions"]
    ["descriptionText"] = "DictKey_descriptionText_1",
    ["pictureFileNameR"] = 
    {
    }, -- end of ["pictureFileNameR"]
    ["descriptionBlueTask"] = "DictKey_descriptionBlueTask_3",
    ["descriptionRedTask"] = "DictKey_descriptionRedTask_2",
    ["pictureFileNameB"] = 
    {
    }, -- end of ["pictureFileNameB"]
    ["coalition"] = 
    {
        ["neutrals"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 0,
                ["x"] = 0,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "neutrals",
            ["country"] = 
            {
            }, -- end of ["country"]
        }, -- end of ["neutrals"]
        ["blue"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 617414,
                ["x"] = -291014,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "blue",
            ["country"] = 
            {
            }, -- end of ["country"]
        }, -- end of ["blue"]
        ["red"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 371700,
                ["x"] = 11557,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "red",
            ["country"] = 
            {
                [1] = 
                {
                    ["id"] = 81,
                    ["name"] = "CJTF Red",
                    ["plane"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAS",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "CAS",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Helicopters",
                                                                    [2] = "Ground Units",
                                                                    [3] = "Light armed ships",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                        [2] = 
                                                        {
                                                            ["number"] = 2,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 2,
                                                                        ["name"] = 1,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [2]
                                                        [3] = 
                                                        {
                                                            ["number"] = 3,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 1,
                                                                        ["name"] = 3,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [3]
                                                        [4] = 
                                                        {
                                                            ["number"] = 4,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["variantIndex"] = 2,
                                                                        ["name"] = 5,
                                                                        ["formationIndex"] = 2,
                                                                        ["value"] = 131074,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [4]
                                                        [5] = 
                                                        {
                                                            ["number"] = 5,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["name"] = 15,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [5]
                                                        [6] = 
                                                        {
                                                            ["number"] = 6,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["targetTypes"] = 
                                                                        {
                                                                        }, -- end of ["targetTypes"]
                                                                        ["name"] = 21,
                                                                        ["value"] = "none;",
                                                                        ["noTargetTypes"] = 
                                                                        {
                                                                            [1] = "Fighters",
                                                                            [2] = "Multirole fighters",
                                                                            [3] = "Bombers",
                                                                            [4] = "Helicopters",
                                                                            [5] = "Infantry",
                                                                            [6] = "Fortifications",
                                                                            [7] = "Tanks",
                                                                            [8] = "IFV",
                                                                            [9] = "APC",
                                                                            [10] = "Artillery",
                                                                            [11] = "Unarmed vehicles",
                                                                            [12] = "AAA",
                                                                            [13] = "SR SAM",
                                                                            [14] = "MR SAM",
                                                                            [15] = "LR SAM",
                                                                            [16] = "Aircraft Carriers",
                                                                            [17] = "Cruisers",
                                                                            [18] = "Destroyers",
                                                                            [19] = "Frigates",
                                                                            [20] = "Corvettes",
                                                                            [21] = "Light armed ships",
                                                                            [22] = "Unarmed ships",
                                                                            [23] = "Submarines",
                                                                            [24] = "Cruise missiles",
                                                                            [25] = "Antiship Missiles",
                                                                            [26] = "AA Missiles",
                                                                            [27] = "AG Missiles",
                                                                            [28] = "SA Missiles",
                                                                        }, -- end of ["noTargetTypes"]
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [6]
                                                        [7] = 
                                                        {
                                                            ["number"] = 7,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["name"] = 19,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [7]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 646159.10072834,
                                            ["x"] = -281690.34936119,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 1,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Algerian AF Desert KU-03",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["type"] = "Su-25T",
                                        ["unitId"] = 1,
                                        ["psi"] = -1.6755160819146,
                                        ["y"] = 646159.10072834,
                                        ["x"] = -281690.34936119,
                                        ["name"] = "Aerial-1-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "3790",
                                            ["flare"] = 128,
                                            ["chaff"] = 128,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.6755160819146,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Enfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "010",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 646159.10072834,
                                ["x"] = -281690.34936119,
                                ["name"] = "Aerial-1",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [1]
                        }, -- end of ["group"]
                    }, -- end of ["plane"]
                }, -- end of [1]
            }, -- end of ["country"]
        }, -- end of ["red"]
    }, -- end of ["coalition"]
    ["sortie"] = "DictKey_sortie_5",
    ["version"] = 20,
    ["trigrules"] = 
    {
        [1] = 
        {
            ["rules"] = 
            {
            }, -- end of ["rules"]
            ["comment"] = "Load DML",
            ["eventlist"] = "",
            ["actions"] = 
            {
                [1] = 
                {
                    ["text"] = "dcsCommon = {}\
dcsCommon.version = \"2.5.9\"\
--[[-- VERSION HISTORY\
 2.2.6 - compassPositionOfARelativeToB\
       - clockPositionOfARelativeToB\
 2.2.7 - isTroopCarrier \
       - distFlat\
 2.2.8 - fixed event2text \
 2.2.9 - getUnitAGL\
       - getUnitAlt\
       - getUnitSpeed \
       - getUnitHeading\
       - getUnitHeadingDegrees\
       - mag\
       - clockPositionOfARelativeToB with own heading \
 2.3.0 - unitIsInfantry\
 2.3.1 - bool2YesNo\
       - bool2Text\
 2.3.2 - getGroupAvgSpeed\
       - getGroupMaxSpeed\
 2.3.3 - getSizeOfTable\
 2.3.4 - isSceneryObject\
         coalition2county\
 2.3.5 - smallRandom\
         pickRandom uses smallRandom\
         airfield handling, parking \
         flight waypoint handling\
         landing waypoint creation\
         take-off waypoint creation\
 2.3.6 - createOverheadAirdromeRoutPintData(aerodrome)\
 2.3.7 - coalition2county - warning when creating UN \
 2.3.8 - improved headingOfBInDegrees, new getClockDirection\
 2.3.9 - getClosingVelocity\
       - dot product \
       - magSquare\
       - vMag\
 2.4.0 - libCheck\
 2.4.1 - grid/square/rect formation \
       - arrangeGroupInNColumns formation \
       - 2Columns formation deep and wide formation\
 2.4.2 - getAirbasesInRangeOfPoint\
 2.4.3 - lerp \
 2.4.4 - getClosestAirbaseTo\
       - fixed bug in containsString when strings equal\
 2.4.5 - added cargo and mass options to createStaticObjectData\
 2.4.6 - fixed randompercent \
 2.4.7 - smokeColor2Num(smokeColor)\
 2.4.8 - linkStaticDataToUnit()\
 2.4.9 - trim functions \
       - createGroundUnitData uses trim function to remove leading/trailing blanks\
         so now we can use blanks after comma to separate types \
       - dcsCommon.trimArray(\
       - createStaticObjectData uses trim for type \
       - getEnemyCoalitionFor understands strings, still returns number\
       - coalition2county also undertsands 'red' and 'blue'\
 2.5.0 - \"Line\" formation with one unit places unit at center     \
 2.5.1 - vNorm(a)  \
 2.5.1 - added SA-18 Igla manpad to unitIsInfantry()\
 2.5.2 - added copyArray method\
       - corrected heading in createStaticObjectData\
 2.5.3 - corrected rotateGroupData bug for cz \
       - removed forced error in failed pickRandom\
 2.5.4 - rotateUnitData()\
       - randomBetween()\
 2.5.5 - stringStartsWithDigit()\
       - stringStartsWithLetter()\
       - stringIsPositiveNumber()\
 2.5.6 - corrected stringEndsWith() bug with str\
 2.5.7 - point2text(p) \
 2.5.8 - string2GroupCat()\
 2.5.9 - string2ObjectCat()\
       \
--]]--\
\
    -- dcsCommon is a library of common lua functions \
    -- for easy access and simple mission programming\
    -- (c) 2021, 2022 by Chritian Franz and cf/x AG\
\
    dcsCommon.verbose = false -- set to true to see debug messages. Lots of them\
    dcsCommon.uuidStr = \"uuid-\"\
\
    -- globals\
    dcsCommon.cbID = 0 -- callback id for simple callback scheduling\
    dcsCommon.troopCarriers = {\"Mi-8MT\", \"UH-1H\", \"Mi-24P\"} -- Ka-50 and Gazelle can't carry troops\
\
    -- verify that a module is loaded. obviously not required\
    -- for dcsCommon, but all higher-order modules\
    function dcsCommon.libCheck(testingFor, requiredLibs)\
        local canRun = true \
        for idx, libName in pairs(requiredLibs) do \
            if not _G[libName] then \
                trigger.action.outText(\"*** \" .. testingFor .. \" requires \" .. libName, 30)\
                canRun = false \
            end\
        end\
        return canRun\
    end\
\
    -- returns only positive values, lo must be >0 and <= hi \
    function dcsCommon.randomBetween(loBound, hiBound)\
        if not loBound then loBound = 1 end \
        if not hiBound then hiBound = 1 end \
        if loBound == hiBound then return loBound end \
\
        local delayMin = loBound\
        local delayMax = hiBound \
        local delay = delayMax \
    \
        if delayMin ~= delayMax then \
            -- pick random in range , say 3-7 --> 5 s!\
            local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\
            delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\
            delay = delay + delayMin \
            if delay > delayMax then delay = delayMax end \
            if delay < 1 then delay = 1 end \
        \
            if dcsCommon.verbose then \
                trigger.action.outText(\"+++dcsC: delay range \" .. delayMin .. \"-\" .. delayMax .. \": selected \" .. delay, 30)\
            end\
        end\
        \
        return delay\
    end\
    \
\
    -- taken inspiration from mist, as dcs lua has issues with\
    -- random numbers smaller than 50. Given a range of x numbers 1..x, it is \
    -- repeated a number of times until it fills an array of at least \
    -- 50 items (usually some more), and only then one itemis picked from \
    -- that array with a random number that is from a greater range (0..50+)\
    function dcsCommon.smallRandom(theNum) -- adapted from mist, only support ints\
        if theNum >= 50 then return math.random(theNum) end\
        \
        -- for small randoms (<50) \
        local lowNum, highNum\
        highNum = theNum\
        lowNum = 1\
        local total = 1\
        if math.abs(highNum - lowNum + 1) < 50 then -- if total values is less than 50\
            total = math.modf(50/math.abs(highNum - lowNum + 1)) -- number of times to repeat whole range to get above 50. e.g. 11 would be 5 times 1 .. 11, giving us 55 items total \
        end\
        local choices = {}\
        for i = 1, total do -- iterate required number of times\
            for x = lowNum, highNum do -- iterate between the range\
                choices[#choices +1] = x -- add each entry to a table\
            end\
        end\
        local rtnVal; -- = math.random(#choices) -- will now do a math.random of at least 50 choices\
        for i = 1, 15 do\
            rtnVal = math.random(#choices) -- iterate 15 times for randomization\
        end\
        return choices[rtnVal] -- return indexed\
    end\
    \
\
    function dcsCommon.getSizeOfTable(theTable)\
        local count = 0\
        for _ in pairs(theTable) do count = count + 1 end\
        return count\
    end\
\
    function dcsCommon.findAndRemoveFromTable(theTable, theElement) -- assumes array \
        if not theElement then return false end \
        if not theTable then return false end \
        for i=1, #theTable do \
            if theTable[i] == theElement then \
                -- this element found. remove from table \
                table.remove(theTable, i)\
                return true \
            end\
        end\
    end\
\
    function dcsCommon.pickRandom(theTable)\
        if not theTable then \
            trigger.action.outText(\"*** warning: nil table in pick random\", 30)\
        end\
        \
        if #theTable < 1 then \
            trigger.action.outText(\"*** warning: zero choice in pick random\", 30)\
            --local k = i.ll \
            return nil\
        end\
        if #theTable == 1 then return theTable[1] end\
        r = dcsCommon.smallRandom(#theTable) --r = math.random(#theTable)\
        return theTable[r]\
    end\
\
    -- enumerateTable - make an array out of a table for indexed access\
    function dcsCommon.enumerateTable(theTable)\
        if not theTable then theTable = {} end\
        local array = {}\
        for key, value in pairs(theTable) do \
            table.insert(array, value)\
        end\
        return array\
    end\
\
-- \
-- A I R F I E L D S  A N D  F A R P S  \
--\
\
    -- airfield management \
    function dcsCommon.getAirbaseCat(aBase)\
        if not aBase then return nil end \
        \
        local airDesc = aBase:getDesc()\
        if not airDesc then return nil end \
        \
        local airCat = airDesc.category\
        return airCat \
    end\
\
    -- get free parking slot. optional parkingType can be used to \
    -- filter for a scpecific type, e.g. 104 = open field\
    function dcsCommon.getFirstFreeParkingSlot(aerodrome, parkingType) \
        if not aerodrome then return nil end \
        local freeSlots = aerodrome:getParking(true)\
        \
        for idx, theSlot in pairs(freeSlots) do \
            if not parkingType then \
                -- simply return the first we come across\
                return theSlot\
            end        \
            \
            if theSlot.Term_Type == parkingType then \
                return theSlot \
            end\
        end\
        \
        return nil \
    end\
\
    -- getAirbasesInRangeOfPoint: get airbases that are in range of point \
    function dcsCommon.getAirbasesInRangeOfPoint(center, range, filterCat, filterCoalition)\
        if not center then return {} end \
        if not range then range = 500 end -- 500m default \
        local basesInRange = {}\
        \
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition)\
        for idx, aBase in pairs(allAB) do             \
            local delta = dcsCommon.dist(center, aBase:getPoint())\
            if delta <= range then \
                table.insert(basesInRange, aBase)\
            end\
        end\
        return basesInRange\
    end\
\
    -- getAirbasesInRangeOfAirbase returns all airbases that \
    -- are in range of the given airbase \
    function dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeCenter, range, filterCat, filterCoalition)\
        if not airbase then return {} end\
        if not range then range = 150000 end \
        local center = airbase:getPoint() \
        local centerName = airbase:getName() \
        \
        local ABinRange = {}\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition)\
        \
        for idx, aBase in pairs(allAB) do \
            if aBase:getName() ~= centerName then \
                local delta = dcsCommon.dist(center, aBase:getPoint())\
                if delta <= range then \
                    table.insert(ABinRange, aBase)\
                end\
            end        \
        end\
        \
        if includeCenter then \
            table.insert(ABinRange, airbase)\
        end\
        \
        return ABinRange\
    end\
\
    function dcsCommon.getAirbasesInRangeOfAirbaseList(theCenterList, includeList, range, filterCat, filterCoalition)\
        local collectorDict = {}\
        for idx, aCenter in pairs(theCenterList) do \
            -- get all surrounding airbases. returns list of airfields \
            local surroundingAB = dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeList, range, filterCat, filterCoalition)\
            \
            for idx2, theAirField in pairs (surroundingAB) do \
                collectorDict[airField] = theAirField \
            end\
        end\
        \
        -- make result an array\
        local theABList = dcsCommon.enumerateTable(collectorDict)\
        return theABList\
    end\
\
    -- getAirbasesWhoseNameContains - get all airbases containing \
    -- a name. filterCat is optional and can be aerodrome (0), farp (1), ship (2)\
    -- filterCoalition is optional and can be 0 (neutral), 1 (red), 2 (blue) \
    -- if no name given or aName = \"*\", then all bases are returned prior to filtering \
    function dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\
        --trigger.action.outText(\"getAB(name): enter with \" .. aName, 30)\
        if not aName then aName = \"*\" end \
        local allYourBase = world.getAirbases() -- get em all \
        local areBelongToUs = {}\
        -- now iterate all bases\
        for idx, aBase in pairs(allYourBase) do\
            local airBaseName = aBase:getName() -- get display name\
            if aName == \"*\" or dcsCommon.containsString(airBaseName, aName) then \
                -- containsString is case insesitive unless told otherwise\
                --if aName ~= \"*\" then \
                --    trigger.action.outText(\"getAB(name): matched \" .. airBaseName, 30)\
                --end \
                local doAdd = true \
                if filterCat then \
                    -- make sure the airbase is of that category \
                    local airCat = dcsCommon.getAirbaseCat(aBase)\
                    doAdd = doAdd and airCat == filterCat \
                end\
                \
                if filterCoalition then \
                    doAdd = doAdd and filterCoalition == aBase:getCoalition()\
                end\
                \
                if doAdd then \
                    -- all good, add to table\
                    table.insert(areBelongToUs, aBase)\
                end            \
            end\
        end\
        return areBelongToUs\
    end\
\
    function dcsCommon.getFirstAirbaseWhoseNameContains(aName, filterCat, filterCoalition)\
        local allBases = dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\
        for idx, aBase in pairs (allBases) do \
            -- simply return first \
            return aBase\
        end\
        return nil \
    end    \
\
    function dcsCommon.getClosestAirbaseTo(thePoint, filterCat, filterCoalition)\
        local delta = math.huge\
        local allYourBase = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition) -- get em all and filter\
        local closestBase = nil \
        for idx, aBase in pairs(allYourBase) do\
            -- iterate them all \
            local abPoint = aBase:getPoint()\
            newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\
            if newDelta < delta then \
                delta = newDelta\
                closestBase = aBase\
            end\
        end\
        return closestBase, delta \
    end\
\
-- \
-- U N I T S   M A N A G E M E N T \
--\
\
    -- number of living units in group\
    function dcsCommon.livingUnitsInGroup(group)\
        local living = 0\
        local allUnits = group:getUnits()\
        for key, aUnit in pairs(allUnits) do \
            if aUnit:isExist() and aUnit:getLife() >= 1 then \
                living = living + 1\
            end\
        end\
        return living\
    end\
\
    -- closest living unit in group to a point\
    function dcsCommon.getClosestLivingUnitToPoint(group, p)\
        if not p then return nil end\
        if not group then return nil end\
        local closestUnit = nil\
        local closestDist = math.huge\
        local allUnits = group:getUnits()\
        for key, aUnit in pairs(allUnits) do \
            if aUnit:isExist() and aUnit:getLife() >= 1 then \
                local thisDist = dcsCommon.dist(p, aUnit:getPoint())\
                if thisDist < closestDist then \
                    closestDist = thisDist\
                    closestUnit = aUnit \
                end\
            end\
        end\
        return closestUnit, closestDist\
    end\
    \
    -- closest living group to a point - cat can be nil or one of Group.Category = { AIRPLANE = 0, HELICOPTER = 1, GROUND = 2, SHIP = 3, TRAIN = 4}\
    function dcsCommon.getClosestLivingGroupToPoint(p, coal, cat) \
        if not cat then cat = 2 end -- ground is default \
        local closestGroup = nil;\
        local closestGroupDist = math.huge\
        local allGroups =  coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \
        for key, grp in pairs(allGroups) do\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\
            if closestUnit then \
                if dist < closestGroupDist then \
                    closestGroup = grp\
                    closestGroupDist = dist\
                end\
            end            \
        end\
        return closestGroup, closestGroupDist\
    end\
\
    function dcsCommon.getLivingGroupsAndDistInRangeToPoint(p, range, coal, cat) \
        if not cat then cat = 2 end -- ground is default \
        local groupsInRange = {};\
        local allGroups = coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \
        for key, grp in pairs(allGroups) do\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\
            if closestUnit then \
                if dist < range then \
                    table.insert(groupsInRange, {group = grp, dist = dist}) -- array\
                end\
            end            \
        end\
        -- sort the groups by distance\
        table.sort(groupsInRange, function (left, right) return left.dist < right.dist end )\
        return groupsInRange\
    end\
\
    -- distFlat ignores y, input must be xyz points, NOT xy points  \
    function dcsCommon.distFlat(p1, p2) \
        local point1 = {x = p1.x, y = 0, z=p1.z}\
        local point2 = {x = p2.x, y = 0, z=p2.z}\
        return dcsCommon.dist(point1, point2)\
    end\
    \
    -- distance between points\
    function dcsCommon.dist(point1, point2)     -- returns distance between two points\
      -- supports xyz and xy notations\
      if not point1 then \
        trigger.action.outText(\"+++ warning: nil point1 in common:dist\", 30)\
        point1 = {x=0, y=0, z=0}\
      end\
\
      if not point2 then \
        trigger.action.outText(\"+++ warning: nil point2 in common:dist\", 30)\
        point2 = {x=0, y=0, z=0}\
        stop.here.now = 1\
      end\
      \
      local p1 = {x = point1.x, y = point1.y}\
      if not point1.z then \
        p1.z = p1.y\
        p1.y = 0\
      else \
        p1.z = point1.z\
      end\
      \
      local p2 = {x = point2.x, y = point2.y}\
      if not point2.z then \
        p2.z = p2.y\
        p2.y = 0\
      else \
        p2.z = point2.z\
      end\
      \
      local x = p1.x - p2.x\
      local y = p1.y - p2.y \
      local z = p1.z - p2.z\
      \
      return (x*x + y*y + z*z)^0.5\
    end\
\
    function dcsCommon.delta(name1, name2) -- returns distance (in meters) of two named objects\
      local n1Pos = Unit.getByName(name1):getPosition().p\
      local n2Pos = Unit.getByName(name2):getPosition().p\
      return dcsCommon.dist(n1Pos, n2Pos)\
    end\
\
    -- lerp between a and b, x being 0..1 (percentage), clipped to [0..1]\
    function dcsCommon.lerp(a, b, x) \
        if not a then return 0 end\
        if not b then return 0 end\
        if not x then return a end\
        if x < 0 then x = 0 end \
        if x > 1 then x = 1 end \
        return a + (b - a ) * x\
    end\
\
    function dcsCommon.bearingFromAtoB(A, B) -- coords in x, z \
        dx = B.x - A.x\
        dz = B.z - A.z\
        bearing = math.atan2(dz, dx) -- in radiants\
        return bearing\
    end\
\
    function dcsCommon.bearingInDegreesFromAtoB(A, B)\
        local bearing = dcsCommon.bearingFromAtoB(A, B) -- in rads \
        bearing = math.floor(bearing / math.pi * 180)\
        if bearing < 0 then bearing = bearing + 360 end\
        if bearing > 360 then bearing = bearing - 360 end\
        return bearing\
    end\
    \
    function dcsCommon.compassPositionOfARelativeToB(A, B)\
        -- warning: is REVERSE in order for bearing, returns a string like 'Sorth', 'Southwest'\
        if not A then return \"***error:A***\" end\
        if not B then return \"***error:B***\" end\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\
        if bearing < 23 then return \"North\" end \
        if bearing < 68 then return \"NE\" end\
        if bearing < 112 then return \"East\" end \
        if bearing < 158 then return \"SE\" end \
        if bearing < 202 then return \"South\" end \
        if bearing < 248 then return \"SW\" end \
        if bearing < 292 then return \"West\" end\
        if bearing < 338 then return \"NW\" end \
        return \"North\"\
    end\
    \
    function dcsCommon.clockPositionOfARelativeToB(A, B, headingOfBInDegrees)\
        -- o'clock notation \
        if not A then return \"***error:A***\" end\
        if not B then return \"***error:B***\" end\
        if not headingOfBInDegrees then headingOfBInDegrees = 0 end \
        \
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\
--        trigger.action.outText(\"+++comm: oclock - bearing = \" .. bearing .. \" and inHeading = \" .. headingOfBInDegrees, 30) \
        bearing = bearing - headingOfBInDegrees\
        return dcsCommon.getClockDirection(bearing)\
        \
    end \
    \
    -- given a heading, return clock with 0 being 12, 180 being 6 etc.\
    function dcsCommon.getClockDirection(direction) -- inspired by cws, improvements my own\
        if not direction then return 0 end\
        direction = math.fmod (direction, 360)\
        while direction < 0 do \
            direction = direction + 360\
        end\
        \
        if direction < 15 then -- special case 12 o'clock past 12 o'clock\
            return 12\
        end\
    \
        direction = direction + 15 -- add offset so we get all other times correct\
        return math.floor(direction/30)\
    \
    end\
\
    \
    function dcsCommon.randomDegrees()\
        local degrees = math.random(360) * 3.14152 / 180\
        return degrees\
    end\
\
    function dcsCommon.randomPercent()\
        local percent = math.random(100)/100\
        return percent\
    end\
\
    function dcsCommon.randomPointOnPerimeter(sourceRadius, x, z) \
        return dcsCommon.randomPointInCircle(sourceRadius, sourceRadius-1, x, z)\
    end\
\
    function dcsCommon.randomPointInCircle(sourceRadius, innerRadius, x, z)\
        if not x then x = 0 end\
        --local y = 0\
        if not innerRadius then innerRadius = 0 end        \
        if innerRadius < 0 then innerRadius = 0 end\
        \
        local percent = dcsCommon.randomPercent() -- 1 / math.random(100)\
        -- now lets get a random degree\
        local degrees = dcsCommon.randomDegrees() -- math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \
        local r = (sourceRadius-innerRadius) * percent \
        local x = x + (innerRadius + r) * math.cos(degrees)\
        local z = z + (innerRadius + r) * math.sin(degrees)\
    \
        local thePoint = {}\
        thePoint.x = x\
        thePoint.y = 0\
        thePoint.z = z \
        \
        return thePoint, degrees\
    end\
\
    -- get group location: get the group's location by \
    -- accessing the fist existing, alive member of the group that it finds\
    function dcsCommon.getGroupLocation(group)\
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                return theUnit:getPosition().p \
            end;\
        end\
\
        -- if we get here, there was no live unit \
        --trigger.action.outText(\"+++cmn: A group has no live units. returning nil\", 10)\
        return nil \
        \
    end\
\
    -- get the group's first Unit that exists and is \
    -- alive \
    function dcsCommon.getGroupUnit(group)\
        if not group then return nil  end\
        \
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        if not group:isExist() then return nil end \
        \
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                return theUnit\
            end;\
        end\
\
        -- if we get here, there was no live unit \
        --trigger.action.outText(\"+++cmn A group has no live units. returning nil\", 10)\
        return nil \
        \
    end\
\
    -- and here the alias\
    function dcsCommon.getFirstLivingUnit(group)\
        return dcsCommon.getGroupUnit(group)\
    end\
    \
    -- isGroupAlive returns true if there is at least one unit in the group that isn't dead\
    function dcsCommon.isGroupAlive(group)\
        return (dcsCommon.getGroupUnit(group) ~= nil) \
    end\
\
    function dcsCommon.getLiveGroupUnits(group)\
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        local liveUnits = {}\
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                table.insert(liveUnits, theUnit) \
            end;\
        end\
\
        -- if we get here, there was no live unit \
        return liveUnits\
    end\
\
    function dcsCommon.getGroupTypeString(group) -- convert into comma separated types \
        if not group then \
            trigger.action.outText(\"+++cmn getGroupTypeString: nil group\", 30)\
            return \"\" \
        end\
        if not dcsCommon.isGroupAlive(group) then \
            trigger.action.outText(\"+++cmn getGroupTypeString: dead group\", 30)\
            return \"\" \
        end \
        local theTypes = \"\"\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\
        for i=1, #liveUnits do \
            if i > 1 then theTypes = theTypes .. \",\" end\
            theTypes = theTypes .. liveUnits[i]:getTypeName()\
        end\
        return theTypes\
    end\
\
    function dcsCommon.getGroupTypes(group) \
        if not group then \
            trigger.action.outText(\"+++cmn getGroupTypes: nil group\", 30)\
            return {}\
        end\
        if not dcsCommon.isGroupAlive(group) then \
            trigger.action.outText(\"+++cmn getGroupTypes: dead group\", 30)\
            return {}\
        end \
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\
        local unitTypes = {}\
        for i=1, #liveUnits do \
            table.insert(unitTypes, liveUnits[i]:getTypeName())\
        end\
        return unitTypes\
    end\
\
    function dcsCommon.getEnemyCoalitionFor(aCoalition)\
        if aCoalition == 1 then return 2 end\
        if aCoalition == 2 then return 1 end\
        if type(aCoalition) == \"string\" then \
            aCoalition = aCoalition:lower()\
            if aCoalition == \"red\" then return 2 end\
            if aCoalition == \"blue\" then return 1 end\
        end\
        return nil\
    end\
\
    function dcsCommon.getACountryForCoalition(aCoalition)\
        -- scan the table of countries and get the first country that is part of aCoalition\
        -- this is useful if you want to create troops for a coalition but don't know the\
        -- coalition's countries \
        -- we start with id=0 (Russia), go to id=85 (Slovenia), but skip id = 14\
        local i = 0\
        while i < 86 do \
            if i ~= 14 then \
                if (coalition.getCountryCoalition(i) == aCoalition) then return i end\
            end\
            i = i + 1\
        end\
        \
        return nil\
    end\
--\
--\
-- C A L L B A C K   H A N D L E R \
--\
--\
\
    -- installing callbacks\
    -- based on mist, with optional additional hooks for pre- and post-\
    -- processing of the event\
    -- when filtering occurs in pre, an alternative 'rejected' handler can be called \
    function dcsCommon.addEventHandler(f, pre, post, rejected) -- returns ID \
        local handler = {} -- build a wrapper and connect the onEvent\
        --dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\
        handler.id = dcsCommon.uuid(\"eventHandler\")\
        handler.f = f -- the callback itself\
        if (rejected) then handler.rejected = rejected end\
        -- now set up pre- and post-processors. defaults are set in place\
        -- so pre and post are optional. If pre returns false, the callback will\
        -- not be invoked\
        if (pre) then handler.pre = pre else handler.pre = dcsCommon.preCall end\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\
        function handler:onEvent(event)\
            if not self.pre(event) then \
                if dcsCommon.verbose then\
--                    trigger.action.outText(\"event \" .. event.id .. \" discarded by pre-processor\", 10)\
                end\
                if (self.rejected) then self.rejected(event) end \
                return\
            end\
            self.f(event) -- call the handler\
            self.post(event) -- do post-processing\
        end\
        world.addEventHandler(handler)\
        return handler.id\
    end\
\
    function dcsCommon.preCall(e)\
        -- we can filter here\
        -- if we return false, the call is abortet\
        if dcsCommon.verbose then\
            trigger.action.outText(\"event \" .. e.id .. \" received: PRE-PROCESSING\", 10)\
        end\
        return true;\
    end;\
\
    function dcsCommon.postCall(e)\
        -- we do pos proccing here \
        if dcsCommon.verbose then\
            trigger.action.outText(\"event \" .. e.id .. \" received: post proc\", 10)\
        end\
    end\
    \
    -- highly specific eventhandler for one event only\
    -- based on above, with direct filtering built in; skips pre\
    -- but does post\
    function dcsCommon.addEventHandlerForEventTypes(f, evTypes, post, rejected) -- returns ID \
        local handler = {} -- build a wrapper and connect the onEvent\
        dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\
        handler.id = dcsCommon.cbID\
        handler.what = evTypes\
        if (rejected) then handler.rejected = rejected end \
        \
        handler.f = f -- set the callback itself\
        -- now set up post-processor. pre is hard-coded to match evType\
        -- post is optional. If event.id is not in evTypes, the callback will\
        -- not be invoked\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\
        function handler:onEvent(event)\
            hasMatch = false;\
            for key, evType in pairs(self.what) do\
                if evType == event.id then\
                    hasMatch = true;\
                    break;\
                end;\
            end;\
            if not hasMatch then \
                if dcsCommon.verbose then\
                    trigger.action.outText(\"event \" .. e.id .. \" discarded - not in whitelist evTypes\", 10)\
                end\
                if (self.rejected) then self.rejected(event) end \
                return;\
            end;\
            \
            self.f(event) -- call the actual handler as passed to us\
            self.post(event) -- do post-processing \
        end\
        world.addEventHandler(handler) -- add to event handlers\
        return handler.id\
    end\
    \
    \
    \
    -- remove event handler / callback, identical to Mist \
    -- note we don't call world.removeEventHandler, but rather directly \
    -- access world.eventHandlers directly and remove kvp directly.\
    function dcsCommon.removeEventHandler(id)\
        for key, handler in pairs(world.eventHandlers) do\
            if handler.id and handler.id == id then\
                world.eventHandlers[key] = nil\
                return true\
            end\
        end\
        return false\
    end\
\
--\
--\
-- C L O N I N G \
--\
--\
    -- topClone is a shallow clone of orig, only top level is iterated,\
    -- all values are ref-copied\
    function dcsCommon.topClone(orig)\
        local orig_type = type(orig)\
        local copy\
        if orig_type == 'table' then\
            copy = {}\
            for orig_key, orig_value in pairs(orig) do\
                copy[orig_key] = orig_value\
            end\
        else -- number, string, boolean, etc\
            copy = orig\
        end\
        return copy\
    end\
\
    -- clone is a recursive clone which will also clone\
    -- deeper levels, as used in units \
    function dcsCommon.clone(orig)\
        local orig_type = type(orig)\
        local copy\
        if orig_type == 'table' then\
            copy = {}\
            for orig_key, orig_value in next, orig, nil do\
                copy[dcsCommon.clone(orig_key)] = dcsCommon.clone(orig_value)\
            end\
            setmetatable(copy, dcsCommon.clone(getmetatable(orig)))\
        else -- number, string, boolean, etc\
            copy = orig\
        end\
        return copy\
    end\
\
    function dcsCommon.copyArray(inArray)\
        -- warning: this is a ref copy!\
        local theCopy = {}\
        for idx, element in pairs(inArray) do \
            table.insert(theCopy, element)\
        end\
        return theCopy \
    end\
--\
-- \
-- S P A W N I N G \
-- \
-- \
\
    function dcsCommon.createEmptyGroundGroupData (name)\
        local theGroup = {} -- empty group\
        theGroup.visible = false\
        theGroup.taskSelected = true\
        -- theGroup.route = {}\
        -- theGroup.groupId = id\
        theGroup.tasks = {}\
        -- theGroup.hidden = false -- hidden on f10?\
\
        theGroup.units = { } -- insert units here! -- use addUnitToGroupData\
\
        theGroup.x = 0\
        theGroup.y = 0\
        theGroup.name = name\
        -- theGroup.start_time = 0\
        theGroup.task = \"Ground Nothing\"\
        \
        return theGroup\
    end;\
\
    function dcsCommon.createEmptyAircraftGroupData (name)\
        local theGroup = dcsCommon.createEmptyGroundGroupData(name)--{} -- empty group\
\
        theGroup.task = \"Nothing\" -- can be others, like Transport, CAS, etc\
        -- returns with empty route\
        theGroup.route = dcsCommon.createEmptyAircraftRouteData() -- we can add points here \
        return theGroup\
    end;\
\
    function dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\
        local rp = {}\
        rp.x = x\
        rp.y = z\
        rp.action = \"Turning Point\"\
        rp.type = \"Turning Point\"\
        if action then rp.action = action; rp.type = action end -- warning: may not be correct, need to verify later\
        rp.alt = altitudeInFeet * 0.3048\
        rp.speed = knots * 0.514444 -- we use \
        rp.alt_type = \"BARO\"\
        if (altType) then rp.alt_type = altType end \
        return rp\
    end\
\
    function dcsCommon.addRoutePointDataToRouteData(inRoute, x, z, altitudeInFeet, knots, altType, action)\
        local p = dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\
        local thePoints = inRoute.points \
        table.insert(thePoints, p)\
    end\
    \
    function dcsCommon.addRoutePointDataToGroupData(group, x, z, altitudeInFeet, knots, altType, action)\
        if not group.route then group.route = dcsCommon.createEmptyAircraftRouteData() end\
        local theRoute = group.route \
        dcsCommon.addRoutePointDataToRouteData(theRoute, x, z, altitudeInFeet, knots, altType, action)\
    end\
\
    function dcsCommon.addRoutePointForGroupData(theGroup, theRP)\
        if not theGroup then return end \
        if not theGroup.route then theGroup.route = dcsCommon.createEmptyAircraftRouteData() end\
        \
        local theRoute = theGroup.route \
        local thePoints = theRoute.points \
        table.insert(thePoints, theRP)\
    end\
    \
    function dcsCommon.createEmptyAircraftRouteData()\
        local route = {}\
        route.points = {}\
        return route\
    end\
\
    function dcsCommon.createTakeOffFromParkingRoutePointData(aerodrome)\
        if not aerodrome then return nil end \
            \
        local rp = {}    \
        local freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome, 104) -- get big slot first \
        if not freeParkingSlot then \
            freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome) -- try any size\
        end\
            \
        if not freeParkingSlot then \
            trigger.action.outText(\"civA: no free parking at \" .. aerodrome:getName(), 30)\
            return nil \
        end\
            \
        local p = freeParkingSlot.vTerminalPos\
            \
        rp.airdromeId = aerodrome:getID() \
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y \
        rp.action = \"From Parking Area\"\
        rp.type = \"TakeOffParking\"\
            \
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
\
    function dcsCommon.createOverheadAirdromeRoutPintData(aerodrome)\
        if not aerodrome then return nil end \
        local rp = {}            \
        local p = aerodrome:getPoint()\
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y + 2000 -- 6000 ft overhead\
        rp.action = \"Turning Point\"\
        rp.type = \"Turning Point\"\
            \
        rp.speed = 133; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
    \
\
    function dcsCommon.createLandAtAerodromeRoutePointData(aerodrome)\
        if not aerodrome then return nil end \
            \
        local rp = {}            \
        local p = aerodrome:getPoint()\
        rp.airdromeId = aerodrome:getID() \
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y \
        rp.action = \"Landing\"\
        rp.type = \"Land\"\
            \
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
\
    \
    function dcsCommon.createRPFormationData(findex) -- must be added as \"task\" to an RP. use 4 for Echelon right\
        local task = {}\
        task.id = \"ComboTask\"\
        local params = {}\
        task.params = params\
        local tasks = {}\
        params.tasks = tasks\
        local t1 = {}\
        tasks[1] = t1\
        t1.number = 1\
        t1.auto = false \
        t1.id = \"WrappedAction\"\
        t1.enabled = true\
        local t1p = {}\
        t1.params = t1p\
        local action = {}\
        t1p.action = action \
        action.id = \"Option\"\
        local ap = {}\
        action.params = ap\
        ap.variantIndex = 3\
        ap.name = 5 -- AI.Option.Air.ID 5 = Formation \
        ap.formationIndex = findex -- 4 is echelon_right\
        ap.value = 262147\
        \
        return task \
    end\
\
    function dcsCommon.addTaskDataToRP(theTask, theGroup, rpIndex)\
        local theRoute = theGroup.route\
        local thePoints = theRoute.points\
        local rp = thePoints[rpIndex]\
        rp.task = theTask\
    end\
    \
    -- create a minimal payload table that is compatible with creating \
    -- a unit. you may need to alter this before adding the unit to\
    -- the mission. all params optional \
    function dcsCommon.createPayload(fuel, flare, chaff, gun) \
        local payload = {}\
        payload.pylons = {}\
        if not fuel then fuel = 1000 end -- in kg. check against fuelMassMax in type desc\
        if not flare then flare = 0 end\
        if not chaff then chaff = 0 end\
        if not gun then gun = 0 end\
        return payload \
        \
    end\
\
    function dcsCommon.createCallsign(cs) \
        local callsign = {}\
        callsign[1] = 1\
        callsign[2] = 1\
        callsign[3] = 1\
        if not cs then cs = \"Enfield11\" end\
        callsign.name = cs\
        return callsign\
    end\
    \
\
    -- create the data table required to spawn a unit.\
    -- unit types are defined in https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\
    function dcsCommon.createGroundUnitData(name, unitType, transportable)\
        local theUnit = {}\
        unitType = dcsCommon.trim(unitType)\
        theUnit.type = unitType -- e.g. \"LAV-25\",\
        if not transportable then transportable = false end -- elaborate, not requried code\
        theUnit.transportable = {[\"randomTransportable\"] = transportable} \
        -- theUnit.unitId = id \
        theUnit.skill = \"Average\" -- always average \
        theUnit.x = 0 -- make it zero, zero!\
        theUnit.y = 0\
        theUnit.name = name\
        theUnit.playerCanDrive = false\
        theUnit.heading = 0\
        return theUnit\
    end \
\
    function dcsCommon.createAircraftUnitData(name, unitType, transportable, altitude, speed, heading)\
        local theAirUnit = dcsCommon.createGroundUnitData(name, unitType, transportable)\
        theAirUnit.alt = 100 -- make it 100m\
        if altitude then theAirUnit.alt = altitude end \
        theAirUnit.alt_type = \"RADIO\" -- AGL\
        theAirUnit.speed = 77 -- m/s --> 150 knots\
        if speed then theAirUnit.speed = speed end \
        if heading then theAirUnit.heading = heading end \
        theAirUnit.payload = dcsCommon.createPayload()\
        theAirUnit.callsign = dcsCommon.createCallsign()\
        return theAirUnit\
    end\
    \
\
    function dcsCommon.addUnitToGroupData(theUnit, theGroup, dx, dy, heading)\
        -- add a unit to a group, and place it at dx, dy of group's position,\
        -- taking into account unit's own current location\
        if not dx then dx = 0 end\
        if not dy then dy = 0 end\
        if not heading then heading = 0 end\
        theUnit.x = theUnit.x + dx + theGroup.x\
        theUnit.y = theUnit.y + dy + theGroup.y \
        theUnit.heading = heading\
        table.insert(theGroup.units, theUnit)\
    end;\
\
    function dcsCommon.createSingleUnitGroup(name, theUnitType, x, z, heading) \
        -- create the container \
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\
        local aUnit = {}\
        aUnit = dcsCommon.createGroundUnitData(name .. \"-1\", theUnitType, false)\
--        trigger.action.outText(\"dcsCommon - unit name retval \" .. aUnit.name, 30)\
        dcsCommon.addUnitToGroupData(aUnit, theNewGroup, x, z, heading)\
        return theNewGroup\
    end\
    \
\
    function dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\
        -- formations:\
        --    (default) \"line\" (left to right along x) -- that is Y direction\
        --    \"line_v\" a line top to bottom -- that is X direction\
        --    \"chevron\" - left to right middle too top\
        --    \"scattered\", \"random\" -- random, innerRadius used to clear area in center\
        --       \"circle\", \"circle_forward\" -- circle, forward facing\
        --    \"circle_in\" -- circle, inwarf facing\
        --    \"circle_out\" -- circle, outward facing\
        --    \"grid\", \"square\", \"rect\" -- optimal rectangle\
        --    \"2cols\", \"2deep\" -- 2 columns, n deep \
        --    \"2wide\" -- 2 columns wide, 2 deep \
\
        local num = #theNewGroup.units \
        \
        -- now do the formation stuff\
        -- make sure that they keep minimum  distance \
--        trigger.action.outText(\"dcsCommon - processing formation \" .. formation .. \" with radius = \" .. radius, 30)\
        if formation == \"LINE_V\" then \
            -- top to bottom in zone (heding 0). -- will run through x-coordinate \
            -- use entire radius top to bottom \
            local currX = -radius\
            local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            for i=1, num do\
            \
                local u = theNewGroup.units[i]\
--                trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currX, 30)\
                u.x = currX\
                currX = currX + increment\
            end\
        \
        elseif formation == \"LINE\" then \
            -- left to right in zone. runs through Y\
            -- left and right are y because at heading 0, forward is x (not y as expected)\
            -- if only one, place in middle of circle and be done \
            if num == 1 then \
                -- nothing. just stay in the middle \
            else \
                local currY = -radius\
                local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
                for i=1, num do\
                    local u = theNewGroup.units[i]\
--                    trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currY, 30)\
                    u.y = currY\
                    currY = currY + increment\
                end    \
            end \
            \
        elseif formation == \"CHEVRON\" then \
            -- left to right in zone. runs through Y\
            -- left and right are y because at heading 0, forward is x (not y as expected)\
            local currY = -radius\
            local currX = 0\
            local incrementY = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            local incrementX = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            for i=1, num do\
                local u = theNewGroup.units[i]\
--                trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currX .. \" currY = \" .. currY, 30)\
                u.x = currX\
                u.y = currY\
                -- calc coords for NEXT iteration\
                currY = currY + incrementY -- march left to right\
                if i < num / 2 then -- march up\
                    currX = currX + incrementX \
                elseif i == num / 2 then -- even number, keep height\
                    currX = currX + 0 \
                else \
                    currX = currX - incrementX -- march down \
                end \
                -- note: when unit number even, the wedge is sloped. may need an odd/even test for better looks\
            end    \
\
        elseif formation == \"SCATTERED\" or formation == \"RANDOM\" then \
            -- use randomPointInCircle and tehn iterate over all vehicles for mindelta\
            processedUnits = {}\
            for i=1, num do\
                local emergencyBreak = 1 -- prevent endless loop\
                local lowDist = 10000\
                local uPoint = {}\
                local thePoint = {}\
                repeat     -- get random point intil mindistance to all is kept or emergencybreak\
                    for idx, rUnit in pairs(processedUnits) do -- get min dist to all positioned units\
                        thePoint = dcsCommon.randomPointInCircle(radius, innerRadius) -- returns x, 0, z\
                        uPoint.x = rUnit.x\
                        uPoint.y = 0\
                        uPoint.z = rUnit.y \
                        local dist = dcsCommon.dist(thePoint, uPoint) -- measure distance to unit\
                        if (dist < lowDist) then lowDist = dist end\
                    end\
                    emergencyBreak = emergencyBreak + 1\
                until (emergencyBreak > 20) or (lowDist > minDist)\
                -- we have random x, y \
                local u = theNewGroup.units[i] -- get unit to position\
                u.x = thePoint.x\
                u.y = thePoint.z -- z --> y mapping! \
                -- now add the unit to the 'processed' set \
                table.insert(processedUnits, u)\
            end    \
\
        elseif dcsCommon.stringStartsWith(formation, \"CIRCLE\") then\
            -- units are arranged on perimeter of circle defined by radius \
--            trigger.action.outText(\"formation circle detected\", 30)\
            local currAngle = 0\
            local angleInc = 2 * 3.14157 / num -- increase per spoke \
            for i=1, num do\
                local u = theNewGroup.units[i] -- get unit \
                u.x = radius * math.cos(currAngle)\
                u.y = radius * math.sin(currAngle)\
                \
                -- now baldower out heading \
                -- circle, circle_forward no modifier of heading\
                if dcsCommon.stringStartsWith(formation, \"CIRCLE_IN\") then \
                    -- make the heading inward faceing - that's angle + pi\
                    u.heading = u.heading + currAngle + 3.14157\
                elseif dcsCommon.stringStartsWith(formation, \"CIRCLE_OUT\") then \
                    u.heading = u.heading + currAngle + 0\
                end\
\
                currAngle = currAngle + angleInc\
            end\
        elseif formation == \"GRID\" or formation == \"SQUARE\" or formation == \"RECT\" then \
            if num < 2 then return end \
            -- arrange units in an w x h grid\
            -- e-g- 12 units = 4 x 3. \
            -- calculate w \
            local w = math.floor(num^(0.5) + 0.5)\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
            --[[--\
            local h = math.floor(num / w)\
            --trigger.action.outText(\"AdcsC: num=\" .. num .. \" w=\" .. w .. \"h=\" .. h .. \" -- num%w=\" .. num%w, 30)\
            if (num % w) > 0 then \
                h = h + 1\
            end\
            \
            --trigger.action.outText(\"BdcsC: num=\" .. num .. \" w=\" .. w .. \"h=\" .. h, 30)\
            \
            -- now w * h always >= num and num items fir in that grid\
            -- w is width, h is height, of course :) \
            -- now calculat xInc and yInc\
            local i = 1\
            local xInc = 0 \
            if w > 1 then xInc = 2 * radius / (w-1) end\
            local yInc = 0\
            if h > 1 then yInc = 2 * radius / (h-1) end \
            local currY = radius \
            if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\
            while h > 0 do \
                local currX = radius \
                local wCnt = w \
                while wCnt > 0 and (i <= num) do \
                    local u = theNewGroup.units[i] -- get unit \
                    u.x = currX\
                    u.y = currY\
                    currX = currX - xInc\
                    wCnt = wCnt - 1\
                    i = i + 1\
                end\
                currY = currY - yInc \
                h = h - 1\
            end\
            --]]--\
        elseif formation == \"2DEEP\" or formation == \"2COLS\" then\
            if num < 2 then return end \
            -- arrange units in an 2 x h grid\
            local w = 2\
            dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\
\
        elseif formation == \"2WIDE\" then\
            if num < 2 then return end \
            -- arrange units in an 2 x h grid\
            local w = 2\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
        else \
            trigger.action.outText(\"dcsCommon - unknown formation: \" .. formation, 30)\
        end\
    \
    end\
    \
    function dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
        local num = #theNewGroup.units\
        local h = math.floor(num / w)\
        if (num % w) > 0 then \
            h = h + 1\
        end\
        local i = 1\
        local xInc = 0 \
        if w > 1 then xInc = 2 * radius / (w-1) end\
        local yInc = 0\
        if h > 1 then yInc = 2 * radius / (h-1) end \
        local currY = radius \
        if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\
        while h > 0 do \
            local currX = radius \
            local wCnt = w \
            while wCnt > 0 and (i <= num) do \
                local u = theNewGroup.units[i] -- get unit \
                u.x = currX\
                u.y = currY\
                currX = currX - xInc\
                wCnt = wCnt - 1\
                i = i + 1\
            end\
            currY = currY - yInc \
            h = h - 1\
        end\
    end\
    \
    function dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\
        local num = #theNewGroup.units\
        local h = math.floor(num / w)\
        if (num % w) > 0 then \
            h = h + 1\
        end\
        local i = 1\
        local yInc = 0 \
        if w > 1 then yInc = 2 * radius / (w-1) end\
        local xInc = 0\
        if h > 1 then xInc = 2 * radius / (h-1) end \
        local currX = radius \
        if h < 2 then currX = 0 end -- special:_ place in Y middle if only one row)\
        while h > 0 do \
            local currY = radius \
            local wCnt = w \
            while wCnt > 0 and (i <= num) do \
                local u = theNewGroup.units[i] -- get unit \
                u.x = currX\
                u.y = currY\
                currY = currY - yInc\
                wCnt = wCnt - 1\
                i = i + 1\
            end\
            currX = currX - xInc \
            h = h - 1\
        end\
    end\
    \
    \
    function dcsCommon.createGroundGroupWithUnits(name, theUnitTypes, radius, minDist, formation, innerRadius)\
        if not minDist then mindist = 4 end -- meters\
        if not formation then formation = \"line\" end \
        if not radius then radius = 30 end -- meters \
        if not innerRadius then innerRadius = 0 end\
        formation = formation:upper()\
        -- theUnitTypes can be either a single string or a table of strings\
        -- see here for TypeName https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\
        -- formation defines how the units are going to be arranged in the\
        -- formation specified. \
        -- formations:\
        --    (default) \"line\" (left to right along x) -- that is Y direction\
        --    \"line_V\" a line top to bottom -- that is X direction\
        --    \"chevron\" - left to right middle too top\
        --    \"scattered\", \"random\" -- random, innerRadius used to clear area in center\
        --       \"circle\", \"circle_forward\" -- circle, forward facing\
        --    \"circle_in\" -- circle, inwarf facing\
        --    \"circle_out\" -- circle, outward facing\
\
        -- first, we create a group\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\
        \
        -- now add a single unit or multiple units\
        if type(theUnitTypes) ~= \"table\" then \
--            trigger.action.outText(\"dcsCommon - i am here\", 30)\
--            trigger.action.outText(\"dcsCommon - name \" .. name, 30)\
--            trigger.action.outText(\"dcsCommon - unit type \" .. theUnitTypes, 30)\
            \
            local aUnit = {}\
            aUnit = dcsCommon.createGroundUnitData(name .. \"-1\", theUnitTypes, false)\
--            trigger.action.outText(\"dcsCommon - unit name retval \" .. aUnit.name, 30)\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0) -- create with data at location (0,0)\
            return theNewGroup\
        end \
\
        -- if we get here, theUnitTypes is a table\
        -- now loop and create a unit for each table\
        local num = 1\
        for key, theType in pairs(theUnitTypes) do \
            -- trigger.action.outText(\"+++dcsC: creating unit \" .. name .. \"-\" .. num .. \": \" .. theType, 30)\
            local aUnit = dcsCommon.createGroundUnitData(name .. \"-\"..num, theType, false)\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0)\
            num = num + 1\
        end\
        \
        dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\
        return theNewGroup\
\
    \
    end\
\
-- create a new group, based on group in mission. Groups coords are 0,0 for group and all\
-- x,y and heading\
    function dcsCommon.createGroupDataFromLiveGroup(name, newName) \
        if not newName then newName = dcsCommon.uuid(\"uniqName\") end\
        -- get access to the group\
        local liveGroup = Group.getByName(name)\
        if not liveGroup then return nil end\
        -- get the categorty\
        local cat = liveGroup:getCategory()\
        local theNewGroup = {}\
        \
        -- create a new empty group at (0,0) \
        if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \
            theNewGroup = dcsCommon.createEmptyAircraftGroupData(newName)\
        elseif cat == Group.Category.GROUND then\
            theNewGroup = dcsCommon.createEmptyGroudGroupData(newName)\
        else \
            trigger.action.outText(\"dcsCommon - unknown category: \" .. cat, 30)\
            return nil\
        end\
        \
\
        -- now get all units from live group and create data units\
        -- note that unit data for group has x=0, y=0\
        liveUnits = liveGroup:getUnits()\
        \
        for index, theUnit in pairs(liveUnits) do \
            -- for each unit we get the desc \
            local desc = theUnit:getDesc() -- of interest is only typename \
            local newUnit = dcsCommon.createGroundUnitData(dcsCommon.uuid(newName),\
                                                           desc.typeName,\
                                                           false)\
            -- we now basically have a ground unit at (0,0) \
            -- add mandatory fields by type\
            if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \
                newUnit.alt = 100 -- make it 100m\
                newUnit.alt_type = \"RADIO\" -- AGL\
                newUnit.speed = 77 -- m/s --> 150 knots\
                newUnit.payload = dcsCommon.createPayload() -- empty payload\
                newUnit.callsign = dcsCommon.createCallsign() -- 'enfield11'\
                \
            elseif cat == Group.Category.GROUND then\
                -- we got all we need\
            else \
                -- trigger.action.outText(\"dcsCommon - unknown category: \" .. cat, 30)\
                -- return nil\
                -- we also got all we need\
            end            \
            \
        end\
    \
    end;\
    \
\
    function dcsCommon.rotatePointAroundOrigin(inX, inY, angle) -- angle in degrees\
        local degrees =  3.14152 / 180 -- ok, it's actually radiants. \
        angle = angle * degrees -- turns into rads\
        local c = math.cos(angle)\
        local s = math.sin(angle)\
        local px\
        local py \
        px = inX * c - inY * s\
        py = inX * s + inY * c\
        return px, py        \
    end\
\
    function dcsCommon.rotateUnitData(theUnit, degrees, cx, cy)\
        if not cx then cx = 0 end\
        if not cz then cz = 0 end\
        local cy = cz \
        --trigger.action.outText(\"+++dcsC:rotGrp cy,cy = \"..cx .. \",\" .. cy, 30)\
        \
        local rads = degrees *  3.14152 / 180\
        do\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\
            theUnit.y = theUnit.y - cy                 \
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\
            theUnit.x = theUnit.x + cx -- MOVE BACK \
            theUnit.y = theUnit.y + cy                 \
\
            -- may also want to increase heading by degreess\
            theUnit.heading = theUnit.heading + rads \
        end\
    end\
    \
\
    function dcsCommon.rotateGroupData(theGroup, degrees, cx, cz)\
        if not cx then cx = 0 end\
        if not cz then cz = 0 end\
        local cy = cz \
        --trigger.action.outText(\"+++dcsC:rotGrp cy,cy = \"..cx .. \",\" .. cy, 30)\
        \
        local rads = degrees *  3.14152 / 180\
        -- turns all units in group around the group's center by degrees.\
        -- may also need to turn individual units by same amount\
        for i, theUnit in pairs (theGroup.units) do\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\
            theUnit.y = theUnit.y - cy                 \
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\
            theUnit.x = theUnit.x + cx -- MOVE BACK \
            theUnit.y = theUnit.y + cy                 \
\
            -- may also want to increase heading by degreess\
            theUnit.heading = theUnit.heading + rads \
        end\
    end\
\
    function dcsCommon.offsetGroupData(theGroup, dx, dy)\
        -- add dx and dy to group's and all unit's coords\
        for i, theUnit in pairs (theGroup.units) do \
            theUnit.x = theUnit.x + dx\
            theUnit.y = theUnit.y + dy\
        end\
        \
        theGroup.x = theGroup.x + dx\
        theGroup.y = theGroup.y + dy \
    end\
    \
    function dcsCommon.moveGroupDataTo(theGroup, xAbs, yAbs)\
        local dx = xAbs-theGroup.x\
        local dy = yAbs-theGroup.y\
        dcsCommon.offsetGroupData(theGroup, dx, dy)\
    end\
    \
    -- static objectr shapes and types are defined here\
    -- https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB/Statics\
    \
    function dcsCommon.createStaticObjectData(name, objType, heading, dead, cargo, mass)\
        local staticObj = {}\
        if not heading then heading = 0 end \
        if not dead then dead = false end \
        if not cargo then cargo = false end \
        objType = dcsCommon.trim(objType) \
        \
        staticObj.heading = heading\
        -- staticObj.groupId = 0\
        -- staticObj.shape_name = shape -- e.g. H-Windsock_RW\
        staticObj.type = objType  -- e.g. Windsock\
        -- [\"unitId\"] = 3,\
        staticObj.rate = 1 -- score when killed\
        staticObj.name = name\
        -- staticObj.category = \"Fortifications\",\
        staticObj.y = 0\
        staticObj.x = 0\
        staticObj.dead = dead\
        staticObj.canCargo = cargo -- to cargo\
        if cargo then \
            if not mass then mass = 1234 end \
            staticObj.mass = mass -- to cargo\
        end\
        return staticObj\
    end\
    \
    function dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\
        local theData = dcsCommon.createStaticObjectData(name, objType, heading, dead)\
        theData.x = loc.x\
        theData.y = loc.z \
        return theData\
    end\
    \
    function dcsCommon.createStaticObjectForCoalitionAtLocation(theCoalition, loc, name, objType, heading, dead) \
        if not heading then heading = math.random(360) * 3.1415 / 180 end\
        local theData = dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\
        return theStatic\
    end\
    \
    function dcsCommon.createStaticObjectForCoalitionInRandomRing(theCoalition, objType, x, z, innerRadius, outerRadius, heading, alive) \
        if not outerRadius then outerRadius = innerRadius end\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\
        local dead = not alive\
        local p = dcsCommon.randomPointInCircle(outerRadius, innerRadius, x, z)\
        local theData = dcsCommon.createStaticObjectData(dcsCommon.uuid(\"static\"), objType, heading, dead)\
        theData.x = p.x\
        theData.y = p.z \
        \
        local theStatic = coalition.addStaticObject(theCoalition, theData)\
        return theStatic\
    end\
    \
    \
    \
    function dcsCommon.linkStaticDataToUnit(theStatic, theUnit, dx, dy, heading)\
        if not theStatic then \
            trigger.action.OutText(\"+++dcsC: NIL theStatic on linkStatic!\", 30)\
            return \
        end\
        -- NOTE: we may get current heading and subtract/add \
        -- to original heading \
        local rotX, rotY = dcsCommon.rotatePointAroundOrigin(dx, dy, -heading)\
        \
        if not theUnit then return end\
        if not theUnit:isExist() then return end \
        theStatic.linkOffset = true \
        theStatic.linkUnit = theUnit:getID()\
        local unitPos = theUnit:getPoint()\
        local offsets = {}\
        offsets.x = rotX  \
        offsets.y = rotY \
        offsets.angle = 0\
        theStatic.offsets = offsets\
    end\
    \
    function dcsCommon.offsetStaticData(theStatic, dx, dy)\
        theStatic.x = theStatic.x + dx\
        theStatic.y = theStatic.y + dy\
        -- now check if thre is a route (for linked objects)\
        if theStatic.route then \
            -- access points[1] x and y and copy from main\
            theStatic.route.points[1].x = theStatic.x\
            theStatic.route.points[1].y = theStatic.y\
        end\
    end\
    \
    function dcsCommon.moveStaticDataTo(theStatic, x, y)\
        theStatic.x = x\
        theStatic.y = y\
        -- now check if thre is a route (for linked objects)\
        if theStatic.route then \
            -- access points[1] x and y and copy from main\
            theStatic.route.points[1].x = theStatic.x\
            theStatic.route.points[1].y = theStatic.y\
        end\
\
    end\
    \
--\
--\
-- M I S C   M E T H O D S \
--\
--\
\
    function dcsCommon.arrayContainsString(theArray, theString) \
        if not theArray then return false end\
        if not theString then return false end\
        for i = 1, #theArray do \
            if theArray[i] == theString then return true end \
        end\
        return false \
    end\
    \
    function dcsCommon.splitString(inputstr, sep) \
        if sep == nil then\
            sep = \"%s\"\
        end\
        if inputstr == nil then \
            inputstr = \"\"\
        end\
        \
        local t={}\
        for str in string.gmatch(inputstr, \"([^\"..sep..\"]+)\") do\
            table.insert(t, str)\
        end\
        return t\
    \
    end\
    \
    function dcsCommon.trimFront(inputstr) \
        if not inputstr then return nil end \
        local s = inputstr\
        while string.len(s) > 1 and string.sub(s, 1, 1) == \" \" do \
            local snew = string.sub(s, 2) -- all except first\
            s = snew\
        end\
        return s\
    end\
    \
    function dcsCommon.trimBack(inputstr)\
        if not inputstr then return nil end \
        local s = inputstr\
        while string.len(s) > 1 and string.sub(s, -1) == \" \" do \
            local snew = string.sub(s, 1, -2) -- all except last\
            s = snew\
        end\
        return s\
    end\
    \
    function dcsCommon.trim(inputstr) \
        local t1 = dcsCommon.trimFront(inputstr)\
        local t2 = dcsCommon.trimBack(t1)\
        return t2\
    end\
    \
    function dcsCommon.trimArray(theArray)\
        local trimmedArray = {}\
        for idx, element in pairs(theArray) do \
            local tel = dcsCommon.trim(element)\
            table.insert(trimmedArray, tel)\
        end\
        return trimmedArray\
    end\
    \
    function dcsCommon.stringIsPositiveNumber(theString)\
        -- only full integer positive numbers supported \
        if not theString then return false end \
--        if theString == \"\" then return false end \
        for i = 1, #theString do \
            local c = theString:sub(i,i)\
            if c < \"0\" or c > \"9\" then return false end \
        end\
        return true \
    end\
    \
    function dcsCommon.stringStartsWithDigit(theString)\
        if #theString < 1 then return false end \
        local c = string.sub(theString, 1, 1) \
        return c >= \"0\" and c <= \"9\" \
    end\
    \
    function dcsCommon.stringStartsWithLetter(theString)\
        if #theString < 1 then return false end \
        local c = string.sub(theString, 1, 1)\
        if c >= \"a\" and c <= \"z\" then return true end  \
        if c >= \"A\" and c <= \"Z\" then return true end \
        return false \
    end\
    \
    function dcsCommon.stringStartsWith(theString, thePrefix)\
        return theString:find(thePrefix) == 1\
    end\
    \
    function dcsCommon.removePrefix(theString, thePrefix)\
        if not dcsCommon.stringStartsWith(theString, thePrefix) then \
            return theString\
        end;\
        return theString:sub(1 + #thePrefix)\
    end\
    \
    function dcsCommon.stringEndsWith(theString, theEnding)\
        return theEnding == \"\" or theString:sub(-#theEnding) == theEnding\
    end\
    \
    function dcsCommon.removeEnding(theString, theEnding) \
        if not dcsCommon.stringEndsWith(theString, theEnding) then \
            return theString\
        end\
        return theString:sub(1, #theString - #theEnding)\
    end\
    \
    function dcsCommon.containsString(inString, what, caseSensitive)\
        if (not caseSensitive) then \
            inString = string.upper(inString)\
            what = string.upper(what)\
        end\
        if inString == what then return true end -- when entire match \
        return string.find(inString, what)\
    end\
    \
    function dcsCommon.bool2Text(theBool) \
        if not theBool then theBool = false end \
        if theBool then return \"true\" end \
        return \"false\"\
    end\
    \
    function dcsCommon.bool2YesNo(theBool)\
        if not theBool then theBool = false end \
        if theBool then return \"yes\" end \
        return \"no\"\
    end\
\
    function dcsCommon.point2text(p) \
        if not p then return \"<!NIL!>\" end \
        local t = \"[x=\"\
        if p.x then t = t .. p.x .. \", \" else t = t .. \"<nil>, \" end \
        if p.y then t = t .. p.y .. \", \" else t = t .. \"<nil>, \" end \
        if p.z then t = t .. p.z .. \"]\" else t = t .. \"<nil>]\" end \
        return t \
    end\
\
    function dcsCommon.string2GroupCat(inString)\
\
        if not inString then return 2 end -- default ground \
        inString = inString:lower()\
        inString = dcsCommon.trim(inString)\
\
        local catNum = tonumber(inString)\
        if catNum then \
            if catNum < 0 then catNum = 0 end \
            if catNum > 4 then catNum = 4 end \
            return catNum \
        end\
    \
        catNum = 2 -- ground default \
        if dcsCommon.stringStartsWith(inString, \"grou\") then catNum = 2 end \
        if dcsCommon.stringStartsWith(inString, \"air\") then catNum = 0 end\
        if dcsCommon.stringStartsWith(inString, \"hel\") then catNum = 1 end\
        if dcsCommon.stringStartsWith(inString, \"shi\") then catNum = 3 end\
        if dcsCommon.stringStartsWith(inString, \"trai\") then catNum = 4 end\
\
        return catNum\
    end\
\
    function dcsCommon.string2ObjectCat(inString)\
\
        if not inString then return 3 end -- default static \
        inString = inString:lower()\
        inString = dcsCommon.trim(inString)\
\
        local catNum = tonumber(inString)\
        if catNum then \
            if catNum < 0 then catNum = 0 end \
            if catNum > 6 then catNum = 6 end \
            return catNum \
        end\
    \
        catNum = 3 -- static default \
        if dcsCommon.stringStartsWith(inString, \"uni\") then catNum = 1 end \
        if dcsCommon.stringStartsWith(inString, \"wea\") then catNum = 2 end\
        if dcsCommon.stringStartsWith(inString, \"bas\") then catNum = 4 end\
        if dcsCommon.stringStartsWith(inString, \"sce\") then catNum = 5 end\
        if dcsCommon.stringStartsWith(inString, \"car\") then catNum = 6 end\
\
        return catNum\
    end\
\
    -- recursively show the contents of a variable\
    function dcsCommon.dumpVar(key, value, prefix, inrecursion)\
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            env.info(\"*** dcsCommon vardump START\")\
        end\
        if not value then value = \"nil\" end\
        if not prefix then prefix = \"\" end\
        prefix = \" \" .. prefix\
        if type(value) == \"table\" then \
            env.info(prefix .. key .. \": [ \")\
            -- iterate through all kvp\
            for k,v in pairs (value) do\
                dcsCommon.dumpVar(k, v, prefix, true)\
            end\
            env.info(prefix .. \" ] - end \" .. key)\
            \
        elseif type(value) == \"boolean\" then \
            local b = \"false\"\
            if value then b = \"true\" end\
            env.info(prefix .. key .. \": \" .. b)\
            \
        else -- simple var, show contents, ends recursion\
            env.info(prefix .. key .. \": \" .. value)\
        end\
        \
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"=== dcsCommon vardump END\", 30)\
            env.info(\"=== dcsCommon vardump END\")\
        end\
    end\
    \
    function dcsCommon.dumpVar2Str(key, value, prefix, inrecursion)\
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"*** dcsCommon vardump START\",30)\
        end\
        if not value then value = \"nil\" end\
        if not prefix then prefix = \"\" end\
        prefix = \" \" .. prefix\
        if type(value) == \"table\" then \
            trigger.action.outText(prefix .. key .. \": [ \", 30)\
            -- iterate through all kvp\
            for k,v in pairs (value) do\
                dcsCommon.dumpVar2Str(k, v, prefix, true)\
            end\
            trigger.action.outText(prefix .. \" ] - end \" .. key, 30)\
            \
        elseif type(value) == \"boolean\" then \
            local b = \"false\"\
            if value then b = \"true\" end\
            trigger.action.outText(prefix .. key .. \": \" .. b, 30)\
            \
        else -- simple var, show contents, ends recursion\
            trigger.action.outText(prefix .. key .. \": \" .. value, 30)\
        end\
        \
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"=== dcsCommon vardump END\", 30)\
            --env.info(\"=== dcsCommon vardump END\")\
        end\
    end\
    \
\
    dcsCommon.simpleUUID = 76543 -- a number to start. as good as any\
    function dcsCommon.numberUUID()\
        dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1\
        return dcsCommon.simpleUUID\
    end\
\
    function dcsCommon.uuid(prefix)\
        dcsCommon.uuIdent = dcsCommon.uuIdent + 1\
        if not prefix then prefix = dcsCommon.uuidStr end\
        return prefix .. \"-\" .. dcsCommon.uuIdent\
    end\
    \
    function dcsCommon.event2text(id) \
        if not id then return \"error\" end\
        if id == 0 then return \"invalid\" end\
        -- translate the event id to text\
        local events = {\"shot\", \"hit\", \"takeoff\", \"land\",\
                        \"crash\", \"eject\", \"refuel\", \"dead\",\
                        \"pilot dead\", \"base captured\", \"mission start\", \"mission end\", -- 12\
                        \"took control\", \"refuel stop\", \"birth\", \"human failure\", \
                        \"det. failure\", \"engine start\", \"engine stop\", \"player enter unit\",\
                        \"player leave unit\", \"player comment\", \"start shoot\", \"end shoot\",\
                        \"mark add\", \"mark changed\", \"makr removed\", \"kill\", \
                        \"score\", \"unit lost\", \"land after eject\", \"Paratrooper land\", \
                        \"chair discard after eject\", \"weapon add\", \"trigger zone\", \"landing quality mark\",\
                        \"BDA\", \"max\"}\
        if id > #events then return \"Unknown (ID=\" .. id .. \")\" end\
        return events[id]\
    end\
\
    function dcsCommon.smokeColor2Text(smokeColor)\
        if (smokeColor == 0) then return \"Green\" end\
        if (smokeColor == 1) then return \"Red\" end\
        if (smokeColor == 2) then return \"White\" end\
        if (smokeColor == 3) then return \"Orange\" end\
        if (smokeColor == 4) then return \"Blue\" end\
        \
        return (\"unknown: \" .. smokeColor)\
    end\
    \
    function dcsCommon.smokeColor2Num(smokeColor)\
        if not smokeColor then smokeColor = \"green\" end \
        if type(smokeColor) ~= \"string\" then return 0 end \
        smokeColor = smokeColor:lower()\
        if (smokeColor == \"green\") then return 0 end \
        if (smokeColor == \"red\") then return 1 end \
        if (smokeColor == \"white\") then return 2 end \
        if (smokeColor == \"orange\") then return 3 end \
        if (smokeColor == \"blue\") then return 4 end \
        return 0\
    end\
    \
    function dcsCommon.markPointWithSmoke(p, smokeColor)\
        local x = p.x \
        local z = p.z -- do NOT change the point directly\
        -- height-correct\
        local y = land.getHeight({x = x, y = z})\
        local newPoint= {x = x, y = y + 2, z = z}\
        trigger.action.smoke(newPoint, smokeColor)\
    end\
\
--\
--\
-- V E C T O R   M A T H \
--\
--\
function dcsCommon.vAdd(a, b) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    r.x = a.x + b.x \
    r.y = a.y + b.y \
    r.z = a.z + b.z \
    return r \
end\
\
function dcsCommon.vSub(a, b) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    r.x = a.x - b.x \
    r.y = a.y - b.y \
    r.z = a.z - b.z \
    return r \
end\
\
function dcsCommon.vMultScalar(a, f) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not f then f = 0 end\
    r.x = a.x * f \
    r.y = a.y * f \
    r.z = a.z * f \
    return r \
end\
\
function dcsCommon.vLerp (a, b, t)\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    \
    local d = dcsCommon.vSub(b, a)\
    local dt = dcsCommon.vMultScalar(d, t)\
    local r = dcsCommon.vAdd(a, dt)\
    return r\
end\
\
function dcsCommon.mag(x, y, z) \
    if not x then x = 0 end\
    if not y then y = 0 end \
    if not z then z = 0 end \
    \
    return (x * x + y * y + z * z)^0.5\
end\
\
function dcsCommon.vMag(a) \
    if not a then return 0 end \
    if not a.x then a.x = 0 end \
    if not a.y then a.y = 0 end \
    if not a.z then a.z = 0 end\
    return dcsCommon.mag(a.x, a.y, a.z) \
end\
\
function dcsCommon.magSquare(x, y, z) \
    if not x then x = 0 end\
    if not y then y = 0 end \
    if not z then z = 0 end \
    \
    return (x * x + y * y + z * z)\
end\
\
function dcsCommon.vNorm(a) \
    if not a then return {x = 0, y = 0, z = 0} end \
    m = dcsCommon.vMag(a)\
    if m <= 0 then return {x = 0, y = 0, z = 0} end \
    local r = {}\
    r.x = a.x / m \
    r.y = a.y / m \
    r.z = a.z / m\
    return r \
end\
\
function dcsCommon.dot (a, b) \
    if not a then a = {} end \
    if not a.x then a.x = 0 end \
    if not a.y then a.y = 0 end \
    if not a.z then a.z = 0 end\
    if not b then b = {} end \
    if not b.x then b.x = 0 end \
    if not b.y then b.y = 0 end \
    if not b.z then b.z = 0 end \
    \
    return a.x * b.x + a.y * b.y + a.z * b.z \
end\
--\
-- UNIT MISC\
-- \
function dcsCommon.isSceneryObject(theUnit)\
    if not theUnit then return false end\
    return theUnit.getCoalition == nil -- scenery objects do not return a coalition \
end\
\
function dcsCommon.isTroopCarrier(theUnit)\
    -- return true if conf can carry troups\
    if not theUnit then return false end \
    local uType = theUnit:getTypeName()\
    if dcsCommon.arrayContainsString(dcsCommon.troopCarriers, uType) then \
        -- may add additional tests before returning true\
        return true\
    end\
    return false\
end\
\
function dcsCommon.getUnitAlt(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local p = theUnit:getPoint()\
    return p.y \
end\
\
function dcsCommon.getUnitAGL(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local p = theUnit:getPoint()\
    local alt = p.y \
    local loc = {x = p.x, y = p.z}\
    local landElev = land.getHeight(loc)\
    return alt - landElev\
end \
\
function dcsCommon.getUnitSpeed(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local v = theUnit:getVelocity()\
    return dcsCommon.mag(v.x, v.y, v.z)\
end\
\
-- closing velocity of u1 and u2, seen from u1\
function dcsCommon.getClosingVelocity(u1, u2)\
    if not u1 then return 0 end \
    if not u2 then return 0 end \
    if not u1:isExist() then return 0 end \
    if not u2:isExist() then return 0 end \
    local v1 = u1:getVelocity()\
    local v2 = u2:getVelocity()\
    local dV = dcsCommon.vSub(v1,v2)\
    local a = u1:getPoint()\
    local b = u2:getPoint() \
    local aMinusB = dcsCommon.vSub(a,b) -- vector from u2 to u1\
    local abMag = dcsCommon.vMag(aMinusB) -- distance u1 to u2 \
    if abMag < .0001 then return 0 end \
    -- project deltaV onto vector from u2 to u1 \
    local vClose = dcsCommon.dot(dV, aMinusB) / abMag \
    return vClose \
end\
\
function dcsCommon.getGroupAvgSpeed(theGroup)\
    if not theGroup then return 0 end \
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \
    local totalSpeed = 0\
    local cnt = 0 \
    local livingUnits = theGroup:getUnits()\
    for idx, theUnit in pairs(livingUnits) do \
        cnt = cnt + 1\
        totalSpeed = totalSpeed + dcsCommon.getUnitSpeed(theUnit)\
    end \
    if cnt == 0 then return 0 end \
    return totalSpeed / cnt \
end\
 \
function dcsCommon.getGroupMaxSpeed(theGroup)\
    if not theGroup then return 0 end \
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \
    local maxSpeed = 0\
    local livingUnits = theGroup:getUnits()\
    for idx, theUnit in pairs(livingUnits) do \
        currSpeed = dcsCommon.getUnitSpeed(theUnit)\
        if currSpeed > maxSpeed then maxSpeed = currSpeed end \
    end \
    return maxSpeed\
end \
\
function dcsCommon.getUnitHeading(theUnit)\
    if not theUnit then return 0 end \
    if not theUnit:isExist() then return 0 end \
    local pos = theUnit:getPosition() -- returns three vectors, p is location\
\
    local heading = math.atan2(pos.x.z, pos.x.x)\
    -- make sure positive only, add 260 degrees\
    if heading < 0 then\
        heading = heading + 2 * math.pi    -- put heading in range of 0 to 2*pi\
    end\
    return heading \
end\
\
function dcsCommon.getUnitHeadingDegrees(theUnit)\
    local heading = dcsCommon.getUnitHeading(theUnit)\
    return heading * 57.2958 -- 180 / math.pi \
end\
\
function dcsCommon.unitIsInfantry(theUnit)\
    if not theUnit then return false end \
    if not theUnit:isExist() then return end\
    local theType = theUnit:getTypeName()\
    local isInfantry =  \
                dcsCommon.containsString(theType, \"infantry\", false) or \
                dcsCommon.containsString(theType, \"paratrooper\", false) or\
                dcsCommon.containsString(theType, \"stinger\", false) or\
                dcsCommon.containsString(theType, \"manpad\", false) or\
                dcsCommon.containsString(theType, \"soldier\", false) or \
                dcsCommon.containsString(theType, \"SA-18 Igla\", false)\
    return isInfantry\
end\
\
function dcsCommon.coalition2county(inCoalition)\
    -- simply return UN troops for 0 neutral,\
    -- joint red for 1  red\
    -- joint blue for 2 blue \
    if inCoalition == 1 then return 81 end -- cjtf red\
    if inCoalition == 2 then return 80 end -- blue \
    if type(inCoalition) == \"string\" then \
            inCoalition = inCoalition:lower()\
            if inCoalition == \"red\" then return 81 end\
            if inCoalition == \"blue\" then return 80 end\
    end\
        \
    trigger.action.outText(\"+++dcsC: coalition2county in (\" .. inCoalition .. \") converts to UN (82)!\", 30)\
    return 82 -- UN \
    \
end\
\
--\
--\
-- INIT\
--\
--\
    -- init any variables the lib requires internally\
    function dcsCommon.init()\
        cbID = 0\
        dcsCommon.uuIdent = 0\
        if (dcsCommon.verbose) or true then\
          trigger.action.outText(\"dcsCommon v\" .. dcsCommon.version .. \" loaded\", 10)\
        end\
    end\
\
    \
-- do init. \
dcsCommon.init()\
\
--[[--\
\
to do: \
- formation 2Column\
- formation 3Column\
\
-]]--\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [1]
                [2] = 
                {
                    ["text"] = "-- cf/x zone management module\
-- reads dcs zones and makes them accessible and mutable \
-- by scripting.\
--\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\
--\
\
cfxZones = {}\
cfxZones.version = \"2.7.0\"\
--[[-- VERSION HISTORY\
 - 2.2.4 - getCoalitionFromZoneProperty\
         - getStringFromZoneProperty\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \
 - 2.2.8 - getBoolFromZoneProperty supports default \
         - cfxZones.hasProperty\
 - 2.3.0 - property names are case insensitive \
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \
         - markZoneWithSmoke raised by 3 meters\
 - 2.4.2 - getClosestZone also returns delta \
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \
           createUniqueZoneName()\
           getStringFromZoneProperty returns default if property value = \"\"\
           corrected bug in addZoneToManagedZones\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\
         - linkUnit can use \"useOffset\" property to keep relative position\
 - 2.4.5 - updated various methods to support getPoint when referencing \
           zone.point  \
 - 2.4.6 - corrected spelling in markZoneWithSmoke\
 - 2.4.7 - copy reference to dcs zone into cfx zone \
 - 2.4.8 - getAllZoneProperties\
 - 2.4.9 - createSimpleZone no longer requires location \
         - parse dcs adds empty .properties = {} if none tehre \
         - createCircleZone adds empty properties \
         - createPolyZone adds empty properties \
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\
          - getBoolFromZoneProperty also recognizes 0, 1\
          - removed autostart\
 - 2.4.11 - removed typo in get closest zone \
 - 2.4.12 - getStringFromZoneProperty\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \
 - 2.5.2  - getPoint also writes through to zone itself for optimization\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
 - 2.5.3  - new getAllGroupsInZone()\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \
          - extractPropertyFromDCS trims key and property \
 - 2.5.5  - pollFlag() centralized for banging \
          - allStaticsInZone\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \
          - pollFlag supports theZone as final parameter\
          - randomDelayFromPositiveRange\
          - isMEFlag\
 - 2.5.7  - pollFlag supports dml flags\
 - 2.5.8  - flagArrayFromString\
          - getFlagNumber invokes tonumber() before returning result \
 - 2.5.9  - removed pass-back flag in getPoint() \
 - 2.6.0  - testZoneFlag() method based flag testing\
 - 2.6.1  - Watchflag parsing of zone condition for number-named flags\
          - case insensitive\
          - verbose for zone-local accepted (but not acted upon)\
          - hasProperty now offers active information when looking for '*?' and '*!'\
 - 2.7.0  - doPollFlag - fully support multiple flags per bang!\
 - 2.7.1  - setFlagValueMult()\
 \
--]]--\
cfxZones.verbose = false\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \
cfxZones.ups = 1 -- updates per second. updates moving zones\
\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\
\
-- a zone has the following attributes\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\
-- radius (zero if quad zone)\
-- isCircle (true if quad zone)\
-- poly the quad coords are in the poly attribute and are a \
-- 1..n, wound counter-clockwise as (currently) in DCS:\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \
--          for both circle and poly, all (x, 0, z)\
\
-- zones can carry information in their names that can get processed into attributes\
-- use \
-- zones can also carry information in their 'properties' tag that ME allows to \
-- edit. cfxZones provides an easy method to access these properties \
--  - getZoneProperty (returns as string)\
--  - getMinMaxFromZoneProperty\
--  - getBoolFromZoneProperty\
--  - getNumberFromZoneProperty\
\
\
-- SUPPORTED PROPERTIES\
-- - \"linkedUnit\" - zone moves with unit of that name. must be exact match\
--   can be combined with other attributes that extend (e.g. scar manager and\
--   limited pilots/airframes \
--\
\
--\
-- readZonesFromDCS is executed exactly once at the beginning\
-- from then on, use only the cfxZones.zones table \
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \
-- indexed by upper case. If you have two zones with same name but \
-- different case, one will be replaced\
--\
\
function cfxZones.readFromDCS(clearfirst)\
    if (clearfirst) then\
        cfxZones.zones = {}\
    end\
    -- not all missions have triggers or zones\
    if not env.mission.triggers then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no env.triggers defined\", 10)\
        end\
        return\
    end\
    \
    if not env.mission.triggers.zones then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no zones defined\", 10)\
        end\
        return;\
    end\
\
    -- we only retrieve the data we need. At this point it is name, location and radius\
    -- and put this in our own little  structure. we also convert to all upper case name for index\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\
    -- so we can quickly create other sets from this\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\
    --   name - name in upper case\
    --   isCircle - true if circular zone \
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\
    --   radius - number, zero when quad\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\
    --   poly - array 1..n of poly points, wound counter-clockwise \
    \
    for i, dcsZone in pairs(env.mission.triggers.zones) do\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\
                                         -- dcs data is like a box of chocolates...\
            local newZone = {}\
            -- name, converted to upper is used only for indexing\
            -- the original name remains untouched\
            newZone.dcsZone = dcsZone\
            newZone.name = dcsZone.name\
            newZone.isCircle = false\
            newZone.isPoly = false\
            newZone.radius = 0\
            newZone.poly = {}\
            newZone.bounds = {}\
            newZone.properties = {} -- dcs has this too, copy if present\
            if dcsZone.properties then \
                newZone.properties = dcsZone.properties \
            else\
                newZone.properties = {}\
            end -- WARNING: REF COPY. May need to clone \
            \
            local upperName = newZone.name:upper()\
            \
            -- location as 'point'\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\
            --          altitude (they are an infinite cylinder) this works. Remember to \
            --          drop y from zone calculations to see if inside. \
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\
\
\
            -- start type processing. if zone.type exists, we have a mission \
            -- created with 2.7 or above, else earlier \
            local zoneType = 0\
            if (dcsZone.type) then \
                zoneType = dcsZone.type \
            end\
            \
            if zoneType == 0 then \
                -- circular zone \
                newZone.isCircle = true \
                newZone.radius = dcsZone.radius\
    \
            elseif zoneType == 2 then\
                -- polyZone\
                newZone.isPoly = true \
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\
                -- now transfer all point in the poly\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\
                -- correct vor this \
                local verts = {}\
                if dcsZone.verticies then verts = dcsZone.verticies \
                else \
                    -- in later versions, this was corrected\
                    verts = dcsZone.vertices -- see if this is ever called\
                end\
                \
                for v=1, #verts do\
                    local dcsPoint = verts[v]\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\
                    newZone.poly[v] = polyPoint\
                end\
            else \
                \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" unknown type \" .. zoneType, 10)\
            end\
            \
\
            -- calculate bounds\
            cfxZones.calculateZoneBounds(newZone) \
\
            -- add to my table\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\
            --trigger.action.outText(\"znd: procced \" .. newZone.name .. \" with radius \" .. newZone.radius, 30)\
        else\
            if cfxZones.verbose then \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" dropped\", 10)\
            end\
        end -- else var not a table\
        \
    end -- for all zones kvp\
end -- readFromDCS\
\
function cfxZones.calculateZoneBounds(theZone)\
    if not (theZone) then return \
    end\
    \
    local bounds = theZone.bounds -- copy ref!\
    \
    if theZone.isCircle then \
        -- aabb are easy: center +/- radius \
        local center = theZone.point\
        local radius = theZone.radius \
        -- dcs uses z+ is down on map\
        -- upper left is center - radius \
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\
        \
    elseif theZone.isPoly then\
        local poly = theZone.poly -- ref copy!\
        -- create the four points\
        local ll = cfxZones.createPointFromPoint(poly[1])\
        local lr = cfxZones.createPointFromPoint(poly[1])\
        local ul = cfxZones.createPointFromPoint(poly[1])\
        local ur = cfxZones.createPointFromPoint(poly[1])\
\
        -- now iterate through all points and adjust bounds accordingly \
        for v=2, #poly do \
             local vertex = poly[v]\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \
            \
        end\
        \
        -- now keep the new point references\
        -- and store them in the zone's bounds\
        bounds.ll = ll\
        bounds.lr = lr\
        bounds.ul = ul\
        bounds.ur = ur \
    else \
        -- huston, we have a problem\
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: calc bounds: zone \" .. theZone.name .. \" has unknown type\", 30)\
        end\
    end\
    \
end\
\
function cfxZones.createPoint(x, y, z)\
    local newPoint = {}\
    newPoint.x = x\
    newPoint.y = y\
    newPoint.z = z \
    return newPoint\
end\
\
function cfxZones.copyPoint(inPoint) \
    local newPoint = {}\
    newPoint.x = inPoint.x\
    newPoint.y = inPoint.y\
    newPoint.z = inPoint.z \
    return newPoint    \
end\
\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\
    return cP\
end\
\
function cfxZones.getHeightCorrectedZonePoint(theZone)\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\
end\
\
function cfxZones.createPointFromPoint(inPoint)\
    return cfxZones.copyPoint(inPoint)\
end\
\
function cfxZones.createPointFromDCSPoint(inPoint) \
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\
end\
\
\
function cfxZones.createRandomPointInsideBounds(bounds)\
    local x = math.random(bounds.ll.x, ur.x)\
    local z = math.random(bounds.ll.z, ur.z)\
    return cfxZones.createPoint(x, 0, z)\
end\
\
function cfxZones.addZoneToManagedZones(theZone)\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\
    cfxZones.zones[upperName] = theZone\
end\
\
function cfxZones.createUniqueZoneName(inName, searchSet)\
    if not inName then return nil end \
    if not searchSet then searchSet = cfxZones.zones end \
    inName = inName:upper()\
    while searchSet[inName] ~= nil do \
        inName = inName .. \"X\"\
    end\
    return inName\
end\
\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\
    if not radius then radius = 10 end\
    if not addToManaged then addToManaged = false end \
    if not location then \
        location = {}\
    end\
    if not location.x then location.x = 0 end \
    if not location.z then location.z = 0 end \
    \
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\
    \
    if addToManaged then \
        cfxZones.addZoneToManagedZones(newZone)\
    end\
    return newZone\
end\
\
function cfxZones.createCircleZone(name, x, z, radius) \
    local newZone = {}\
    newZone.isCircle = true\
    newZone.isPoly = false\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = radius\
    newZone.point = cfxZones.createPoint(x, 0, z)\
 \
    -- props \
    newZone.properties = {}\
    \
    -- calculate my bounds\
    cfxZones.calculateZoneBounds(newZone)\
    \
    return newZone\
end\
\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\
local newZone = {}\
    newZone.isCircle = false\
    newZone.isPoly = true\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = 0\
    -- copy poly\
    for v=1, #poly do \
        local theVertex = poly[v] \
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \
    end\
    \
    -- properties \
    newZone.properties = {}\
    \
    cfxZones.calculateZoneBounds(newZone)\
end\
\
\
\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\
    -- create a new circular zone with center placed inside inZone\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\
    -- inZone.\
    \
--    trigger.action.outText(\"Zones: creating rZiZ with tr = \" .. targetRadius .. \" for \" .. inZone.name .. \" that as r = \" .. inZone.radius, 10)\
    \
    if inZone.isCircle then \
        local sourceRadius = inZone.radius\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\
    \
        -- ok, let's first create a random percentage value for the new radius\
        local percent = 1 / math.random(100)\
        -- now lets get a random degree\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \
        local r = sourceRadius * percent \
        local x = inZone.point.x + r * math.cos(degrees)\
        local z = inZone.point.z + r * math.sin(degrees)\
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\
        return newZone\
    \
    elseif inZone.isPoly then \
        -- we have a poly zone. the way we do this is simple:\
        -- generate random x, z with ranges of the bounding box \
        -- until the point falls within the polygon.\
        local newPoint = {}\
        local emergencyBrake = 0\
        repeat\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\
            emergencyBrake = emergencyBrake + 1\
            if (emergencyBrake > 100) then \
                newPoint = cfxZones.copyPoint(inZone.Point)\
                trigger.action.outText(\"CreateZoneInZone: mergency brake for inZone\" .. inZone.name,  10)\
                break\
            end\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\
        \
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\
        return newZone\
        \
    else \
        -- zone type unknown\
        trigger.action.outText(\"CreateZoneInZone: unknown zone type for inZone =\" .. inZone.name ,  10)\
        return nil \
    end\
end\
\
-- polygon inside zone calculations\
\
\
-- isleft returns true if point P is to the left of line AB \
-- by determining the sign (up or down) of the normal vector of \
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\
-- left as being > 0, so right is <= 0. As long as we always use the \
-- same comparison, it does not matter what up or down mean.\
-- this is important because we don't know if dcs always winds quads\
-- the same way, we must simply assume that they are wound as a polygon \
function cfxZones.isLeftXZ(A, B, P)\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\
end\
\
-- returns true/false for inside\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \
    -- Inside test (only convex polygons): \
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\
    -- how do we find out which side a point lies on? via the cross product\
    -- see isLeft below\
    \
    -- so all we need to do is make sure all results of isLeft for all\
    -- four sides are the same\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\
                                       -- they just must be the same side.\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\
    return true\
end\
\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\
function cfxZones.isPointInsidePoly(thePoint, poly)\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\
    for v=2, #poly-1 do \
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\
    end\
    -- final test\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\
    \
    return true\
end;\
\
function cfxZones.isPointInsideZone(thePoint, theZone)\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\
    if (theZone.isCircle) then \
        local zp = cfxZones.getPoint(theZone)\
        local d = dcsCommon.dist(p, theZone.point)\
        return d < theZone.radius\
    end \
    \
    if (theZone.isPoly) then \
        --trigger.action.outText(\"zne: isPointInside: \" .. theZone.name .. \" is Polyzone!\", 30)\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\
    end\
\
    trigger.action.outText(\"isPointInsideZone: Unknown zone type for \" .. outerZone.name, 10)\
end\
\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\
\
    \
end\
\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containerZones = {}\
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            table.insert(containerZones, tData)\
        end\
    end\
\
    return containerZones\
end\
\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            return tData\
        end\
    end\
\
    return nil\
end\
\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containedZones = {}\
    for zName, zData in pairs(testZones) do\
        if cfxZones.isZoneInsideZone(zData, superZone) then \
            if zData ~= superZone then \
                -- we filter superzone because superzone usually resides \
                -- inside itself \
                table.insert(containedZones, zData)\
            end\
        end\
    end\
    return containedZones \
end\
\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\
    if not testZones then testZones = cfxZones.zones end \
    local attributZones = {}\
    for aName,aZone in pairs(testZones) do\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\
        if attr then \
            -- this zone has the requested attribute\
            table.insert(attributZones, aZone)\
        end\
    end\
    return attributZones\
end\
\
--\
-- units / groups in zone\
--\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    --trigger.action.outText(\"Zone \" .. theZone.name .. \" radius \" .. theZone.radius, 30)\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allGroups = coalition.getGroups(coa, categ)\
        for key, group in pairs(allGroups) do -- iterate all groups\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(inZones, group)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allStats = coalition.getStaticObjects(coa)\
        for key, statO in pairs(allStats) do -- iterate all groups\
            local oP = statO:getPoint()\
            if cfxZones.pointInZone(oP, theZone) then\
                table.insert(inZones, statO)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\
    local groupsInZone = {}\
    local allGroups = coalition.getGroups(coal, categ)\
    for key, group in pairs(allGroups) do -- iterate all groups\
        if group:isExist() then\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(groupsInZone, group)            \
            end\
        end\
    end\
    return groupsInZone\
end\
\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
        \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then         \
            local p = aUnit:getPoint()\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \
                --trigger.action.outText(\"zne: YAY <\" .. aUnit:getName() .. \"> IS IN \" .. aZone.name, 30) \
                return true\
            end \
            --trigger.action.outText(\"zne: <\" .. aUnit:getName() .. \"> not in \" .. aZone.name .. \", dist = \" .. dist .. \", rad = \", aZone.radius, 30) \
        end\
    end\
    return false\
end\
\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then \
            local p = aUnit:getPoint()\
            if not cfxZones.isPointInsideZone(p, aZone) then \
                return false\
            end\
        end\
    end\
    return true\
end\
\
\
--\
-- Zone Manipulation\
--\
\
function cfxZones.offsetZone(theZone, dx, dz)\
    -- first, update center \
    theZone.point.x = theZone.point.x + dx\
    theZone.point.z = theZone.point.z + dz \
    \
    -- now process all polygon points - it's empty for circular, so don't worry\
    for v=1, #theZone.poly do \
        theZone.poly[v].x = theZone.poly[v].x + dx\
        theZone.poly[v].z = theZone.poly[v].z + dz \
    end\
end\
\
function cfxZones.moveZoneTo(theZone, x, z)\
    local dx = x - theZone.point.x\
    local dz = z - theZone.point.z \
    cfxZones.offsetZone(theZone, dx, dz)\
end;\
\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \
    local thePoint = theUnit:getPoint()\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\
end\
\
\
--[[\
-- no longer makes sense with poly zones\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\
    local reducedR = outerZone.radius - innerZone.radius\
    return d < reducedR\
end;\
--]]\
\
function cfxZones.dumpZones(zoneTable)\
    if not zoneTable then zoneTable = cfxZones.zones end \
    \
    trigger.action.outText(\"Zones START\", 10)\
    for i, zone in pairs(zoneTable) do \
        local myType = \"unknown\"\
        if zone.isCircle then myType = \"Circle\" end\
        if zone.isPoly then myType = \"Poly\" end \
        \
        trigger.action.outText(\"#\".. i .. \": \" .. zone.name .. \" of type \" .. myType, 10)\
    end\
    trigger.action.outText(\"Zones END\", 10)\
end\
\
function cfxZones.stringStartsWith(theString, thePrefix)\
    return theString:find(thePrefix) == 1\
end\
\
function cfxZones.keysForTable(theTable)\
    local keyset={}\
    local n=0\
\
    for k,v in pairs(tab) do\
        n=n+1\
        keyset[n]=k\
    end\
    return keyset\
end\
\
\
--\
-- return all zones that have a specific named property\
--\
function cfxZones.zonesWithProperty(propertyName, searchSet)\
    if not searchSet then searchSet = cfxZones.zones end \
    local theZones = {}\
    for k, aZone in pairs(searchSet) do \
        if not aZone then \
            trigger.action.outText(\"+++zone: nil aZone for \" .. k, 30)\
        else \
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\
            if lU then \
                table.insert(theZones, aZone)\
            end\
        end\
    end    \
    return theZones\
end\
\
--\
-- return all zones from the zone table that begin with string prefix\
--\
function cfxZones.zonesStartingWithName(prefix, searchSet)\
    \
    if not searchSet then searchSet = cfxZones.zones end \
    \
--    trigger.action.outText(\"Enter: zonesStartingWithName for \" .. prefix , 30)\
    local prefixZones = {}\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\
    for name, zone in pairs(searchSet) do\
--        trigger.action.outText(\"testing \" .. name:upper() .. \" starts with \" .. prefix , 30)\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\
            prefixZones[name] = zone -- note: ref copy!\
            --trigger.action.outText(\"zone with prefix <\" .. prefix .. \"> found: \" .. name, 10)\
        end\
    end\
    \
    return prefixZones\
end\
\
--\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\
-- with '+' and return only those. Use during debugging to force finding a specific zone\
--\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\
    -- you can force zones by having their name start with \"+\"\
    -- which will force them to return immediately if debugging is true for this call\
\
    if (debugging) then \
        local debugZones = cfxZones.zonesStartingWithName(\"+\", searchSet)\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \
            --trigger.action.outText(\"returning zones with prefix <\" .. prefix .. \">\", 10)\
            return debugZones \
        end \
    end\
    \
    --trigger.action.outText(\"#debugZones is  <\" .. #debugZones .. \">\", 10)\
\
    if (type(prefix) == \"string\") then \
        return cfxZones.zonesStartingWithName(prefix, searchSet)\
    end\
    \
    local allZones = {}\
    for i=1, #prefix do \
        -- iterate through all names in prefix set\
        local theName = prefix[i]\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\
        -- add them all to current table\
        for zName, zInfo in pairs(newZones) do \
            allZones[zName] = zInfo -- will also replace doublets\
        end\
    end\
    \
    return allZones\
end\
\
function cfxZones.getZoneByName(aName, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end \
    aName = aName:upper()\
    return searchSet[aName] -- the joys of key value pairs\
end\
\
function cfxZones.getZonesContainingString(aString, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end\
    aString = string.upper(aString)\
    resultSet = {}\
    for zName, zData in pairs(searchSet) do \
        if aString == string.upper(zData.name) then \
            resultSet[zName] = zData\
        end\
    end\
    \
end;\
\
-- filter zones by range to a point. returns indexed set\
function cfxZones.getZonesInRange(point, range, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    \
    local inRangeSet = {}\
    for zName, zData in pairs (theZones) do \
        if dcsCommon.dist(point, zData.point) < range then \
            table.insert(inRangeSet, zData)\
        end\
    end\
    return inRangeSet \
end\
\
-- get closest zone returns the zone that is closest to point \
function cfxZones.getClosestZone(point, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    local currDelta = math.huge \
    local closestZone = nil\
    for zName, zData in pairs(theZones) do \
        local zPoint = cfxZones.getPoint(zData)\
        local delta = dcsCommon.dist(point, zPoint)\
        if (delta < currDelta) then \
            currDelta = delta\
            closestZone = zData\
        end\
    end\
    return closestZone, currDelta \
end\
\
-- return a random zone from the table passed in zones\
function cfxZones.pickRandomZoneFrom(zones)\
    if not zones then zones = cfxZones.zones end\
    local indexedZones = dcsCommon.enumerateTable(zones)\
    local r = math.random(#indexedZones)\
    return indexedZones[r]\
end\
\
-- return an zone element by index \
function cfxZones.getZoneByIndex(theZones, theIndex) \
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\
    if (theIndex > #enumeratedZones) then\
        trigger.action.outText(\"WARNING: zone index \" .. theIndex .. \" out of bounds - max = \" .. #enumeratedZones, 30)\
        return nil end\
    if (theIndex < 1) then return nil end\
    \
    return enumeratedZones[theIndex]\
end\
\
-- place a smoke marker in center of zone, offset by dx, dy \
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
    if not alt then alt = 5 end \
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\
    point.x = point.x + dx -- getpoint updates and returns copy \
    point.z = point.z + dz \
    -- get height at point \
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\
    -- height-correct\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\
    trigger.action.smoke(point, smokeColor)\
end\
\
-- place a smoke marker in center of zone, offset by radius and degrees \
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\
    local rads = degrees * math.pi / 180\
    local dx = radius * math.sin(rads)\
    local dz = radius * math.cos(rads)\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
end\
\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\
    local degrees = math.random(360)\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\
end\
\
\
-- unitInZone returns true if theUnit is inside the zone \
-- the second value returned is the percentage of distance\
-- from center to rim, with 100% being entirely in center, 0 = outside\
-- the third value returned is the distance to center\
function cfxZones.pointInZone(thePoint, theZone)\
\
    if not (theZone) then return false, 0, 0 end\
        \
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\
    \
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \
    local ppoint = thePoint -- xyz\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\
    local dist = dcsCommon.dist(zpoint, pflat)\
    \
    if theZone.isCircle then \
        if theZone.radius <= 0 then \
            return false, 0, 0\
        end\
\
        local success = dist < theZone.radius\
        local percentage = 0\
        if (success) then \
            percentage = 1 - dist / theZone.radius \
        end\
        return success, percentage, dist \
    \
    elseif theZone.isPoly then\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\
        return success, 0, dist\
    else \
        trigger.action.outText(\"pointInZone: Unknown zone type for \" .. theZone.name, 10)\
    end\
\
    return false\
end\
\
function cfxZones.unitInZone(theUnit, theZone)\
    if not (theUnit) then return false, 0, 0 end\
    if not (theUnit:isExist()) then return false, 0, 0 end\
    -- force zone update if it is linked to another zone \
    -- pointInZone does update\
    local thePoint = theUnit:getPoint()\
    return cfxZones.pointInZone(thePoint, theZone)\
    \
end\
\
-- returns all units of the input set that are inside the zone \
function cfxZones.unitsInZone(theUnits, theZone)\
    if not theUnits then return {} end\
    if not theZone then return {} end\
    \
    local zoneUnits = {}\
    for index, aUnit in pairs(theUnits) do \
        if cfxZones.unitInZone(aUnit, theZone) then \
            table.insert( zoneUnits, aUnit)\
        end\
    end\
    return zoneUnits\
end\
\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\
    -- does not care if they really are in zone. call unitsInZone first\
    -- if you need to have them filtered\
    -- theUnits MUST BE ARRAY\
    if not theUnits then return nil end\
    if #theUnits == 0 then return nil end\
    local closestUnit = theUnits[1]\
    for i=2, #theUnits do\
        local aUnit = theUnits[i]\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \
            closestUnit = aUnit\
        end\
    end\
    return closestUnit\
end\
\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\
        local playerUnit = pinfo.unit\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \
            return true, playerUnit\
        end\
    end -- for all players \
    return false, nil\
end\
\
\
-- grow zone\
function cfxZones.growZone()\
    -- circular zones simply increase radius\
    -- poly zones: not defined \
    \
end\
\
\
-- creating units in a zone\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \
    -- theUnits can be string or table of string \
    if not groupName then groupName = \"G_\"..theZone.name end \
    -- group name will be taken from zone name and prependend with \"G_\"\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\
    \
    -- turn the entire formation to heading\
    if (not heading) then heading = 0 end\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\
    \
    \
    -- now move the group to center of theZone\
    dcsCommon.moveGroupDataTo(theGroup, \
                          theZone.point.x, \
                          theZone.point.z) -- watchit: Z!!!\
\
\
    -- create the group in the world and return it\
    -- first we need to translate the coalition to a legal \
    -- country. we use UN for neutral, cjtf for red and blue \
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\
\
end\
\
-- parsing zone names. The first part of the name until the first blank \" \" \
-- is the prefix and is dropped unless keepPrefix is true. \
-- all others are regarded as key:value pairs and are then added \
-- to the zone \
-- separated by equal sign \"=\" AND MUST NOT CONTAIN BLANKS\
--\
-- example usage \"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\
--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
-- \
--[[--\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\
--    trigger.action.outText(\"Parsing zone:  \".. theZone.name, 30)\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\
    -- now split the name into space-separated strings\
    local attributes = dcsCommon.splitString(theZone.name, \" \")\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\
\
    -- now parse all substrings and add them as attributes to theZone\
    for i=1, #attributes do \
        local a = attributes[i]\
        local kvp = dcsCommon.splitString(a, \"=\")\
        if #kvp == 2 then \
            -- we have key value pair\
            local theKey = kvp[1]\
            local theValue = kvp[2]\
            theZone[theKey] = theValue \
--            trigger.action.outText(\"Zone \".. theZone.name .. \" parsed: Key = \" .. theKey .. \", Value = \" .. theValue, 30)\
        else \
--            trigger.action.outText(\"Zone \".. theZone.name .. \": dropped attribute \" .. a, 30)\
        end\
    end \
end\
--]]--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
--[[--\
function cfxZones.processCraterZones ()\
    local craters = cfxZones.zonesStartingWith(\"crater\")\
\
    \
\
    -- all these zones need to be processed and their name infor placed into attributes\
    for cName, cZone in pairs(craters) do\
        cfxZones.parseZoneNameIntoAttributes(cZone)\
        \
        -- blow stuff up at the location of the zone \
        local cPoint = cZone.point\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\
        trigger.action.explosion(cPoint, 900)\
         \
        -- now interpret and act on the crater info \
        -- to destroy and place fire. \
        \
        -- fire has small, medium, large \
        -- eg. fire=large\
        \
    end\
end\
--]]--\
--\
-- Flag Pulling \
--\
function cfxZones.pollFlag(theFlag, method, theZone) \
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zones: polling flag \" .. theFlag .. \" with \" .. method, 30)\
    end \
    \
    if not theZone then \
        trigger.action.outText(\"+++zones: nil theZone on pollFlag\", 30)\
    end\
    \
    method = method:lower()\
    --trigger.action.outText(\"+++zones: polling \" .. theZone.name .. \" method \" .. method .. \" flag \" .. theFlag, 30)\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\
    if method == \"inc\" or method == \"f+1\" then \
        --trigger.action.setUserFlag(theFlag, currVal + 1)\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\
        \
    elseif method == \"dec\" or method == \"f-1\" then \
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\
\
    elseif method == \"off\" or method == \"f=0\" then \
        -- trigger.action.setUserFlag(theFlag, 0)\
        cfxZones.setFlagValue(theFlag, 0, theZone)\
\
    elseif method == \"flip\" or method == \"xor\" then \
        if currVal ~= 0 then \
--            trigger.action.setUserFlag(theFlag, 0)\
            cfxZones.setFlagValue(theFlag, 0, theZone)\
\
        else \
            --trigger.action.setUserFlag(theFlag, 1)\
            cfxZones.setFlagValue(theFlag, 1, theZone)\
        end\
        \
    else \
        if method ~= \"on\" and method ~= \"f=1\" then \
            trigger.action.outText(\"+++zones: unknown method <\" .. method .. \"> - using 'on'\", 30)\
        end\
        -- default: on.\
--        trigger.action.setUserFlag(theFlag, 1)\
        cfxZones.setFlagValue(theFlag, 1, theZone)\
\
    end\
    \
    if cfxZones.verbose then\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\
        trigger.action.outText(\"+++zones: flag <\" .. theFlag .. \"> changed from \" .. currVal .. \" to \" .. newVal, 30)\
    end \
end\
\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on setFlagValue\")\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight set, ME flag \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
        theFlag = zoneName .. theFlag\
    end\
    trigger.action.setUserFlag(theFlag, theValue)\
end \
\
function cfxZones.getFlagValue(theFlag, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on getFlagValue\", 30)\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight get, ME flag \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
            theFlag = zoneName .. theFlag\
    end\
    return tonumber(trigger.misc.getUserFlag(theFlag))\
end\
\
function cfxZones.isMEFlag(inFlag)\
    -- do NOT use me\
    trigger.action.outText(\"+++zne: warning: deprecated isMEFlag\", 30)\
    return true \
    -- returns true if inFlag is a pure positive number\
--    inFlag = dcsCommon.trim(inFlag)\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\
end\
\
-- method-based flag testing \
function cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\
    -- return true/false based on theMethod's contraints \
    -- simple constraints\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \
    local lMethod = string.lower(theMethod)\
    if lMethod == \"#\" or lMethod == \"change\" then \
        -- check if currVal different from lastVal\
        return currVal ~= lastVal  \
    end\
    \
    if lMethod == \"0\" or lMethod == \"no\" or lMethod == \"false\" \
       or lMethod == \"off\" then \
        -- WARNING: ONLY RETURNS TRUE IF FALSE AND lastval not zero!\
        return currVal == 0 and currVal ~= lastVal  \
    end\
    \
    if lMethod == \"1\" or lMethod == \"yes\" or lMethod == \"true\" \
       or lMethod == \"on\" then \
        -- WARNING: only returns true if lastval was false!!!!\
        return (currVal ~= 0 and lastVal == 0)  \
    end\
    \
    if lMethod == \"inc\" or lMethod == \"+1\" then \
        return currVal == lastVal+1\
    end\
    \
    if lMethod == \"dec\" or lMethod == \"-1\" then \
        return currVal == lastVal-1\
    end \
    \
    -- number constraints\
    -- or flag constraints \
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \
    local op = string.sub(theMethod, 1, 1) \
    local remainder = string.sub(theMethod, 2)\
    remainder = dcsCommon.trim(remainder) -- remove all leading and trailing spaces\
    local rNum = tonumber(remainder)\
    if not rNum then \
        -- we use remainder as name for flag \
        -- PROCESS ESCAPE SEQUENCES\
        local esc = string.sub(remainder, 1, 1)\
        local last = string.sub(remainder, -1)\
        if esc == \"@\" then \
            remainder = string.sub(remainder, 2)\
            remainder = dcsCommon.trim(remainder)\
        end\
        \
        if esc == \"(\" and last == \")\" and string.len(remainder) > 2 then \
            -- note: iisues with startswith(\"(\") ???\
            remainder = string.sub(remainder, 2, -2)\
            remainder = dcsCommon.trim(remainder)        \
        end\
        if esc == \"\\\"\" and last == \"\\\"\" and string.len(remainder) > 2 then \
            remainder = string.sub(remainder, 2, -2)\
            remainder = dcsCommon.trim(remainder)        \
        end\
        if cfxZones.verbose then \
            trigger.action.outText(\"+++zne: accessing flag <\" .. remainder .. \">\", 30)\
        end \
        rNum = cfxZones.getFlagValue(remainder, theZone)\
    end \
    if rNum then \
        -- we have a comparison = \">\", \"=\", \"<\" followed by a number \
        -- THEY TRIGGER EACH TIME lastVal <> currVal AND condition IS MET  \
        if op == \"=\" then \
            return currVal == rNum and lastVal ~= currVal\
        end\
        \
        if op == \"#\" or op == \"~\" then \
            return currVal ~= rNum and lastVal ~= currVal \
        end \
        \
        if op == \"<\" then \
            return currVal < rNum and lastVal ~= currVal\
        end\
        \
        if op == \">\" then \
            return currVal > rNum and lastVal ~= currVal\
        end\
    end\
    \
    -- if we get here, we have an error \
    local zoneName = \"<NIL>\"\
    if theZone then zoneName = theZone.name end \
    trigger.action.outText(\"+++Zne: illegal method constraints |\" .. theMethod .. \"| for zone \" .. zoneName, 30 )\
    return false \
end\
\
function cfxZones.testZoneFlag(theZone, theFlagName, theMethod, latchName)\
    -- returns true if method contraints are met for flag theFlagName\
    -- as defined by theMethod \
    if not theMethod then \
        theMethod = \"change\"\
    end \
    \
    -- will read and update theZone[latchName] as appropriate \
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone for testZoneFlag\", 30)\
        return\
    end \
    if not theFlagName then \
        -- this is common, no error, only on verbose \
        if cfxZones.verbose then \
            trigger.action.outText(\"+++Zne: no flagName for zone \" .. theZone.name .. \" for testZoneFlag\", 30)\
        end \
        return\
    end\
    if not latchName then \
        trigger.action.outText(\"+++Zne: no latchName for zone \" .. theZone.name .. \" for testZoneFlag\", 30)\
        return    \
    end\
    -- get current value \
    local currVal = cfxZones.getFlagValue(theFlagName, theZone)\
    \
    -- get last value from latch\
    local lastVal = theZone[latchName]\
    if not lastVal then \
        trigger.action.outText(\"+++Zne: latch <\" .. latchName .. \"> not valid for zone \" .. theZone.name, 30)\
        return \
    end\
    \
    -- now, test by method \
    -- we should only test if currVal <> lastVal \
    if currVal == lastVal then\
        return false \
    end \
    \
    --trigger.action.outText(\"+++Zne: about to test: c = \" .. currVal .. \", l = \" .. lastVal, 30)\
    local testResult = cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\
\
    -- update latch by method\
    theZone[latchName] = currVal \
\
    -- return result\
    return testResult\
end\
\
\
\
function cfxZones.flagArrayFromString(inString)\
-- original code from RND flag\
    if string.len(inString) < 1 then \
        trigger.action.outText(\"+++zne: empty flags\", 30)\
        return {} \
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: processing <\" .. inString .. \">\", 30)\
    end \
    \
    local flags = {}\
    local rawElements = dcsCommon.splitString(inString, \",\")\
    -- go over all elements \
    for idx, anElement in pairs(rawElements) do \
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \"-\") then \
            -- interpret this as a range\
            local theRange = dcsCommon.splitString(anElement, \"-\")\
            local lowerBound = theRange[1]\
            lowerBound = tonumber(lowerBound)\
            local upperBound = theRange[2]\
            upperBound = tonumber(upperBound)\
            if lowerBound and upperBound then\
                -- swap if wrong order\
                if lowerBound > upperBound then \
                    local temp = upperBound\
                    upperBound = lowerBound\
                    lowerBound = temp \
                end\
                -- now add add numbers to flags\
                for f=lowerBound, upperBound do \
                    table.insert(flags, tostring(f))\
                end\
            else\
                -- bounds illegal\
                trigger.action.outText(\"+++zne: ignored range <\" .. anElement .. \"> (range)\", 30)\
            end\
        else\
            -- single number\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\
            if f then \
                table.insert(flags, f)\
\
            else \
                trigger.action.outText(\"+++zne: ignored element <\" .. anElement .. \"> (single)\", 30)\
            end\
        end\
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: <\" .. #flags .. \"> flags total\", 30)\
    end \
    return flags\
end\
\
--\
-- PROPERTY PROCESSING \
--\
\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \
    if not caseInsensitive then caseInsensitive = false end \
    if not theZone then return {} end \
    \
    local dcsProps = theZone.properties -- zone properties in dcs format \
    local props = {}\
    -- dcs has all properties as array with values .key and .value \
    -- so convert them into a dictionary \
    for i=1, #dcsProps do \
        local theProp = dcsProps[i]\
        local theKey = \"dummy\"\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \
        if caseInsensitive then theKey = theKey:upper() end \
        props[theKey] = theProp.value\
    end\
    return props \
end\
\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\
-- trim\
    theKey = dcsCommon.trim(theKey) \
--    make lower case conversion if not case sensitive\
    if not cfxZones.caseSensitiveProperties then \
        theKey = string.lower(theKey)\
    end\
\
-- iterate all keys and compare to what we are looking for     \
    for i=1, #theProperties do\
        local theP = theProperties[i]\
         \
        local existingKey = dcsCommon.trim(theP.key)  \
        if not cfxZones.caseSensitiveProperties then \
            existingKey = string.lower(existingKey)\
        end\
        if existingKey == theKey then \
            return theP.value\
        end\
    end\
    return nil \
end\
\
function cfxZones.getZoneProperty(cZone, theKey)\
    if not cZone then \
        trigger.action.outText(\"+++zone: no zone in getZoneProperty\", 30)\
        return nil\
    end \
    if not theKey then \
        trigger.action.outText(\"+++zone: no property key in getZoneProperty for zone \" .. cZone.name, 30)\
--        breakme.here = 1\
        return \
    end    \
\
    local props = cZone.properties\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\
    return theVal\
end\
\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    \
    if not default then default = \"\" end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end\
    if type(p) == \"string\" then \
        if p == \"\" then p = default end \
        return p\
    end\
    return default -- warning. what if it was a number first?\
end\
\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    local theNumbers = dcsCommon.splitString(p, \" \")\
\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\
    \
end\
\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \
    if not maxVal then return minVal end \
    if not minVal then return maxVal end \
    local delay = maxVal\
    if minVal > 0 and minVal < delay then \
        -- we want a randomized from time from minTime .. delay\
        local varPart = delay - minVal + 1\
        varPart = dcsCommon.smallRandom(varPart) - 1\
        delay = minVal + varPart\
    end\
    return delay \
end\
\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
    -- reads property as string, and interprets as range 'a-b'. \
    -- if not a range but single number, returns both for upper and lower \
    --trigger.action.outText(\"***Zne: enter with <\" .. theZone.name .. \">: range for property <\" .. theProperty .. \">!\", 30)\
    if not default then default = 0 end \
    local lowerBound = default\
    local upperBound = default \
    \
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    if dcsCommon.containsString(rangeString, \"-\") then \
        local theRange = dcsCommon.splitString(rangeString, \"-\")\
        lowerBound = theRange[1]\
        lowerBound = tonumber(lowerBound)\
        upperBound = theRange[2]\
        upperBound = tonumber(upperBound)\
        if lowerBound and upperBound then\
            -- swap if wrong order\
            if lowerBound > upperBound then \
                local temp = upperBound\
                upperBound = lowerBound\
                lowerBound = temp \
            end\
--            if rndFlags.verbose then \
--            trigger.action.outText(\"+++Zne: detected range <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
--            end\
        else\
            -- bounds illegal\
            trigger.action.outText(\"+++Zne: illegal range  <\" .. rangeString .. \">, using \" .. default .. \"-\" .. default, 30)\
            lowerBound = default\
            upperBound = default \
        end\
    else \
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \
        lowerBound = upperBound\
    end\
--    trigger.action.outText(\"+++Zne: returning <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
    return lowerBound, upperBound\
end\
\
function cfxZones.hasProperty(theZone, theProperty) \
    return cfxZones.getZoneProperty(theZone, theProperty) ~= nil \
end\
\
\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\
    if not defaultVal then defaultVal = false end \
    if type(defaultVal) ~= \"boolean\" then \
        defaultVal = false \
    end\
\
    if not theZone then \
        trigger.action.outText(\"WARNING: NIL Zone in getBoolFromZoneProperty\", 30)\
        return defaultVal\
    end\
\
\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return defaultVal end\
\
    -- make sure we compare so default always works when \
    -- answer isn't exactly the opposite\
    p = p:lower() \
    if defaultVal == false then \
        -- only go true if exact match to yes or true \
        theBool = false \
        theBool = (p == 'true') or (p == 'yes') or p == \"1\"\
        return theBool\
    end\
    \
    local theBool = true \
    -- only go false if exactly no or false or \"0\"\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \"0\") \
    return theBool\
end\
\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end  \
    if type(p) == \"number\" then -- can't currently really happen\
        if p == 1 then return 1 end \
        if p == 2 then return 2 end \
        return 0\
    end\
    \
    if type(p) == \"string\" then \
        if p == \"1\" then return 1 end \
        if p == \"2\" then return 2 end \
        if p == \"0\" then return 0 end \
        \
        p = p:lower()\
        \
        if p == \"red\" then return 1 end \
        if p == \"blue\" then return 2 end \
        if p == \"neutral\" then return 0 end\
        if p == \"all\" then return 0 end \
        return default \
    end\
    \
    return default \
end\
\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\
--TODO: trim string \
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    p = tonumber(p)\
    if not p then return default else return p end\
end\
\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\
    if not minDims then minDims = 0 end \
    if not defaultVal then defaultVal = 0 end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    local sVec = dcsCommon.splitString(s, \",\")\
    local nVec = {}\
    for idx, numString in pairs (sVec) do \
        local n = tonumber(numString)\
        if not n then n = defaultVal end\
        table.insert(nVec, n)\
    end\
    -- make sure vector contains at least minDims values \
    while #nVec < minDims do \
        table.insert(nVec, defaultVal)\
    end\
    \
    return nVec \
end\
\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\
    if not default then default = \"red\" end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    s = s:lower()\
    s = dcsCommon.trim(s)\
    -- check numbers \
    if (s == \"0\") then return \"green\" end\
    if (s == \"1\") then return \"red\" end\
    if (s == \"2\") then return \"white\" end\
    if (s == \"3\") then return \"orange\" end\
    if (s == \"4\") then return \"blue\" end\
    \
    if s == \"green\" or\
       s == \"red\" or\
       s == \"white\" or\
       s == \"orange\" or\
       s == \"blue\" then return s end\
\
    return default \
end\
\
--\
-- Moving Zones. They contain a link to their unit\
-- they are always located at an offset (x,z) or delta, phi \
-- to their master unit. delta phi allows adjustment for heading\
-- The cool thing about moving zones in cfx is that they do not\
-- require special handling, they are always updated \
-- and work with 'pointinzone' etc automatically\
\
-- Always works on cfx Zones, NEVER on DCS zones.\
--\
-- requires that readFromDCS has been done\
--\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \
    if aZone.linkedUnit then \
        local theUnit = aZone.linkedUnit\
        -- has a link. is link existing?\
        if theUnit:isExist() then \
            -- updates zone position \
            cfxZones.centerZoneOnUnit(aZone, theUnit)\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
        end\
    end\
    local thePos = {}\
    thePos.x = aZone.point.x\
    thePos.y = 0 -- aZone.y \
    thePos.z = aZone.point.z\
    -- update the zone as well -- that's stupid!\
    --[[-- aZone.point = thePos \
    local retPoint = {} -- create new copy to pass back \
    retPoint.x = thePos.x\
    retPoint.y = 0 \
    retPoint.z = thePos.z\
    --]]--\
    return thePos \
end\
\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\
    theZone.linkedUnit = theUnit\
    if not dx then dx = 0 end\
    if not dy then dy = 0 end \
    theZone.dx = dx\
    theZone.dy = dy \
end\
\
function cfxZones.updateMovingZones()\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\
    -- simply scan all cfx zones for the linkedUnit property and if there\
    -- update the zone's points\
    for aName,aZone in pairs(cfxZones.zones) do\
        if aZone.linkedUnit then \
            local theUnit = aZone.linkedUnit\
            -- has a link. is link existing?\
            if theUnit:isExist() then \
                cfxZones.centerZoneOnUnit(aZone, theUnit)\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
                --trigger.action.outText(\"cf/x zones update \" .. aZone.name, 30)\
            end\
        end\
    end\
end\
\
function cfxZones.startMovingZones()\
    -- read all zoness, and look for a property called 'linkedUnit'\
    -- which will make them a linked zone if there is a unit that exists\
    for aName,aZone in pairs(cfxZones.zones) do\
        local lU = cfxZones.getZoneProperty(aZone, \"linkedUnit\")\
        if lU then \
            -- this zone is linked to a unit\
            theUnit = Unit.getByName(lU)\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \"useOffset\", false)\
            if useOffset then aZone.useOffset = true end\
            if theUnit then\
                local dx = 0\
                local dz = 0\
                if useOffset then \
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \
                    dx = delta.x \
                    dz = delta.z\
                end\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\
                --trigger.action.outText(\"cf/x zones: linked \" .. aZone.name .. \" to \" .. theUnit:getName(), 30)\
                if useOffset then \
                    --trigger.action.outText(\"and dx = \" .. dx .. \" dz = \" .. dz, 30)\
                end\
            end\
        end\
        -- support for local verbose flag \
        aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, \"verbose\", false)\
    end\
end\
\
--\
-- init\
--\
\
function cfxZones.init()\
    -- read all zones into my own db\
    cfxZones.readFromDCS(true) -- true: erase old\
    \
    -- now, pre-read zone owner for all zones\
    -- note, all zones with this property are by definition owned zones.\
    -- and hence will be read anyway. this will merely ensure that the \
    -- ownership is established right away\
    -- unless owned zones module is missing, in which case \
    -- ownership is still established \
    local pZones = cfxZones.zonesWithProperty(\"owner\")\
    for n, aZone in pairs(pZones) do\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \"owner\", 0)\
    end\
        \
    \
    -- now initialize moving zones\
    cfxZones.startMovingZones()\
    cfxZones.updateMovingZones() -- will auto-repeat\
    \
    trigger.action.outText(\"cf/x Zones v\".. cfxZones.version .. \": loaded\", 10)\
end\
\
-- get everything rolling\
cfxZones.init()\
-- cf/x zone management module\
-- reads dcs zones and makes them accessible and mutable \
-- by scripting.\
--\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\
--\
\
cfxZones = {}\
cfxZones.version = \"2.6.1\"\
--[[-- VERSION HISTORY\
 - 2.2.4 - getCoalitionFromZoneProperty\
         - getStringFromZoneProperty\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \
 - 2.2.8 - getBoolFromZoneProperty supports default \
         - cfxZones.hasProperty\
 - 2.3.0 - property names are case insensitive \
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \
         - markZoneWithSmoke raised by 3 meters\
 - 2.4.2 - getClosestZone also returns delta \
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \
           createUniqueZoneName()\
           getStringFromZoneProperty returns default if property value = \"\"\
           corrected bug in addZoneToManagedZones\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\
         - linkUnit can use \"useOffset\" property to keep relative position\
 - 2.4.5 - updated various methods to support getPoint when referencing \
           zone.point  \
 - 2.4.6 - corrected spelling in markZoneWithSmoke\
 - 2.4.7 - copy reference to dcs zone into cfx zone \
 - 2.4.8 - getAllZoneProperties\
 - 2.4.9 - createSimpleZone no longer requires location \
         - parse dcs adds empty .properties = {} if none tehre \
         - createCircleZone adds empty properties \
         - createPolyZone adds empty properties \
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\
          - getBoolFromZoneProperty also recognizes 0, 1\
          - removed autostart\
 - 2.4.11 - removed typo in get closest zone \
 - 2.4.12 - getStringFromZoneProperty\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \
 - 2.5.2  - getPoint also writes through to zone itself for optimization\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
 - 2.5.3  - new getAllGroupsInZone()\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \
          - extractPropertyFromDCS trims key and property \
 - 2.5.5  - pollFlag() centralized for banging \
          - allStaticsInZone\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \
          - pollFlag supports theZone as final parameter\
          - randomDelayFromPositiveRange\
          - isMEFlag\
 - 2.5.7  - pollFlag supports dml flags\
 - 2.5.8  - flagArrayFromString\
          - getFlagNumber invokes tonumber() before returning result \
 - 2.5.9  - removed pass-back flag in getPoint() \
 - 2.6.0  - testZoneFlag() method based flag testing\
 - 2.6.1  - Watchflag parsing of zone condition for number-named flags\
          - case insensitive  \
 \
--]]--\
cfxZones.verbose = false\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \
cfxZones.ups = 1 -- updates per second. updates moving zones\
\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\
\
-- a zone has the following attributes\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\
-- radius (zero if quad zone)\
-- isCircle (true if quad zone)\
-- poly the quad coords are in the poly attribute and are a \
-- 1..n, wound counter-clockwise as (currently) in DCS:\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \
--          for both circle and poly, all (x, 0, z)\
\
-- zones can carry information in their names that can get processed into attributes\
-- use \
-- zones can also carry information in their 'properties' tag that ME allows to \
-- edit. cfxZones provides an easy method to access these properties \
--  - getZoneProperty (returns as string)\
--  - getMinMaxFromZoneProperty\
--  - getBoolFromZoneProperty\
--  - getNumberFromZoneProperty\
\
\
-- SUPPORTED PROPERTIES\
-- - \"linkedUnit\" - zone moves with unit of that name. must be exact match\
--   can be combined with other attributes that extend (e.g. scar manager and\
--   limited pilots/airframes \
--\
\
--\
-- readZonesFromDCS is executed exactly once at the beginning\
-- from then on, use only the cfxZones.zones table \
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \
-- indexed by upper case. If you have two zones with same name but \
-- different case, one will be replaced\
--\
\
function cfxZones.readFromDCS(clearfirst)\
    if (clearfirst) then\
        cfxZones.zones = {}\
    end\
    -- not all missions have triggers or zones\
    if not env.mission.triggers then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no env.triggers defined\", 10)\
        end\
        return\
    end\
    \
    if not env.mission.triggers.zones then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no zones defined\", 10)\
        end\
        return;\
    end\
\
    -- we only retrieve the data we need. At this point it is name, location and radius\
    -- and put this in our own little  structure. we also convert to all upper case name for index\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\
    -- so we can quickly create other sets from this\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\
    --   name - name in upper case\
    --   isCircle - true if circular zone \
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\
    --   radius - number, zero when quad\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\
    --   poly - array 1..n of poly points, wound counter-clockwise \
    \
    for i, dcsZone in pairs(env.mission.triggers.zones) do\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\
                                         -- dcs data is like a box of chocolates...\
            local newZone = {}\
            -- name, converted to upper is used only for indexing\
            -- the original name remains untouched\
            newZone.dcsZone = dcsZone\
            newZone.name = dcsZone.name\
            newZone.isCircle = false\
            newZone.isPoly = false\
            newZone.radius = 0\
            newZone.poly = {}\
            newZone.bounds = {}\
            newZone.properties = {} -- dcs has this too, copy if present\
            if dcsZone.properties then \
                newZone.properties = dcsZone.properties \
            else\
                newZone.properties = {}\
            end -- WARNING: REF COPY. May need to clone \
            \
            local upperName = newZone.name:upper()\
            \
            -- location as 'point'\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\
            --          altitude (they are an infinite cylinder) this works. Remember to \
            --          drop y from zone calculations to see if inside. \
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\
\
\
            -- start type processing. if zone.type exists, we have a mission \
            -- created with 2.7 or above, else earlier \
            local zoneType = 0\
            if (dcsZone.type) then \
                zoneType = dcsZone.type \
            end\
            \
            if zoneType == 0 then \
                -- circular zone \
                newZone.isCircle = true \
                newZone.radius = dcsZone.radius\
    \
            elseif zoneType == 2 then\
                -- polyZone\
                newZone.isPoly = true \
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\
                -- now transfer all point in the poly\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\
                -- correct vor this \
                local verts = {}\
                if dcsZone.verticies then verts = dcsZone.verticies \
                else \
                    -- in later versions, this was corrected\
                    verts = dcsZone.vertices -- see if this is ever called\
                end\
                \
                for v=1, #verts do\
                    local dcsPoint = verts[v]\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\
                    newZone.poly[v] = polyPoint\
                end\
            else \
                \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" unknown type \" .. zoneType, 10)\
            end\
            \
\
            -- calculate bounds\
            cfxZones.calculateZoneBounds(newZone) \
\
            -- add to my table\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\
            --trigger.action.outText(\"znd: procced \" .. newZone.name .. \" with radius \" .. newZone.radius, 30)\
        else\
            if cfxZones.verbose then \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" dropped\", 10)\
            end\
        end -- else var not a table\
        \
    end -- for all zones kvp\
end -- readFromDCS\
\
function cfxZones.calculateZoneBounds(theZone)\
    if not (theZone) then return \
    end\
    \
    local bounds = theZone.bounds -- copy ref!\
    \
    if theZone.isCircle then \
        -- aabb are easy: center +/- radius \
        local center = theZone.point\
        local radius = theZone.radius \
        -- dcs uses z+ is down on map\
        -- upper left is center - radius \
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\
        \
    elseif theZone.isPoly then\
        local poly = theZone.poly -- ref copy!\
        -- create the four points\
        local ll = cfxZones.createPointFromPoint(poly[1])\
        local lr = cfxZones.createPointFromPoint(poly[1])\
        local ul = cfxZones.createPointFromPoint(poly[1])\
        local ur = cfxZones.createPointFromPoint(poly[1])\
\
        -- now iterate through all points and adjust bounds accordingly \
        for v=2, #poly do \
             local vertex = poly[v]\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \
            \
        end\
        \
        -- now keep the new point references\
        -- and store them in the zone's bounds\
        bounds.ll = ll\
        bounds.lr = lr\
        bounds.ul = ul\
        bounds.ur = ur \
    else \
        -- huston, we have a problem\
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: calc bounds: zone \" .. theZone.name .. \" has unknown type\", 30)\
        end\
    end\
    \
end\
\
function cfxZones.createPoint(x, y, z)\
    local newPoint = {}\
    newPoint.x = x\
    newPoint.y = y\
    newPoint.z = z \
    return newPoint\
end\
\
function cfxZones.copyPoint(inPoint) \
    local newPoint = {}\
    newPoint.x = inPoint.x\
    newPoint.y = inPoint.y\
    newPoint.z = inPoint.z \
    return newPoint    \
end\
\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\
    return cP\
end\
\
function cfxZones.getHeightCorrectedZonePoint(theZone)\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\
end\
\
function cfxZones.createPointFromPoint(inPoint)\
    return cfxZones.copyPoint(inPoint)\
end\
\
function cfxZones.createPointFromDCSPoint(inPoint) \
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\
end\
\
\
function cfxZones.createRandomPointInsideBounds(bounds)\
    local x = math.random(bounds.ll.x, ur.x)\
    local z = math.random(bounds.ll.z, ur.z)\
    return cfxZones.createPoint(x, 0, z)\
end\
\
function cfxZones.addZoneToManagedZones(theZone)\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\
    cfxZones.zones[upperName] = theZone\
end\
\
function cfxZones.createUniqueZoneName(inName, searchSet)\
    if not inName then return nil end \
    if not searchSet then searchSet = cfxZones.zones end \
    inName = inName:upper()\
    while searchSet[inName] ~= nil do \
        inName = inName .. \"X\"\
    end\
    return inName\
end\
\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\
    if not radius then radius = 10 end\
    if not addToManaged then addToManaged = false end \
    if not location then \
        location = {}\
    end\
    if not location.x then location.x = 0 end \
    if not location.z then location.z = 0 end \
    \
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\
    \
    if addToManaged then \
        cfxZones.addZoneToManagedZones(newZone)\
    end\
    return newZone\
end\
\
function cfxZones.createCircleZone(name, x, z, radius) \
    local newZone = {}\
    newZone.isCircle = true\
    newZone.isPoly = false\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = radius\
    newZone.point = cfxZones.createPoint(x, 0, z)\
 \
    -- props \
    newZone.properties = {}\
    \
    -- calculate my bounds\
    cfxZones.calculateZoneBounds(newZone)\
    \
    return newZone\
end\
\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\
local newZone = {}\
    newZone.isCircle = false\
    newZone.isPoly = true\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = 0\
    -- copy poly\
    for v=1, #poly do \
        local theVertex = poly[v] \
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \
    end\
    \
    -- properties \
    newZone.properties = {}\
    \
    cfxZones.calculateZoneBounds(newZone)\
end\
\
\
\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\
    -- create a new circular zone with center placed inside inZone\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\
    -- inZone.\
    \
--    trigger.action.outText(\"Zones: creating rZiZ with tr = \" .. targetRadius .. \" for \" .. inZone.name .. \" that as r = \" .. inZone.radius, 10)\
    \
    if inZone.isCircle then \
        local sourceRadius = inZone.radius\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\
    \
        -- ok, let's first create a random percentage value for the new radius\
        local percent = 1 / math.random(100)\
        -- now lets get a random degree\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \
        local r = sourceRadius * percent \
        local x = inZone.point.x + r * math.cos(degrees)\
        local z = inZone.point.z + r * math.sin(degrees)\
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\
        return newZone\
    \
    elseif inZone.isPoly then \
        -- we have a poly zone. the way we do this is simple:\
        -- generate random x, z with ranges of the bounding box \
        -- until the point falls within the polygon.\
        local newPoint = {}\
        local emergencyBrake = 0\
        repeat\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\
            emergencyBrake = emergencyBrake + 1\
            if (emergencyBrake > 100) then \
                newPoint = cfxZones.copyPoint(inZone.Point)\
                trigger.action.outText(\"CreateZoneInZone: mergency brake for inZone\" .. inZone.name,  10)\
                break\
            end\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\
        \
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\
        return newZone\
        \
    else \
        -- zone type unknown\
        trigger.action.outText(\"CreateZoneInZone: unknown zone type for inZone =\" .. inZone.name ,  10)\
        return nil \
    end\
end\
\
-- polygon inside zone calculations\
\
\
-- isleft returns true if point P is to the left of line AB \
-- by determining the sign (up or down) of the normal vector of \
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\
-- left as being > 0, so right is <= 0. As long as we always use the \
-- same comparison, it does not matter what up or down mean.\
-- this is important because we don't know if dcs always winds quads\
-- the same way, we must simply assume that they are wound as a polygon \
function cfxZones.isLeftXZ(A, B, P)\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\
end\
\
-- returns true/false for inside\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \
    -- Inside test (only convex polygons): \
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\
    -- how do we find out which side a point lies on? via the cross product\
    -- see isLeft below\
    \
    -- so all we need to do is make sure all results of isLeft for all\
    -- four sides are the same\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\
                                       -- they just must be the same side.\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\
    return true\
end\
\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\
function cfxZones.isPointInsidePoly(thePoint, poly)\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\
    for v=2, #poly-1 do \
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\
    end\
    -- final test\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\
    \
    return true\
end;\
\
function cfxZones.isPointInsideZone(thePoint, theZone)\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\
    if (theZone.isCircle) then \
        local zp = cfxZones.getPoint(theZone)\
        local d = dcsCommon.dist(p, theZone.point)\
        return d < theZone.radius\
    end \
    \
    if (theZone.isPoly) then \
        --trigger.action.outText(\"zne: isPointInside: \" .. theZone.name .. \" is Polyzone!\", 30)\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\
    end\
\
    trigger.action.outText(\"isPointInsideZone: Unknown zone type for \" .. outerZone.name, 10)\
end\
\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\
\
    \
end\
\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containerZones = {}\
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            table.insert(containerZones, tData)\
        end\
    end\
\
    return containerZones\
end\
\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            return tData\
        end\
    end\
\
    return nil\
end\
\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containedZones = {}\
    for zName, zData in pairs(testZones) do\
        if cfxZones.isZoneInsideZone(zData, superZone) then \
            if zData ~= superZone then \
                -- we filter superzone because superzone usually resides \
                -- inside itself \
                table.insert(containedZones, zData)\
            end\
        end\
    end\
    return containedZones \
end\
\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\
    if not testZones then testZones = cfxZones.zones end \
    local attributZones = {}\
    for aName,aZone in pairs(testZones) do\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\
        if attr then \
            -- this zone has the requested attribute\
            table.insert(attributZones, aZone)\
        end\
    end\
    return attributZones\
end\
\
--\
-- units / groups in zone\
--\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    --trigger.action.outText(\"Zone \" .. theZone.name .. \" radius \" .. theZone.radius, 30)\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allGroups = coalition.getGroups(coa, categ)\
        for key, group in pairs(allGroups) do -- iterate all groups\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(inZones, group)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allStats = coalition.getStaticObjects(coa)\
        for key, statO in pairs(allStats) do -- iterate all groups\
            local oP = statO:getPoint()\
            if cfxZones.pointInZone(oP, theZone) then\
                table.insert(inZones, statO)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\
    local groupsInZone = {}\
    local allGroups = coalition.getGroups(coal, categ)\
    for key, group in pairs(allGroups) do -- iterate all groups\
        if group:isExist() then\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(groupsInZone, group)            \
            end\
        end\
    end\
    return groupsInZone\
end\
\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
        \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then         \
            local p = aUnit:getPoint()\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \
                --trigger.action.outText(\"zne: YAY <\" .. aUnit:getName() .. \"> IS IN \" .. aZone.name, 30) \
                return true\
            end \
            --trigger.action.outText(\"zne: <\" .. aUnit:getName() .. \"> not in \" .. aZone.name .. \", dist = \" .. dist .. \", rad = \", aZone.radius, 30) \
        end\
    end\
    return false\
end\
\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then \
            local p = aUnit:getPoint()\
            if not cfxZones.isPointInsideZone(p, aZone) then \
                return false\
            end\
        end\
    end\
    return true\
end\
\
\
--\
-- Zone Manipulation\
--\
\
function cfxZones.offsetZone(theZone, dx, dz)\
    -- first, update center \
    theZone.point.x = theZone.point.x + dx\
    theZone.point.z = theZone.point.z + dz \
    \
    -- now process all polygon points - it's empty for circular, so don't worry\
    for v=1, #theZone.poly do \
        theZone.poly[v].x = theZone.poly[v].x + dx\
        theZone.poly[v].z = theZone.poly[v].z + dz \
    end\
end\
\
function cfxZones.moveZoneTo(theZone, x, z)\
    local dx = x - theZone.point.x\
    local dz = z - theZone.point.z \
    cfxZones.offsetZone(theZone, dx, dz)\
end;\
\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \
    local thePoint = theUnit:getPoint()\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\
end\
\
\
--[[\
-- no longer makes sense with poly zones\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\
    local reducedR = outerZone.radius - innerZone.radius\
    return d < reducedR\
end;\
--]]\
\
function cfxZones.dumpZones(zoneTable)\
    if not zoneTable then zoneTable = cfxZones.zones end \
    \
    trigger.action.outText(\"Zones START\", 10)\
    for i, zone in pairs(zoneTable) do \
        local myType = \"unknown\"\
        if zone.isCircle then myType = \"Circle\" end\
        if zone.isPoly then myType = \"Poly\" end \
        \
        trigger.action.outText(\"#\".. i .. \": \" .. zone.name .. \" of type \" .. myType, 10)\
    end\
    trigger.action.outText(\"Zones END\", 10)\
end\
\
function cfxZones.stringStartsWith(theString, thePrefix)\
    return theString:find(thePrefix) == 1\
end\
\
function cfxZones.keysForTable(theTable)\
    local keyset={}\
    local n=0\
\
    for k,v in pairs(tab) do\
        n=n+1\
        keyset[n]=k\
    end\
    return keyset\
end\
\
\
--\
-- return all zones that have a specific named property\
--\
function cfxZones.zonesWithProperty(propertyName, searchSet)\
    if not searchSet then searchSet = cfxZones.zones end \
    local theZones = {}\
    for k, aZone in pairs(searchSet) do \
        if not aZone then \
            trigger.action.outText(\"+++zone: nil aZone for \" .. k, 30)\
        else \
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\
            if lU then \
                table.insert(theZones, aZone)\
            end\
        end\
    end    \
    return theZones\
end\
\
--\
-- return all zones from the zone table that begin with string prefix\
--\
function cfxZones.zonesStartingWithName(prefix, searchSet)\
    \
    if not searchSet then searchSet = cfxZones.zones end \
    \
--    trigger.action.outText(\"Enter: zonesStartingWithName for \" .. prefix , 30)\
    local prefixZones = {}\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\
    for name, zone in pairs(searchSet) do\
--        trigger.action.outText(\"testing \" .. name:upper() .. \" starts with \" .. prefix , 30)\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\
            prefixZones[name] = zone -- note: ref copy!\
            --trigger.action.outText(\"zone with prefix <\" .. prefix .. \"> found: \" .. name, 10)\
        end\
    end\
    \
    return prefixZones\
end\
\
--\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\
-- with '+' and return only those. Use during debugging to force finding a specific zone\
--\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\
    -- you can force zones by having their name start with \"+\"\
    -- which will force them to return immediately if debugging is true for this call\
\
    if (debugging) then \
        local debugZones = cfxZones.zonesStartingWithName(\"+\", searchSet)\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \
            --trigger.action.outText(\"returning zones with prefix <\" .. prefix .. \">\", 10)\
            return debugZones \
        end \
    end\
    \
    --trigger.action.outText(\"#debugZones is  <\" .. #debugZones .. \">\", 10)\
\
    if (type(prefix) == \"string\") then \
        return cfxZones.zonesStartingWithName(prefix, searchSet)\
    end\
    \
    local allZones = {}\
    for i=1, #prefix do \
        -- iterate through all names in prefix set\
        local theName = prefix[i]\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\
        -- add them all to current table\
        for zName, zInfo in pairs(newZones) do \
            allZones[zName] = zInfo -- will also replace doublets\
        end\
    end\
    \
    return allZones\
end\
\
function cfxZones.getZoneByName(aName, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end \
    aName = aName:upper()\
    return searchSet[aName] -- the joys of key value pairs\
end\
\
function cfxZones.getZonesContainingString(aString, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end\
    aString = string.upper(aString)\
    resultSet = {}\
    for zName, zData in pairs(searchSet) do \
        if aString == string.upper(zData.name) then \
            resultSet[zName] = zData\
        end\
    end\
    \
end;\
\
-- filter zones by range to a point. returns indexed set\
function cfxZones.getZonesInRange(point, range, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    \
    local inRangeSet = {}\
    for zName, zData in pairs (theZones) do \
        if dcsCommon.dist(point, zData.point) < range then \
            table.insert(inRangeSet, zData)\
        end\
    end\
    return inRangeSet \
end\
\
-- get closest zone returns the zone that is closest to point \
function cfxZones.getClosestZone(point, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    local currDelta = math.huge \
    local closestZone = nil\
    for zName, zData in pairs(theZones) do \
        local zPoint = cfxZones.getPoint(zData)\
        local delta = dcsCommon.dist(point, zPoint)\
        if (delta < currDelta) then \
            currDelta = delta\
            closestZone = zData\
        end\
    end\
    return closestZone, currDelta \
end\
\
-- return a random zone from the table passed in zones\
function cfxZones.pickRandomZoneFrom(zones)\
    if not zones then zones = cfxZones.zones end\
    local indexedZones = dcsCommon.enumerateTable(zones)\
    local r = math.random(#indexedZones)\
    return indexedZones[r]\
end\
\
-- return an zone element by index \
function cfxZones.getZoneByIndex(theZones, theIndex) \
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\
    if (theIndex > #enumeratedZones) then\
        trigger.action.outText(\"WARNING: zone index \" .. theIndex .. \" out of bounds - max = \" .. #enumeratedZones, 30)\
        return nil end\
    if (theIndex < 1) then return nil end\
    \
    return enumeratedZones[theIndex]\
end\
\
-- place a smoke marker in center of zone, offset by dx, dy \
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
    if not alt then alt = 5 end \
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\
    point.x = point.x + dx -- getpoint updates and returns copy \
    point.z = point.z + dz \
    -- get height at point \
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\
    -- height-correct\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\
    trigger.action.smoke(point, smokeColor)\
end\
\
-- place a smoke marker in center of zone, offset by radius and degrees \
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\
    local rads = degrees * math.pi / 180\
    local dx = radius * math.sin(rads)\
    local dz = radius * math.cos(rads)\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
end\
\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\
    local degrees = math.random(360)\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\
end\
\
\
-- unitInZone returns true if theUnit is inside the zone \
-- the second value returned is the percentage of distance\
-- from center to rim, with 100% being entirely in center, 0 = outside\
-- the third value returned is the distance to center\
function cfxZones.pointInZone(thePoint, theZone)\
\
    if not (theZone) then return false, 0, 0 end\
        \
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\
    \
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \
    local ppoint = thePoint -- xyz\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\
    local dist = dcsCommon.dist(zpoint, pflat)\
    \
    if theZone.isCircle then \
        if theZone.radius <= 0 then \
            return false, 0, 0\
        end\
\
        local success = dist < theZone.radius\
        local percentage = 0\
        if (success) then \
            percentage = 1 - dist / theZone.radius \
        end\
        return success, percentage, dist \
    \
    elseif theZone.isPoly then\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\
        return success, 0, dist\
    else \
        trigger.action.outText(\"pointInZone: Unknown zone type for \" .. theZone.name, 10)\
    end\
\
    return false\
end\
\
function cfxZones.unitInZone(theUnit, theZone)\
    if not (theUnit) then return false, 0, 0 end\
    if not (theUnit:isExist()) then return false, 0, 0 end\
    -- force zone update if it is linked to another zone \
    -- pointInZone does update\
    local thePoint = theUnit:getPoint()\
    return cfxZones.pointInZone(thePoint, theZone)\
    \
end\
\
-- returns all units of the input set that are inside the zone \
function cfxZones.unitsInZone(theUnits, theZone)\
    if not theUnits then return {} end\
    if not theZone then return {} end\
    \
    local zoneUnits = {}\
    for index, aUnit in pairs(theUnits) do \
        if cfxZones.unitInZone(aUnit, theZone) then \
            table.insert( zoneUnits, aUnit)\
        end\
    end\
    return zoneUnits\
end\
\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\
    -- does not care if they really are in zone. call unitsInZone first\
    -- if you need to have them filtered\
    -- theUnits MUST BE ARRAY\
    if not theUnits then return nil end\
    if #theUnits == 0 then return nil end\
    local closestUnit = theUnits[1]\
    for i=2, #theUnits do\
        local aUnit = theUnits[i]\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \
            closestUnit = aUnit\
        end\
    end\
    return closestUnit\
end\
\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\
        local playerUnit = pinfo.unit\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \
            return true, playerUnit\
        end\
    end -- for all players \
    return false, nil\
end\
\
\
-- grow zone\
function cfxZones.growZone()\
    -- circular zones simply increase radius\
    -- poly zones: not defined \
    \
end\
\
\
-- creating units in a zone\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \
    -- theUnits can be string or table of string \
    if not groupName then groupName = \"G_\"..theZone.name end \
    -- group name will be taken from zone name and prependend with \"G_\"\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\
    \
    -- turn the entire formation to heading\
    if (not heading) then heading = 0 end\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\
    \
    \
    -- now move the group to center of theZone\
    dcsCommon.moveGroupDataTo(theGroup, \
                          theZone.point.x, \
                          theZone.point.z) -- watchit: Z!!!\
\
\
    -- create the group in the world and return it\
    -- first we need to translate the coalition to a legal \
    -- country. we use UN for neutral, cjtf for red and blue \
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\
\
end\
\
-- parsing zone names. The first part of the name until the first blank \" \" \
-- is the prefix and is dropped unless keepPrefix is true. \
-- all others are regarded as key:value pairs and are then added \
-- to the zone \
-- separated by equal sign \"=\" AND MUST NOT CONTAIN BLANKS\
--\
-- example usage \"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\
--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
-- \
--[[--\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\
--    trigger.action.outText(\"Parsing zone:  \".. theZone.name, 30)\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\
    -- now split the name into space-separated strings\
    local attributes = dcsCommon.splitString(theZone.name, \" \")\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\
\
    -- now parse all substrings and add them as attributes to theZone\
    for i=1, #attributes do \
        local a = attributes[i]\
        local kvp = dcsCommon.splitString(a, \"=\")\
        if #kvp == 2 then \
            -- we have key value pair\
            local theKey = kvp[1]\
            local theValue = kvp[2]\
            theZone[theKey] = theValue \
--            trigger.action.outText(\"Zone \".. theZone.name .. \" parsed: Key = \" .. theKey .. \", Value = \" .. theValue, 30)\
        else \
--            trigger.action.outText(\"Zone \".. theZone.name .. \": dropped attribute \" .. a, 30)\
        end\
    end \
end\
--]]--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
--[[--\
function cfxZones.processCraterZones ()\
    local craters = cfxZones.zonesStartingWith(\"crater\")\
\
    \
\
    -- all these zones need to be processed and their name infor placed into attributes\
    for cName, cZone in pairs(craters) do\
        cfxZones.parseZoneNameIntoAttributes(cZone)\
        \
        -- blow stuff up at the location of the zone \
        local cPoint = cZone.point\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\
        trigger.action.explosion(cPoint, 900)\
         \
        -- now interpret and act on the crater info \
        -- to destroy and place fire. \
        \
        -- fire has small, medium, large \
        -- eg. fire=large\
        \
    end\
end\
--]]--\
--\
-- Flag Pulling \
--\
function cfxZones.doPollFlag(theFlag, method, theZone)\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zones: polling flag \" .. theFlag .. \" with \" .. method, 30)\
    end \
    \
    if not theZone then \
        trigger.action.outText(\"+++zones: nil theZone on pollFlag\", 30)\
    end\
    \
    method = method:lower()\
    --trigger.action.outText(\"+++zones: polling \" .. theZone.name .. \" method \" .. method .. \" flag \" .. theFlag, 30)\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\
    if method == \"inc\" or method == \"f+1\" then \
        --trigger.action.setUserFlag(theFlag, currVal + 1)\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\
        \
    elseif method == \"dec\" or method == \"f-1\" then \
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\
\
    elseif method == \"off\" or method == \"f=0\" then \
        -- trigger.action.setUserFlag(theFlag, 0)\
        cfxZones.setFlagValue(theFlag, 0, theZone)\
\
    elseif method == \"flip\" or method == \"xor\" then \
        if currVal ~= 0 then \
--            trigger.action.setUserFlag(theFlag, 0)\
            cfxZones.setFlagValue(theFlag, 0, theZone)\
\
        else \
            --trigger.action.setUserFlag(theFlag, 1)\
            cfxZones.setFlagValue(theFlag, 1, theZone)\
        end\
        \
    else \
        if method ~= \"on\" and method ~= \"f=1\" then \
            trigger.action.outText(\"+++zones: unknown method <\" .. method .. \"> - using 'on'\", 30)\
        end\
        -- default: on.\
--        trigger.action.setUserFlag(theFlag, 1)\
        cfxZones.setFlagValue(theFlag, 1, theZone)\
\
    end\
    \
    if cfxZones.verbose then\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\
        trigger.action.outText(\"+++zones: flag <\" .. theFlag .. \"> changed from \" .. currVal .. \" to \" .. newVal, 30)\
    end \
end\
\
function cfxZones.pollFlag(theFlag, method, theZone) \
    local allFlags = {}\
    if dcsCommon.containsString(theFlag, \",\") then \
        if cfxZones.verbose then \
            trigger.action.outText(\"+++zones: will poll flag set <\" .. theFlag .. \"> with \" .. method, 30)\
        end\
        allFlags = dcsCommon.splitString(theFlag, \",\")\
    else \
        table.insert(allFlags, theFlag)\
    end\
    \
    for idx, aFlag in pairs(allFlags) do \
        aFlag = dcsCommon.trim(aFlag)\
        -- note: mey require range preprocessing, but that's not\
        -- a priority \
        cfxZones.doPollFlag(aFlag, method, theZone)\
    end \
    \
end\
\
function cfxZones.setFlagValueMult(theFlag, theValue, theZone)\
    local allFlags = {}\
    if dcsCommon.containsString(theFlag, \",\") then \
        if cfxZones.verbose then \
            trigger.action.outText(\"+++zones: will multi-set flags <\" .. theFlag .. \"> to \" .. theValue, 30)\
        end\
        allFlags = dcsCommon.splitString(theFlag, \",\")\
    else \
        table.insert(allFlags, theFlag)\
    end\
    \
    for idx, aFlag in pairs(allFlags) do \
        aFlag = dcsCommon.trim(aFlag)\
        -- note: mey require range preprocessing, but that's not\
        -- a priority \
        cfxZones.setFlagValue(aFlag, theValue, theZone)\
    end \
end\
\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on setFlagValue\")\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight set, ME flag \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
        theFlag = zoneName .. theFlag\
    end\
    trigger.action.setUserFlag(theFlag, theValue)\
end \
\
function cfxZones.getFlagValue(theFlag, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on getFlagValue\", 30)\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight get, ME flag \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
            theFlag = zoneName .. theFlag\
    end\
    return tonumber(trigger.misc.getUserFlag(theFlag))\
end\
\
function cfxZones.isMEFlag(inFlag)\
    -- do NOT use me\
    trigger.action.outText(\"+++zne: warning: deprecated isMEFlag\", 30)\
    return true \
    -- returns true if inFlag is a pure positive number\
--    inFlag = dcsCommon.trim(inFlag)\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\
end\
\
-- method-based flag testing \
function cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\
    -- return true/false based on theMethod's contraints \
    -- simple constraints\
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \
    local lMethod = string.lower(theMethod)\
    if lMethod == \"#\" or lMethod == \"change\" then \
        -- check if currVal different from lastVal\
        return currVal ~= lastVal  \
    end\
    \
    if lMethod == \"0\" or lMethod == \"no\" or lMethod == \"false\" \
       or lMethod == \"off\" then \
        -- WARNING: ONLY RETURNS TRUE IF FALSE AND lastval not zero!\
        return currVal == 0 and currVal ~= lastVal  \
    end\
    \
    if lMethod == \"1\" or lMethod == \"yes\" or lMethod == \"true\" \
       or lMethod == \"on\" then \
        -- WARNING: only returns true if lastval was false!!!!\
        return (currVal ~= 0 and lastVal == 0)  \
    end\
    \
    if lMethod == \"inc\" or lMethod == \"+1\" then \
        return currVal == lastVal+1\
    end\
    \
    if lMethod == \"dec\" or lMethod == \"-1\" then \
        return currVal == lastVal-1\
    end \
    \
    -- number constraints\
    -- or flag constraints \
    -- ONLY RETURN TRUE IF CHANGE AND CONSTRAINT MET \
    local op = string.sub(theMethod, 1, 1) \
    local remainder = string.sub(theMethod, 2)\
    remainder = dcsCommon.trim(remainder) -- remove all leading and trailing spaces\
    local rNum = tonumber(remainder)\
    if not rNum then \
        -- we use remainder as name for flag \
        -- PROCESS ESCAPE SEQUENCES\
        local esc = string.sub(remainder, 1, 1)\
        local last = string.sub(remainder, -1)\
        if esc == \"@\" then \
            remainder = string.sub(remainder, 2)\
            remainder = dcsCommon.trim(remainder)\
        end\
        \
        if esc == \"(\" and last == \")\" and string.len(remainder) > 2 then \
            -- note: iisues with startswith(\"(\") ???\
            remainder = string.sub(remainder, 2, -2)\
            remainder = dcsCommon.trim(remainder)        \
        end\
        if esc == \"\\\"\" and last == \"\\\"\" and string.len(remainder) > 2 then \
            remainder = string.sub(remainder, 2, -2)\
            remainder = dcsCommon.trim(remainder)        \
        end\
        if cfxZones.verbose then \
            trigger.action.outText(\"+++zne: accessing flag <\" .. remainder .. \">\", 30)\
        end \
        rNum = cfxZones.getFlagValue(remainder, theZone)\
    end \
    if rNum then \
        -- we have a comparison = \">\", \"=\", \"<\" followed by a number \
        -- THEY TRIGGER EACH TIME lastVal <> currVal AND condition IS MET  \
        if op == \"=\" then \
            return currVal == rNum and lastVal ~= currVal\
        end\
        \
        if op == \"#\" or op == \"~\" then \
            return currVal ~= rNum and lastVal ~= currVal \
        end \
        \
        if op == \"<\" then \
            return currVal < rNum and lastVal ~= currVal\
        end\
        \
        if op == \">\" then \
            return currVal > rNum and lastVal ~= currVal\
        end\
    end\
    \
    -- if we get here, we have an error \
    local zoneName = \"<NIL>\"\
    if theZone then zoneName = theZone.name end \
    trigger.action.outText(\"+++Zne: illegal method constraints |\" .. theMethod .. \"| for zone \" .. zoneName, 30 )\
    return false \
end\
\
function cfxZones.testZoneFlag(theZone, theFlagName, theMethod, latchName)\
    -- returns true if method constraints are met for flag theFlagName\
    -- as defined by theMethod \
    if not theMethod then \
        theMethod = \"change\"\
    end \
    \
    -- will read and update theZone[latchName] as appropriate \
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone for testZoneFlag\", 30)\
        return\
    end \
    if not theFlagName then \
        -- this is common, no error, only on verbose \
        if cfxZones.verbose then \
            trigger.action.outText(\"+++Zne: no flagName for zone \" .. theZone.name .. \" for testZoneFlag\", 30)\
        end \
        return\
    end\
    if not latchName then \
        trigger.action.outText(\"+++Zne: no latchName for zone \" .. theZone.name .. \" for testZoneFlag\", 30)\
        return    \
    end\
    -- get current value \
    local currVal = cfxZones.getFlagValue(theFlagName, theZone)\
    \
    -- get last value from latch\
    local lastVal = theZone[latchName]\
    if not lastVal then \
        trigger.action.outText(\"+++Zne: latch <\" .. latchName .. \"> not valid for zone \" .. theZone.name, 30)\
        return \
    end\
    \
    -- now, test by method \
    -- we should only test if currVal <> lastVal \
    if currVal == lastVal then\
        return false \
    end \
    \
    --trigger.action.outText(\"+++Zne: about to test: c = \" .. currVal .. \", l = \" .. lastVal, 30)\
    local testResult = cfxZones.testFlagByMethodForZone(currVal, lastVal, theMethod, theZone)\
\
    -- update latch by method\
    theZone[latchName] = currVal \
\
    -- return result\
    return testResult\
end\
\
\
\
function cfxZones.flagArrayFromString(inString)\
-- original code from RND flag\
    if string.len(inString) < 1 then \
        trigger.action.outText(\"+++zne: empty flags\", 30)\
        return {} \
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: processing <\" .. inString .. \">\", 30)\
    end \
    \
    local flags = {}\
    local rawElements = dcsCommon.splitString(inString, \",\")\
    -- go over all elements \
    for idx, anElement in pairs(rawElements) do \
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \"-\") then \
            -- interpret this as a range\
            local theRange = dcsCommon.splitString(anElement, \"-\")\
            local lowerBound = theRange[1]\
            lowerBound = tonumber(lowerBound)\
            local upperBound = theRange[2]\
            upperBound = tonumber(upperBound)\
            if lowerBound and upperBound then\
                -- swap if wrong order\
                if lowerBound > upperBound then \
                    local temp = upperBound\
                    upperBound = lowerBound\
                    lowerBound = temp \
                end\
                -- now add add numbers to flags\
                for f=lowerBound, upperBound do \
                    table.insert(flags, tostring(f))\
                end\
            else\
                -- bounds illegal\
                trigger.action.outText(\"+++zne: ignored range <\" .. anElement .. \"> (range)\", 30)\
            end\
        else\
            -- single number\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\
            if f then \
                table.insert(flags, f)\
\
            else \
                trigger.action.outText(\"+++zne: ignored element <\" .. anElement .. \"> (single)\", 30)\
            end\
        end\
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: <\" .. #flags .. \"> flags total\", 30)\
    end \
    return flags\
end\
\
--\
-- PROPERTY PROCESSING \
--\
\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \
    if not caseInsensitive then caseInsensitive = false end \
    if not theZone then return {} end \
    \
    local dcsProps = theZone.properties -- zone properties in dcs format \
    local props = {}\
    -- dcs has all properties as array with values .key and .value \
    -- so convert them into a dictionary \
    for i=1, #dcsProps do \
        local theProp = dcsProps[i]\
        local theKey = \"dummy\"\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \
        if caseInsensitive then theKey = theKey:upper() end \
        props[theKey] = theProp.value\
    end\
    return props \
end\
\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\
-- trim\
    theKey = dcsCommon.trim(theKey) \
--    make lower case conversion if not case sensitive\
    if not cfxZones.caseSensitiveProperties then \
        theKey = string.lower(theKey)\
    end\
\
-- iterate all keys and compare to what we are looking for     \
    for i=1, #theProperties do\
        local theP = theProperties[i]\
         \
        local existingKey = dcsCommon.trim(theP.key)  \
        if not cfxZones.caseSensitiveProperties then \
            existingKey = string.lower(existingKey)\
        end\
        if existingKey == theKey then \
            return theP.value\
        end\
    end\
    return nil \
end\
\
function cfxZones.getZoneProperty(cZone, theKey)\
    if not cZone then \
        trigger.action.outText(\"+++zone: no zone in getZoneProperty\", 30)\
        return nil\
    end \
    if not theKey then \
        trigger.action.outText(\"+++zone: no property key in getZoneProperty for zone \" .. cZone.name, 30)\
--        breakme.here = 1\
        return \
    end    \
\
    local props = cZone.properties\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\
    return theVal\
end\
\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    \
    if not default then default = \"\" end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end\
    if type(p) == \"string\" then \
        if p == \"\" then p = default end \
        return p\
    end\
    return default -- warning. what if it was a number first?\
end\
\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    local theNumbers = dcsCommon.splitString(p, \" \")\
\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\
    \
end\
\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \
    if not maxVal then return minVal end \
    if not minVal then return maxVal end \
    local delay = maxVal\
    if minVal > 0 and minVal < delay then \
        -- we want a randomized from time from minTime .. delay\
        local varPart = delay - minVal + 1\
        varPart = dcsCommon.smallRandom(varPart) - 1\
        delay = minVal + varPart\
    end\
    return delay \
end\
\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
    -- reads property as string, and interprets as range 'a-b'. \
    -- if not a range but single number, returns both for upper and lower \
    --trigger.action.outText(\"***Zne: enter with <\" .. theZone.name .. \">: range for property <\" .. theProperty .. \">!\", 30)\
    if not default then default = 0 end \
    local lowerBound = default\
    local upperBound = default \
    \
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    if dcsCommon.containsString(rangeString, \"-\") then \
        local theRange = dcsCommon.splitString(rangeString, \"-\")\
        lowerBound = theRange[1]\
        lowerBound = tonumber(lowerBound)\
        upperBound = theRange[2]\
        upperBound = tonumber(upperBound)\
        if lowerBound and upperBound then\
            -- swap if wrong order\
            if lowerBound > upperBound then \
                local temp = upperBound\
                upperBound = lowerBound\
                lowerBound = temp \
            end\
--            if rndFlags.verbose then \
--            trigger.action.outText(\"+++Zne: detected range <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
--            end\
        else\
            -- bounds illegal\
            trigger.action.outText(\"+++Zne: illegal range  <\" .. rangeString .. \">, using \" .. default .. \"-\" .. default, 30)\
            lowerBound = default\
            upperBound = default \
        end\
    else \
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \
        lowerBound = upperBound\
    end\
--    trigger.action.outText(\"+++Zne: returning <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
    return lowerBound, upperBound\
end\
\
function cfxZones.hasProperty(theZone, theProperty) \
    local foundIt = cfxZones.getZoneProperty(theZone, theProperty)\
    if not foundIt then \
        if string.sub(theProperty, -1) == \"?\" then \
            local lessOp = theProperty:sub(1,-2)\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \
                trigger.action.outText(\"*** NOTE: \" .. theZone.name .. \"'s property <\" .. lessOp .. \"> may be missing a Query ('?') symbol\", 30)\
            end\
            return false \
        end\
        \
        if string.sub(theProperty, -1) == \"!\" then \
            local lessOp = theProperty:sub(1,-2)\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \
                trigger.action.outText(\"*** NOTE: \" .. theZone.name .. \"'s property <\" .. lessOp .. \"> may be missing a Bang! ('!') symbol\", 30)\
            end\
            return false \
        end\
        \
        if string.sub(theProperty, -1) == \":\" then \
            local lessOp = theProperty:sub(1,-2)\
            if cfxZones.getZoneProperty(theZone, lessOp) ~= nil then \
                trigger.action.outText(\"*** NOTE: \" .. theZone.name .. \"'s property <\" .. lessOp .. \"> may be missing a colon (':') at end\", 30)\
            end\
            return false \
        end\
        \
        return false \
    end\
    return true \
--    return foundIt ~= nil \
end\
\
\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\
    if not defaultVal then defaultVal = false end \
    if type(defaultVal) ~= \"boolean\" then \
        defaultVal = false \
    end\
\
    if not theZone then \
        trigger.action.outText(\"WARNING: NIL Zone in getBoolFromZoneProperty\", 30) -- intentional bug\
        return defaultVal\
    end\
\
\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return defaultVal end\
\
    -- make sure we compare so default always works when \
    -- answer isn't exactly the opposite\
    p = p:lower() \
    if defaultVal == false then \
        -- only go true if exact match to yes or true \
        theBool = false \
        theBool = (p == 'true') or (p == 'yes') or p == \"1\"\
        return theBool\
    end\
    \
    local theBool = true \
    -- only go false if exactly no or false or \"0\"\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \"0\") \
    return theBool\
end\
\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end  \
    if type(p) == \"number\" then -- can't currently really happen\
        if p == 1 then return 1 end \
        if p == 2 then return 2 end \
        return 0\
    end\
    \
    if type(p) == \"string\" then \
        if p == \"1\" then return 1 end \
        if p == \"2\" then return 2 end \
        if p == \"0\" then return 0 end \
        \
        p = p:lower()\
        \
        if p == \"red\" then return 1 end \
        if p == \"blue\" then return 2 end \
        if p == \"neutral\" then return 0 end\
        if p == \"all\" then return 0 end \
        return default \
    end\
    \
    return default \
end\
\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\
--TODO: trim string \
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    p = tonumber(p)\
    if not p then return default else return p end\
end\
\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\
    if not minDims then minDims = 0 end \
    if not defaultVal then defaultVal = 0 end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    local sVec = dcsCommon.splitString(s, \",\")\
    local nVec = {}\
    for idx, numString in pairs (sVec) do \
        local n = tonumber(numString)\
        if not n then n = defaultVal end\
        table.insert(nVec, n)\
    end\
    -- make sure vector contains at least minDims values \
    while #nVec < minDims do \
        table.insert(nVec, defaultVal)\
    end\
    \
    return nVec \
end\
\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\
    if not default then default = \"red\" end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    s = s:lower()\
    s = dcsCommon.trim(s)\
    -- check numbers \
    if (s == \"0\") then return \"green\" end\
    if (s == \"1\") then return \"red\" end\
    if (s == \"2\") then return \"white\" end\
    if (s == \"3\") then return \"orange\" end\
    if (s == \"4\") then return \"blue\" end\
    \
    if s == \"green\" or\
       s == \"red\" or\
       s == \"white\" or\
       s == \"orange\" or\
       s == \"blue\" then return s end\
\
    return default \
end\
\
--\
-- Moving Zones. They contain a link to their unit\
-- they are always located at an offset (x,z) or delta, phi \
-- to their master unit. delta phi allows adjustment for heading\
-- The cool thing about moving zones in cfx is that they do not\
-- require special handling, they are always updated \
-- and work with 'pointinzone' etc automatically\
\
-- Always works on cfx Zones, NEVER on DCS zones.\
--\
-- requires that readFromDCS has been done\
--\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \
    if aZone.linkedUnit then \
        local theUnit = aZone.linkedUnit\
        -- has a link. is link existing?\
        if theUnit:isExist() then \
            -- updates zone position \
            cfxZones.centerZoneOnUnit(aZone, theUnit)\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
        end\
    end\
    local thePos = {}\
    thePos.x = aZone.point.x\
    thePos.y = 0 -- aZone.y \
    thePos.z = aZone.point.z\
    -- update the zone as well -- that's stupid!\
    --[[-- aZone.point = thePos \
    local retPoint = {} -- create new copy to pass back \
    retPoint.x = thePos.x\
    retPoint.y = 0 \
    retPoint.z = thePos.z\
    --]]--\
    return thePos \
end\
\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\
    theZone.linkedUnit = theUnit\
    if not dx then dx = 0 end\
    if not dy then dy = 0 end \
    theZone.dx = dx\
    theZone.dy = dy \
end\
\
function cfxZones.updateMovingZones()\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\
    -- simply scan all cfx zones for the linkedUnit property and if there\
    -- update the zone's points\
    for aName,aZone in pairs(cfxZones.zones) do\
        if aZone.linkedUnit then \
            local theUnit = aZone.linkedUnit\
            -- has a link. is link existing?\
            if theUnit:isExist() then \
                cfxZones.centerZoneOnUnit(aZone, theUnit)\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
                --trigger.action.outText(\"cf/x zones update \" .. aZone.name, 30)\
            end\
        end\
    end\
end\
\
function cfxZones.startMovingZones()\
    -- read all zoness, and look for a property called 'linkedUnit'\
    -- which will make them a linked zone if there is a unit that exists\
    -- also scans for 'verbose' flag.\
    for aName,aZone in pairs(cfxZones.zones) do\
        local lU = cfxZones.getZoneProperty(aZone, \"linkedUnit\")\
        if lU then \
            -- this zone is linked to a unit\
            theUnit = Unit.getByName(lU)\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \"useOffset\", false)\
            if useOffset then aZone.useOffset = true end\
            if theUnit then\
                local dx = 0\
                local dz = 0\
                if useOffset then \
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \
                    dx = delta.x \
                    dz = delta.z\
                end\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\
                --trigger.action.outText(\"cf/x zones: linked \" .. aZone.name .. \" to \" .. theUnit:getName(), 30)\
                if useOffset then \
                    --trigger.action.outText(\"and dx = \" .. dx .. \" dz = \" .. dz, 30)\
                end\
            end\
        end\
        -- support for local verbose flag \
        aZone.verbose = cfxZones.getBoolFromZoneProperty(aZone, \"verbose\", false)\
    end\
end\
\
--\
-- init\
--\
\
function cfxZones.init()\
    -- read all zones into my own db\
    cfxZones.readFromDCS(true) -- true: erase old\
    \
    -- now, pre-read zone owner for all zones\
    -- note, all zones with this property are by definition owned zones.\
    -- and hence will be read anyway. this will merely ensure that the \
    -- ownership is established right away\
    -- unless owned zones module is missing, in which case \
    -- ownership is still established \
    local pZones = cfxZones.zonesWithProperty(\"owner\")\
    for n, aZone in pairs(pZones) do\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \"owner\", 0)\
    end\
        \
    \
    -- now initialize moving zones\
    cfxZones.startMovingZones()\
    cfxZones.updateMovingZones() -- will auto-repeat\
    \
    trigger.action.outText(\"cf/x Zones v\".. cfxZones.version .. \": loaded\", 10)\
end\
\
-- get everything rolling\
cfxZones.init()\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [2]
                [3] = 
                {
                    ["text"] = "cfxSmokeZone = {}\
cfxSmokeZone.version = \"1.1.0\" \
cfxSmokeZone.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
--[[--\
    Version History\
 1.0.0 - initial version\
 1.0.1 - added removeSmokeZone\
 1.0.2 - added altitude\
 1.0.3 - added paused attribute \
       - added f? attribute --> onFlag \
       - broke out startSmoke \
 1.0.4 - startSmoke? synonym\
       - alphanum DML flag upgrade \
       - random color support \
 1.1.0 - Watchflag upgrade \
 \
    SMOKE ZONES *** EXTENDS ZONES ***\
    keeps 'eternal' smoke up for any zone that has the \
    'smoke' attribute \
    \
    USAGE\
    add a 'smoke' attribute to the zone. the value of the attribute \
    defines the color. Valid values are: red, green, blue, white, orange, 0 (results in green smoke), 1 (red smoke), 2 (white), 3 (orange), 4 (blue)\
    defaults to \"green\"\
    altiude is meters above ground height, defaults to 5m\
--]]--\
cfxSmokeZone.smokeZones = {}\
cfxSmokeZone.updateDelay = 5 * 60 -- every 5 minutes \
\
function cfxSmokeZone.processSmokeZone(aZone)\
    local rawVal = cfxZones.getStringFromZoneProperty(aZone, \"smoke\", \"green\")\
    rawVal = rawVal:lower()\
    local theColor = 0 \
    if rawVal == \"red\" or rawVal == \"1\" then theColor = 1 end \
    if rawVal == \"white\" or rawVal == \"2\" then theColor = 2 end \
    if rawVal == \"orange\" or rawVal == \"3\" then theColor = 3 end \
    if rawVal == \"blue\" or rawVal == \"4\" then theColor = 4 end \
    if rawVal == \"?\" or rawVal == \"random\" or rawVal == \"rnd\" then \
        theColor = dcsCommon.smallRandom(5) - 1\
    end\
\
    aZone.smokeColor = theColor\
    aZone.smokeAlt = cfxZones.getNumberFromZoneProperty(aZone, \"altitude\", 1)\
    \
    -- paused \
    aZone.paused = cfxZones.getBoolFromZoneProperty(aZone, \"paused\", false)\
    \
    -- f? query flags \
    if cfxZones.hasProperty(aZone, \"f?\") then \
        aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, \"f?\", \"*<none>\")\
    end\
    \
    if cfxZones.hasProperty(aZone, \"startSmoke?\") then \
        aZone.onFlag = cfxZones.getStringFromZoneProperty(aZone, \"startSmoke?\", \"none\")\
    end\
    \
    if aZone.onFlag then \
        aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- save last value\
    end\
    \
    -- watchflags:\
    -- triggerMethod\
    aZone.smokeTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, \"triggerMethod\", \"change\")\
\
    if cfxZones.hasProperty(aZone, \"smokeTriggerMethod\") then \
        aZone.delayTriggerMethod = cfxZones.getStringFromZoneProperty(aZone, \"smokeTriggerMethod\", \"change\")\
    end\
    \
end\
\
function cfxSmokeZone.addSmokeZone(aZone)\
    table.insert(cfxSmokeZone.smokeZones, aZone)\
end\
\
function cfxSmokeZone.addSmokeZoneWithColor(aZone, aColor, anAltitude, paused, onFlag)\
    if not aColor then aColor = 0 end -- default green \
    if not anAltitude then anAltitude = 5 end \
    if not aZone then return end \
    if not paused then paused = false end \
    \
    aZone.smokeColor = aColor\
    aZone.smokeAlt = anAltitude\
    aZone.paused = paused \
    \
    if onFlag then \
        aZone.onFlag = onFlag \
        aZone.onFlagVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- trigger.misc.getUserFlag(onFlag)\
    end\
    \
    cfxSmokeZone.addSmokeZone(aZone) -- add to update loop\
    if not paused then \
        cfxSmokeZone.startSmoke(aZone)\
    end\
    \
end\
\
function cfxSmokeZone.startSmoke(aZone)\
    if type(aZone) == \"string\" then \
        aZone = cfxZones.getZoneByName(aZone) \
    end\
    if not aZone then return end \
    if not aZone.smokeColor then return end \
    aZone.paused = false \
    cfxZones.markZoneWithSmoke(aZone, 0, 0, aZone.smokeColor, aZone.smokeAlt)\
end\
\
function cfxSmokeZone.removeSmokeZone(aZone)\
    if type(aZone) == \"string\" then \
        aZone = cfxZones.getZoneByName(aZone) \
    end\
    if not aZone then return end \
    \
    -- now create new table \
    local filtered = {}\
    for idx, theZone in pairs(cfxSmokeZone.smokeZones) do \
        if theZone ~= aZone then \
            table.insert(filtered, theZone)\
        end \
    end\
    cfxSmokeZone.smokeZones = filtered \
end\
\
\
function cfxSmokeZone.update()\
    -- call me in a couple of minutes to 'rekindle'\
    timer.scheduleFunction(cfxSmokeZone.update, {}, timer.getTime() + cfxSmokeZone.updateDelay)\
    \
    -- re-smoke all zones after delay\
    for idx, aZone in pairs(cfxSmokeZone.smokeZones) do \
        if not aZone.paused and aZone.smokeColor then \
            cfxSmokeZone.startSmoke(aZone)\
        end\
    end\
end\
\
\
function cfxSmokeZone.checkFlags()\
    timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1) -- every second \
    for idx, aZone in pairs(cfxSmokeZone.smokeZones) do \
        \
        if aZone.paused and aZone.onFlagVal then \
            -- see if this changed \
            if cfxZones.testZoneFlag(aZone, aZone.onFlag, aZone.smokeTriggerMethod, \"onFlagVal\") then\
                cfxSmokeZone.startSmoke(aZone)\
            end \
--[[--            \
            -- old code \
            local currTriggerVal = cfxZones.getFlagValue(aZone.onFlag, aZone) -- trigger.misc.getUserFlag(aZone.onFlag)\
            if currTriggerVal ~= aZone.onFlagVal then\
                -- yupp, trigger start \
                cfxSmokeZone.startSmoke(aZone)\
                aZone.onFlagVal = currTriggerVal\
            end    \
--]]--            \
        end\
    end\
end\
\
function cfxSmokeZone.start()\
    if not dcsCommon.libCheck(\"cfx Smoke Zones\", \
        cfxSmokeZone.requiredLibs) then\
        return false \
    end\
    \
    -- collect all zones with 'smoke' attribute \
    -- collect all spawn zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"smoke\")\
    \
    -- now create a smoker for all, add them to updater,\
    -- smoke all that aren't paused \
    for k, aZone in pairs(attrZones) do \
        cfxSmokeZone.processSmokeZone(aZone) -- process attribute and add to zone\
        cfxSmokeZone.addSmokeZone(aZone) -- remember it so we can smoke it\
    end\
\
    -- start update loop\
    cfxSmokeZone.update() -- also starts all unpaused \
    \
    -- start check loop in one second \
    timer.scheduleFunction(cfxSmokeZone.checkFlags, {}, timer.getTime() + 1)\
    \
    -- say hi\
    trigger.action.outText(\"cfx Smoke Zones v\" .. cfxSmokeZone.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go \
if not cfxSmokeZone.start() then \
    trigger.action.outText(\"cf/x Smoke Zones aborted: missing libraries\", 30)\
    cfxSmokeZone = nil \
end",
                    ["predicate"] = "a_do_script",
                }, -- end of [3]
            }, -- end of ["actions"]
            ["predicate"] = "triggerStart",
        }, -- end of [1]
        [2] = 
        {
            ["rules"] = 
            {
                [1] = 
                {
                    ["coalitionlist"] = "red",
                    ["unitType"] = "ALL",
                    ["zone"] = 333,
                    ["predicate"] = "c_time_after",
                    ["seconds"] = 1,
                }, -- end of [1]
            }, -- end of ["rules"]
            ["eventlist"] = "",
            ["actions"] = 
            {
                [1] = 
                {
                    ["color"] = "1",
                    ["altitude"] = 1,
                    ["predicate"] = "a_explosion_marker",
                    ["zone"] = 333,
                }, -- end of [1]
            }, -- end of ["actions"]
            ["predicate"] = "triggerOnce",
            ["comment"] = "Start ME Smoke",
        }, -- end of [2]
    }, -- end of ["trigrules"]
    ["currentKey"] = 304,
    ["start_time"] = 28800,
    ["forcedOptions"] = 
    {
    }, -- end of ["forcedOptions"]
    ["failures"] = 
    {
        ["pp_damage_EmergMaxTempr"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_EmergMaxTempr",
            ["mm"] = 0,
        }, -- end of ["pp_damage_EmergMaxTempr"]
        ["CTRL_RUDDER_ROD_MAJOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_RUDDER_ROD_MAJOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_RUDDER_ROD_MAJOR_DAMAGE"]
        ["AN_ALR69V_FAILURE_SENSOR_TAIL_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALR69V_FAILURE_SENSOR_TAIL_RIGHT",
            ["mm"] = 0,
        }, -- end of ["AN_ALR69V_FAILURE_SENSOR_TAIL_RIGHT"]
        ["CTRL_ELEVATOR_ROD_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_ELEVATOR_ROD_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["CTRL_ELEVATOR_ROD_DESTROYED"]
        ["ELEC_STARTER_BURNOUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_STARTER_BURNOUT",
            ["mm"] = 0,
        }, -- end of ["ELEC_STARTER_BURNOUT"]
        ["ADI_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ADI_UNIT",
            ["mm"] = 0,
        }, -- end of ["ADI_UNIT"]
        ["CTRL_RUDDER_TRIM_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_RUDDER_TRIM_FAILURE",
            ["mm"] = 0,
        }, -- end of ["CTRL_RUDDER_TRIM_FAILURE"]
        ["tail_reductor_chip"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "tail_reductor_chip",
            ["mm"] = 0,
        }, -- end of ["tail_reductor_chip"]
        ["UNCR_C_STRUT_DOWN_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_C_STRUT_DOWN_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_C_STRUT_DOWN_LOCK_FAILURE"]
        ["MWMMC_FAILURE_CPU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_CPU",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_CPU"]
        ["AN_ALE_40V_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALE_40V_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["AN_ALE_40V_FAILURE_TOTAL"]
        ["FR24RADIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR24RADIO",
            ["mm"] = 0,
        }, -- end of ["FR24RADIO"]
        ["SWMMC_FAILURE_CPU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_CPU",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_CPU"]
        ["FLEX_S_BKP_LAMP_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FLEX_S_BKP_LAMP_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["FLEX_S_BKP_LAMP_DEFECTIVE"]
        ["FCS_FAILURE_P_SENSOR_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_P_SENSOR_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_P_SENSOR_1"]
        ["oil_press_drop"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "oil_press_drop",
            ["mm"] = 0,
        }, -- end of ["oil_press_drop"]
        ["Failure_Fuel_RightBoostPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_RightBoostPump",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_RightBoostPump"]
        ["Failure_ECS_Valve"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_ECS_Valve",
            ["mm"] = 0,
        }, -- end of ["Failure_ECS_Valve"]
        ["CNI_FAILURE_COM2_SECOS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_COM2_SECOS",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_COM2_SECOS"]
        ["MWMMC_FAILURE_1553B_RWR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_RWR",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_RWR"]
        ["BOOSTER_COIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOOSTER_COIL",
            ["mm"] = 0,
        }, -- end of ["BOOSTER_COIL"]
        ["pp_damage_OilPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_OilPump",
            ["mm"] = 0,
        }, -- end of ["pp_damage_OilPump"]
        ["GUN_FAIL_LEFT_CENTER_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_LEFT_CENTER_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_LEFT_CENTER_GUN"]
        ["EMMC_FAILURE_BATTERY_FCS1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_BATTERY_FCS1",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_BATTERY_FCS1"]
        ["CADC_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_TOTAL"]
        ["es_damage_MainGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_MainGenerator",
            ["mm"] = 0,
        }, -- end of ["es_damage_MainGenerator"]
        ["WEAPONS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "WEAPONS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["WEAPONS_FAILURE_TOTAL"]
        ["FAILURE_SMS_PYLON_7"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_7",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_7"]
        ["RWR_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_TOTAL"]
        ["CNI_FAILURE_IFF_TX"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_IFF_TX",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_IFF_TX"]
        ["FAILURE_EXT_LIGHT_LAND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_LAND",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_LAND"]
        ["es_damage_RadarInverter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_RadarInverter",
            ["mm"] = 0,
        }, -- end of ["es_damage_RadarInverter"]
        ["REAR_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "REAR_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["REAR_TANK_LEAK"]
        ["GUN_LEFT_MG131_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG131_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG131_OPEN_CIRCUIT"]
        ["CTRL_ELEVATOR_ROD_MAJOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_ELEVATOR_ROD_MAJOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_ELEVATOR_ROD_MAJOR_DAMAGE"]
        ["ELEC_STARTER_RELAY_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_STARTER_RELAY_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_STARTER_RELAY_FAILURE"]
        ["fsf_RightBoostPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fsf_RightBoostPump",
            ["mm"] = 0,
        }, -- end of ["fsf_RightBoostPump"]
        ["asc_r"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "asc_r",
            ["mm"] = 0,
        }, -- end of ["asc_r"]
        ["BOMBS_SOLENOID_FAULT_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_SOLENOID_FAULT_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_SOLENOID_FAULT_LEFT"]
        ["BOMBS_ARMING_NO_VOLATAGE_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_NO_VOLATAGE_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_NO_VOLATAGE_LEFT"]
        ["ELEC_BOOSTER_FUEL_PUMP_1_COIL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_1_COIL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_1_COIL_FAILURE"]
        ["ELEC_STARTER_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_STARTER_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_STARTER_FAILURE"]
        ["PITOT_HEAT_ELEMENT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PITOT_HEAT_ELEMENT",
            ["mm"] = 0,
        }, -- end of ["PITOT_HEAT_ELEMENT"]
        ["FUEL_VALVE_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_VALVE_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_VALVE_LEAK"]
        ["AN_ALE_40V_FAILURE_CONTAINER_LEFT_GEAR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALE_40V_FAILURE_CONTAINER_LEFT_GEAR",
            ["mm"] = 0,
        }, -- end of ["AN_ALE_40V_FAILURE_CONTAINER_LEFT_GEAR"]
        ["INST_MASTER_COMPASS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_MASTER_COMPASS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["INST_MASTER_COMPASS_FAILURE"]
        ["CARBAIR_SHORT_CIRCUIT_BLB"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_SHORT_CIRCUIT_BLB",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_SHORT_CIRCUIT_BLB"]
        ["BATT_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BATT_FAIL",
            ["mm"] = 0,
        }, -- end of ["BATT_FAIL"]
        ["LEFT_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["LEFT_TANK_PUMP_FAULT"]
        ["Failure_Ctrl_LEF"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_LEF",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_LEF"]
        ["GUN_FAIL_LEFT_IN_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_LEFT_IN_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_LEFT_IN_GUN"]
        ["EMMC_FAILURE_BATTERY_DC2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_BATTERY_DC2",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_BATTERY_DC2"]
        ["ELEC_UC_LAMP_CD_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UC_LAMP_CD_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UC_LAMP_CD_BULB_FAILURE"]
        ["COOLANT_SHORT_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_SHORT_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["COOLANT_SHORT_CIRCUIT"]
        ["abris_hardware"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "abris_hardware",
            ["mm"] = 0,
        }, -- end of ["abris_hardware"]
        ["EEC_Failure_LeftEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EEC_Failure_LeftEngine",
            ["mm"] = 0,
        }, -- end of ["EEC_Failure_LeftEngine"]
        ["RWR_FAILURE_CONTROL_BOX"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_CONTROL_BOX",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_CONTROL_BOX"]
        ["COM1_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COM1_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["COM1_FAILURE_TOTAL"]
        ["ecm"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ecm",
            ["mm"] = 0,
        }, -- end of ["ecm"]
        ["CADC_RUDDER_AUTHORITY_COMMAND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_RUDDER_AUTHORITY_COMMAND",
            ["mm"] = 0,
        }, -- end of ["CADC_RUDDER_AUTHORITY_COMMAND"]
        ["hs_damage_AltHydro"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_AltHydro",
            ["mm"] = 0,
        }, -- end of ["hs_damage_AltHydro"]
        ["ELEC_BOOSTER_FUEL_PUMP_0_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_0_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_0_FAILURE"]
        ["UNCR_LH_STRUT_UP_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_LH_STRUT_UP_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_LH_STRUT_UP_LOCK_FAILURE"]
        ["asc_a"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "asc_a",
            ["mm"] = 0,
        }, -- end of ["asc_a"]
        ["TURNIND_POINTER_VIBRATES"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_POINTER_VIBRATES",
            ["mm"] = 0,
        }, -- end of ["TURNIND_POINTER_VIBRATES"]
        ["EMMC_FAILURE_DC_GENERATOR_CONTROLLER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DC_GENERATOR_CONTROLLER",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DC_GENERATOR_CONTROLLER"]
        ["ELEC_MSB_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_MSB_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["ELEC_MSB_DAMAGED"]
        ["engine_seized"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_seized",
            ["mm"] = 0,
        }, -- end of ["engine_seized"]
        ["ELEC_GENERATOR_REGULATOR_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_GENERATOR_REGULATOR_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ELEC_GENERATOR_REGULATOR_MALFUNCTION"]
        ["R_GEAR_BRAKE_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_BRAKE_FAULT",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_BRAKE_FAULT"]
        ["FUEL_TANK_01_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_MINOR_LEAK",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_MINOR_LEAK"]
        ["COMPASS_NO_TORQUE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPASS_NO_TORQUE",
            ["mm"] = 0,
        }, -- end of ["COMPASS_NO_TORQUE"]
        ["COOLANT_BREAK_BULB"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_BREAK_BULB",
            ["mm"] = 0,
        }, -- end of ["COOLANT_BREAK_BULB"]
        ["L_GEAR_BRAKE_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_BRAKE_FAULT",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_BRAKE_FAULT"]
        ["MAINPOWER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINPOWER",
            ["mm"] = 0,
        }, -- end of ["MAINPOWER"]
        ["ef_vibration"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_vibration",
            ["mm"] = 0,
        }, -- end of ["ef_vibration"]
        ["STARTER_BURNOUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_BURNOUT",
            ["mm"] = 0,
        }, -- end of ["STARTER_BURNOUT"]
        ["SWMMC_FAILURE_CMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_CMFCD",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_CMFCD"]
        ["OXYN_PRIMARY_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYN_PRIMARY_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["OXYN_PRIMARY_CONTAINER_PERFORATED"]
        ["FAILURE_HYDRAULICS_1_ACCU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_1_ACCU",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_1_ACCU"]
        ["OIL_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_LEAK",
            ["mm"] = 0,
        }, -- end of ["OIL_LEAK"]
        ["FCS_FAILURE_LG_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_LG_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_LG_3"]
        ["OIL_SYSTEM_FAIL_050"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_SYSTEM_FAIL_050",
            ["mm"] = 0,
        }, -- end of ["OIL_SYSTEM_FAIL_050"]
        ["ENGINE_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_TOTAL"]
        ["ELEC_MASTER_COMPASS_HARNESS_CUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_MASTER_COMPASS_HARNESS_CUT",
            ["mm"] = 0,
        }, -- end of ["ELEC_MASTER_COMPASS_HARNESS_CUT"]
        ["CTRL_RUDDER_ROD_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_RUDDER_ROD_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["CTRL_RUDDER_ROD_DESTROYED"]
        ["HYDR1PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR1PUMP",
            ["mm"] = 0,
        }, -- end of ["HYDR1PUMP"]
        ["GUN_RIGHT_IN_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_IN_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_IN_BARREL_WORN"]
        ["FUEL_FUEL_PUMP_P1_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_FUEL_PUMP_P1_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_FUEL_PUMP_P1_DEGRADED"]
        ["FUEL_NITRO_TANK_MAJOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "FUEL_NITRO_TANK_MAJOR_LEAK",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_NITRO_TANK_MAJOR_LEAK"]
        ["HYD_Flight"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_Flight",
            ["mm"] = 0,
        }, -- end of ["HYD_Flight"]
        ["INS_PART_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_PART_FAIL",
            ["mm"] = 0,
        }, -- end of ["INS_PART_FAIL"]
        ["GUN_RIGHT_OUT_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_OUT_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_OUT_BARREL_WORN"]
        ["PITOT_HEAT_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PITOT_HEAT_WIRING",
            ["mm"] = 0,
        }, -- end of ["PITOT_HEAT_WIRING"]
        ["MD1_GYRO_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MD1_GYRO_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["MD1_GYRO_TOTAL_FAILURE"]
        ["COOLANT_T_IND_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_T_IND_FAULT",
            ["mm"] = 0,
        }, -- end of ["COOLANT_T_IND_FAULT"]
        ["ENG0_WATERRADIATOR0_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_WATERRADIATOR0_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_WATERRADIATOR0_PIERCED"]
        ["FUEL_TANK_00_MAJOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_MAJOR_LEAK",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_MAJOR_LEAK"]
        ["IMU_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IMU_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["IMU_FAILURE_TOTAL"]
        ["FLEX_S_NO_GUN_SIGN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FLEX_S_NO_GUN_SIGN",
            ["mm"] = 0,
        }, -- end of ["FLEX_S_NO_GUN_SIGN"]
        ["GUN_LEFT_IN_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_IN_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_IN_OPEN_CIRCUIT"]
        ["HYD_PUMP_1_FAIL_100"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_PUMP_1_FAIL_100",
            ["mm"] = 0,
        }, -- end of ["HYD_PUMP_1_FAIL_100"]
        ["eng_computer_total_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "eng_computer_total_fail",
            ["mm"] = 0,
        }, -- end of ["eng_computer_total_fail"]
        ["hs_damage_GainPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_GainPump",
            ["mm"] = 0,
        }, -- end of ["hs_damage_GainPump"]
        ["FCS_FAILURE_PITCH_RATE_GYRO_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_RATE_GYRO_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_RATE_GYRO_3"]
        ["CTRL_AILERON_ROD_MAJOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_AILERON_ROD_MAJOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_AILERON_ROD_MAJOR_DAMAGE"]
        ["CK_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CK_UNIT",
            ["mm"] = 0,
        }, -- end of ["CK_UNIT"]
        ["FUEL_ENGINE0_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_ENGINE0_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_ENGINE0_FUEL_PUMP_FAILURE"]
        ["RWR_FAILURE_ANTENNA_REAR_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_ANTENNA_REAR_RIGHT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_ANTENNA_REAR_RIGHT"]
        ["RADARALTUNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARALTUNIT",
            ["mm"] = 0,
        }, -- end of ["RADARALTUNIT"]
        ["EMMC_FAILURE_DC_GENERATOR_VOLTAGE_LOW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DC_GENERATOR_VOLTAGE_LOW",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DC_GENERATOR_VOLTAGE_LOW"]
        ["CARBAIR_OPEN_CIRCUIT_BLB"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_OPEN_CIRCUIT_BLB",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_OPEN_CIRCUIT_BLB"]
        ["Failure_Comp_ADC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Comp_ADC",
            ["mm"] = 0,
        }, -- end of ["Failure_Comp_ADC"]
        ["ENG0_OIL_HOSE_1_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_HOSE_1_LEAK",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_HOSE_1_LEAK"]
        ["HYDRO_LOW_AIR_PRESSURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDRO_LOW_AIR_PRESSURE",
            ["mm"] = 0,
        }, -- end of ["HYDRO_LOW_AIR_PRESSURE"]
        ["ELEC_GREEN_SIGNAL_LIGHT_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_GREEN_SIGNAL_LIGHT_BROKEN",
            ["mm"] = 0,
        }, -- end of ["ELEC_GREEN_SIGNAL_LIGHT_BROKEN"]
        ["FUEL_MAIN_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_MAIN_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_MAIN_FUEL_PUMP_FAILURE"]
        ["ELEC_GENERATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_GENERATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_GENERATOR_FAILURE"]
        ["FR24ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR24ANTENNA",
            ["mm"] = 0,
        }, -- end of ["FR24ANTENNA"]
        ["FCS_FAILURE_L_ELEVATOR_HYD_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_HYD_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_HYD_2"]
        ["GENERATOR_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GENERATOR_FAULT",
            ["mm"] = 0,
        }, -- end of ["GENERATOR_FAULT"]
        ["ssf_static_pressure_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ssf_static_pressure_fail",
            ["mm"] = 0,
        }, -- end of ["ssf_static_pressure_fail"]
        ["FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_PUMP_FAILURE"]
        ["ppf_RightNozzleControl"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_RightNozzleControl",
            ["mm"] = 0,
        }, -- end of ["ppf_RightNozzleControl"]
        ["ELEC_NAVLIGHT_RED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_NAVLIGHT_RED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_NAVLIGHT_RED_FAILURE"]
        ["RWR_FAILURE_QUAD45"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_QUAD45",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_QUAD45"]
        ["JAMMER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "JAMMER",
            ["mm"] = 0,
        }, -- end of ["JAMMER"]
        ["INS_FAILURE_ALT_INVALID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_ALT_INVALID",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_ALT_INVALID"]
        ["INS_FAILURE_VELOCITY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_VELOCITY",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_VELOCITY"]
        ["ARBS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ARBS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["ARBS_FAILURE_TOTAL"]
        ["GUN_FAIL_RIGHT_IN_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_RIGHT_IN_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_RIGHT_IN_GUN"]
        ["fs_damage_right_cell_boost_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_right_cell_boost_pump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_right_cell_boost_pump"]
        ["GUN_RIGHT_OUT_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_OUT_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_OUT_MOUNT_LOOSE"]
        ["ef_fuel_reg"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_fuel_reg",
            ["mm"] = 0,
        }, -- end of ["ef_fuel_reg"]
        ["ENG0_WATER_RADIATOR_1_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_WATER_RADIATOR_1_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_WATER_RADIATOR_1_PIERCED"]
        ["GSH23_CHARGED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GSH23_CHARGED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["GSH23_CHARGED_FAILURE"]
        ["TACH_POOR_CONNECTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACH_POOR_CONNECTION",
            ["mm"] = 0,
        }, -- end of ["TACH_POOR_CONNECTION"]
        ["CTRL_RH_SLAT_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_RH_SLAT_JAMMED",
            ["mm"] = 0,
        }, -- end of ["CTRL_RH_SLAT_JAMMED"]
        ["PNEM_ENGINE_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_ENGINE_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_ENGINE_HOSE_PERFORATED"]
        ["Failure_PP_EngR_AB_FFCS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngR_AB_FFCS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngR_AB_FFCS"]
        ["ENG0_OIL_RADIATOR_1_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_RADIATOR_1_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_RADIATOR_1_PIERCED"]
        ["R_GEAR_UPL_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_UPL_JAMMED",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_UPL_JAMMED"]
        ["hydro_left"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro_left",
            ["mm"] = 0,
        }, -- end of ["hydro_left"]
        ["FCS_FAILURE_YAW_LVDT_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_LVDT_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_LVDT_2"]
        ["L_GEAR_UPL_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_UPL_JAMMED",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_UPL_JAMMED"]
        ["fs_damage_BoosterPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_BoosterPump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_BoosterPump"]
        ["UHF_ARC_159_FAILURE_REMOTE_DISPLAY_RIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_REMOTE_DISPLAY_RIO",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_REMOTE_DISPLAY_RIO"]
        ["RWR_FAILURE_DISPLAY_PILOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_DISPLAY_PILOT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_DISPLAY_PILOT"]
        ["STATION_3_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_3_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_3_FAILURE"]
        ["RIGHT_FLAP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_FLAP_FAULT",
            ["mm"] = 0,
        }, -- end of ["RIGHT_FLAP_FAULT"]
        ["INT_HYDRO_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INT_HYDRO_LEAK",
            ["mm"] = 0,
        }, -- end of ["INT_HYDRO_LEAK"]
        ["FAILURE_EXT_LIGHT_FORMATION_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_FORMATION_LEFT",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_FORMATION_LEFT"]
        ["STARTER_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_WIRING",
            ["mm"] = 0,
        }, -- end of ["STARTER_WIRING"]
        ["pitch_trim_runaway_up"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pitch_trim_runaway_up",
            ["mm"] = 0,
        }, -- end of ["pitch_trim_runaway_up"]
        ["ELEVONSERVINNERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVINNERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVINNERRIGHT"]
        ["es_damage_GeneratorLeft"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_GeneratorLeft",
            ["mm"] = 0,
        }, -- end of ["es_damage_GeneratorLeft"]
        ["engine_chip"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_chip",
            ["mm"] = 0,
        }, -- end of ["engine_chip"]
        ["GMC_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GMC_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["GMC_TOTAL_FAILURE"]
        ["CADC_FAILURE_MACH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_MACH",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_MACH"]
        ["esf_RightRectifier"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "esf_RightRectifier",
            ["mm"] = 0,
        }, -- end of ["esf_RightRectifier"]
        ["RightEngine_ShaveInOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RightEngine_ShaveInOil",
            ["mm"] = 0,
        }, -- end of ["RightEngine_ShaveInOil"]
        ["es_damage_EmergGen"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_EmergGen",
            ["mm"] = 0,
        }, -- end of ["es_damage_EmergGen"]
        ["rudder_loss"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "rudder_loss",
            ["mm"] = 0,
        }, -- end of ["rudder_loss"]
        ["FR22ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR22ANTENNA",
            ["mm"] = 0,
        }, -- end of ["FR22ANTENNA"]
        ["laser_failure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "laser_failure",
            ["mm"] = 0,
        }, -- end of ["laser_failure"]
        ["tacan_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["mm"] = 0,
        }, -- end of ["tacan_fail"]
        ["BOMBS_NO_VOLATAGE_BOTH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_NO_VOLATAGE_BOTH",
            ["mm"] = 0,
        }, -- end of ["BOMBS_NO_VOLATAGE_BOTH"]
        ["FUEL_FUSELAGE_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_FUSELAGE_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_FUSELAGE_TANK_MINOR_LEAK"]
        ["CARBAIR_SHORT_CIRCUIT_LEADS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_SHORT_CIRCUIT_LEADS",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_SHORT_CIRCUIT_LEADS"]
        ["PITOT_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PITOT_FAILURE",
            ["mm"] = 0,
        }, -- end of ["PITOT_FAILURE"]
        ["ELEC_BOOSTER_FUEL_PUMP_2_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_2_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_2_FAILURE"]
        ["SNS_FAILURE_COMPUTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SNS_FAILURE_COMPUTER",
            ["mm"] = 0,
        }, -- end of ["SNS_FAILURE_COMPUTER"]
        ["csf_PitchTrim"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "csf_PitchTrim",
            ["mm"] = 0,
        }, -- end of ["csf_PitchTrim"]
        ["CANARDSERVOLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDSERVOLEFT",
            ["mm"] = 0,
        }, -- end of ["CANARDSERVOLEFT"]
        ["FWD_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FWD_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["FWD_TANK_PUMP_FAULT"]
        ["CNI_FAILURE_COM1_SECOS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_COM1_SECOS",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_COM1_SECOS"]
        ["INS_DATA_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_DATA_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["INS_DATA_DEGRADED"]
        ["Failure_PP_EngR_OilLeak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngR_OilLeak",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngR_OilLeak"]
        ["RKL_41_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RKL_41_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RKL_41_TOTAL_FAILURE"]
        ["EMMC_FAILURE_DADS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DADS",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DADS"]
        ["hs_damage_UtilityHydro"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_UtilityHydro",
            ["mm"] = 0,
        }, -- end of ["hs_damage_UtilityHydro"]
        ["ILS_FAILURE_ANT_MARKER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_ANT_MARKER",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_ANT_MARKER"]
        ["FCS_FAILURE_PITCH_RATE_GYRO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_RATE_GYRO_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_RATE_GYRO_1"]
        ["MWMMC_FAILURE_1553B_TACAN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_TACAN",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_TACAN"]
        ["HYDR_UNLOAD_VALVE_NOT_UNLOAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_UNLOAD_VALVE_NOT_UNLOAD",
            ["mm"] = 0,
        }, -- end of ["HYDR_UNLOAD_VALVE_NOT_UNLOAD"]
        ["FCS_FAILURE_L_ELEVATOR_ELEC_D"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_ELEC_D",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_ELEC_D"]
        ["FUEL_TANK_01_MEDIUM_LEAK"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "FUEL_TANK_01_MEDIUM_LEAK",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_MEDIUM_LEAK"]
        ["EPRSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EPRSENSOR",
            ["mm"] = 0,
        }, -- end of ["EPRSENSOR"]
        ["MWMMC_FAILURE_1553B_IFF"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_IFF",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_IFF"]
        ["RWRUNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRUNIT",
            ["mm"] = 0,
        }, -- end of ["RWRUNIT"]
        ["ENG_ALT_2_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG_ALT_2_FAIL",
            ["mm"] = 0,
        }, -- end of ["ENG_ALT_2_FAIL"]
        ["ZCP_FAILURE_MALFUNC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ZCP_FAILURE_MALFUNC",
            ["mm"] = 0,
        }, -- end of ["ZCP_FAILURE_MALFUNC"]
        ["ICS_FAILURE_AMPLIFIER_PILOT_NORM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ICS_FAILURE_AMPLIFIER_PILOT_NORM",
            ["mm"] = 0,
        }, -- end of ["ICS_FAILURE_AMPLIFIER_PILOT_NORM"]
        ["oxy_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "oxy_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["oxy_FAILURE_TOTAL"]
        ["ICS_FAILURE_AMPLIFIER_RIO_NORM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ICS_FAILURE_AMPLIFIER_RIO_NORM",
            ["mm"] = 0,
        }, -- end of ["ICS_FAILURE_AMPLIFIER_RIO_NORM"]
        ["ENGINE_FAILURE_N2_TURBINE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_N2_TURBINE",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_N2_TURBINE"]
        ["BOMBS_ARMING_BROKEN_SOLENOID_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_BROKEN_SOLENOID_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_BROKEN_SOLENOID_RIGHT"]
        ["mlws"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "mlws",
            ["mm"] = 0,
        }, -- end of ["mlws"]
        ["STARTER_LOSE_CON"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_LOSE_CON",
            ["mm"] = 0,
        }, -- end of ["STARTER_LOSE_CON"]
        ["Failure_PP_EngL_Nozzle_CS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngL_Nozzle_CS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngL_Nozzle_CS"]
        ["FCS_FAILURE_COMP_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_COMP_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_COMP_2"]
        ["FCS_FAILURE_PITCH_LVDT_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_LVDT_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_LVDT_3"]
        ["W_S_R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "W_S_R",
            ["mm"] = 0,
        }, -- end of ["W_S_R"]
        ["SAR_2_95"] = 
        {
            ["hh"] = 0,
            ["id"] = "SAR_2_95",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["SAR_2_95"]
        ["UNCR_C_STRUT_UP_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_C_STRUT_UP_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_C_STRUT_UP_LOCK_FAILURE"]
        ["EZ42_NO_POWER_SUPPLY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EZ42_NO_POWER_SUPPLY",
            ["mm"] = 0,
        }, -- end of ["EZ42_NO_POWER_SUPPLY"]
        ["COMPASS_ERRATIC_INDIACATON"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPASS_ERRATIC_INDIACATON",
            ["mm"] = 0,
        }, -- end of ["COMPASS_ERRATIC_INDIACATON"]
        ["FCS_FAILURE_NZ_SENSOR_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NZ_SENSOR_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NZ_SENSOR_3"]
        ["PUMP_SEPARATOR_CLOGGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PUMP_SEPARATOR_CLOGGED",
            ["mm"] = 0,
        }, -- end of ["PUMP_SEPARATOR_CLOGGED"]
        ["Vibration_LeftEngine"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "Vibration_LeftEngine",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["Vibration_LeftEngine"]
        ["explosive_depressurization"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "explosive_depressurization",
            ["mm"] = 0,
        }, -- end of ["explosive_depressurization"]
        ["UNCR_LH_WHEEL_BRAKE_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_LH_WHEEL_BRAKE_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["UNCR_LH_WHEEL_BRAKE_DAMAGED"]
        ["DOORS_TV_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DOORS_TV_JAMMED",
            ["mm"] = 0,
        }, -- end of ["DOORS_TV_JAMMED"]
        ["D2_RIGHT_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "D2_RIGHT_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["D2_RIGHT_CYLINDER"]
        ["AN_ALR69V_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALR69V_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["AN_ALR69V_FAILURE_TOTAL"]
        ["Failure_Hyd_HYD1A_Leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Hyd_HYD1A_Leak",
            ["mm"] = 0,
        }, -- end of ["Failure_Hyd_HYD1A_Leak"]
        ["R_GEAR_MOTOR_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_MOTOR_FAULT",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_MOTOR_FAULT"]
        ["es_damage_Inverter115_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Inverter115_1",
            ["mm"] = 0,
        }, -- end of ["es_damage_Inverter115_1"]
        ["PNEM_MACHINE_GUNS_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_MACHINE_GUNS_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_MACHINE_GUNS_HOSE_PERFORATED"]
        ["FCS_FAILURE_ROLL_ELEC_SERVO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_ELEC_SERVO_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_ELEC_SERVO_1"]
        ["ENGINE_FAILURE_AB_IGNITION_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_AB_IGNITION_UNIT",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_AB_IGNITION_UNIT"]
        ["L_GEAR_MOTOR_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_MOTOR_FAULT",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_MOTOR_FAULT"]
        ["ELEVONINNERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONINNERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONINNERRIGHT"]
        ["helmet"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "helmet",
            ["mm"] = 0,
        }, -- end of ["helmet"]
        ["batteries_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "batteries_fail",
            ["mm"] = 0,
        }, -- end of ["batteries_fail"]
        ["hs_damage_MainPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_MainPump",
            ["mm"] = 0,
        }, -- end of ["hs_damage_MainPump"]
        ["MainReductor_ShaveInOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MainReductor_ShaveInOil",
            ["mm"] = 0,
        }, -- end of ["MainReductor_ShaveInOil"]
        ["COOLANT_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_LEAK",
            ["mm"] = 0,
        }, -- end of ["COOLANT_LEAK"]
        ["FUEL_FUEL_PUMP_P2_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_FUEL_PUMP_P2_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_FUEL_PUMP_P2_DEGRADED"]
        ["PNEM_SECONDARY_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_SECONDARY_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_SECONDARY_CONTAINER_PERFORATED"]
        ["PNEM_RH_FLAP_JACK_BUSTED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_RH_FLAP_JACK_BUSTED",
            ["mm"] = 0,
        }, -- end of ["PNEM_RH_FLAP_JACK_BUSTED"]
        ["WEAP_GUN_02_AMMO_BELT_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "WEAP_GUN_02_AMMO_BELT_SEVERED",
            ["mm"] = 0,
        }, -- end of ["WEAP_GUN_02_AMMO_BELT_SEVERED"]
        ["AAR_47_FAILURE_SENSOR_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AAR_47_FAILURE_SENSOR_LEFT",
            ["mm"] = 0,
        }, -- end of ["AAR_47_FAILURE_SENSOR_LEFT"]
        ["VHF_ARC_182_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_TOTAL"]
        ["GUN_LEFT_MG131_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG131_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG131_BARREL_WORN"]
        ["OXYN_PRIMARY_CONTAINER_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYN_PRIMARY_CONTAINER_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["OXYN_PRIMARY_CONTAINER_MINOR_LEAK"]
        ["PPF_RE_TEMPER_LIM_OFF"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "PPF_RE_TEMPER_LIM_OFF",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["PPF_RE_TEMPER_LIM_OFF"]
        ["FCS_FAILURE_R_ELEVATOR_ELEC_A"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_ELEC_A",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_ELEC_A"]
        ["DC_BUS_GENERATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DC_BUS_GENERATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["DC_BUS_GENERATOR_FAILURE"]
        ["ELEC_BATTERY_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BATTERY_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["ELEC_BATTERY_DESTROYED"]
        ["Failure_Sens_LeftPitotHeater"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Sens_LeftPitotHeater",
            ["mm"] = 0,
        }, -- end of ["Failure_Sens_LeftPitotHeater"]
        ["HYD_ALT_2_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_ALT_2_FAIL",
            ["mm"] = 0,
        }, -- end of ["HYD_ALT_2_FAIL"]
        ["RDR_FAILURE_TRANSMITTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_TRANSMITTER",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_TRANSMITTER"]
        ["ols_damage_OilPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ols_damage_OilPump",
            ["mm"] = 0,
        }, -- end of ["ols_damage_OilPump"]
        ["LeftEngine_ShaveInOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LeftEngine_ShaveInOil",
            ["mm"] = 0,
        }, -- end of ["LeftEngine_ShaveInOil"]
        ["ELEC_UC_LAMP_RHD_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UC_LAMP_RHD_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UC_LAMP_RHD_BULB_FAILURE"]
        ["MAIN_R_GEAR_D_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAIN_R_GEAR_D_LOCK",
            ["mm"] = 0,
        }, -- end of ["MAIN_R_GEAR_D_LOCK"]
        ["FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE"]
        ["ENGINE_FAILURE_N2_COMPRESSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_N2_COMPRESSOR",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_N2_COMPRESSOR"]
        ["CMDISP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CMDISP",
            ["mm"] = 0,
        }, -- end of ["CMDISP"]
        ["ELEC_FUEL_PUMP_P1_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_FUEL_PUMP_P1_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_FUEL_PUMP_P1_FAILURE"]
        ["K14_FIXED_LAMP_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "K14_FIXED_LAMP_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["K14_FIXED_LAMP_DEFECTIVE"]
        ["RDR_FAILURE_RX_FRONT_END_DEGRATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_RX_FRONT_END_DEGRATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_RX_FRONT_END_DEGRATION"]
        ["EMMC_FAILURE_ELECT_EQUIP_HOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_ELECT_EQUIP_HOT",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_ELECT_EQUIP_HOT"]
        ["TGP_FAILURE_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TGP_FAILURE_LEFT",
            ["mm"] = 0,
        }, -- end of ["TGP_FAILURE_LEFT"]
        ["Failure_Elec_LeftGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_LeftGenerator",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_LeftGenerator"]
        ["SNS_FAILURE_ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SNS_FAILURE_ANTENNA",
            ["mm"] = 0,
        }, -- end of ["SNS_FAILURE_ANTENNA"]
        ["RWR_FAILURE_SENSOR_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_SENSOR_LEFT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_SENSOR_LEFT"]
        ["MWMMC_FAILURE_1553B_ILS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_ILS",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_ILS"]
        ["ppf_RightOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_RightOil",
            ["mm"] = 0,
        }, -- end of ["ppf_RightOil"]
        ["TOP_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TOP_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["TOP_CYLINDER"]
        ["RADAR_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADAR_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["RADAR_FAILURE_TOTAL"]
        ["PNEM_FLAPS_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_FLAPS_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_FLAPS_HOSE_PERFORATED"]
        ["KPP_1273_GYRO_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "KPP_1273_GYRO_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["KPP_1273_GYRO_TOTAL_FAILURE"]
        ["L_GEAR_UPL_NOT_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_UPL_NOT_LOCK",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_UPL_NOT_LOCK"]
        ["FUEL_MAIN_FUEL_PUMP_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_MAIN_FUEL_PUMP_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_MAIN_FUEL_PUMP_DEGRADED"]
        ["sas_yaw_left"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sas_yaw_left",
            ["mm"] = 0,
        }, -- end of ["sas_yaw_left"]
        ["AC_BUS_PO7501_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AC_BUS_PO7501_FAILURE",
            ["mm"] = 0,
        }, -- end of ["AC_BUS_PO7501_FAILURE"]
        ["FAILURE_EXT_LIGHT_TAXI"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_TAXI",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_TAXI"]
        ["Failure_PP_RightAMAD_OilLeak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_RightAMAD_OilLeak",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_RightAMAD_OilLeak"]
        ["ELEC_RH_FLAPS_DRIVE_WIRE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RH_FLAPS_DRIVE_WIRE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["ELEC_RH_FLAPS_DRIVE_WIRE_SEVERED"]
        ["starter_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "starter_fail",
            ["mm"] = 0,
        }, -- end of ["starter_fail"]
        ["MWMMC_FAILURE_1553B_SPJ"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_SPJ",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_SPJ"]
        ["CNI_FAILURE_TACAN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_TACAN",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_TACAN"]
        ["RightEngine_Fire"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RightEngine_Fire",
            ["mm"] = 0,
        }, -- end of ["RightEngine_Fire"]
        ["VHF_ARC_182_FAILURE_DISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_DISPLAY",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_DISPLAY"]
        ["UNCR_LH_STRUT_UP_LOCK_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_LH_STRUT_UP_LOCK_JAMMED",
            ["mm"] = 0,
        }, -- end of ["UNCR_LH_STRUT_UP_LOCK_JAMMED"]
        ["LIGHTS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LIGHTS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["LIGHTS_FAILURE"]
        ["asc_p"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "asc_p",
            ["mm"] = 0,
        }, -- end of ["asc_p"]
        ["BOMBS_ARMING_BROKEN_SOLENOID_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_BROKEN_SOLENOID_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_BROKEN_SOLENOID_LEFT"]
        ["Failure_PP_EngR_Main_FFCS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngR_Main_FFCS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngR_Main_FFCS"]
        ["FUEL_NITRO_TANK_LEAK_STOPPED"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "FUEL_NITRO_TANK_LEAK_STOPPED",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_NITRO_TANK_LEAK_STOPPED"]
        ["FCS_FAILURE_EFCS_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_EFCS_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_EFCS_2"]
        ["Failure_Hyd_IsolatedHYD2BSystem_Leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Hyd_IsolatedHYD2BSystem_Leak",
            ["mm"] = 0,
        }, -- end of ["Failure_Hyd_IsolatedHYD2BSystem_Leak"]
        ["COMPASS_POINTER_PULLS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPASS_POINTER_PULLS",
            ["mm"] = 0,
        }, -- end of ["COMPASS_POINTER_PULLS"]
        ["GUN_RIGHT_OUT_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_OUT_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_OUT_OPEN_CIRCUIT"]
        ["ELEC_NAVLIGHT_WHITE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_NAVLIGHT_WHITE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_NAVLIGHT_WHITE_FAILURE"]
        ["AIRBRAKE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AIRBRAKE",
            ["mm"] = 0,
        }, -- end of ["AIRBRAKE"]
        ["Failure_Gear_WOW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Gear_WOW",
            ["mm"] = 0,
        }, -- end of ["Failure_Gear_WOW"]
        ["TURNIND_INCORRECT_SENS_VAC_HIGH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_INCORRECT_SENS_VAC_HIGH",
            ["mm"] = 0,
        }, -- end of ["TURNIND_INCORRECT_SENS_VAC_HIGH"]
        ["IGNITION_NO_OUTPUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IGNITION_NO_OUTPUT",
            ["mm"] = 0,
        }, -- end of ["IGNITION_NO_OUTPUT"]
        ["BOMBS_ARMING_BROKEN_WIRING_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_BROKEN_WIRING_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_BROKEN_WIRING_RIGHT"]
        ["chip_in_oil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "chip_in_oil",
            ["mm"] = 0,
        }, -- end of ["chip_in_oil"]
        ["ELEC_BOOSTER_FUEL_PUMP_1_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_1_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_1_FAILURE"]
        ["COMPASS_ERRATIC_OPERATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPASS_ERRATIC_OPERATION",
            ["mm"] = 0,
        }, -- end of ["COMPASS_ERRATIC_OPERATION"]
        ["TID_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TID_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["TID_FAILURE_TOTAL"]
        ["ELEVONSERVOUTERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVOUTERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVOUTERRIGHT"]
        ["ELEC_UC_LAMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UC_LAMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UC_LAMP_FAILURE"]
        ["STATION_5_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_5_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_5_FAILURE"]
        ["EMMC_FAILURE_SHARS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_SHARS",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_SHARS"]
        ["D2_LEFT_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "D2_LEFT_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["D2_LEFT_CYLINDER"]
        ["Surge_LeftEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Surge_LeftEngine",
            ["mm"] = 0,
        }, -- end of ["Surge_LeftEngine"]
        ["BOMBS_RUST_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_RUST_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_RUST_LEFT"]
        ["STATION_7_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_7_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_7_FAILURE"]
        ["AHRS_FAILURE_MAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AHRS_FAILURE_MAD",
            ["mm"] = 0,
        }, -- end of ["AHRS_FAILURE_MAD"]
        ["csf_PitchDamper"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "csf_PitchDamper",
            ["mm"] = 0,
        }, -- end of ["csf_PitchDamper"]
        ["asc"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "asc",
            ["mm"] = 0,
        }, -- end of ["asc"]
        ["FAILURE_HYDRAULICS_EMERGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_EMERGE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_EMERGE"]
        ["ENG0_OILRADIATOR0_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OILRADIATOR0_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_OILRADIATOR0_PIERCED"]
        ["DTC_FAILURE_DATA_DECIPHER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DTC_FAILURE_DATA_DECIPHER",
            ["mm"] = 0,
        }, -- end of ["DTC_FAILURE_DATA_DECIPHER"]
        ["ENG0_CARBURETTOR_OIL_FEED_CLOGGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_CARBURETTOR_OIL_FEED_CLOGGED",
            ["mm"] = 0,
        }, -- end of ["ENG0_CARBURETTOR_OIL_FEED_CLOGGED"]
        ["Failure_Ctrl_Aileron"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_Aileron",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_Aileron"]
        ["es_damage_SpareInverter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_SpareInverter",
            ["mm"] = 0,
        }, -- end of ["es_damage_SpareInverter"]
        ["EMMC_FAILURE_SCU_AC2AC36V"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_SCU_AC2AC36V",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_SCU_AC2AC36V"]
        ["UNLOAD_VALVE_NOT_LOAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNLOAD_VALVE_NOT_LOAD",
            ["mm"] = 0,
        }, -- end of ["UNLOAD_VALVE_NOT_LOAD"]
        ["TURNIND_INCORRECT_SENS_VAC_LOW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_INCORRECT_SENS_VAC_LOW",
            ["mm"] = 0,
        }, -- end of ["TURNIND_INCORRECT_SENS_VAC_LOW"]
        ["ELEC_RH_CABIN_LIGHT_POOR_CONTACT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RH_CABIN_LIGHT_POOR_CONTACT",
            ["mm"] = 0,
        }, -- end of ["ELEC_RH_CABIN_LIGHT_POOR_CONTACT"]
        ["RDR_FAILURE_DEGRATED_PERFORMANCE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_DEGRATED_PERFORMANCE",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_DEGRATED_PERFORMANCE"]
        ["RWRANTREAR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTREAR",
            ["mm"] = 0,
        }, -- end of ["RWRANTREAR"]
        ["EMMC_FAILURE_TRU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_TRU",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_TRU"]
        ["OESP_FAILURE_CH_DISP_L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_CH_DISP_L",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_CH_DISP_L"]
        ["UHF_ARC_159_FAILURE_DISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_DISPLAY",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_DISPLAY"]
        ["ILS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_TOTAL"]
        ["INS_FAILURE_HEADING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_HEADING",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_HEADING"]
        ["Vibration_RightEngine"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "Vibration_RightEngine",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["Vibration_RightEngine"]
        ["as_damage_Depressurization"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "as_damage_Depressurization",
            ["mm"] = 0,
        }, -- end of ["as_damage_Depressurization"]
        ["ELEVONINNERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONINNERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONINNERLEFT"]
        ["TURNIND_POINTER_NOT_SET_ZERO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_POINTER_NOT_SET_ZERO",
            ["mm"] = 0,
        }, -- end of ["TURNIND_POINTER_NOT_SET_ZERO"]
        ["FAILURE_HYDRAULICS_2_PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_2_PUMP",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_2_PUMP"]
        ["EMMC_FAILURE_BATTERY_FCS2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_BATTERY_FCS2",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_BATTERY_FCS2"]
        ["SWMMC_FAILURE_RMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_RMFCD",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_RMFCD"]
        ["RIGHT_MFCD_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_MFCD_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RIGHT_MFCD_FAILURE"]
        ["SMS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SMS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["SMS_FAILURE_TOTAL"]
        ["Failure_Comp_MC1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Comp_MC1",
            ["mm"] = 0,
        }, -- end of ["Failure_Comp_MC1"]
        ["INST_PITOT_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_PITOT_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["INST_PITOT_DAMAGE"]
        ["SWMMC_FAILURE_LMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_LMFCD",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_LMFCD"]
        ["UHF_RADIO_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_RADIO_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["UHF_RADIO_FAILURE_TOTAL"]
        ["MWMMC_FAILURE_1553B_RMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_RMFCD",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_RMFCD"]
        ["FAILURE_SMS_PYLON_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_1",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_1"]
        ["APU_Fire"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "APU_Fire",
            ["mm"] = 0,
        }, -- end of ["APU_Fire"]
        ["ENG0_WATERRADIATOR1_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_WATERRADIATOR1_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_WATERRADIATOR1_PIERCED"]
        ["es_damage_InverterPT500C"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_InverterPT500C",
            ["mm"] = 0,
        }, -- end of ["es_damage_InverterPT500C"]
        ["LANDING_LIGHTS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LANDING_LIGHTS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["LANDING_LIGHTS_FAILURE"]
        ["GUN_LEFT_MG131_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG131_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG131_AMMUN_FAULT"]
        ["RWR_FAILURE_RECEIVER_XX1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_RECEIVER_XX1",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_RECEIVER_XX1"]
        ["SWMMC_FAILURE_PS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_PS",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_PS"]
        ["GUN_LEFT_OUT_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_OUT_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_OUT_OPEN_CIRCUIT"]
        ["TRN_FAIL_AUX"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TRN_FAIL_AUX",
            ["mm"] = 0,
        }, -- end of ["TRN_FAIL_AUX"]
        ["FLEX_S_NO_POWER_SUPPLY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FLEX_S_NO_POWER_SUPPLY",
            ["mm"] = 0,
        }, -- end of ["FLEX_S_NO_POWER_SUPPLY"]
        ["BAT_SOLENOID_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BAT_SOLENOID_WIRING",
            ["mm"] = 0,
        }, -- end of ["BAT_SOLENOID_WIRING"]
        ["EMMC_FAILURE_FUEL_START_PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_FUEL_START_PUMP",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_FUEL_START_PUMP"]
        ["FUEL_FORWARD_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_FORWARD_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_FORWARD_TANK_MINOR_LEAK"]
        ["INS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_TOTAL"]
        ["sensf_CADC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sensf_CADC",
            ["mm"] = 0,
        }, -- end of ["sensf_CADC"]
        ["RADAR_ALTIMETR_LEFT_ANT_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADAR_ALTIMETR_LEFT_ANT_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RADAR_ALTIMETR_LEFT_ANT_FAILURE"]
        ["hydro"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro",
            ["mm"] = 0,
        }, -- end of ["hydro"]
        ["FUEL_TANK_02_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_TANK_02_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_02_MINOR_LEAK"]
        ["HUD_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HUD_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["HUD_FAILURE_TOTAL"]
        ["ELEC_BATTERY_OVERHEAT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BATTERY_OVERHEAT",
            ["mm"] = 0,
        }, -- end of ["ELEC_BATTERY_OVERHEAT"]
        ["TACH_RESISTANCE_ADJ"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACH_RESISTANCE_ADJ",
            ["mm"] = 0,
        }, -- end of ["TACH_RESISTANCE_ADJ"]
        ["Failure_ECS_OBOGS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_ECS_OBOGS",
            ["mm"] = 0,
        }, -- end of ["Failure_ECS_OBOGS"]
        ["EMMC_FAILURE_CANOPY_UNLOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_CANOPY_UNLOCK",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_CANOPY_UNLOCK"]
        ["fire_sys_fireko50"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fire_sys_fireko50",
            ["mm"] = 0,
        }, -- end of ["fire_sys_fireko50"]
        ["FUEL_TANK_01_EXPLODED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_EXPLODED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_EXPLODED"]
        ["AHRS_FAILURE_GYRO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AHRS_FAILURE_GYRO",
            ["mm"] = 0,
        }, -- end of ["AHRS_FAILURE_GYRO"]
        ["es_damage_VU2"] = 
        {
            ["hh"] = 0,
            ["id"] = "es_damage_VU2",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["es_damage_VU2"]
        ["ENG0_OIL_HOSE_1_BURST"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_HOSE_1_BURST",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_HOSE_1_BURST"]
        ["AN_ALE_40V_FAILURE_CONTAINER_RIGHT_WING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALE_40V_FAILURE_CONTAINER_RIGHT_WING",
            ["mm"] = 0,
        }, -- end of ["AN_ALE_40V_FAILURE_CONTAINER_RIGHT_WING"]
        ["TailReductor_LowOilPressure"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "TailReductor_LowOilPressure",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["TailReductor_LowOilPressure"]
        ["INS_FAILURE_DATA_INVALID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_DATA_INVALID",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_DATA_INVALID"]
        ["OXY_FAILURE_AUTO_100_O2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_AUTO_100_O2",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_AUTO_100_O2"]
        ["EMMC_FAILURE_AC_GROUND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_AC_GROUND",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_AC_GROUND"]
        ["pp_damage_MainStabFactor"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_MainStabFactor",
            ["mm"] = 0,
        }, -- end of ["pp_damage_MainStabFactor"]
        ["hydro_right"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro_right",
            ["mm"] = 0,
        }, -- end of ["hydro_right"]
        ["FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE_SEVERE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE_SEVERE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_1_EXTERNAL_LEAKAGE_SEVERE"]
        ["INST_TACH1_POOR_CONNECTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH1_POOR_CONNECTION",
            ["mm"] = 0,
        }, -- end of ["INST_TACH1_POOR_CONNECTION"]
        ["TRIMMER_DRIVE_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TRIMMER_DRIVE_FAULT",
            ["mm"] = 0,
        }, -- end of ["TRIMMER_DRIVE_FAULT"]
        ["SADL_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SADL_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["SADL_FAILURE_TOTAL"]
        ["EMMC_FAILURE_STATIC_INVERTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_STATIC_INVERTER",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_STATIC_INVERTER"]
        ["Failure_Elec_RightGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_RightGenerator",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_RightGenerator"]
        ["ELEVONOUTERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONOUTERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONOUTERLEFT"]
        ["SAR_1_95"] = 
        {
            ["hh"] = 0,
            ["id"] = "SAR_1_95",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["SAR_1_95"]
        ["TEMPSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TEMPSENSOR",
            ["mm"] = 0,
        }, -- end of ["TEMPSENSOR"]
        ["flaps_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "flaps_fault",
            ["mm"] = 0,
        }, -- end of ["flaps_fault"]
        ["TAIL_GEAR_C_CABLE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_C_CABLE",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_C_CABLE"]
        ["damper"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "damper",
            ["mm"] = 0,
        }, -- end of ["damper"]
        ["BCKGYRO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BCKGYRO",
            ["mm"] = 0,
        }, -- end of ["BCKGYRO"]
        ["CANARDFLAPRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDFLAPRIGHT",
            ["mm"] = 0,
        }, -- end of ["CANARDFLAPRIGHT"]
        ["BCKPITOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BCKPITOT",
            ["mm"] = 0,
        }, -- end of ["BCKPITOT"]
        ["GMC_MAGN_COMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GMC_MAGN_COMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["GMC_MAGN_COMP_FAILURE"]
        ["fire_sys_fire_RE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fire_sys_fire_RE",
            ["mm"] = 0,
        }, -- end of ["fire_sys_fire_RE"]
        ["EMMC_FAILURE_AC_GENERATOR_FEED_LINE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_AC_GENERATOR_FEED_LINE",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_AC_GENERATOR_FEED_LINE"]
        ["ENG0_GOVERNOR_REGULATOR_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_GOVERNOR_REGULATOR_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ENG0_GOVERNOR_REGULATOR_MALFUNCTION"]
        ["ENG0_STARTER_CLUTCH_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_STARTER_CLUTCH_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ENG0_STARTER_CLUTCH_FAILURE"]
        ["ELEC_PITOT_HEAT_ELEMENT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_PITOT_HEAT_ELEMENT",
            ["mm"] = 0,
        }, -- end of ["ELEC_PITOT_HEAT_ELEMENT"]
        ["pp_damage_MainMaxNormFreq"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_MainMaxNormFreq",
            ["mm"] = 0,
        }, -- end of ["pp_damage_MainMaxNormFreq"]
        ["ARN_83_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ARN_83_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ARN_83_TOTAL_FAILURE"]
        ["CTRL_LANDING_FLAPS_MECHANICAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LANDING_FLAPS_MECHANICAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["CTRL_LANDING_FLAPS_MECHANICAL_FAILURE"]
        ["SWMMC_CSU_NO_RS422_COMM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_CSU_NO_RS422_COMM",
            ["mm"] = 0,
        }, -- end of ["SWMMC_CSU_NO_RS422_COMM"]
        ["Failure_Hyd_HYD2A_Leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Hyd_HYD2A_Leak",
            ["mm"] = 0,
        }, -- end of ["Failure_Hyd_HYD2A_Leak"]
        ["CADC_WING_SWEEP_INDICATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_WING_SWEEP_INDICATOR",
            ["mm"] = 0,
        }, -- end of ["CADC_WING_SWEEP_INDICATOR"]
        ["sight_lamps_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sight_lamps_fail",
            ["mm"] = 0,
        }, -- end of ["sight_lamps_fail"]
        ["EMMC_FAILURE_AC_GENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_AC_GENERATOR",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_AC_GENERATOR"]
        ["RADARASS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARASS",
            ["mm"] = 0,
        }, -- end of ["RADARASS"]
        ["fs_aft_LH_leakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_aft_LH_leakage",
            ["mm"] = 0,
        }, -- end of ["fs_aft_LH_leakage"]
        ["aileron_trim_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "aileron_trim_fail",
            ["mm"] = 0,
        }, -- end of ["aileron_trim_fail"]
        ["CADC_WING_SWEEP_COMMAND_CHANNEL_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_WING_SWEEP_COMMAND_CHANNEL_1",
            ["mm"] = 0,
        }, -- end of ["CADC_WING_SWEEP_COMMAND_CHANNEL_1"]
        ["FCS_FAILURE_ROLL_LVDT_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_LVDT_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_LVDT_1"]
        ["FUEL_TANK_00_FIRE"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_FIRE",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_FIRE"]
        ["UNCR_RH_STRUT_UP_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_RH_STRUT_UP_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_RH_STRUT_UP_LOCK_FAILURE"]
        ["CADC_FAILURE_DYNAMIC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_DYNAMIC",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_DYNAMIC"]
        ["RWR_FAILURE_LOW_BAND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_LOW_BAND",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_LOW_BAND"]
        ["MWMMC_FAILURE_1553B_CMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_CMFCD",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_CMFCD"]
        ["fuel_sys_left_transfer_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fuel_sys_left_transfer_pump",
            ["mm"] = 0,
        }, -- end of ["fuel_sys_left_transfer_pump"]
        ["rudder_trim_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "rudder_trim_fail",
            ["mm"] = 0,
        }, -- end of ["rudder_trim_fail"]
        ["HYD_Transf"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_Transf",
            ["mm"] = 0,
        }, -- end of ["HYD_Transf"]
        ["FCS_FAILURE_L_ELEVATOR_ELEC_C"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_ELEC_C",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_ELEC_C"]
        ["es_damage_StarterGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_StarterGenerator",
            ["mm"] = 0,
        }, -- end of ["es_damage_StarterGenerator"]
        ["FUEL_TANK_00_FIRE_STOPPED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_FIRE_STOPPED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_FIRE_STOPPED"]
        ["ppf_FireLeft"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_FireLeft",
            ["mm"] = 0,
        }, -- end of ["ppf_FireLeft"]
        ["EMMC_FAILURE_DC_GENERATOR_VOLTAGE_HIGH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DC_GENERATOR_VOLTAGE_HIGH",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DC_GENERATOR_VOLTAGE_HIGH"]
        ["VHF_AM_RADIO_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_AM_RADIO_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["VHF_AM_RADIO_FAILURE_TOTAL"]
        ["UNCR_RH_STRUT_DOWN_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_RH_STRUT_DOWN_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_RH_STRUT_DOWN_LOCK_FAILURE"]
        ["RPMFault_LeftEngine"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "RPMFault_LeftEngine",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["RPMFault_LeftEngine"]
        ["F2_TOP_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "F2_TOP_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["F2_TOP_CYLINDER"]
        ["FUEL_BOOSTER_FUEL_PUMP_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_DEGRADED"]
        ["INST_SPEEDOMETER_DEPRESSURIZATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_SPEEDOMETER_DEPRESSURIZATION",
            ["mm"] = 0,
        }, -- end of ["INST_SPEEDOMETER_DEPRESSURIZATION"]
        ["Failure_PP_EngL_Main_FFCS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngL_Main_FFCS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngL_Main_FFCS"]
        ["K14_NO_POWER_SUPPLY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "K14_NO_POWER_SUPPLY",
            ["mm"] = 0,
        }, -- end of ["K14_NO_POWER_SUPPLY"]
        ["INS_FAILURE_ATTITUDE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_ATTITUDE",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_ATTITUDE"]
        ["INST_TACH0_POOR_CONNECTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH0_POOR_CONNECTION",
            ["mm"] = 0,
        }, -- end of ["INST_TACH0_POOR_CONNECTION"]
        ["ENG0_BOOST_REGULATOR_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_BOOST_REGULATOR_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ENG0_BOOST_REGULATOR_MALFUNCTION"]
        ["MANIFOLD_LINE_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MANIFOLD_LINE_LEAK",
            ["mm"] = 0,
        }, -- end of ["MANIFOLD_LINE_LEAK"]
        ["INS_FAILURE_ACC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_ACC",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_ACC"]
        ["IFFCC_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IFFCC_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["IFFCC_FAILURE_TOTAL"]
        ["RWR_FAILURE_QUAD225"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_QUAD225",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_QUAD225"]
        ["FCS_FAILURE_ROLL_ELEC_SERVO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_ELEC_SERVO_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_ELEC_SERVO_2"]
        ["RDR_FAILURE_PREESURIZATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_PREESURIZATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_PREESURIZATION"]
        ["ENGINE_FAILURE_APD88_STARTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_APD88_STARTER",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_APD88_STARTER"]
        ["AN_ALR69V_FAILURE_SENSOR_NOSE_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALR69V_FAILURE_SENSOR_NOSE_LEFT",
            ["mm"] = 0,
        }, -- end of ["AN_ALR69V_FAILURE_SENSOR_NOSE_LEFT"]
        ["Failure_PP_RightPTS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_RightPTS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_RightPTS"]
        ["GUN_RIGHT_MG131_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG131_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG131_OPEN_CIRCUIT"]
        ["RUDDERSERV"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RUDDERSERV",
            ["mm"] = 0,
        }, -- end of ["RUDDERSERV"]
        ["TACAN_FAILURE_TRANSMITTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACAN_FAILURE_TRANSMITTER",
            ["mm"] = 0,
        }, -- end of ["TACAN_FAILURE_TRANSMITTER"]
        ["GUN_RIGHT_MG151_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG151_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG151_BARREL_WORN"]
        ["GUN_LEFT_IN_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_IN_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_IN_BARREL_WORN"]
        ["SAR_fast"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "SAR_fast",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["SAR_fast"]
        ["CTRL_TAIL_ROTOR_CONTROL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["id"] = "CTRL_TAIL_ROTOR_CONTROL_FAILURE",
            ["mmint"] = 1,
            ["enable"] = false,
            ["mm"] = 0,
        }, -- end of ["CTRL_TAIL_ROTOR_CONTROL_FAILURE"]
        ["W_S_L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "W_S_L",
            ["mm"] = 0,
        }, -- end of ["W_S_L"]
        ["FCS_FAILURE_Q_SENSOR_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_Q_SENSOR_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_Q_SENSOR_2"]
        ["fsf_LeftBoostPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fsf_LeftBoostPump",
            ["mm"] = 0,
        }, -- end of ["fsf_LeftBoostPump"]
        ["OIL_DILUTION_SOLENOID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_DILUTION_SOLENOID",
            ["mm"] = 0,
        }, -- end of ["OIL_DILUTION_SOLENOID"]
        ["OXYN_RIGHT_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYN_RIGHT_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["OXYN_RIGHT_CONTAINER_PERFORATED"]
        ["FCS_FAILURE_L_ELEVATOR_HYD_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_HYD_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_HYD_1"]
        ["AOASENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AOASENSOR",
            ["mm"] = 0,
        }, -- end of ["AOASENSOR"]
        ["hydro_main_irreversible_valve"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro_main_irreversible_valve",
            ["mm"] = 0,
        }, -- end of ["hydro_main_irreversible_valve"]
        ["fuel_sys_feed_tank_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["id"] = "fuel_sys_feed_tank_pump",
            ["mmint"] = 1,
            ["enable"] = false,
            ["mm"] = 0,
        }, -- end of ["fuel_sys_feed_tank_pump"]
        ["GMC1AE_GYRO_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GMC1AE_GYRO_FAILURE",
            ["mm"] = 0,
        }, -- end of ["GMC1AE_GYRO_FAILURE"]
        ["RDR_FAILURE_RECEIVER_DEGRATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_RECEIVER_DEGRATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_RECEIVER_DEGRATION"]
        ["SOPLO_FAILURE_PARTIAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SOPLO_FAILURE_PARTIAL",
            ["mm"] = 0,
        }, -- end of ["SOPLO_FAILURE_PARTIAL"]
        ["hsf_ControlHydraulic"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hsf_ControlHydraulic",
            ["mm"] = 0,
        }, -- end of ["hsf_ControlHydraulic"]
        ["JADRO_1A_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "JADRO_1A_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["JADRO_1A_FAILURE_TOTAL"]
        ["KPP_FAILURE_PARTIAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "KPP_FAILURE_PARTIAL",
            ["mm"] = 0,
        }, -- end of ["KPP_FAILURE_PARTIAL"]
        ["OIL_RADIATOR_SENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_RADIATOR_SENSOR",
            ["mm"] = 0,
        }, -- end of ["OIL_RADIATOR_SENSOR"]
        ["DMT_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DMT_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["DMT_FAILURE_TOTAL"]
        ["hs_damage_GainAccumulator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_GainAccumulator",
            ["mm"] = 0,
        }, -- end of ["hs_damage_GainAccumulator"]
        ["FWD_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FWD_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["FWD_TANK_LEAK"]
        ["radioalt_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "radioalt_fail",
            ["mm"] = 0,
        }, -- end of ["radioalt_fail"]
        ["INST_VARIOMETER_CLOGGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_VARIOMETER_CLOGGED",
            ["mm"] = 0,
        }, -- end of ["INST_VARIOMETER_CLOGGED"]
        ["OESP_FAILURE_FL_DISP_L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_FL_DISP_L",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_FL_DISP_L"]
        ["Failure_Gear_NWS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Gear_NWS",
            ["mm"] = 0,
        }, -- end of ["Failure_Gear_NWS"]
        ["rws"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "rws",
            ["mm"] = 0,
        }, -- end of ["rws"]
        ["HUDDISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HUDDISPLAY",
            ["mm"] = 0,
        }, -- end of ["HUDDISPLAY"]
        ["l_gen"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "l_gen",
            ["mm"] = 0,
        }, -- end of ["l_gen"]
        ["OIL_RADIATOR_MOTOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_RADIATOR_MOTOR",
            ["mm"] = 0,
        }, -- end of ["OIL_RADIATOR_MOTOR"]
        ["hs_damage_GainAutoUnload"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_GainAutoUnload",
            ["mm"] = 0,
        }, -- end of ["hs_damage_GainAutoUnload"]
        ["FUSELAGE_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUSELAGE_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUSELAGE_TANK_LEAK"]
        ["MWMMC_FAILURE_IOC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_IOC",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_IOC"]
        ["SAR_hover_flight_glide"] = 
        {
            ["hh"] = 0,
            ["id"] = "SAR_hover_flight_glide",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["SAR_hover_flight_glide"]
        ["HORIZON_BAR_NOT_SETTLE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HORIZON_BAR_NOT_SETTLE",
            ["mm"] = 0,
        }, -- end of ["HORIZON_BAR_NOT_SETTLE"]
        ["r_gen"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "r_gen",
            ["mm"] = 0,
        }, -- end of ["r_gen"]
        ["OIL_DILUTION_WIRE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_DILUTION_WIRE",
            ["mm"] = 0,
        }, -- end of ["OIL_DILUTION_WIRE"]
        ["GUN_RIGHT_MG151_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG151_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG151_OPEN_CIRCUIT"]
        ["FCS_FAILURE_YAW_ELEC_SERVO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_ELEC_SERVO_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_ELEC_SERVO_2"]
        ["ELEC_SIGNAL_LIGHTS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_SIGNAL_LIGHTS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_SIGNAL_LIGHTS_FAILURE"]
        ["AAR_47_FAILURE_SENSOR_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AAR_47_FAILURE_SENSOR_RIGHT",
            ["mm"] = 0,
        }, -- end of ["AAR_47_FAILURE_SENSOR_RIGHT"]
        ["FAILURE_HYDRAULICS_1_PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_1_PUMP",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_1_PUMP"]
        ["R_GEAR_DLK_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_DLK_FAULT",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_DLK_FAULT"]
        ["fuel_sys_300left"] = 
        {
            ["hh"] = 0,
            ["id"] = "fuel_sys_300left",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["fuel_sys_300left"]
        ["FUEL_NITRO_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "FUEL_NITRO_TANK_MINOR_LEAK",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_NITRO_TANK_MINOR_LEAK"]
        ["FUEL_DROPTANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_DROPTANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_DROPTANK_MINOR_LEAK"]
        ["ELEC_RH_GEAR_DRIVE_WIRE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RH_GEAR_DRIVE_WIRE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["ELEC_RH_GEAR_DRIVE_WIRE_SEVERED"]
        ["INST_HUD_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_HUD_FAILURE",
            ["mm"] = 0,
        }, -- end of ["INST_HUD_FAILURE"]
        ["L_GEAR_DLK_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_DLK_FAULT",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_DLK_FAULT"]
        ["ELEC_LH_JUNCTION_BOX_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_LH_JUNCTION_BOX_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["ELEC_LH_JUNCTION_BOX_DESTROYED"]
        ["IGNITION_TERM_CONNECT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IGNITION_TERM_CONNECT",
            ["mm"] = 0,
        }, -- end of ["IGNITION_TERM_CONNECT"]
        ["ELEVONSERVOUTERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVOUTERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVOUTERLEFT"]
        ["NGear_ret_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "NGear_ret_fault",
            ["mm"] = 0,
        }, -- end of ["NGear_ret_fault"]
        ["FUELTANK3R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK3R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK3R"]
        ["LGear_ret_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LGear_ret_fault",
            ["mm"] = 0,
        }, -- end of ["LGear_ret_fault"]
        ["aileron_loss"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "aileron_loss",
            ["mm"] = 0,
        }, -- end of ["aileron_loss"]
        ["FCS_FAILURE_ROLL_RATE_GYRO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_RATE_GYRO_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_RATE_GYRO_1"]
        ["RKL_41_ANT_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RKL_41_ANT_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["RKL_41_ANT_DAMAGE"]
        ["Failure_PP_LeftAMAD_OilLeak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_LeftAMAD_OilLeak",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_LeftAMAD_OilLeak"]
        ["Failure_PP_EngR_Nozzle_CS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngR_Nozzle_CS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngR_Nozzle_CS"]
        ["hydro_main"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro_main",
            ["mm"] = 0,
        }, -- end of ["hydro_main"]
        ["RGear_ret_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RGear_ret_fault",
            ["mm"] = 0,
        }, -- end of ["RGear_ret_fault"]
        ["TACH_BREAK_IN_INDICATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACH_BREAK_IN_INDICATOR",
            ["mm"] = 0,
        }, -- end of ["TACH_BREAK_IN_INDICATOR"]
        ["TAIL_GEAR_U_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_U_LOCK",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_U_LOCK"]
        ["RADAR_ALT_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADAR_ALT_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RADAR_ALT_TOTAL_FAILURE"]
        ["INST_VARIOMETER_DEPRESSURIZATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_VARIOMETER_DEPRESSURIZATION",
            ["mm"] = 0,
        }, -- end of ["INST_VARIOMETER_DEPRESSURIZATION"]
        ["RDR_FAILURE_SERVO_OVERHEAT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_SERVO_OVERHEAT",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_SERVO_OVERHEAT"]
        ["FUEL_TANK_01_MAJOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_MAJOR_LEAK",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_MAJOR_LEAK"]
        ["MWMMC_FAILURE_1553B_FCS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_FCS",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_FCS"]
        ["hsf_UtilityHydraulic"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hsf_UtilityHydraulic",
            ["mm"] = 0,
        }, -- end of ["hsf_UtilityHydraulic"]
        ["ELEVONSERVINNERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVINNERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVINNERLEFT"]
        ["TAPEREC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAPEREC",
            ["mm"] = 0,
        }, -- end of ["TAPEREC"]
        ["ILS_FAILURE_ANT_LOCALIZER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_ANT_LOCALIZER",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_ANT_LOCALIZER"]
        ["csf_AutoFlap"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "csf_AutoFlap",
            ["mm"] = 0,
        }, -- end of ["csf_AutoFlap"]
        ["TVDISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TVDISPLAY",
            ["mm"] = 0,
        }, -- end of ["TVDISPLAY"]
        ["RDR_FAILURE_PEDESTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_PEDESTAL",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_PEDESTAL"]
        ["RDR_FAILURE_SERVOLOOP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_SERVOLOOP",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_SERVOLOOP"]
        ["ENG0_OIL_HOSE_0_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_HOSE_0_LEAK",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_HOSE_0_LEAK"]
        ["ELEC_EMERGENCY_GENERATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_EMERGENCY_GENERATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_EMERGENCY_GENERATOR_FAILURE"]
        ["ICS_FAILURE_AMPLIFIER_RIO_BU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ICS_FAILURE_AMPLIFIER_RIO_BU",
            ["mm"] = 0,
        }, -- end of ["ICS_FAILURE_AMPLIFIER_RIO_BU"]
        ["STARTER_SOL_SHORT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_SOL_SHORT",
            ["mm"] = 0,
        }, -- end of ["STARTER_SOL_SHORT"]
        ["FCS_FAILURE_NZ_SENSOR_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NZ_SENSOR_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NZ_SENSOR_2"]
        ["FCS_FAILURE_COMP_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_COMP_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_COMP_3"]
        ["PUMP_RELIEF_VALVE_SCREEN_CLOGGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PUMP_RELIEF_VALVE_SCREEN_CLOGGED",
            ["mm"] = 0,
        }, -- end of ["PUMP_RELIEF_VALVE_SCREEN_CLOGGED"]
        ["FCS_FAILURE_YAW_RATE_GYRO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_RATE_GYRO_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_RATE_GYRO_2"]
        ["OESP_FAILURE_MAWS_R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_MAWS_R",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_MAWS_R"]
        ["RWR_FAILURE_COMPUTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_COMPUTER",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_COMPUTER"]
        ["esf_LeftRectifier"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "esf_LeftRectifier",
            ["mm"] = 0,
        }, -- end of ["esf_LeftRectifier"]
        ["ELEC_BOOSTER_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_FAILURE"]
        ["AAR_47_FAILURE_SENSOR_BOTTOM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AAR_47_FAILURE_SENSOR_BOTTOM",
            ["mm"] = 0,
        }, -- end of ["AAR_47_FAILURE_SENSOR_BOTTOM"]
        ["BOMBS_ARMING_BROKEN_WIRING_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_BROKEN_WIRING_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_BROKEN_WIRING_LEFT"]
        ["MAINPITOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINPITOT",
            ["mm"] = 0,
        }, -- end of ["MAINPITOT"]
        ["FCS_FAILURE_R_ELEVATOR_ELEC_D"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_ELEC_D",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_ELEC_D"]
        ["AAR_47_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AAR_47_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["AAR_47_FAILURE_TOTAL"]
        ["CTRL_AILERON_ROD_MINOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_AILERON_ROD_MINOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_AILERON_ROD_MINOR_DAMAGE"]
        ["FCS_FAILURE_COMP_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_COMP_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_COMP_1"]
        ["COOLANT_RADIATOR_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_RADIATOR_WIRING",
            ["mm"] = 0,
        }, -- end of ["COOLANT_RADIATOR_WIRING"]
        ["FUEL_MW50_TANK_DRAIN_VALVE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_MW50_TANK_DRAIN_VALVE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["FUEL_MW50_TANK_DRAIN_VALVE_SEVERED"]
        ["AIRSPEED_INDICATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AIRSPEED_INDICATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["AIRSPEED_INDICATOR_FAILURE"]
        ["ELEC_RH_JUNCTION_BOX_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RH_JUNCTION_BOX_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["ELEC_RH_JUNCTION_BOX_DESTROYED"]
        ["abris_software"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "abris_software",
            ["mm"] = 0,
        }, -- end of ["abris_software"]
        ["GUN_FAIL_LEFT_OUT_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_LEFT_OUT_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_LEFT_OUT_GUN"]
        ["ROCKETS_INTERVALOMETER_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ROCKETS_INTERVALOMETER_WIRING",
            ["mm"] = 0,
        }, -- end of ["ROCKETS_INTERVALOMETER_WIRING"]
        ["pitot_blocked"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pitot_blocked",
            ["mm"] = 0,
        }, -- end of ["pitot_blocked"]
        ["CANARDFLAPLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDFLAPLEFT",
            ["mm"] = 0,
        }, -- end of ["CANARDFLAPLEFT"]
        ["fs_forward_LH_leakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_forward_LH_leakage",
            ["mm"] = 0,
        }, -- end of ["fs_forward_LH_leakage"]
        ["GYROS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GYROS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["GYROS_FAILURE_TOTAL"]
        ["RB05ANT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RB05ANT",
            ["mm"] = 0,
        }, -- end of ["RB05ANT"]
        ["GUN_RIGHT_CENTER_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_CENTER_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_CENTER_BARREL_WORN"]
        ["MWMMC_FAILURE_1553B_OESP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_OESP",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_OESP"]
        ["CTRL_ELEVATOR_TRIM_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_ELEVATOR_TRIM_FAILURE",
            ["mm"] = 0,
        }, -- end of ["CTRL_ELEVATOR_TRIM_FAILURE"]
        ["FUELTANK4R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK4R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK4R"]
        ["static_blocked"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "static_blocked",
            ["mm"] = 0,
        }, -- end of ["static_blocked"]
        ["MainReducer_Fire"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MainReducer_Fire",
            ["mm"] = 0,
        }, -- end of ["MainReducer_Fire"]
        ["CTRL_ELEVATOR_ROD_MINOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_ELEVATOR_ROD_MINOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_ELEVATOR_ROD_MINOR_DAMAGE"]
        ["FAILURE_HYDRAULICS_2_INTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_2_INTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_2_INTERNAL_LEAKAGE"]
        ["MWMMC_FAILURE_1553B_HUD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_HUD",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_HUD"]
        ["HORIZON_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HORIZON_FAULT",
            ["mm"] = 0,
        }, -- end of ["HORIZON_FAULT"]
        ["ELEC_BOOSTER_FUEL_PUMP_COIL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_COIL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_COIL_FAILURE"]
        ["ELEC_SUPERCHARGER_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_SUPERCHARGER_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_SUPERCHARGER_BULB_FAILURE"]
        ["PNEM_SUPERCHARGER_JACK_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_SUPERCHARGER_JACK_JAMMED",
            ["mm"] = 0,
        }, -- end of ["PNEM_SUPERCHARGER_JACK_JAMMED"]
        ["HYD_PUMP_3_FAIL_100"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_PUMP_3_FAIL_100",
            ["mm"] = 0,
        }, -- end of ["HYD_PUMP_3_FAIL_100"]
        ["FCS_FAILURE_ROLL_RATE_GYRO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_RATE_GYRO_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_RATE_GYRO_2"]
        ["ELEC_FUEL_PUMP_P2_COIL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_FUEL_PUMP_P2_COIL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_FUEL_PUMP_P2_COIL_FAILURE"]
        ["CANARDSERVORIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDSERVORIGHT",
            ["mm"] = 0,
        }, -- end of ["CANARDSERVORIGHT"]
        ["DVMS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DVMS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["DVMS_FAILURE_TOTAL"]
        ["VHF_FM_RADIO_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_FM_RADIO_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["VHF_FM_RADIO_FAILURE_TOTAL"]
        ["BOMBS_DAMAGE_ELINKAGE_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_ELINKAGE_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_ELINKAGE_RIGHT"]
        ["FUELTANK1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK1",
            ["mm"] = 0,
        }, -- end of ["FUELTANK1"]
        ["EMMC_FAILURE_BATTERY_DC1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_BATTERY_DC1",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_BATTERY_DC1"]
        ["CADC_WING_SWEEP_COMMAND_CHANNEL_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_WING_SWEEP_COMMAND_CHANNEL_2",
            ["mm"] = 0,
        }, -- end of ["CADC_WING_SWEEP_COMMAND_CHANNEL_2"]
        ["ELEC_GOVERNOR_BOX_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_GOVERNOR_BOX_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["ELEC_GOVERNOR_BOX_DAMAGED"]
        ["DTC_FAILURE_CARD_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DTC_FAILURE_CARD_BROKEN",
            ["mm"] = 0,
        }, -- end of ["DTC_FAILURE_CARD_BROKEN"]
        ["REVERSER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "REVERSER",
            ["mm"] = 0,
        }, -- end of ["REVERSER"]
        ["OXY_FAILURE_HIGH_PRESS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_HIGH_PRESS",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_HIGH_PRESS"]
        ["RDR_FAILURE_TRANSMITTER_DEGRATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_TRANSMITTER_DEGRATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_TRANSMITTER_DEGRATION"]
        ["TransitionalReductor_ShaveInOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TransitionalReductor_ShaveInOil",
            ["mm"] = 0,
        }, -- end of ["TransitionalReductor_ShaveInOil"]
        ["TURBINE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURBINE",
            ["mm"] = 0,
        }, -- end of ["TURBINE"]
        ["AUTOPILOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AUTOPILOT",
            ["mm"] = 0,
        }, -- end of ["AUTOPILOT"]
        ["dme_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "dme_fail",
            ["mm"] = 0,
        }, -- end of ["dme_fail"]
        ["UHF_ARC_159_FAILURE_REMOTE_DISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_REMOTE_DISPLAY",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_REMOTE_DISPLAY"]
        ["Failure_Ctrl_FCS_Ch1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_FCS_Ch1",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_FCS_Ch1"]
        ["RDR_FAILURE_PROCESSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_PROCESSOR",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_PROCESSOR"]
        ["OXYN_LEFT_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYN_LEFT_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["OXYN_LEFT_CONTAINER_PERFORATED"]
        ["RDR_FAILURE_PROCESSOR_DEGRATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_PROCESSOR_DEGRATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_PROCESSOR_DEGRATION"]
        ["ELEC_SIGNAL_LIGHTS_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_SIGNAL_LIGHTS_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ELEC_SIGNAL_LIGHTS_MALFUNCTION"]
        ["ef_rt12"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_rt12",
            ["mm"] = 0,
        }, -- end of ["ef_rt12"]
        ["es_damage_DMR"] = 
        {
            ["hh"] = 0,
            ["id"] = "es_damage_DMR",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["es_damage_DMR"]
        ["CTRL_LANDING_FLAPS_LH_MECHANICAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LANDING_FLAPS_LH_MECHANICAL",
            ["mm"] = 0,
        }, -- end of ["CTRL_LANDING_FLAPS_LH_MECHANICAL"]
        ["RDR_FAILURE_RECEIVER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_RECEIVER",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_RECEIVER"]
        ["EMMC_FAILURE_COCKPIT_PRESSURE_LOW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_COCKPIT_PRESSURE_LOW",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_COCKPIT_PRESSURE_LOW"]
        ["EMMC_FAILURE_BAU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_BAU",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_BAU"]
        ["MAGNETO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAGNETO_1",
            ["mm"] = 0,
        }, -- end of ["MAGNETO_1"]
        ["BOMBS_NO_VOLATAGE_AT_RACK_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_NO_VOLATAGE_AT_RACK_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_NO_VOLATAGE_AT_RACK_RIGHT"]
        ["FCS_FAILURE_WOW_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_WOW_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_WOW_2"]
        ["STATION_6_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_6_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_6_FAILURE"]
        ["EMMC_FAILURE_DADS_RPTU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DADS_RPTU",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DADS_RPTU"]
        ["TransitionalReductor_LowOilPressure"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "TransitionalReductor_LowOilPressure",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["TransitionalReductor_LowOilPressure"]
        ["OIL_SYSTEM_FAIL_100"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_SYSTEM_FAIL_100",
            ["mm"] = 0,
        }, -- end of ["OIL_SYSTEM_FAIL_100"]
        ["FAILURE_HYDRAULICS_2_ACCU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_2_ACCU",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_2_ACCU"]
        ["INST_TACH1_LOOM_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH1_LOOM_SEVERED",
            ["mm"] = 0,
        }, -- end of ["INST_TACH1_LOOM_SEVERED"]
        ["EMMC_FAILURE_TRU_AC2DC28V"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_TRU_AC2DC28V",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_TRU_AC2DC28V"]
        ["TAIL_GEAR_D_LOCK_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_D_LOCK_FAULT",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_D_LOCK_FAULT"]
        ["ELEVONOUTERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONOUTERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONOUTERRIGHT"]
        ["fsf_CrossfeedValve"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fsf_CrossfeedValve",
            ["mm"] = 0,
        }, -- end of ["fsf_CrossfeedValve"]
        ["FCS_FAILURE_LG_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_LG_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_LG_4"]
        ["ENG0_WASTEGATE_OIL_FEED_CLOGGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_WASTEGATE_OIL_FEED_CLOGGED",
            ["mm"] = 0,
        }, -- end of ["ENG0_WASTEGATE_OIL_FEED_CLOGGED"]
        ["BOOST_REG"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOOST_REG",
            ["mm"] = 0,
        }, -- end of ["BOOST_REG"]
        ["r_conv"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "r_conv",
            ["mm"] = 0,
        }, -- end of ["r_conv"]
        ["DDD_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DDD_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["DDD_FAILURE_TOTAL"]
        ["FUELTANK2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK2",
            ["mm"] = 0,
        }, -- end of ["FUELTANK2"]
        ["BOMBS_SOLENOID_FAULT_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_SOLENOID_FAULT_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_SOLENOID_FAULT_RIGHT"]
        ["FLIR_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FLIR_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["FLIR_FAILURE_TOTAL"]
        ["inverters_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "inverters_fail",
            ["mm"] = 0,
        }, -- end of ["inverters_fail"]
        ["l_conv"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "l_conv",
            ["mm"] = 0,
        }, -- end of ["l_conv"]
        ["STRAKE_LEFT_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STRAKE_LEFT_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STRAKE_LEFT_FAILURE"]
        ["CMS_FAILURE_PROGRAMMER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CMS_FAILURE_PROGRAMMER",
            ["mm"] = 0,
        }, -- end of ["CMS_FAILURE_PROGRAMMER"]
        ["ELEC_RED_SIGNAL_LIGHT_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RED_SIGNAL_LIGHT_BROKEN",
            ["mm"] = 0,
        }, -- end of ["ELEC_RED_SIGNAL_LIGHT_BROKEN"]
        ["HUD_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HUD_FAILURE",
            ["mm"] = 0,
        }, -- end of ["HUD_FAILURE"]
        ["mfd"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "mfd",
            ["mm"] = 0,
        }, -- end of ["mfd"]
        ["CARBAIR_GND_LEAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_GND_LEAD",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_GND_LEAD"]
        ["fuel_leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fuel_leak",
            ["mm"] = 0,
        }, -- end of ["fuel_leak"]
        ["hs_damage_MainAccumulator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_MainAccumulator",
            ["mm"] = 0,
        }, -- end of ["hs_damage_MainAccumulator"]
        ["PNEM_LH_BRAKE_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_LH_BRAKE_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_LH_BRAKE_HOSE_PERFORATED"]
        ["AFK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AFK",
            ["mm"] = 0,
        }, -- end of ["AFK"]
        ["UHF_ARC_159_FAILURE_INTERNAL_MODULE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_INTERNAL_MODULE",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_INTERNAL_MODULE"]
        ["INST_CLOCK_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_CLOCK_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["INST_CLOCK_MALFUNCTION"]
        ["CADC_CSDC_CONNECTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_CSDC_CONNECTION",
            ["mm"] = 0,
        }, -- end of ["CADC_CSDC_CONNECTION"]
        ["SUPERCHARGER_SOLENOID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SUPERCHARGER_SOLENOID",
            ["mm"] = 0,
        }, -- end of ["SUPERCHARGER_SOLENOID"]
        ["EEC_Failure_RightEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EEC_Failure_RightEngine",
            ["mm"] = 0,
        }, -- end of ["EEC_Failure_RightEngine"]
        ["hydro_auxiliary"] = 
        {
            ["hh"] = 0,
            ["id"] = "hydro_auxiliary",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["hydro_auxiliary"]
        ["GUN_LEFT_MG151_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG151_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG151_OPEN_CIRCUIT"]
        ["slats"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "slats",
            ["mm"] = 0,
        }, -- end of ["slats"]
        ["ROCKETS_DEFECTIVE_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ROCKETS_DEFECTIVE_WIRING",
            ["mm"] = 0,
        }, -- end of ["ROCKETS_DEFECTIVE_WIRING"]
        ["ICS_FAILURE_AMPLIFIER_PILOT_BU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ICS_FAILURE_AMPLIFIER_PILOT_BU",
            ["mm"] = 0,
        }, -- end of ["ICS_FAILURE_AMPLIFIER_PILOT_BU"]
        ["hydro_diaphragm"] = 
        {
            ["hh"] = 0,
            ["id"] = "hydro_diaphragm",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["hydro_diaphragm"]
        ["MWMMC_FAILURE_DMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_DMP",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_DMP"]
        ["fsf_AutoBalance"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fsf_AutoBalance",
            ["mm"] = 0,
        }, -- end of ["fsf_AutoBalance"]
        ["FCS_FAILURE_PITCH_LVDT_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_LVDT_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_LVDT_4"]
        ["NOSE_AIRSPEED_INDICATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "NOSE_AIRSPEED_INDICATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["NOSE_AIRSPEED_INDICATOR_FAILURE"]
        ["SWMMC_FAILURE_DMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_DMP",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_DMP"]
        ["EMMC_FAILURE_EMMC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_EMMC",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_EMMC"]
        ["ELEC_BOMBABWGERAT_RELEASE_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOMBABWGERAT_RELEASE_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOMBABWGERAT_RELEASE_MALFUNCTION"]
        ["EXT_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EXT_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["EXT_TANK_PUMP_FAULT"]
        ["acs"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["mm"] = 0,
        }, -- end of ["acs"]
        ["FCS_FAILURE_YAW_LVDT_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_LVDT_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_LVDT_1"]
        ["AN_ALE_40V_FAILURE_CONTAINER_RIGHT_GEAR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALE_40V_FAILURE_CONTAINER_RIGHT_GEAR",
            ["mm"] = 0,
        }, -- end of ["AN_ALE_40V_FAILURE_CONTAINER_RIGHT_GEAR"]
        ["os_damage_BalloonLeakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "os_damage_BalloonLeakage",
            ["mm"] = 0,
        }, -- end of ["os_damage_BalloonLeakage"]
        ["RWR_FAILURE_ANTENNA_FRONT_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_ANTENNA_FRONT_RIGHT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_ANTENNA_FRONT_RIGHT"]
        ["MWMMC_FAILURE_1553B_EMMC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_EMMC",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_EMMC"]
        ["RWR_FAILURE_SENSOR_TAIL_R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_SENSOR_TAIL_R",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_SENSOR_TAIL_R"]
        ["STRAKE_RIGHT_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STRAKE_RIGHT_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STRAKE_RIGHT_FAILURE"]
        ["FCS_FAILURE_WOW_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_WOW_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_WOW_4"]
        ["FCS_FAILURE_NZ_SENSOR_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NZ_SENSOR_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NZ_SENSOR_1"]
        ["ENG0_GOVERNOR_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_GOVERNOR_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["ENG0_GOVERNOR_MALFUNCTION"]
        ["ENG0_GOVERNOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_GOVERNOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ENG0_GOVERNOR_FAILURE"]
        ["main_reductor_chip"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "main_reductor_chip",
            ["mm"] = 0,
        }, -- end of ["main_reductor_chip"]
        ["AIRBRAKESERVO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AIRBRAKESERVO",
            ["mm"] = 0,
        }, -- end of ["AIRBRAKESERVO"]
        ["FAILURE_SMS_PYLON_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_2",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_2"]
        ["FUEL_TANK_00_LEAK_STOPPED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_LEAK_STOPPED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_LEAK_STOPPED"]
        ["INST_COMPASS_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_COMPASS_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["INST_COMPASS_MALFUNCTION"]
        ["ELEC_REAR_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_REAR_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_REAR_FUEL_PUMP_FAILURE"]
        ["fs_forward_RH_leakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_forward_RH_leakage",
            ["mm"] = 0,
        }, -- end of ["fs_forward_RH_leakage"]
        ["CADC_FAILURE_PRESSURE_ALT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_PRESSURE_ALT",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_PRESSURE_ALT"]
        ["elevator_loss"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "elevator_loss",
            ["mm"] = 0,
        }, -- end of ["elevator_loss"]
        ["STATION_2_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_2_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_2_FAILURE"]
        ["DEFECTIVE_INSTRUMENT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DEFECTIVE_INSTRUMENT",
            ["mm"] = 0,
        }, -- end of ["DEFECTIVE_INSTRUMENT"]
        ["gs_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "gs_fail",
            ["mm"] = 0,
        }, -- end of ["gs_fail"]
        ["FCS_FAILURE_P_SENSOR_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_P_SENSOR_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_P_SENSOR_2"]
        ["pp_damage_EmergMaxNormFreq"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_EmergMaxNormFreq",
            ["mm"] = 0,
        }, -- end of ["pp_damage_EmergMaxNormFreq"]
        ["ELEC_FORWARD_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_FORWARD_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_FORWARD_FUEL_PUMP_FAILURE"]
        ["ppf_LeftOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_LeftOil",
            ["mm"] = 0,
        }, -- end of ["ppf_LeftOil"]
        ["CADC_MANEUVER_FLAP_COMMAND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_MANEUVER_FLAP_COMMAND",
            ["mm"] = 0,
        }, -- end of ["CADC_MANEUVER_FLAP_COMMAND"]
        ["GTS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GTS",
            ["mm"] = 0,
        }, -- end of ["GTS"]
        ["GUN_RIGHT_IN_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_IN_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_IN_OPEN_CIRCUIT"]
        ["RWR_FAILURE_QUAD315"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_QUAD315",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_QUAD315"]
        ["FCS_FAILURE_COMP_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_COMP_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_COMP_4"]
        ["ef_shutdown"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_shutdown",
            ["mm"] = 0,
        }, -- end of ["ef_shutdown"]
        ["FCS_FAILURE_LG_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_LG_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_LG_2"]
        ["ELEC_FUEL_PUMP_P2_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_FUEL_PUMP_P2_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_FUEL_PUMP_P2_FAILURE"]
        ["r_engine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "r_engine",
            ["mm"] = 0,
        }, -- end of ["r_engine"]
        ["TRN_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TRN_FAIL",
            ["mm"] = 0,
        }, -- end of ["TRN_FAIL"]
        ["FCS_FAILURE_NZ_SENSOR_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NZ_SENSOR_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NZ_SENSOR_4"]
        ["FCS_FAILURE_YAW_AUGD_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_AUGD_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_AUGD_1"]
        ["DTC_FAILURE_READER_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DTC_FAILURE_READER_BROKEN",
            ["mm"] = 0,
        }, -- end of ["DTC_FAILURE_READER_BROKEN"]
        ["FAILURE_SMS_PYLON_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_3",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_3"]
        ["es_damage_Generator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Generator",
            ["mm"] = 0,
        }, -- end of ["es_damage_Generator"]
        ["ELEC_C5_LAMP_POOR_CONTACT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_C5_LAMP_POOR_CONTACT",
            ["mm"] = 0,
        }, -- end of ["ELEC_C5_LAMP_POOR_CONTACT"]
        ["ELEC_CABIN_LIGHTS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_CABIN_LIGHTS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_CABIN_LIGHTS_FAILURE"]
        ["INS_PU_REJECTED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_PU_REJECTED",
            ["mm"] = 0,
        }, -- end of ["INS_PU_REJECTED"]
        ["AGK_47B_GYRO_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AGK_47B_GYRO_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["AGK_47B_GYRO_TOTAL_FAILURE"]
        ["HYDR_ACCUMULATOR_LOW_AIR_PRESSURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_ACCUMULATOR_LOW_AIR_PRESSURE",
            ["mm"] = 0,
        }, -- end of ["HYDR_ACCUMULATOR_LOW_AIR_PRESSURE"]
        ["CTRL_COMPASS_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_COMPASS_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["CTRL_COMPASS_DESTROYED"]
        ["ELEC_FUEL_PUMP_P1_COIL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_FUEL_PUMP_P1_COIL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_FUEL_PUMP_P1_COIL_FAILURE"]
        ["BOMBS_DAMAGE_LINKAGE_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_LINKAGE_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_LINKAGE_LEFT"]
        ["RDR_FAILURE_ANTENNA_DEGRATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_ANTENNA_DEGRATION",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_ANTENNA_DEGRATION"]
        ["FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE_SEVERE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE_SEVERE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE_SEVERE"]
        ["es_damage_Battery"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Battery",
            ["mm"] = 0,
        }, -- end of ["es_damage_Battery"]
        ["FCS_FAILURE_PITCH_RATE_GYRO_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_RATE_GYRO_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_RATE_GYRO_4"]
        ["CTRL_LH_SLAT_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LH_SLAT_JAMMED",
            ["mm"] = 0,
        }, -- end of ["CTRL_LH_SLAT_JAMMED"]
        ["CMS_FAILURE_RIGHT_DISPENSER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CMS_FAILURE_RIGHT_DISPENSER",
            ["mm"] = 0,
        }, -- end of ["CMS_FAILURE_RIGHT_DISPENSER"]
        ["SWMMC_FAILURE_CTVS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_CTVS",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_CTVS"]
        ["Failure_Elec_RightTransformerRectifier"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_RightTransformerRectifier",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_RightTransformerRectifier"]
        ["TURNIND_POINTER_FAILS_NO_VACUUM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_POINTER_FAILS_NO_VACUUM",
            ["mm"] = 0,
        }, -- end of ["TURNIND_POINTER_FAILS_NO_VACUUM"]
        ["UNLOAD_VALVE_NOT_UNLOAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNLOAD_VALVE_NOT_UNLOAD",
            ["mm"] = 0,
        }, -- end of ["UNLOAD_VALVE_NOT_UNLOAD"]
        ["TailRotorControlFailure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TailRotorControlFailure",
            ["mm"] = 0,
        }, -- end of ["TailRotorControlFailure"]
        ["HYDR1ACC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR1ACC",
            ["mm"] = 0,
        }, -- end of ["HYDR1ACC"]
        ["FCS_FAILURE_L_ELEVATOR_ELEC_B"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_ELEC_B",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_ELEC_B"]
        ["PNEM_CANNONS_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_CANNONS_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_CANNONS_HOSE_PERFORATED"]
        ["HYD_ALT_1_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_ALT_1_FAIL",
            ["mm"] = 0,
        }, -- end of ["HYD_ALT_1_FAIL"]
        ["es_damage_MainInverter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_MainInverter",
            ["mm"] = 0,
        }, -- end of ["es_damage_MainInverter"]
        ["AUX_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AUX_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["AUX_TANK_LEAK"]
        ["PUMP_FAILS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PUMP_FAILS",
            ["mm"] = 0,
        }, -- end of ["PUMP_FAILS"]
        ["FUELTANK3L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK3L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK3L"]
        ["ENGINE_FAILURE_COMBUSTOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_COMBUSTOR",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_COMBUSTOR"]
        ["asc_y"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "asc_y",
            ["mm"] = 0,
        }, -- end of ["asc_y"]
        ["FCS_FAILURE_WOW_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_WOW_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_WOW_3"]
        ["MAIN_L_GEAR_D_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAIN_L_GEAR_D_LOCK",
            ["mm"] = 0,
        }, -- end of ["MAIN_L_GEAR_D_LOCK"]
        ["SWMMC_DVR_NO_RS422_COMM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_DVR_NO_RS422_COMM",
            ["mm"] = 0,
        }, -- end of ["SWMMC_DVR_NO_RS422_COMM"]
        ["adf_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "adf_fail",
            ["mm"] = 0,
        }, -- end of ["adf_fail"]
        ["FUEL_RH_WING_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_RH_WING_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_RH_WING_TANK_MINOR_LEAK"]
        ["Failure_Hyd_HYD1B_Leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Hyd_HYD1B_Leak",
            ["mm"] = 0,
        }, -- end of ["Failure_Hyd_HYD1B_Leak"]
        ["STARTER_RELAY_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_RELAY_FAULT",
            ["mm"] = 0,
        }, -- end of ["STARTER_RELAY_FAULT"]
        ["EMMC_FAILURE_LWC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_LWC",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_LWC"]
        ["ENG0_WATER_RADIATOR_0_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_WATER_RADIATOR_0_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_WATER_RADIATOR_0_PIERCED"]
        ["FAILURE_SMS_PYLON_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_4",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_4"]
        ["TILS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TILS",
            ["mm"] = 0,
        }, -- end of ["TILS"]
        ["BOMBS_ARMING_BROKEN_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_BROKEN_WIRING",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_BROKEN_WIRING"]
        ["CADC_FAILURE_TEMPERATURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_TEMPERATURE",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_TEMPERATURE"]
        ["es_damage_AltInverter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_AltInverter",
            ["mm"] = 0,
        }, -- end of ["es_damage_AltInverter"]
        ["Surge_RightEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Surge_RightEngine",
            ["mm"] = 0,
        }, -- end of ["Surge_RightEngine"]
        ["sensf_PITOT_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sensf_PITOT_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["sensf_PITOT_DAMAGE"]
        ["TAIL_GEAR_FAIL_GO_DOWN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_FAIL_GO_DOWN",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_FAIL_GO_DOWN"]
        ["ef_fire"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_fire",
            ["mm"] = 0,
        }, -- end of ["ef_fire"]
        ["fs_damage_transfer_pumps"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_transfer_pumps",
            ["mm"] = 0,
        }, -- end of ["fs_damage_transfer_pumps"]
        ["DEFECTIVE_MECHANISM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DEFECTIVE_MECHANISM",
            ["mm"] = 0,
        }, -- end of ["DEFECTIVE_MECHANISM"]
        ["fire_sys_fireAPU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fire_sys_fireAPU",
            ["mm"] = 0,
        }, -- end of ["fire_sys_fireAPU"]
        ["CADC_FAILURE_STATIC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_STATIC",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_STATIC"]
        ["CADC_FAILURE_IAS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_IAS",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_IAS"]
        ["RWRANTLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTLEFT",
            ["mm"] = 0,
        }, -- end of ["RWRANTLEFT"]
        ["es_damage_VU3"] = 
        {
            ["hh"] = 0,
            ["id"] = "es_damage_VU3",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["es_damage_VU3"]
        ["fs_damage_swapping_pumps"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_swapping_pumps",
            ["mm"] = 0,
        }, -- end of ["fs_damage_swapping_pumps"]
        ["FAILURE_SMS_PYLON_5"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_5",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_5"]
        ["ecf"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["mm"] = 0,
        }, -- end of ["ecf"]
        ["GUN_LEFT_CENTER_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_CENTER_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_CENTER_MOUNT_LOOSE"]
        ["ELEC_BOMBABWGERAT_RELEASE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOMBABWGERAT_RELEASE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOMBABWGERAT_RELEASE_FAILURE"]
        ["ELEC_PITOT_HEAT_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_PITOT_HEAT_WIRING",
            ["mm"] = 0,
        }, -- end of ["ELEC_PITOT_HEAT_WIRING"]
        ["FUEL_AUX_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_AUX_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_AUX_TANK_MINOR_LEAK"]
        ["Failure_Fuel_QuantityGaging"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_QuantityGaging",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_QuantityGaging"]
        ["fire_sys_fire_LE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fire_sys_fire_LE",
            ["mm"] = 0,
        }, -- end of ["fire_sys_fire_LE"]
        ["GUN_LEFT_MG151_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG151_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG151_BARREL_WORN"]
        ["JESTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "JESTER",
            ["mm"] = 0,
        }, -- end of ["JESTER"]
        ["PNEM_BRAKE_RELAY_MALFUNCTION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_BRAKE_RELAY_MALFUNCTION",
            ["mm"] = 0,
        }, -- end of ["PNEM_BRAKE_RELAY_MALFUNCTION"]
        ["FCS_FAILURE_AOA_SENSOR_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_AOA_SENSOR_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_AOA_SENSOR_1"]
        ["VHF_ARC_182_FAILURE_REMOTE_DISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_REMOTE_DISPLAY",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_REMOTE_DISPLAY"]
        ["GMC_GYRO_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GMC_GYRO_FAILURE",
            ["mm"] = 0,
        }, -- end of ["GMC_GYRO_FAILURE"]
        ["MWMMC_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE"]
        ["FCS_FAILURE_YAW_AUGD_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_AUGD_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_AUGD_2"]
        ["FUEL_MAIN_TANK_MAJOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_MAIN_TANK_MAJOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_MAIN_TANK_MAJOR_LEAK"]
        ["UHF_ARC_159_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_TOTAL"]
        ["MWMMC_FAILURE_AVI"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_AVI",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_AVI"]
        ["ENGINE_FAILURE_N1_COMPRESSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_N1_COMPRESSOR",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_N1_COMPRESSOR"]
        ["RIGHT_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["RIGHT_CYLINDER"]
        ["SWMMC_FAILURE_AVI"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_AVI",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_AVI"]
        ["Failure_Ctrl_FCS_Ch2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_FCS_Ch2",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_FCS_Ch2"]
        ["fs_damage_engine_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_engine_pump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_engine_pump"]
        ["FCS_FAILURE_WOW_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_WOW_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_WOW_1"]
        ["ROOF_AIRSPEED_INDICATOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ROOF_AIRSPEED_INDICATOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ROOF_AIRSPEED_INDICATOR_FAILURE"]
        ["RADARDISPL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARDISPL",
            ["mm"] = 0,
        }, -- end of ["RADARDISPL"]
        ["OESP_FAILURE_FL_DISP_R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_FL_DISP_R",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_FL_DISP_R"]
        ["loc_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "loc_fail",
            ["mm"] = 0,
        }, -- end of ["loc_fail"]
        ["fuel_sys_right_transfer_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fuel_sys_right_transfer_pump",
            ["mm"] = 0,
        }, -- end of ["fuel_sys_right_transfer_pump"]
        ["ENG0_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_JAMMED",
            ["mm"] = 0,
        }, -- end of ["ENG0_JAMMED"]
        ["COOLANT_POOR_CONNTECT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_POOR_CONNTECT",
            ["mm"] = 0,
        }, -- end of ["COOLANT_POOR_CONNTECT"]
        ["TURNIND_POINTER_FAILS_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_POINTER_FAILS_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["TURNIND_POINTER_FAILS_DEFECTIVE"]
        ["FCS_FAILURE_R_ELEVATOR_HYD_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_HYD_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_HYD_1"]
        ["CTRL_LANDING_FLAPS_RH_MECHANICAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LANDING_FLAPS_RH_MECHANICAL",
            ["mm"] = 0,
        }, -- end of ["CTRL_LANDING_FLAPS_RH_MECHANICAL"]
        ["GUN_FAIL_RIGHT_OUT_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_RIGHT_OUT_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_RIGHT_OUT_GUN"]
        ["A11_CLOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "A11_CLOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["A11_CLOCK_FAILURE"]
        ["ENG0_STARTER_MOTOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_STARTER_MOTOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ENG0_STARTER_MOTOR_FAILURE"]
        ["FUELTANK4L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK4L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK4L"]
        ["pp_damage_Ignition"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_Ignition",
            ["mm"] = 0,
        }, -- end of ["pp_damage_Ignition"]
        ["Failure_Elec_LeftTransformerRectifier"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_LeftTransformerRectifier",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_LeftTransformerRectifier"]
        ["FAILURE_EXT_LIGHT_NAV_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_NAV_RIGHT",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_NAV_RIGHT"]
        ["ELEC_STARTER_SOLENOID_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_STARTER_SOLENOID_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_STARTER_SOLENOID_FAILURE"]
        ["RWR_FAILURE_BLANKER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_BLANKER",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_BLANKER"]
        ["GUN_LEFT_OUT_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_OUT_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_OUT_MOUNT_LOOSE"]
        ["VHF_CRFUEL_MAIN_TANK_MINOR_LEAKYSTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_CRFUEL_MAIN_TANK_MINOR_LEAKYSTAL",
            ["mm"] = 0,
        }, -- end of ["VHF_CRFUEL_MAIN_TANK_MINOR_LEAKYSTAL"]
        ["ELEC_LH_GEAR_DRIVE_WIRE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_LH_GEAR_DRIVE_WIRE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["ELEC_LH_GEAR_DRIVE_WIRE_SEVERED"]
        ["LEFT_FLAP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_FLAP_FAULT",
            ["mm"] = 0,
        }, -- end of ["LEFT_FLAP_FAULT"]
        ["FUEL_TANK_03_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_TANK_03_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_03_MINOR_LEAK"]
        ["FLEX_S_MAIN_LAMP_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FLEX_S_MAIN_LAMP_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["FLEX_S_MAIN_LAMP_DEFECTIVE"]
        ["FUEL_TANK_04_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_TANK_04_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_04_MINOR_LEAK"]
        ["es_damage_Inverter115_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Inverter115_2",
            ["mm"] = 0,
        }, -- end of ["es_damage_Inverter115_2"]
        ["TAIL_GEAR_FAIL_GO_UP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_FAIL_GO_UP",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_FAIL_GO_UP"]
        ["INS_GYROS_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_GYROS_FAIL",
            ["mm"] = 0,
        }, -- end of ["INS_GYROS_FAIL"]
        ["FCS_FAILURE_EFCS_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_EFCS_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_EFCS_1"]
        ["SHARS_FAILURE_SENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SHARS_FAILURE_SENSOR",
            ["mm"] = 0,
        }, -- end of ["SHARS_FAILURE_SENSOR"]
        ["FCS_FAILURE_P_SENSOR_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_P_SENSOR_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_P_SENSOR_3"]
        ["RADARALTANT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARALTANT",
            ["mm"] = 0,
        }, -- end of ["RADARALTANT"]
        ["EMMC_FAILURE_AC_GENERATOR_SUBSYSTEM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_AC_GENERATOR_SUBSYSTEM",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_AC_GENERATOR_SUBSYSTEM"]
        ["SAR_1_2_95"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SAR_1_2_95",
            ["mm"] = 0,
        }, -- end of ["SAR_1_2_95"]
        ["FCS_FAILURE_PITCH_LVDT_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_LVDT_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_LVDT_1"]
        ["pp_damage_MainMaxFreq"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_MainMaxFreq",
            ["mm"] = 0,
        }, -- end of ["pp_damage_MainMaxFreq"]
        ["Failure_Fuel_Tank4Transfer"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_Tank4Transfer",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_Tank4Transfer"]
        ["CTRL_RUDDER_ROD_MINOR_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_RUDDER_ROD_MINOR_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["CTRL_RUDDER_ROD_MINOR_DAMAGE"]
        ["FUEL_TANK_01_LEAK_STOPPED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_LEAK_STOPPED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_LEAK_STOPPED"]
        ["VHF_ARC_182_FAILURE_INTERNAL_MODULE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_INTERNAL_MODULE",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_INTERNAL_MODULE"]
        ["engine_flameout_recoverable"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_flameout_recoverable",
            ["mm"] = 0,
        }, -- end of ["engine_flameout_recoverable"]
        ["CARBAIR_BREAK_LEADS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_BREAK_LEADS",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_BREAK_LEADS"]
        ["R_GEAR_UPL_NOT_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_UPL_NOT_LOCK",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_UPL_NOT_LOCK"]
        ["Failure_Ctrl_FCS_Ch4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_FCS_Ch4",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_FCS_Ch4"]
        ["UNCR_RH_STRUT_DRIVE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_RH_STRUT_DRIVE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_RH_STRUT_DRIVE_FAILURE"]
        ["GUN_LEFT_CENTER_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_CENTER_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_CENTER_AMMUN_FAULT"]
        ["generator_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "generator_fail",
            ["mm"] = 0,
        }, -- end of ["generator_fail"]
        ["RPMFault_RightEngine"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "RPMFault_RightEngine",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["RPMFault_RightEngine"]
        ["RGear_ext_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RGear_ext_fault",
            ["mm"] = 0,
        }, -- end of ["RGear_ext_fault"]
        ["ELEC_UMFORMER_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UMFORMER_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UMFORMER_FAILURE"]
        ["CDU_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CDU_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["CDU_FAILURE_TOTAL"]
        ["FUELTANK5R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK5R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK5R"]
        ["apus"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "apus",
            ["mm"] = 0,
        }, -- end of ["apus"]
        ["FAILURE_HYDRAULICS_EMERGE_ACCU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_EMERGE_ACCU",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_EMERGE_ACCU"]
        ["CTRL_AILERON_ROD_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_AILERON_ROD_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["CTRL_AILERON_ROD_DESTROYED"]
        ["FCS_FAILURE_PITCH_RATE_GYRO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_RATE_GYRO_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_RATE_GYRO_2"]
        ["UNCR_LH_STRUT_DRIVE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_LH_STRUT_DRIVE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_LH_STRUT_DRIVE_FAILURE"]
        ["ENGINE_FAILURE_N1_TURBINE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_N1_TURBINE",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_N1_TURBINE"]
        ["HYDR_EXTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_EXTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["HYDR_EXTERNAL_LEAKAGE"]
        ["Failure_Comp_MC2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Comp_MC2",
            ["mm"] = 0,
        }, -- end of ["Failure_Comp_MC2"]
        ["pp_damage_BladesBrake"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_BladesBrake",
            ["mm"] = 0,
        }, -- end of ["pp_damage_BladesBrake"]
        ["BATTERY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BATTERY",
            ["mm"] = 0,
        }, -- end of ["BATTERY"]
        ["RWR_FAILURE_RECEIVER_XX3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_RECEIVER_XX3",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_RECEIVER_XX3"]
        ["ELEC_MAIN_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_MAIN_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_MAIN_FUEL_PUMP_FAILURE"]
        ["CADC_ANGLE_OF_ATTACK_SIGNAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_ANGLE_OF_ATTACK_SIGNAL",
            ["mm"] = 0,
        }, -- end of ["CADC_ANGLE_OF_ATTACK_SIGNAL"]
        ["GUN_LEFT_IN_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_IN_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_IN_AMMUN_FAULT"]
        ["EMMC_FAILURE_SCU_DC2AC36V"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_SCU_DC2AC36V",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_SCU_DC2AC36V"]
        ["BOMBS_NO_VOLATAGE_AT_RACK_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_NO_VOLATAGE_AT_RACK_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_NO_VOLATAGE_AT_RACK_LEFT"]
        ["VHF_TOTAL_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_TOTAL_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["VHF_TOTAL_DAMAGE"]
        ["FUEL_TANK_01_FIRE"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_FIRE",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_FIRE"]
        ["ELECTRIC_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELECTRIC_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELECTRIC_FAILURE"]
        ["VHF_VT_BURNED_OUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_VT_BURNED_OUT",
            ["mm"] = 0,
        }, -- end of ["VHF_VT_BURNED_OUT"]
        ["MW_50_VALVE_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MW_50_VALVE_FAULT",
            ["mm"] = 0,
        }, -- end of ["MW_50_VALVE_FAULT"]
        ["HYDR2ACC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR2ACC",
            ["mm"] = 0,
        }, -- end of ["HYDR2ACC"]
        ["fs_aft_RH_leakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_aft_RH_leakage",
            ["mm"] = 0,
        }, -- end of ["fs_aft_RH_leakage"]
        ["FUEL_ENGINE0_FUEL_PUMP_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_ENGINE0_FUEL_PUMP_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_ENGINE0_FUEL_PUMP_DEGRADED"]
        ["Failure_RightEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_RightEngine",
            ["mm"] = 0,
        }, -- end of ["Failure_RightEngine"]
        ["CNI_FAILURE_ILS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_ILS",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_ILS"]
        ["HYDR_INTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_INTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["HYDR_INTERNAL_LEAKAGE"]
        ["VHF_SHORTED_CTL_BOX"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_SHORTED_CTL_BOX",
            ["mm"] = 0,
        }, -- end of ["VHF_SHORTED_CTL_BOX"]
        ["CLOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CLOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["CLOCK_FAILURE"]
        ["FAILURE_EXT_LIGHT_NAV_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_NAV_LEFT",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_NAV_LEFT"]
        ["OIL_RADIATOR_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_RADIATOR_WIRING",
            ["mm"] = 0,
        }, -- end of ["OIL_RADIATOR_WIRING"]
        ["fs_damage_MainPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_MainPump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_MainPump"]
        ["MWMMC_FAILURE_MBI"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_MBI",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_MBI"]
        ["FCS_FAILURE_Q_SENSOR_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_Q_SENSOR_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_Q_SENSOR_1"]
        ["es_damage_Inverter36x3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Inverter36x3",
            ["mm"] = 0,
        }, -- end of ["es_damage_Inverter36x3"]
        ["COOLANT_RADIATOR_SENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_RADIATOR_SENSOR",
            ["mm"] = 0,
        }, -- end of ["COOLANT_RADIATOR_SENSOR"]
        ["IMU_FAILURE_QUANTIZER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IMU_FAILURE_QUANTIZER",
            ["mm"] = 0,
        }, -- end of ["IMU_FAILURE_QUANTIZER"]
        ["CTRL_LANDING_FLAPS_RH_DRIVE_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LANDING_FLAPS_RH_DRIVE_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["CTRL_LANDING_FLAPS_RH_DRIVE_DAMAGED"]
        ["EMMC_FAILURE_DADS_MPTU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DADS_MPTU",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DADS_MPTU"]
        ["MWMMC_FAILURE_1553B_LMFCD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_LMFCD",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_LMFCD"]
        ["SWMMC_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE"]
        ["GUN_LEFT_OUT_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_OUT_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_OUT_AMMUN_FAULT"]
        ["COPILOT_KILLED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COPILOT_KILLED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["COPILOT_KILLED_FAILURE"]
        ["OXY_FAILURE_R_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_R_LEAK",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_R_LEAK"]
        ["ELEC_LH_CABIN_LIGHT_POOR_CONTACT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_LH_CABIN_LIGHT_POOR_CONTACT",
            ["mm"] = 0,
        }, -- end of ["ELEC_LH_CABIN_LIGHT_POOR_CONTACT"]
        ["hydro_common"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydro_common",
            ["mm"] = 0,
        }, -- end of ["hydro_common"]
        ["GUN_LEFT_CENTER_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_CENTER_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_CENTER_BARREL_WORN"]
        ["AC_BUS_PO7502_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AC_BUS_PO7502_FAILURE",
            ["mm"] = 0,
        }, -- end of ["AC_BUS_PO7502_FAILURE"]
        ["FUEL_GAUGE_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_GAUGE_FAULT",
            ["mm"] = 0,
        }, -- end of ["FUEL_GAUGE_FAULT"]
        ["ELEC_DROPTANK_FUEL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_DROPTANK_FUEL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_DROPTANK_FUEL_PUMP_FAILURE"]
        ["FUEL_BOOSTER_FUEL_PUMP_1_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_1_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_1_FAILURE"]
        ["REAR_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "REAR_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["REAR_TANK_PUMP_FAULT"]
        ["SAR_1_101"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SAR_1_101",
            ["mm"] = 0,
        }, -- end of ["SAR_1_101"]
        ["FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_2_EXTERNAL_LEAKAGE"]
        ["ELEC_MSB_CB_BUSTED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_MSB_CB_BUSTED",
            ["mm"] = 0,
        }, -- end of ["ELEC_MSB_CB_BUSTED"]
        ["STATION_4_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_4_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_4_FAILURE"]
        ["FAILURE_EXT_LIGHT_NAV_TAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_NAV_TAIL",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_NAV_TAIL"]
        ["K14_MOTOR_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "K14_MOTOR_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["K14_MOTOR_DEFECTIVE"]
        ["Failure_PP_LeftPTS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_LeftPTS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_LeftPTS"]
        ["MWMMC_FAILURE_1553B_RDR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_RDR",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_RDR"]
        ["FAILURE_SMS_PYLON_6"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SMS_PYLON_6",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SMS_PYLON_6"]
        ["INST_TACH0_LOOM_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH0_LOOM_SEVERED",
            ["mm"] = 0,
        }, -- end of ["INST_TACH0_LOOM_SEVERED"]
        ["MWMMC_FAILURE_1553B_SAIU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_SAIU",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_SAIU"]
        ["DATACARTRIDGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DATACARTRIDGE",
            ["mm"] = 0,
        }, -- end of ["DATACARTRIDGE"]
        ["ENG0_MAGNETO1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_MAGNETO1",
            ["mm"] = 0,
        }, -- end of ["ENG0_MAGNETO1"]
        ["EMMC_FAILURE_AC_GENERATOR_CONTROLLER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_AC_GENERATOR_CONTROLLER",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_AC_GENERATOR_CONTROLLER"]
        ["INSUF_FUEL_PRES"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INSUF_FUEL_PRES",
            ["mm"] = 0,
        }, -- end of ["INSUF_FUEL_PRES"]
        ["SUPERCHARGER_WIRE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SUPERCHARGER_WIRE",
            ["mm"] = 0,
        }, -- end of ["SUPERCHARGER_WIRE"]
        ["FUEL_TANK_00_EXPLODED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_EXPLODED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_EXPLODED"]
        ["PROP_GOVERNOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PROP_GOVERNOR",
            ["mm"] = 0,
        }, -- end of ["PROP_GOVERNOR"]
        ["MANIFOLD_SHIFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MANIFOLD_SHIFT",
            ["mm"] = 0,
        }, -- end of ["MANIFOLD_SHIFT"]
        ["GUN_RIGHT_MG131_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG131_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG131_BARREL_WORN"]
        ["Failure_Fuel_Tank1Transfer"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_Tank1Transfer",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_Tank1Transfer"]
        ["ILS_FAILURE_DECODER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_DECODER",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_DECODER"]
        ["RIGHT_GUNNER_KILLED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_GUNNER_KILLED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RIGHT_GUNNER_KILLED_FAILURE"]
        ["EMMC_FAILURE_FUEL_LOWER_PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_FUEL_LOWER_PUMP",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_FUEL_LOWER_PUMP"]
        ["RIGHT_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["RIGHT_TANK_PUMP_FAULT"]
        ["GUN_RIGHT_MG151_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG151_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG151_AMMUN_FAULT"]
        ["FCS_FAILURE_ROLL_LVDT_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_LVDT_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_LVDT_2"]
        ["fs_damage_EnginePump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_EnginePump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_EnginePump"]
        ["PNEM_COMPRESSOR_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_COMPRESSOR_FAILURE",
            ["mm"] = 0,
        }, -- end of ["PNEM_COMPRESSOR_FAILURE"]
        ["engine_antiice_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_antiice_fail",
            ["mm"] = 0,
        }, -- end of ["engine_antiice_fail"]
        ["FCS_FAILURE_ROLL_AUGD_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_AUGD_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_AUGD_2"]
        ["HYDR_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["HYDR_PUMP_FAILURE"]
        ["RWR_FAILURE_RECEIVER_XX2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_RECEIVER_XX2",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_RECEIVER_XX2"]
        ["CICU_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CICU_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["CICU_FAILURE_TOTAL"]
        ["RADAR_ALTIMETR_RIGHT_ANT_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADAR_ALTIMETR_RIGHT_ANT_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RADAR_ALTIMETR_RIGHT_ANT_FAILURE"]
        ["ENG0_MAGNETO0"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_MAGNETO0",
            ["mm"] = 0,
        }, -- end of ["ENG0_MAGNETO0"]
        ["OXY_FAILURE_AIR_O2_SWITCH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_AIR_O2_SWITCH",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_AIR_O2_SWITCH"]
        ["esf_LeftGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "esf_LeftGenerator",
            ["mm"] = 0,
        }, -- end of ["esf_LeftGenerator"]
        ["GUN_RIGHT_IN_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_IN_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_IN_AMMUN_FAULT"]
        ["EMMC_FAILURE_DADS_LPTU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DADS_LPTU",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DADS_LPTU"]
        ["SWMMC_FAILURE_CSU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_CSU",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_CSU"]
        ["STATION_1_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STATION_1_FAILURE",
            ["mm"] = 0,
        }, -- end of ["STATION_1_FAILURE"]
        ["OESP_FAILURE_MAWS_L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_MAWS_L",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_MAWS_L"]
        ["RUDDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RUDDER",
            ["mm"] = 0,
        }, -- end of ["RUDDER"]
        ["FAULTY_ROCKET_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAULTY_ROCKET_LEFT",
            ["mm"] = 0,
        }, -- end of ["FAULTY_ROCKET_LEFT"]
        ["hs_damage_MainAutoUnload"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_MainAutoUnload",
            ["mm"] = 0,
        }, -- end of ["hs_damage_MainAutoUnload"]
        ["F2_BOTTOM_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "F2_BOTTOM_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["F2_BOTTOM_CYLINDER"]
        ["PILOT_KILLED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PILOT_KILLED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["PILOT_KILLED_FAILURE"]
        ["SUCTION_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SUCTION_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["SUCTION_PUMP_FAILURE"]
        ["fuel_sys_transfer_pumps"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fuel_sys_transfer_pumps",
            ["mm"] = 0,
        }, -- end of ["fuel_sys_transfer_pumps"]
        ["ACCSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ACCSENSOR",
            ["mm"] = 0,
        }, -- end of ["ACCSENSOR"]
        ["CADC_TOTAL_TEMPERATURE_SIGNAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_TOTAL_TEMPERATURE_SIGNAL",
            ["mm"] = 0,
        }, -- end of ["CADC_TOTAL_TEMPERATURE_SIGNAL"]
        ["HYDR2PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR2PUMP",
            ["mm"] = 0,
        }, -- end of ["HYDR2PUMP"]
        ["es_damage_Starter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_Starter",
            ["mm"] = 0,
        }, -- end of ["es_damage_Starter"]
        ["FCS_FAILURE_LG_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_LG_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_LG_1"]
        ["FCS_FAILURE_AOA_SENSOR_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_AOA_SENSOR_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_AOA_SENSOR_2"]
        ["ELEC_NAVLIGHT_GREEN_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_NAVLIGHT_GREEN_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_NAVLIGHT_GREEN_FAILURE"]
        ["UHF_ARC_159_FAILURE_ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_ANTENNA",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_ANTENNA"]
        ["TGP_FAILURE_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TGP_FAILURE_RIGHT",
            ["mm"] = 0,
        }, -- end of ["TGP_FAILURE_RIGHT"]
        ["SWMMC_FAILURE_MBI"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_MBI",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_MBI"]
        ["sas_pitch_left"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sas_pitch_left",
            ["mm"] = 0,
        }, -- end of ["sas_pitch_left"]
        ["EMMC_FAILURE_FUEL_UPPER_PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_FUEL_UPPER_PUMP",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_FUEL_UPPER_PUMP"]
        ["FDU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FDU",
            ["mm"] = 0,
        }, -- end of ["FDU"]
        ["FUEL_TANK_01_FIRE_STOPPED"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_01_FIRE_STOPPED",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_01_FIRE_STOPPED"]
        ["CADC_FAILURE_TAS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_TAS",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_TAS"]
        ["es_damage_GeneratorRight"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "es_damage_GeneratorRight",
            ["mm"] = 0,
        }, -- end of ["es_damage_GeneratorRight"]
        ["LEFT_WING_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_WING_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["LEFT_WING_TANK_LEAK"]
        ["INS_FAILURE_NAV_COMPUTER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_NAV_COMPUTER",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_NAV_COMPUTER"]
        ["UNCR_RH_STRUT_UP_LOCK_JAMMED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_RH_STRUT_UP_LOCK_JAMMED",
            ["mm"] = 0,
        }, -- end of ["UNCR_RH_STRUT_UP_LOCK_JAMMED"]
        ["MAINGENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINGENERATOR",
            ["mm"] = 0,
        }, -- end of ["MAINGENERATOR"]
        ["FUEL_LH_WING_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_LH_WING_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_LH_WING_TANK_MINOR_LEAK"]
        ["esf_StaticInverter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "esf_StaticInverter",
            ["mm"] = 0,
        }, -- end of ["esf_StaticInverter"]
        ["RDR_FAILURE_RX_FRONT_END"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_RX_FRONT_END",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_RX_FRONT_END"]
        ["EGI_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EGI_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["EGI_FAILURE_TOTAL"]
        ["FCS_FAILURE_AOA_SENSOR_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_AOA_SENSOR_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_AOA_SENSOR_3"]
        ["ADC_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ADC_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["ADC_FAILURE_TOTAL"]
        ["SWMMC_FAILURE_AAP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_AAP",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_AAP"]
        ["RDR_FAILURE_TRANSMITTER_OVERHEAT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_TRANSMITTER_OVERHEAT",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_TRANSMITTER_OVERHEAT"]
        ["PPF_LE_TEMPER_LIM_OFF"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "PPF_LE_TEMPER_LIM_OFF",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["PPF_LE_TEMPER_LIM_OFF"]
        ["AHRS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AHRS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["AHRS_FAILURE_TOTAL"]
        ["ppf_FireRight"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_FireRight",
            ["mm"] = 0,
        }, -- end of ["ppf_FireRight"]
        ["ELEC_UC_LAMP_LHD_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UC_LAMP_LHD_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UC_LAMP_LHD_BULB_FAILURE"]
        ["INS_FAILURE_GPS_RECEIVER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_GPS_RECEIVER",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_GPS_RECEIVER"]
        ["VHF_VT207_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_VT207_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["VHF_VT207_DEFECTIVE"]
        ["ELEC_RETICLE_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_RETICLE_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_RETICLE_BULB_FAILURE"]
        ["STARTER_SOLENOID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_SOLENOID",
            ["mm"] = 0,
        }, -- end of ["STARTER_SOLENOID"]
        ["EMMC_FAILURE_PROBES_HEATING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_PROBES_HEATING",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_PROBES_HEATING"]
        ["ppf_LeftGearbox"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_LeftGearbox",
            ["mm"] = 0,
        }, -- end of ["ppf_LeftGearbox"]
        ["CNI_FAILURE_COM1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_COM1",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_COM1"]
        ["FCS_FAILURE_R_ELEVATOR_ELEC_B"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_ELEC_B",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_ELEC_B"]
        ["RightEngine_LowOilPressure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RightEngine_LowOilPressure",
            ["mm"] = 0,
        }, -- end of ["RightEngine_LowOilPressure"]
        ["OXY_FAILURE_L_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_L_LEAK",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_L_LEAK"]
        ["radar"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "radar",
            ["mm"] = 0,
        }, -- end of ["radar"]
        ["AGD1_GYRO_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AGD1_GYRO_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["AGD1_GYRO_TOTAL_FAILURE"]
        ["CADC_FAILURE_BARO_ALT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_FAILURE_BARO_ALT",
            ["mm"] = 0,
        }, -- end of ["CADC_FAILURE_BARO_ALT"]
        ["LEFT_CYLINDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_CYLINDER",
            ["mm"] = 0,
        }, -- end of ["LEFT_CYLINDER"]
        ["EMMC_FAILURE_DC_GENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DC_GENERATOR",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DC_GENERATOR"]
        ["COOLANT_UNPRES"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_UNPRES",
            ["mm"] = 0,
        }, -- end of ["COOLANT_UNPRES"]
        ["ARN_82_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ARN_82_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["ARN_82_FAILURE_TOTAL"]
        ["VHF_ARC_182_FAILURE_TRANSCEIVER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_TRANSCEIVER",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_TRANSCEIVER"]
        ["l_engine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "l_engine",
            ["mm"] = 0,
        }, -- end of ["l_engine"]
        ["TURNIND_INCORRECT_SENS_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURNIND_INCORRECT_SENS_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["TURNIND_INCORRECT_SENS_DEFECTIVE"]
        ["eos"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "eos",
            ["mm"] = 0,
        }, -- end of ["eos"]
        ["HYDR_UNLOAD_VALVE_NOT_LOAD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR_UNLOAD_VALVE_NOT_LOAD",
            ["mm"] = 0,
        }, -- end of ["HYDR_UNLOAD_VALVE_NOT_LOAD"]
        ["CADC_STABILIZER_AUTHORITY_COMMAND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_STABILIZER_AUTHORITY_COMMAND",
            ["mm"] = 0,
        }, -- end of ["CADC_STABILIZER_AUTHORITY_COMMAND"]
        ["OXY_FAILURE_L_LEAK_SEVERE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_L_LEAK_SEVERE",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_L_LEAK_SEVERE"]
        ["PNEM_LH_FLAP_JACK_BUSTED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_LH_FLAP_JACK_BUSTED",
            ["mm"] = 0,
        }, -- end of ["PNEM_LH_FLAP_JACK_BUSTED"]
        ["EMMC_FAILURE_FUEL_LOW_LEVEL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_FUEL_LOW_LEVEL",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_FUEL_LOW_LEVEL"]
        ["ENG0_OIL_RADIATOR_0_PIERCED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_RADIATOR_0_PIERCED",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_RADIATOR_0_PIERCED"]
        ["ENG0_OIL_PUMP_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_PUMP_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_PUMP_FAILURE"]
        ["FUEL_TANK_00_MEDIUM_LEAK"] = 
        {
            ["hh"] = 0,
            ["enable"] = false,
            ["prob"] = 100,
            ["id"] = "FUEL_TANK_00_MEDIUM_LEAK",
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_MEDIUM_LEAK"]
        ["PITOT_HEAT_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PITOT_HEAT_FAULT",
            ["mm"] = 0,
        }, -- end of ["PITOT_HEAT_FAULT"]
        ["FAILURE_HYDRAULICS_1_INTERNAL_LEAKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_HYDRAULICS_1_INTERNAL_LEAKAGE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_HYDRAULICS_1_INTERNAL_LEAKAGE"]
        ["FAILURE_EXT_LIGHT_FORMATION_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_FORMATION_RIGHT",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_FORMATION_RIGHT"]
        ["ELEC_DASHBOARD_HARNESS_CUT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_DASHBOARD_HARNESS_CUT",
            ["mm"] = 0,
        }, -- end of ["ELEC_DASHBOARD_HARNESS_CUT"]
        ["BOMBS_DAMAGE_LINKAGE_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_LINKAGE_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_LINKAGE_RIGHT"]
        ["FCS_FAILURE_L_ELEVATOR_ELEC_A"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_L_ELEVATOR_ELEC_A",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_L_ELEVATOR_ELEC_A"]
        ["BAT_SOLENOID_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BAT_SOLENOID_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["BAT_SOLENOID_DEFECTIVE"]
        ["FCS_FAILURE_NY_SENSOR_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NY_SENSOR_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NY_SENSOR_1"]
        ["SWMMC_FAILURE_IOC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_IOC",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_IOC"]
        ["BOMBS_DAMAGE_ELINKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_ELINKAGE",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_ELINKAGE"]
        ["LeftEngine_Fire"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LeftEngine_Fire",
            ["mm"] = 0,
        }, -- end of ["LeftEngine_Fire"]
        ["AN_ALE_40V_FAILURE_CONTAINER_LEFT_WING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALE_40V_FAILURE_CONTAINER_LEFT_WING",
            ["mm"] = 0,
        }, -- end of ["AN_ALE_40V_FAILURE_CONTAINER_LEFT_WING"]
        ["INS_WIND_INVALID"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_WIND_INVALID",
            ["mm"] = 0,
        }, -- end of ["INS_WIND_INVALID"]
        ["L_GEAR_UPL_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "L_GEAR_UPL_FAULT",
            ["mm"] = 0,
        }, -- end of ["L_GEAR_UPL_FAULT"]
        ["FCS_FAILURE_NY_SENSOR_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_NY_SENSOR_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_NY_SENSOR_2"]
        ["vor_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "vor_fail",
            ["mm"] = 0,
        }, -- end of ["vor_fail"]
        ["VHF_ARC_182_FAILURE_ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_ARC_182_FAILURE_ANTENNA",
            ["mm"] = 0,
        }, -- end of ["VHF_ARC_182_FAILURE_ANTENNA"]
        ["CNI_FAILURE_RALT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_RALT",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_RALT"]
        ["RWR_FAILURE_ANTENNA_FRONT_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_ANTENNA_FRONT_LEFT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_ANTENNA_FRONT_LEFT"]
        ["PNEM_RH_BRAKE_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_RH_BRAKE_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_RH_BRAKE_HOSE_PERFORATED"]
        ["BURNER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BURNER",
            ["mm"] = 0,
        }, -- end of ["BURNER"]
        ["FUEL_DROPTANK_LINE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_DROPTANK_LINE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["FUEL_DROPTANK_LINE_SEVERED"]
        ["TailReductor_ShaveInOil"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TailReductor_ShaveInOil",
            ["mm"] = 0,
        }, -- end of ["TailReductor_ShaveInOil"]
        ["INST_DI_MECHANICAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_DI_MECHANICAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["INST_DI_MECHANICAL_FAILURE"]
        ["ENGINE_FAILURE_DEEC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_DEEC",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_DEEC"]
        ["FCS_FAILURE_P_SENSOR_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_P_SENSOR_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_P_SENSOR_4"]
        ["FCS_FAILURE_YAW_ELEC_SERVO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_ELEC_SERVO_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_ELEC_SERVO_1"]
        ["R_GEAR_UPL_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "R_GEAR_UPL_FAULT",
            ["mm"] = 0,
        }, -- end of ["R_GEAR_UPL_FAULT"]
        ["RWR_FAILURE_DISPLAY_RIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_DISPLAY_RIO",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_DISPLAY_RIO"]
        ["Failure_Fuel_ExtTankTransferL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_ExtTankTransferL",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_ExtTankTransferL"]
        ["engine_surge_failure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_surge_failure",
            ["mm"] = 0,
        }, -- end of ["engine_surge_failure"]
        ["CMS_FAILURE_LEFT_DISPENSER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CMS_FAILURE_LEFT_DISPENSER",
            ["mm"] = 0,
        }, -- end of ["CMS_FAILURE_LEFT_DISPENSER"]
        ["CARBAIR_SHORT_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CARBAIR_SHORT_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["CARBAIR_SHORT_CIRCUIT"]
        ["STARTER_RELAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "STARTER_RELAY",
            ["mm"] = 0,
        }, -- end of ["STARTER_RELAY"]
        ["TACAN_FAILURE_RECEIVER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACAN_FAILURE_RECEIVER",
            ["mm"] = 0,
        }, -- end of ["TACAN_FAILURE_RECEIVER"]
        ["SWMMC_FAILURE_DVR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_DVR",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_DVR"]
        ["CADC_PRESSURE_SENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CADC_PRESSURE_SENSOR",
            ["mm"] = 0,
        }, -- end of ["CADC_PRESSURE_SENSOR"]
        ["COM2_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COM2_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["COM2_FAILURE_TOTAL"]
        ["GUN_LEFT_IN_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_IN_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_IN_MOUNT_LOOSE"]
        ["Failure_Sens_RightPitotHeater"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Sens_RightPitotHeater",
            ["mm"] = 0,
        }, -- end of ["Failure_Sens_RightPitotHeater"]
        ["GUN_RIGHT_IN_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_IN_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_IN_MOUNT_LOOSE"]
        ["HAW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HAW",
            ["mm"] = 0,
        }, -- end of ["HAW"]
        ["BOMBS_TRAIN_DEFECTIVE_WIRING"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_TRAIN_DEFECTIVE_WIRING",
            ["mm"] = 0,
        }, -- end of ["BOMBS_TRAIN_DEFECTIVE_WIRING"]
        ["TACAN_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACAN_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["TACAN_FAILURE_TOTAL"]
        ["RWR_FAILURE_DB_NOT_LOADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_DB_NOT_LOADED",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_DB_NOT_LOADED"]
        ["LEFT_MFCD_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_MFCD_FAILURE",
            ["mm"] = 0,
        }, -- end of ["LEFT_MFCD_FAILURE"]
        ["OXYGEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYGEN",
            ["mm"] = 0,
        }, -- end of ["OXYGEN"]
        ["hydr_leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hydr_leak",
            ["mm"] = 0,
        }, -- end of ["hydr_leak"]
        ["CNI_FAILURE_COM2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_COM2",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_COM2"]
        ["ELEC_SUPERCHARGER_SOLENOID_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_SUPERCHARGER_SOLENOID_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_SUPERCHARGER_SOLENOID_FAILURE"]
        ["DOORS_TVC_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DOORS_TVC_BROKEN",
            ["mm"] = 0,
        }, -- end of ["DOORS_TVC_BROKEN"]
        ["EXT_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EXT_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["EXT_TANK_LEAK"]
        ["HYDRRESERVPUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDRRESERVPUMP",
            ["mm"] = 0,
        }, -- end of ["HYDRRESERVPUMP"]
        ["fs_damage_left_cell_boost_pump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_left_cell_boost_pump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_left_cell_boost_pump"]
        ["FCS_FAILURE_PITCH_LVDT_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_PITCH_LVDT_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_PITCH_LVDT_2"]
        ["BOMBS_DAMAGE_ELINKAGE_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_ELINKAGE_LEFT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_ELINKAGE_LEFT"]
        ["INST_TACH0_RESISTANCE_MISMATCH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH0_RESISTANCE_MISMATCH",
            ["mm"] = 0,
        }, -- end of ["INST_TACH0_RESISTANCE_MISMATCH"]
        ["FCS_FAILURE_Q_SENSOR_4"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_Q_SENSOR_4",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_Q_SENSOR_4"]
        ["ENGINE_JAM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_JAM",
            ["mm"] = 0,
        }, -- end of ["ENGINE_JAM"]
        ["EMMC_FAILURE_LANDING_GEAR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_LANDING_GEAR",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_LANDING_GEAR"]
        ["MAGNETO_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAGNETO_2",
            ["mm"] = 0,
        }, -- end of ["MAGNETO_2"]
        ["FUEL_BOOSTER_FUEL_PUMP_0_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_0_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_0_DEGRADED"]
        ["IFF"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IFF",
            ["mm"] = 0,
        }, -- end of ["IFF"]
        ["RWR_FAILURE_SENSOR_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_SENSOR_RIGHT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_SENSOR_RIGHT"]
        ["Failure_Elec_EmergencyBattery"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_EmergencyBattery",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_EmergencyBattery"]
        ["FUEL_TANK_00_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["id"] = "FUEL_TANK_00_MINOR_LEAK",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["FUEL_TANK_00_MINOR_LEAK"]
        ["GUN_RIGHT_CENTER_MOUNT_LOOSE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_CENTER_MOUNT_LOOSE",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_CENTER_MOUNT_LOOSE"]
        ["INS_FAILURE_GYRO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_GYRO",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_GYRO"]
        ["UNCR_RH_WHEEL_BRAKE_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_RH_WHEEL_BRAKE_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["UNCR_RH_WHEEL_BRAKE_DAMAGED"]
        ["RWR_FAILURE_SENSOR_TAIL_F"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_SENSOR_TAIL_F",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_SENSOR_TAIL_F"]
        ["FCS_FAILURE_Q_SENSOR_3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_Q_SENSOR_3",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_Q_SENSOR_3"]
        ["ELEC_BOOSTER_FUEL_PUMP_0_COIL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_BOOSTER_FUEL_PUMP_0_COIL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_BOOSTER_FUEL_PUMP_0_COIL_FAILURE"]
        ["FUEL_BOOSTER_FUEL_PUMP_0_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_0_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_0_FAILURE"]
        ["engine_driveshaft_failure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_driveshaft_failure",
            ["mm"] = 0,
        }, -- end of ["engine_driveshaft_failure"]
        ["PUMP_RELIEF_VALVE_LEAKS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PUMP_RELIEF_VALVE_LEAKS",
            ["mm"] = 0,
        }, -- end of ["PUMP_RELIEF_VALVE_LEAKS"]
        ["hs_damage_AuxAccumulator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_AuxAccumulator",
            ["mm"] = 0,
        }, -- end of ["hs_damage_AuxAccumulator"]
        ["GUN_RIGHT_MG131_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_MG131_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_MG131_AMMUN_FAULT"]
        ["ENGINE_FAILURE_NOZZLE_CONTROLLER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE_NOZZLE_CONTROLLER",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE_NOZZLE_CONTROLLER"]
        ["FUEL_BOOSTER_FUEL_PUMP_1_DEGRADED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_1_DEGRADED",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_1_DEGRADED"]
        ["Failure_Elec_UtilityBattery"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Elec_UtilityBattery",
            ["mm"] = 0,
        }, -- end of ["Failure_Elec_UtilityBattery"]
        ["FUELTANK5L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK5L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK5L"]
        ["pp_damage_EmergMaxFreq"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_EmergMaxFreq",
            ["mm"] = 0,
        }, -- end of ["pp_damage_EmergMaxFreq"]
        ["IFFCC_FAILURE_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IFFCC_FAILURE_GUN",
            ["mm"] = 0,
        }, -- end of ["IFFCC_FAILURE_GUN"]
        ["MSC_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MSC_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["MSC_FAILURE_TOTAL"]
        ["CNI_FAILURE_IFF_RX"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CNI_FAILURE_IFF_RX",
            ["mm"] = 0,
        }, -- end of ["CNI_FAILURE_IFF_RX"]
        ["OXYN_TOP_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYN_TOP_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["OXYN_TOP_CONTAINER_PERFORATED"]
        ["UNCR_CONTROLLER_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_CONTROLLER_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_CONTROLLER_FAILURE"]
        ["FUEL_MAIN_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_MAIN_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_MAIN_TANK_MINOR_LEAK"]
        ["BAT_SOLENOID_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BAT_SOLENOID_FAULT",
            ["mm"] = 0,
        }, -- end of ["BAT_SOLENOID_FAULT"]
        ["DTC_FAILURE_DATA_CRC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DTC_FAILURE_DATA_CRC",
            ["mm"] = 0,
        }, -- end of ["DTC_FAILURE_DATA_CRC"]
        ["COMPRESSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPRESSOR",
            ["mm"] = 0,
        }, -- end of ["COMPRESSOR"]
        ["pp_damage_OilSeparator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_OilSeparator",
            ["mm"] = 0,
        }, -- end of ["pp_damage_OilSeparator"]
        ["ef_surge"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ef_surge",
            ["mm"] = 0,
        }, -- end of ["ef_surge"]
        ["PNEM_LOW_PRS_JUNCTION_BOX_DESTROYED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_LOW_PRS_JUNCTION_BOX_DESTROYED",
            ["mm"] = 0,
        }, -- end of ["PNEM_LOW_PRS_JUNCTION_BOX_DESTROYED"]
        ["ILS_FAILURE_ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_ANTENNA",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_ANTENNA"]
        ["GUN_RIGHT_OUT_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_OUT_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_OUT_AMMUN_FAULT"]
        ["RWR_FAILURE_MBE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_MBE",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_MBE"]
        ["UHF_ARC_159_FAILURE_TRANSCEIVER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UHF_ARC_159_FAILURE_TRANSCEIVER",
            ["mm"] = 0,
        }, -- end of ["UHF_ARC_159_FAILURE_TRANSCEIVER"]
        ["MWMMC_FAILURE_1553B_RALT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_RALT",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_RALT"]
        ["Failure_PP_EngL_OilLeak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngL_OilLeak",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngL_OilLeak"]
        ["VHF_SQUELCH_RELAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_SQUELCH_RELAY",
            ["mm"] = 0,
        }, -- end of ["VHF_SQUELCH_RELAY"]
        ["K14_MOV_LAMP_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "K14_MOV_LAMP_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["K14_MOV_LAMP_DEFECTIVE"]
        ["hs_damage_MainHydro"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hs_damage_MainHydro",
            ["mm"] = 0,
        }, -- end of ["hs_damage_MainHydro"]
        ["GUN_RIGHT_CENTER_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_CENTER_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_CENTER_AMMUN_FAULT"]
        ["PNEM_PRIMARY_CONTAINER_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_PRIMARY_CONTAINER_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_PRIMARY_CONTAINER_PERFORATED"]
        ["fuel_sys_swapping_pumps"] = 
        {
            ["hh"] = 0,
            ["id"] = "fuel_sys_swapping_pumps",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["fuel_sys_swapping_pumps"]
        ["FCS_FAILURE_R_ELEVATOR_HYD_2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_HYD_2",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_HYD_2"]
        ["AN_ALR69V_FAILURE_SENSOR_TAIL_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALR69V_FAILURE_SENSOR_TAIL_LEFT",
            ["mm"] = 0,
        }, -- end of ["AN_ALR69V_FAILURE_SENSOR_TAIL_LEFT"]
        ["BOMBS_DAMAGE_LINKAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_DAMAGE_LINKAGE",
            ["mm"] = 0,
        }, -- end of ["BOMBS_DAMAGE_LINKAGE"]
        ["WEAP_GUN_02_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "WEAP_GUN_02_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["WEAP_GUN_02_DAMAGED"]
        ["SWMMC_AAP_NO_RS422_COMM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_AAP_NO_RS422_COMM",
            ["mm"] = 0,
        }, -- end of ["SWMMC_AAP_NO_RS422_COMM"]
        ["fs_aft_central_leakage"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_aft_central_leakage",
            ["mm"] = 0,
        }, -- end of ["fs_aft_central_leakage"]
        ["BATTERY_OVERHEAT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BATTERY_OVERHEAT",
            ["mm"] = 0,
        }, -- end of ["BATTERY_OVERHEAT"]
        ["pitch_trim_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pitch_trim_fail",
            ["mm"] = 0,
        }, -- end of ["pitch_trim_fail"]
        ["FUEL_REAR_TANK_MINOR_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_REAR_TANK_MINOR_LEAK",
            ["mm"] = 0,
        }, -- end of ["FUEL_REAR_TANK_MINOR_LEAK"]
        ["RADIO_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADIO_FAILURE",
            ["mm"] = 0,
        }, -- end of ["RADIO_FAILURE"]
        ["RWRANTRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTRIGHT",
            ["mm"] = 0,
        }, -- end of ["RWRANTRIGHT"]
        ["ARN_83_ADF_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ARN_83_ADF_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["ARN_83_ADF_DAMAGE"]
        ["HYD_Combined"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_Combined",
            ["mm"] = 0,
        }, -- end of ["HYD_Combined"]
        ["Failure_PP_EngL_AB_FFCS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_PP_EngL_AB_FFCS",
            ["mm"] = 0,
        }, -- end of ["Failure_PP_EngL_AB_FFCS"]
        ["EMMC_FAILURE_SCU_DC2AC115V"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_SCU_DC2AC115V",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_SCU_DC2AC115V"]
        ["DC_BUS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DC_BUS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["DC_BUS_FAILURE_TOTAL"]
        ["PNEM_RADIATOR_JACK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_RADIATOR_JACK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["PNEM_RADIATOR_JACK_FAILURE"]
        ["TACH_BREAK_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TACH_BREAK_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["TACH_BREAK_CIRCUIT"]
        ["AC_BUS_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AC_BUS_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["AC_BUS_FAILURE_TOTAL"]
        ["TAIL_GEAR_D_LOCK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAIL_GEAR_D_LOCK",
            ["mm"] = 0,
        }, -- end of ["TAIL_GEAR_D_LOCK"]
        ["hud"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "hud",
            ["mm"] = 0,
        }, -- end of ["hud"]
        ["EMMC_FAILURE_ECS_OFF"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_ECS_OFF",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_ECS_OFF"]
        ["PITOT_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PITOT_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["PITOT_FAILURE_TOTAL"]
        ["autopilot"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "autopilot",
            ["mm"] = 0,
        }, -- end of ["autopilot"]
        ["BOMBS_TRAIN_DEFECTIVE_SWITCH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_TRAIN_DEFECTIVE_SWITCH",
            ["mm"] = 0,
        }, -- end of ["BOMBS_TRAIN_DEFECTIVE_SWITCH"]
        ["Failure_Fuel_LeftBoostPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_LeftBoostPump",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_LeftBoostPump"]
        ["EZ42_MOTOR_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EZ42_MOTOR_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["EZ42_MOTOR_DEFECTIVE"]
        ["ssf_full_pressure_fail"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ssf_full_pressure_fail",
            ["mm"] = 0,
        }, -- end of ["ssf_full_pressure_fail"]
        ["FCS_FAILURE_ROLL_AUGD_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_ROLL_AUGD_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_ROLL_AUGD_1"]
        ["sas_yaw_right"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sas_yaw_right",
            ["mm"] = 0,
        }, -- end of ["sas_yaw_right"]
        ["ENG_ALT_1_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG_ALT_1_FAIL",
            ["mm"] = 0,
        }, -- end of ["ENG_ALT_1_FAIL"]
        ["LGear_ext_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LGear_ext_fault",
            ["mm"] = 0,
        }, -- end of ["LGear_ext_fault"]
        ["CTRL_LANDING_FLAPS_LH_DRIVE_DAMAGED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_LANDING_FLAPS_LH_DRIVE_DAMAGED",
            ["mm"] = 0,
        }, -- end of ["CTRL_LANDING_FLAPS_LH_DRIVE_DAMAGED"]
        ["NGear_ext_fault"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "NGear_ext_fault",
            ["mm"] = 0,
        }, -- end of ["NGear_ext_fault"]
        ["INS_FAILURE_ALGNMENT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_FAILURE_ALGNMENT",
            ["mm"] = 0,
        }, -- end of ["INS_FAILURE_ALGNMENT"]
        ["MWMMC_FAILURE_1553B_INS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_1553B_INS",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_1553B_INS"]
        ["sas_pitch_right"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "sas_pitch_right",
            ["mm"] = 0,
        }, -- end of ["sas_pitch_right"]
        ["RPMSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RPMSENSOR",
            ["mm"] = 0,
        }, -- end of ["RPMSENSOR"]
        ["ENG0_OIL_HOSE_0_BURST"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENG0_OIL_HOSE_0_BURST",
            ["mm"] = 0,
        }, -- end of ["ENG0_OIL_HOSE_0_BURST"]
        ["ELEC_STARTER_LOOM_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_STARTER_LOOM_SEVERED",
            ["mm"] = 0,
        }, -- end of ["ELEC_STARTER_LOOM_SEVERED"]
        ["INST_VARIOMETR_DEPRESSURIZATION"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_VARIOMETR_DEPRESSURIZATION",
            ["mm"] = 0,
        }, -- end of ["INST_VARIOMETR_DEPRESSURIZATION"]
        ["AFN2_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AFN2_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["AFN2_DAMAGE"]
        ["VHF_CRYSTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VHF_CRYSTAL",
            ["mm"] = 0,
        }, -- end of ["VHF_CRYSTAL"]
        ["ILS_FAILURE_ANT_GLIDESLOPE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ILS_FAILURE_ANT_GLIDESLOPE",
            ["mm"] = 0,
        }, -- end of ["ILS_FAILURE_ANT_GLIDESLOPE"]
        ["aoa_limiter"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "aoa_limiter",
            ["mm"] = 0,
        }, -- end of ["aoa_limiter"]
        ["Failure_Fuel_ExtTankTransferR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_ExtTankTransferR",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_ExtTankTransferR"]
        ["DOPPLER_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DOPPLER_UNIT",
            ["mm"] = 0,
        }, -- end of ["DOPPLER_UNIT"]
        ["ENGINE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ENGINE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ENGINE_FAILURE"]
        ["FR22RADIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR22RADIO",
            ["mm"] = 0,
        }, -- end of ["FR22RADIO"]
        ["EMMC_FAILURE_DC_GENERATOR_SUBSYSTEM"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EMMC_FAILURE_DC_GENERATOR_SUBSYSTEM",
            ["mm"] = 0,
        }, -- end of ["EMMC_FAILURE_DC_GENERATOR_SUBSYSTEM"]
        ["OESP_FAILURE_CH_DISP_R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OESP_FAILURE_CH_DISP_R",
            ["mm"] = 0,
        }, -- end of ["OESP_FAILURE_CH_DISP_R"]
        ["ppf_RightGearbox"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_RightGearbox",
            ["mm"] = 0,
        }, -- end of ["ppf_RightGearbox"]
        ["fs_damage_FuelBoosterPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_FuelBoosterPump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_FuelBoosterPump"]
        ["EZ42_FIXED_LAMP_DEFECTIVE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EZ42_FIXED_LAMP_DEFECTIVE",
            ["mm"] = 0,
        }, -- end of ["EZ42_FIXED_LAMP_DEFECTIVE"]
        ["FCS_FAILURE_YAW_RATE_GYRO_1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_YAW_RATE_GYRO_1",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_YAW_RATE_GYRO_1"]
        ["PNEM_BRAKE_RELAY_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_BRAKE_RELAY_FAILURE",
            ["mm"] = 0,
        }, -- end of ["PNEM_BRAKE_RELAY_FAILURE"]
        ["COOLANT_DEFECTIVE_IND"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_DEFECTIVE_IND",
            ["mm"] = 0,
        }, -- end of ["COOLANT_DEFECTIVE_IND"]
        ["COPILOT_GYRO_TOTAL_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COPILOT_GYRO_TOTAL_FAILURE",
            ["mm"] = 0,
        }, -- end of ["COPILOT_GYRO_TOTAL_FAILURE"]
        ["GUN_RIGHT_CENTER_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_RIGHT_CENTER_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_RIGHT_CENTER_OPEN_CIRCUIT"]
        ["ELEC_AMBER_SIGNAL_LIGHT_BROKEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_AMBER_SIGNAL_LIGHT_BROKEN",
            ["mm"] = 0,
        }, -- end of ["ELEC_AMBER_SIGNAL_LIGHT_BROKEN"]
        ["ELEC_LH_FLAPS_DRIVE_WIRE_SEVERED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_LH_FLAPS_DRIVE_WIRE_SEVERED",
            ["mm"] = 0,
        }, -- end of ["ELEC_LH_FLAPS_DRIVE_WIRE_SEVERED"]
        ["VDI_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "VDI_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["VDI_FAILURE_TOTAL"]
        ["MWMMC_FAILURE_PS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MWMMC_FAILURE_PS",
            ["mm"] = 0,
        }, -- end of ["MWMMC_FAILURE_PS"]
        ["esf_RightGenerator"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "esf_RightGenerator",
            ["mm"] = 0,
        }, -- end of ["esf_RightGenerator"]
        ["ELEC_UC_LAMP_CU_BULB_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_UC_LAMP_CU_BULB_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_UC_LAMP_CU_BULB_FAILURE"]
        ["ELEC_C5_LAMP_1_POOR_CONTACT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_C5_LAMP_1_POOR_CONTACT",
            ["mm"] = 0,
        }, -- end of ["ELEC_C5_LAMP_1_POOR_CONTACT"]
        ["es_damage_VU1"] = 
        {
            ["hh"] = 0,
            ["id"] = "es_damage_VU1",
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["hidden"] = true,
            ["mm"] = 0,
        }, -- end of ["es_damage_VU1"]
        ["SUPERCHARGER_LIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SUPERCHARGER_LIGHT",
            ["mm"] = 0,
        }, -- end of ["SUPERCHARGER_LIGHT"]
        ["EXT_HYDRO_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EXT_HYDRO_LEAK",
            ["mm"] = 0,
        }, -- end of ["EXT_HYDRO_LEAK"]
        ["PNEM_MAIN_HOSE_PERFORATED"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "PNEM_MAIN_HOSE_PERFORATED",
            ["mm"] = 0,
        }, -- end of ["PNEM_MAIN_HOSE_PERFORATED"]
        ["BOMBS_ARMING_NO_VOLATAGE_BOTH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_NO_VOLATAGE_BOTH",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_NO_VOLATAGE_BOTH"]
        ["engine_flameout_irrecoverable"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_flameout_irrecoverable",
            ["mm"] = 0,
        }, -- end of ["engine_flameout_irrecoverable"]
        ["Failure_Hyd_HYD2B_Leak"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Hyd_HYD2B_Leak",
            ["mm"] = 0,
        }, -- end of ["Failure_Hyd_HYD2B_Leak"]
        ["RWR_FAILURE_ANTENNA_REAR_LEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_ANTENNA_REAR_LEFT",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_ANTENNA_REAR_LEFT"]
        ["pp_damage_MainMaxTempr"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pp_damage_MainMaxTempr",
            ["mm"] = 0,
        }, -- end of ["pp_damage_MainMaxTempr"]
        ["RDR_FAILURE_PROCESSOR_OVERHEAT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_PROCESSOR_OVERHEAT",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_PROCESSOR_OVERHEAT"]
        ["COOLANT_RADIATOR_MOTOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COOLANT_RADIATOR_MOTOR",
            ["mm"] = 0,
        }, -- end of ["COOLANT_RADIATOR_MOTOR"]
        ["OXY_FAILURE_R_LEAK_SEVERE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXY_FAILURE_R_LEAK_SEVERE",
            ["mm"] = 0,
        }, -- end of ["OXY_FAILURE_R_LEAK_SEVERE"]
        ["AAR_47_FAILURE_SENSOR_TAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AAR_47_FAILURE_SENSOR_TAIL",
            ["mm"] = 0,
        }, -- end of ["AAR_47_FAILURE_SENSOR_TAIL"]
        ["GUN_LEFT_CENTER_OPEN_CIRCUIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_CENTER_OPEN_CIRCUIT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_CENTER_OPEN_CIRCUIT"]
        ["CTRL_AILERON_TRIM_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CTRL_AILERON_TRIM_FAILURE",
            ["mm"] = 0,
        }, -- end of ["CTRL_AILERON_TRIM_FAILURE"]
        ["LEFT_GUNNER_KILLED_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LEFT_GUNNER_KILLED_FAILURE",
            ["mm"] = 0,
        }, -- end of ["LEFT_GUNNER_KILLED_FAILURE"]
        ["GUN_FAIL_RIGHT_CENTER_GUN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_FAIL_RIGHT_CENTER_GUN",
            ["mm"] = 0,
        }, -- end of ["GUN_FAIL_RIGHT_CENTER_GUN"]
        ["BACKUPGENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BACKUPGENERATOR",
            ["mm"] = 0,
        }, -- end of ["BACKUPGENERATOR"]
        ["RKL_41_ADF_DAMAGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RKL_41_ADF_DAMAGE",
            ["mm"] = 0,
        }, -- end of ["RKL_41_ADF_DAMAGE"]
        ["Failure_Ctrl_FCS_Ch3"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Ctrl_FCS_Ch3",
            ["mm"] = 0,
        }, -- end of ["Failure_Ctrl_FCS_Ch3"]
        ["RWR_FAILURE_QUAD135"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWR_FAILURE_QUAD135",
            ["mm"] = 0,
        }, -- end of ["RWR_FAILURE_QUAD135"]
        ["engine_droop_failure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "engine_droop_failure",
            ["mm"] = 0,
        }, -- end of ["engine_droop_failure"]
        ["ROCKETS_INTERVALOMETER_SEQ"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ROCKETS_INTERVALOMETER_SEQ",
            ["mm"] = 0,
        }, -- end of ["ROCKETS_INTERVALOMETER_SEQ"]
        ["ppf_LeftNozzleControl"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ppf_LeftNozzleControl",
            ["mm"] = 0,
        }, -- end of ["ppf_LeftNozzleControl"]
        ["SWMMC_FAILURE_HUD"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SWMMC_FAILURE_HUD",
            ["mm"] = 0,
        }, -- end of ["SWMMC_FAILURE_HUD"]
        ["SAR_2_101"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "SAR_2_101",
            ["mm"] = 0,
        }, -- end of ["SAR_2_101"]
        ["OIL_T_IND_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OIL_T_IND_FAULT",
            ["mm"] = 0,
        }, -- end of ["OIL_T_IND_FAULT"]
        ["INST_TACH1_RESISTANCE_MISMATCH"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_TACH1_RESISTANCE_MISMATCH",
            ["mm"] = 0,
        }, -- end of ["INST_TACH1_RESISTANCE_MISMATCH"]
        ["FAULTY_ROCKET_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAULTY_ROCKET_RIGHT",
            ["mm"] = 0,
        }, -- end of ["FAULTY_ROCKET_RIGHT"]
        ["TCN_FAILURE_TOTAL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TCN_FAILURE_TOTAL",
            ["mm"] = 0,
        }, -- end of ["TCN_FAILURE_TOTAL"]
        ["fs_damage_TransferPump"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "fs_damage_TransferPump",
            ["mm"] = 0,
        }, -- end of ["fs_damage_TransferPump"]
        ["UNCR_LH_STRUT_DOWN_LOCK_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "UNCR_LH_STRUT_DOWN_LOCK_FAILURE",
            ["mm"] = 0,
        }, -- end of ["UNCR_LH_STRUT_DOWN_LOCK_FAILURE"]
        ["GUN_LEFT_MG151_AMMUN_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_MG151_AMMUN_FAULT",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_MG151_AMMUN_FAULT"]
        ["MainReductor_LowOilPressure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MainReductor_LowOilPressure",
            ["mm"] = 0,
        }, -- end of ["MainReductor_LowOilPressure"]
        ["BOMBS_RUST_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_RUST_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_RUST_RIGHT"]
        ["CLOGGED_FUEL_STRAINER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CLOGGED_FUEL_STRAINER",
            ["mm"] = 0,
        }, -- end of ["CLOGGED_FUEL_STRAINER"]
        ["FUSELAGE_TANK_PUMP_FAULT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUSELAGE_TANK_PUMP_FAULT",
            ["mm"] = 0,
        }, -- end of ["FUSELAGE_TANK_PUMP_FAULT"]
        ["FUEL_BOOSTER_FUEL_PUMP_2_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUEL_BOOSTER_FUEL_PUMP_2_FAILURE",
            ["mm"] = 0,
        }, -- end of ["FUEL_BOOSTER_FUEL_PUMP_2_FAILURE"]
        ["RIGHT_WING_TANK_LEAK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RIGHT_WING_TANK_LEAK",
            ["mm"] = 0,
        }, -- end of ["RIGHT_WING_TANK_LEAK"]
        ["HYD_PUMP_2_FAIL_100"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYD_PUMP_2_FAIL_100",
            ["mm"] = 0,
        }, -- end of ["HYD_PUMP_2_FAIL_100"]
        ["ELEC_OIL_GAUGE_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_OIL_GAUGE_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_OIL_GAUGE_FAILURE"]
        ["Failure_LeftEngine"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_LeftEngine",
            ["mm"] = 0,
        }, -- end of ["Failure_LeftEngine"]
        ["FAILURE_EXT_LIGHT_ANTICOL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_EXT_LIGHT_ANTICOL",
            ["mm"] = 0,
        }, -- end of ["FAILURE_EXT_LIGHT_ANTICOL"]
        ["AN_ALR69V_FAILURE_SENSOR_NOSE_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AN_ALR69V_FAILURE_SENSOR_NOSE_RIGHT",
            ["mm"] = 0,
        }, -- end of ["AN_ALR69V_FAILURE_SENSOR_NOSE_RIGHT"]
        ["ELEC_MSB_CONTROLS_FAILURE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEC_MSB_CONTROLS_FAILURE",
            ["mm"] = 0,
        }, -- end of ["ELEC_MSB_CONTROLS_FAILURE"]
        ["GUN_LEFT_OUT_BARREL_WORN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GUN_LEFT_OUT_BARREL_WORN",
            ["mm"] = 0,
        }, -- end of ["GUN_LEFT_OUT_BARREL_WORN"]
        ["INST_DI_EXCESSIVE_DRIFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INST_DI_EXCESSIVE_DRIFT",
            ["mm"] = 0,
        }, -- end of ["INST_DI_EXCESSIVE_DRIFT"]
        ["FAILURE_SNS_CABLE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FAILURE_SNS_CABLE",
            ["mm"] = 0,
        }, -- end of ["FAILURE_SNS_CABLE"]
        ["pitch_trim_runaway_down"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "pitch_trim_runaway_down",
            ["mm"] = 0,
        }, -- end of ["pitch_trim_runaway_down"]
        ["EGTSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EGTSENSOR",
            ["mm"] = 0,
        }, -- end of ["EGTSENSOR"]
        ["LeftEngine_LowOilPressure"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "LeftEngine_LowOilPressure",
            ["mm"] = 0,
        }, -- end of ["LeftEngine_LowOilPressure"]
        ["RDR_FAILURE_ARRAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RDR_FAILURE_ARRAY",
            ["mm"] = 0,
        }, -- end of ["RDR_FAILURE_ARRAY"]
        ["INS_TOTAL_FAIL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "INS_TOTAL_FAIL",
            ["mm"] = 0,
        }, -- end of ["INS_TOTAL_FAIL"]
        ["BOMBS_ARMING_NO_VOLATAGE_RIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BOMBS_ARMING_NO_VOLATAGE_RIGHT",
            ["mm"] = 0,
        }, -- end of ["BOMBS_ARMING_NO_VOLATAGE_RIGHT"]
        ["csf_YawDamper"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "csf_YawDamper",
            ["mm"] = 0,
        }, -- end of ["csf_YawDamper"]
        ["Failure_Fuel_ExtTankTransferC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "Failure_Fuel_ExtTankTransferC",
            ["mm"] = 0,
        }, -- end of ["Failure_Fuel_ExtTankTransferC"]
        ["FCS_FAILURE_R_ELEVATOR_ELEC_C"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FCS_FAILURE_R_ELEVATOR_ELEC_C",
            ["mm"] = 0,
        }, -- end of ["FCS_FAILURE_R_ELEVATOR_ELEC_C"]
    }, -- end of ["failures"]
} -- end of mission
