VE Lua Documentation

Press F to search!

sub

Definition


-- @/=[C]:-1
function sub(...)

Callers

@/lua/ge/extensions/editor/masterSpline/splineMgr.lua
          local baseName = decalSpline.name or "Decal Spline"
          local uniqueName = baseName .. " - " .. string.sub(spline.id, 1, 8)
          setNameJumpTable[decalSplineLink.getToolPrefixStr()](spline.id, uniqueName)
@/lua/ge/extensions/flowgraph/graph.lua
  for color, orderList in pairs(rootWork) do
    if string.sub(color.name, 1, 2) == 'on' then
      if self.hookList[color.name] == nil then
@/lua/ge/extensions/gameplay/missions/unlocks.lua
  for _, file in ipairs(files) do
    local aConds = require(file:sub(0,-5))
@/lua/vehicle/controller/drivingDynamics/CMU.lua
      if slashPos then
        controllerName = controllerName:sub(slashPos + 1)
      end
@/lua/ge/extensions/editor/gen/world.lua
		end)
		return string.sub(s, 2)
	end
	lo('?? for_file:'..fname) --..':'..tostring(#data)..':'..#v..':'..jdata)
	fout:write(string.sub(jdata, 2, #jdata-1))
	fout:close()
--					if #atkn == 2 then
			local scorner = string.sub(dobj.dae,1,ind-1)..'_Sco_'..string.sub(dobj.dae,ind+4)
				lo('?? if_SC:'..scorner..':'..tostring(ddae[scorner]))
--					if #atkn == 2 then
			local scorner = string.sub(dobj.dae,1,ind-1)..'_Sco_'..string.sub(dobj.dae,ind+4)
				lo('?? if_SC:'..scorner..':'..tostring(ddae[scorner]))
	jdata = jdata:gsub('},{', '}\r\n{')
	outputFile:write(string.sub(jdata, 2, #jdata-1))
		lo('?? jDATA:'..#list,true) --..':'..dirname..'/items.level.json'..':'..jdata, true)
			local outputFile = io.open(dname..fname, "w")
			outputFile:write(cnt..'\r\n'..string.sub(jdata, 2, #jdata-1))
			outputFile:close()
@/lua/ge/extensions/gameplay/statistic.lua
      local _, file, _ = path.split(filePath)
      local fileName = file:sub(1, -5)
      local extensionPath = "gameplay/statisticModules/" .. fileName
    activityType = "scenario"
    activityDetail = "/fg"..missionId:sub(levelFolder:len()+1):gsub("/","@")
  elseif scenario_scenarios and scenario_scenarios.getScenario() then
@/lua/vehicle/controller/drivingDynamics/actuators/adaptiveDampers.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/core/audio.lua
local function cacheSetEntry(bankFilePath)
 if string.sub(bankFilePath, 1, 1) ~= '/' then
    bankFilePath = "/"..bankFilePath
local function cacheClearEntry(bankFilePath)
 if string.sub(bankFilePath, 1, 1) ~= '/' then
    bankFilePath = "/"..bankFilePath
  for _,filepath in ipairs(bankFiles) do
    if string.sub(filepath, 1, 1) ~= '/' then
      filepath = "/"..filepath
  for _,filepath in ipairs(bankFiles) do
    if string.sub(filepath, 1, 1) ~= '/' then
      filepath = "/"..filepath
  for _,filepath in ipairs(bankFiles) do
    if string.sub(filepath, 1, 1) ~= '/' then
      filepath = "/"..filepath
  for _,filepath in ipairs(bankFiles) do
    if string.sub(filepath, 1, 1) ~= '/' then
      filepath = "/"..filepath
  end
  if string.sub(path, 1, 1) ~= '/' then
    path = "/"..path
local function loadLevelBank(bankFilePath)
  if string.sub(bankFilePath, 1, 1) ~= '/' then
    bankFilePath = "/"..bankFilePath
local function loadVehicleBank(bankPath)
  if string.sub(bankPath, 1, 1) ~= '/' then
    bankPath = "/"..bankPath
    -- make sure the key we use here matches that used previously in loadBaseBank
    if string.sub(filename, 1, 1) ~= '/' then
      filename = "/"..filename
@/lua/common/libs/ezSVG/EzSVG.lua
  if type(k) == "number" then return true end
  if string.sub(k, 1, k.len("__")) == "__" then return false end
  return true
@/lua/vehicle/ai.lua

  return laneConfig:sub(1, leftIdx-1), laneConfig:sub(leftIdx, rightIdx), laneConfig:sub(rightIdx+1, numOfLanes)
end

  return laneConfig:sub(1, leftIdx-1), laneConfig:sub(leftIdx, rightIdx), laneConfig:sub(rightIdx+1, numOfLanes)
end

  return laneConfig:sub(1, leftIdx-1), laneConfig:sub(leftIdx, rightIdx), laneConfig:sub(rightIdx+1, numOfLanes)
end
                local i = string.find(k, '\0')
                local n1id = string.sub(k, 1, i-1)
                local sqDist = positions[n1id]:squaredDistance(ego.pos)
                  target = n1id
                  targetLink = string.sub(k, i+1, #k)
                end
@/lua/ge/extensions/util/trackBuilder/splineTrack.lua
    local _, fn, e = path.split(file)
    local name = fn:sub(1, #fn - #e - 1)
    local read = loadJSON(name)
    local _, fn, e = path.split(file)
    previews[i] = fn:sub(1, #fn - #e - 1)
  end
    local _, fn, e = path.split(file)
    previews[i] = fn:sub(1, #fn - #e - 1)
  end
@/lua/ge/extensions/core/vehicle/partmgmt.lua
    end
  elseif dataType == 'string' and configData:sub(1, 1) == '{' then
    local res, newConfigData = preprocessPartConfig(deserialize(configData))
  -- notify the vehicle selector that the vehicle has been saved and clear the cache
  local configWithoutFilename = string.sub(filename, #(playerVehicleData.vehicleDirectory or "") + 1)
  configWithoutFilename = configWithoutFilename:gsub("%.pc$", "")
  for _, file in pairs(files) do
    local basename = string.sub(file, string.len(playerVehicle.vehicleDirectory) + 1, -1)
    table.insert(result,
      fileName = basename,
      name = string.sub(basename,0, -4),
      official = isOfficialConfig(basename),
@/lua/ge/extensions/editor/vehicleEditor/staticEditor/veJBeamModifierLeakVis.lua
      -- is it a node material?
      if valuePart:sub(1,3) == "NM_" then
        ival = particles.getMaterialIDByName(materials, valuePart:sub(4))
      if valuePart:sub(1,3) == "NM_" then
        ival = particles.getMaterialIDByName(materials, valuePart:sub(4))
        --log('D', "jbeam.replaceSpecialValues", "replaced "..valuePart.." with "..ival)
      elseif sectionName:match('^scale') and type(section) == "number" then
        modsScalers[sectionName:sub(6, #sectionName)] = {modVal = section, partPath = partName}
      end
@/lua/common/libs/LuaIRC/util.lua
    local lineStart = 1
    if line:sub(1,1) == ":" then
        local space = line:find(" ")
        local space = line:find(" ")
        prefix = line:sub(2, space-1)
        lineStart = space
    if trailToken then
        trailing = line:sub(trailToken + 1)
        lineStop = trailToken - 2
    local randindex = random(1, #nick)
    local randchar = sub(nick, randindex, randindex)
    local b = byte(randchar)
    -- Get the halves before and after the changed character
    local first = sub(nick, 1, randindex - 1)
    local last = sub(nick, randindex + 1, #nick)
    local first = sub(nick, 1, randindex - 1)
    local last = sub(nick, randindex + 1, #nick)
    nick = first..char(b)..last  -- Insert the new charachter
@/lua/ge/extensions/editor/veMain.lua
    local _, fn, _ = path.split(file)
    local name = string.sub(fn, 1, -5)
    if name ~= "veMain" then
    local _, fn, _ = path.split(file)
    local name = string.sub(fn, 1, -5)
    if name ~= "veMain" then
    local _, fn, _ = path.split(file)
    local name = string.sub(fn, 1, -5)
    if name ~= "veMain" then
@/lua/vehicle/controller/vehicleController/shiftLogic/automaticGearbox.lua
    modePrefix = "S"
  elseif string.sub(automaticHandling.mode, 1, 1) == "M" then
    modePrefix = "M"
  local manualModeIndex
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  end
  M.isSportModeActive = automaticHandling.mode == "S"
  M.isManualModeActive = string.sub(automaticHandling.mode, 1, 1) == "M"
end
  automaticHandling.defaultForwardMode = mode
  if automaticHandling.mode == "D" or automaticHandling.mode == "S" or tonumber(automaticHandling.mode) or string.sub(automaticHandling.mode, 1, 1) == "M" then
    if mode == "M1" then --we just shifted into M1
    if string.find(automaticHandling.mode, "M") then
      local gearIndex = tonumber(string.sub(automaticHandling.mode, 2))
      gearRatio = gearbox.gearRatios[gearIndex]
    if string.find(automaticHandling.mode, "M") then
      local gearIndex = tonumber(string.sub(automaticHandling.mode, 2))
      gearRatio = gearbox.gearRatios[gearIndex]
  local gearChangeTime = min(max(automaticHandling.gearChangeTimeRange * (M.smoothedValues.drivingAggression - 0.5) * 2 + automaticHandling.maxGearChangeTime, automaticHandling.minGearChangeTime), automaticHandling.maxGearChangeTime)
  local autoMode = string.sub(automaticHandling.mode, 1, 1)
  if (autoMode == "S" or autoMode == "M") then
  local gearboxInputAV = gearbox.inputAV
  local isManualMode = string.sub(automaticHandling.mode, 1, 1) == "M"
  for i = 1, modeCount do
    local mode = modes:sub(i, i)
    if automaticHandling.availableModeLookup[mode] then
@/lua/ge/extensions/ui/console.lua
  if tostring(slashed[1]):len() > 4096 then
    logs[logsTail] = {t,lvl,origin,tostring(slashed[1]):sub(1,4096)} --trim so we save memory and don't stress other part of code
  else
      if tostring(slashed[i]):len() > 4096 then
        logs[logsTail] = {t,lvl,origin,tostring(slashed[i]):sub(1,4096)} --trim so we save memory and don't stress other part of code
      else
              if v ~= 2 and im.GetContentRegionAvailWidth() < txtwidth then
                im.TextColored(lcol,string.format("%s", tostring(v):sub(1,256) ))
                txtwidth = txtwidth * (1/fontConsoleFact[0])
                  while(bt:len() > chunkSize and chunk:len() < 2048) do
                    chunk = chunk..bt:sub(1,chunkSize).."\n"
                    bt = bt:sub(chunkSize+1)
                    chunk = chunk..bt:sub(1,chunkSize).."\n"
                    bt = bt:sub(chunkSize+1)
                  end
                --table.insert(console_log_buffer, {'r', tostring(res)})
                if type(res)=="string" and res:sub(1,7)== "Error: " then
                  log("E", "exec", res)
  strI = strI..", "..vobj:getJBeamFilename()
  if vobj.partConfig:sub(1,1) == "{" or vobj.partConfig:sub(1,1) == "[" then
    strI = strI..", *custom*"
  strI = strI..", "..vobj:getJBeamFilename()
  if vobj.partConfig:sub(1,1) == "{" or vobj.partConfig:sub(1,1) == "[" then
    strI = strI..", *custom*"
@/lua/vehicle/extensions/gameplayInterface.lua
      local _, file, _ = path.split(filePath)
      local fileName = file:sub(1, -5)
      local extensionPath = "gameplayInterfaceModules/" .. fileName
@/inspector/External/three.js/OrbitControls.js

            offset.copy( position ).sub( scope.target );
                var position = scope.object.position;
                offset.copy( position ).sub( scope.target );
                var targetDistance = offset.length();
@/lua/common/graphpath.lua
  local i = string.find(id, delim)
  return string.sub(id, 1, i-1), string.sub(id, i+1, #id)
end
  local i = string.find(id, delim)
  return string.sub(id, 1, i-1), string.sub(id, i+1, #id)
end
@/lua/ge/extensions/editor/dynamicDecals/export.lua
  -- local maps = {"_color", "_colorPalette"}
  local dirPath = string.sub(texturesExport_DirectoryPath, -1) == "/" and texturesExport_DirectoryPath or texturesExport_DirectoryPath .. "/"
@/lua/ge/extensions/career/modules/delivery/progress.lua
    if key:endswith("Reputation") then
      local orgId = key:sub(1, -11)
      local organization = freeroam_organizations.getOrganization(orgId)
@/lua/ge/extensions/util/worker.lua
  local src = daePath
  local dst = dir .. filename:sub(1, -4) .. 'cdae'
  local dstData = dir .. filename:sub(1, -4) .. 'meshes.json'
  local dst = dir .. filename:sub(1, -4) .. 'cdae'
  local dstData = dir .. filename:sub(1, -4) .. 'meshes.json'
@/lua/common/libs/lua-websockets/websocket/frame.lua
  end
  return decoded,fin,opcode,encoded_bak:sub(bytes+1),mask
end
    if #data > 2 then
      reason = data:sub(3)
    end
@/lua/vehicle/controller/drivingDynamics/actuators/activeCenterDiffLock.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/core/schemeCommandServer.lua
    if string.startswith(data, 'beamng:') then
        commandhandler.onSchemeCommand(data:sub(8))
    end
@/lua/ge/extensions/career/career.lua
    local currentSaveSlot, currentSavePath = career_saveSystem.getCurrentSaveSlot()
    imgui.Text((string.sub(currentSavePath, string.len(career_saveSystem.getSaveRootDirectory())+2, -1)))
    imgui.Separator()
@/lua/ge/extensions/editor/levelValidator.lua
          im.PushStyleColor2(im.Col_Text, logColor)
          local textSize = im.CalcTextSize(logItem.message:sub(1, 1000) or "", nil, nil, im.GetColumnWidth(2) - im.GetStyle().ItemSpacing.x)
          if im.Selectable1(" " .. (logItem.logLevel or "") .. "##" .. i, selected == i, im.SelectableFlags_SpanAllColumns, im.ImVec2(0, textSize.y + 5)) then
          -- Add [IGNORED] prefix for ignored items
          local displayMessage = logItem.message:sub(1, 1000) or ""
          if isIgnored then
@/lua/ge/extensions/flowgraph/nodes/string/subString.lua
function C:work()
  self.pinOut.value.value = string.sub(self.pinIn.value.value, self.data.from, self.data.to)
end
@/lua/ge/extensions/editor/missionEditor.lua
      else
        shortId = clickedMission.id:sub(f+1,t)
      end
              table.insert(files, f)
              local dir, filename, ext =path.split(string.sub(f, 2+string.len(lastShownMission.missionFolder)))
              if dir then
@/lua/ge/extensions/gameplay/missions/progress.lua
  for _, file in ipairs(files) do
    local aConds = require(file:sub(0, -5))
@/lua/ge/extensions/gameplay/drag/general.lua
        dragData._originFile = file
        dragData._fnWithoutExt = string.sub(fn, 1, string.len(fn) - string.len(ext)-1)
        dragData._index = i
@/lua/common/libs/luaqrcode/qrencode.lua
    if #a == 2 then
      b1 = asciitbl[string.byte(string.sub(a,1,1))]
      b2 = asciitbl[string.byte(string.sub(a,2,2))]
      b1 = asciitbl[string.byte(string.sub(a,1,1))]
      b2 = asciitbl[string.byte(string.sub(a,2,2))]
      int = b1 * 45 + b2
      cpty_ec_bits = cpty_ec_bits + size_ecblock_bytes * 8
      datablocks[#datablocks + 1] = string.sub(data, pos * 8 + 1,( pos + size_datablock_bytes)*8)
      local tmp_tab = calculate_error_correction(datablocks[#datablocks],size_ecblock_bytes)
      if pos < #datablocks[i] then
        arranged_data = arranged_data .. string.sub(datablocks[i],pos, pos + 7)
      end
      if pos < #ecblocks[i] then
        arranged_ec = arranged_ec .. string.sub(ecblocks[i],pos, pos + 7)
      end
  for i=1,7 do
    bit = string.sub(ec_mask_type,i,i)
    fill_matrix_position(matrix, bit, 9, #matrix - i + 1)
  for i=8,9 do
    bit = string.sub(ec_mask_type,i,i)
    fill_matrix_position(matrix,bit,9,17-i)
  for i=10,15 do
    bit = string.sub(ec_mask_type,i,i)
    fill_matrix_position(matrix,bit,9,16 - i)
  for i=1,6 do
    bit = string.sub(ec_mask_type,i,i)
    fill_matrix_position(matrix,bit,i,9)
  end
  bit = string.sub(ec_mask_type,7,7)
  fill_matrix_position(matrix,bit,8,9)
  for i=8,15 do
    bit = string.sub(ec_mask_type,i,i)
    fill_matrix_position(matrix,bit,#matrix - 15 + i,9)
  for i=1,#bitstring do
    bit = string.sub(bitstring,i,i)
    x = start_x + math.fmod(i - 1,3)
  for i=1,#bitstring do
    bit = string.sub(bitstring,i,i)
    x = start_x + math.floor( (i - 1) / 3 )
      _y = positions[i][2]
      m = get_pixel_with_mask(mask,_x,_y,string.sub(byte,i,i))
      if debugging then
@/lua/ge/extensions/editor/dynamicDecals/layerStack.lua
          local dir, file, ext = path.split(data.filepath)
          file = string.sub(file, 1, #file - (#ext + 1))
          api.exportLayerMask(layer, dir, file, ext)
@/lua/ge/extensions/core/input/bindings.lua
      if string.startswith(device, "xinput") then
        local n = string.sub(device, -1, -1) -- get controller number (xinput3 -> 3)
        local event = {controller = n, connected = true}
      if string.startswith(device, "xinput") then
        local n = string.sub(device, -1, -1) -- get controller number (xinput3 -> 3)
        local event = {controller = n, connected = false}
@/lua/ge/extensions/editor/dynamicDecals/layerTypes/decal.lua
    local dir, fileName, fileExt = path.split(api.getDecalTexturePath("color"))
    newBrushName = string.sub(fileName, 1, #fileName - (#fileExt + 1))
    im.OpenPopup("SaveBrushPopup")
    if im.InputText(string.format("##%s_%s", guiId, "decalLayerFontCharacter"), editor.getTempCharPtr(api.getDecalLayerFontCharacter()), nil, im.InputTextFlags_AutoSelectAll) then
      api.setDecalLayerFontCharacter(string.sub(editor.getTempCharPtr(), 1, 1))
    end
@/lua/ge/extensions/editor/gen/utils.lua
		end
		if (str:sub(i, i + (delimiter:len() - 1)) == delimiter) then
			endPoint = i - 1;
			endPoint = i - 1;
			table.insert(result, str:sub(startPoint, endPoint));
			startPoint = i + (delimiter:len());
			endPoint = str:len();
			table.insert(result, str:sub(startPoint, endPoint));
		end
@/lua/common/tech/pcdLib.lua
function Pcd:addField(name, size, type)
  type = string.sub(type, 1, 1):upper()
  local n = #self.fields + 1
@/lua/common/libs/resty/template.lua
    while s > 0 do
        local c = sub(view, s, s)
        if c == " " or c == "\t" or c == "\0" or c == "\x0B" then
local function escaped(view, s)
    if s > 1 and sub(view, s - 1, s - 1) == "\\" then
        if s > 2 and sub(view, s - 2, s - 2) == "\\" then
    if s > 1 and sub(view, s - 1, s - 1) == "\\" then
        if s > 2 and sub(view, s - 2, s - 2) == "\\" then
            return false, 1
    local file, location = path, vars and var.template_location
    if sub(file, 1)  == "/" then file = sub(file, 2) end
    if location and location ~= "" then
    local file, location = path, vars and var.template_location
    if sub(file, 1)  == "/" then file = sub(file, 2) end
    if location and location ~= "" then
    if location and location ~= "" then
        if sub(location, -1) == "/" then location = sub(location, 1, -2) end
        local res = capture(concat{ location, '/', file})
    if location and location ~= "" then
        if sub(location, -1) == "/" then location = sub(location, 1, -2) end
        local res = capture(concat{ location, '/', file})
    local root = vars and (var.template_root or var.document_root) or prefix
    if sub(root, -1) == "/" then root = sub(root, 1, -2) end
    return readfile(concat{ root, "/", file }) or path
    local root = vars and (var.template_root or var.document_root) or prefix
    if sub(root, -1) == "/" then root = sub(root, 1, -2) end
    return readfile(concat{ root, "/", file }) or path
    while s do
        local t, p = sub(view, s + 1, s + 1), s + 2
        if t == "{" then
                    c[j] = "___[#___+1]=[=[\n"
                    c[j+1] = sub(view, i, s - 1 - w)
                    c[j+2] = "]=]\n"
                    c[j] = "___[#___+1]=template.escape("
                    c[j+1] = trim(sub(view, p, e - 1))
                    c[j+2] = ")\n"
                    c[j] = "___[#___+1]=[=[\n"
                    c[j+1] = sub(view, i, s - 1 - w)
                    c[j+2] = "]=]\n"
                    c[j] = "___[#___+1]=template.output("
                    c[j+1] = trim(sub(view, p, e - 1))
                    c[j+2] = ")\n"
                        c[j] = "___[#___+1]=[=[\n"
                        c[j+1] = sub(view, i, s - 1 - w)
                        c[j+2] = "]=]\n"
                    local n = e + 2
                    if sub(view, n, n) == "\n" then
                        n = n + 1
                        c[j] = "___[#___+1]=[=[\n"
                        c[j+1] = sub(view, i, r)
                        c[j+2] = "]=]\n"
                    end
                    c[j] = trim(sub(view, p, e - 1))
                    c[j+1] = "\n"
                    c[j] = "___[#___+1]=[=[\n"
                    c[j+1] = sub(view, i, s - 1 - w)
                    c[j+2] = "]=]\n"
                else
                    local f = sub(view, p, e - 1)
                    local x = find(f, ",", 2, true)
                        c[j] = "___[#___+1]=include([=["
                        c[j+1] = trim(sub(f, 1, x - 1))
                        c[j+2] = "]=],"
                        c[j+2] = "]=],"
                        c[j+3] = trim(sub(f, x + 1))
                        c[j+4] = ")\n"
                    c[j] = "___[#___+1]=[=[\n"
                    c[j+1] = sub(view, i, s - 1 - w)
                    c[j+2] = "]=]\n"
                    c[j] = "___[#___+1]=include("
                    c[j+1] = trim(sub(view, p, e - 1))
                    c[j+2] = ")\n"
            if e then
                local x, y = find(view, sub(view, s, e + 1), e + 2, true)
                if x then
                            c[j] = "___[#___+1]=[=[\n"
                            c[j+1] = sub(view, i, s - 1 - w)
                            c[j+2] = "]=]\n"
                        x = x - 1
                        if sub(view, y, y) == "\n" then
                            y = y + 1
                        end
                        local b = trim(sub(view, p, e - 1))
                        if b == "verbatim" or b == "raw" then
                                c[j] = "___[#___+1]=[=[\n"
                                c[j+1] = sub(view, i, s - 1 - w)
                                c[j+2] = "]=]\n"
                            c[j] = "___[#___+1]=[=["
                            c[j+1] = sub(view, e + 2, x)
                            c[j+2] = "]=]\n"
                        else
                            if sub(view, x, x) == "\n" then
                                x = x - 1
                                c[j] = "___[#___+1]=[=[\n"
                                c[j+1] = sub(view, i, r)
                                c[j+2] = "]=]\n"
                            c[j+2] = '"]=include[=['
                            c[j+3] = sub(view, e + 2, x)
                            c[j+4] = "]=]\n"
                    c[j] = "___[#___+1]=[=[\n"
                    c[j+1] = sub(view, i, s - 1 - w)
                    c[j+2] = "]=]\n"
                    e = e + 2
                    if sub(view, e, e) == "\n" then
                        e = e + 1
    end
    s = sub(view, i)
    if s and s ~= "" then
@/lua/ge/extensions/util/dependencyTree.lua
    if rootNode and rootNode.materials and #rootNode.materials > 0 then
      local entity = { deps = { material = {}}, provides = { shape = shapeInfoFn:sub(1, -13) }}
      for _, m in pairs(rootNode.materials) do
@/lua/vehicle/controller/drivingDynamics/actuators/adaptiveTorsionBars.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/editor/flowgraph/properties.lua
            if data.filepath:find(pin.node.mgr.savedDir) then
              sel = data.filepath:sub(pin.node.mgr.savedDir:len()+1,-1)
            end
            if validExt then
              local shortPath = file:sub(pin.node.mgr.savedDir:len()+1,-1)
              if im.Selectable1(shortPath) then
@/lua/common/libs/lua-MessagePack/MessagePack.lua
  c.i = i+n
  return s:sub(i, e)
end
  c.i = i+n
  return m.build_ext(tag, s:sub(i, e))
end
    underflow = function(self, e)
            self.s = self.s:sub(self.i)
            e = e - self.i + 1
@/lua/ge/extensions/core/gamestate.lua
  for _, prefix in ipairs(pausedStates) do
    if string.sub(stateName, 1, string.len(prefix)) == prefix then
      return true
@/lua/ge/extensions/editor/resourceChecker/resourceUtil.lua
local function strEnds(s, suffix)
  return s and suffix and s:sub(-#suffix) == suffix
end
    if title then
      title = title:sub(2, -2)
      t[title] = t[title] or {}
      key = key:gsub(' ', "")
      value = value:sub(2, -2)
      t[titleS][key] = value
@/lua/ge/extensions/editor/api/gui.lua
  if withoutExtension then
    filename = string.sub(filename, 1, #filename - 4)
  end
      if not pos2 then
        imgui.TextColored(textColor, text:sub(pos1))
        break
      elseif pos1 < pos2 then
        imgui.TextColored(textColor, text:sub(pos1, pos2 - 1))
        imgui.SameLine()
      local pos3 = pos2 + highlightLowerLen
      imgui.TextColored(textHighlightColor, text:sub(pos2, pos3))
      imgui.SameLine()
@/lua/vehicle/extensions/core/quickAccess.lua
  end
  if string.sub(args.level, string.len(args.level)) ~= "/" then
    args.level = args.level .. "/"
@/lua/ge/extensions/gameplay/missions/missionTypes/editorHelper.lua
        if key ~= "fieldName" and string.startswith(key, "fieldName") then
          table.insert(ret, {label = string.sub(key, 10), fieldName = elem[key], elemLabel = elem.label})
        end
@/lua/ge/extensions/editor/dynamicDecals/layerTypes/path.lua
      for k, v in ipairs(layer.textCharacterPositions) do
        im.TextUnformatted(string.sub(layer.text, k, k))
        im.SameLine()
@/lua/ge/extensions/core/commandhandler.lua
      if arg1:startswith('beamng:') then
        onSchemeCommand(arg1:sub(8), true) -- strip 'beamng:'
        break
@/lua/ge/extensions/editor/gen/exp_meshexplorer.lua
--            local s = dataString:tostring()
--                lo('?? ss:'..string.sub(s, 1, 100))
--[[
                    local c=0
                    for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
                        return string.char(c)
--            local s = ffi.string(dataString:get()) --res)
--                lo('?? ss:'..string.sub(res, 1, 100))
@/lua/common/jbeam/slotSystem.lua
          if type(v3) == "number" and str_byte(k3, 1) == 36 then
            local actualK3 = k3:sub(3) --remove the magic chars at the beginning to get the actual KEY, this can potentially lead to issues if k3 omits the second magic char
            local existingValue = target[sectionKey][actualK3]
@/lua/ge/extensions/gameplay/rally/notebook/pacenote.lua
    if note_field_freeform ~= rallyUtil.autofill_blocker then
      local last_char = note_field_freeform:sub(-1)
      if note_field_freeform == '' then
    -- Get the last character of the note
    local lastChar = note:sub(-1)
    if rallyUtil.hasPunctuation(lastChar) then
      note = string.sub(note, 1, -2)
      lastChar = note:sub(-1)
      note = string.sub(note, 1, -2)
      lastChar = note:sub(-1)
    end
@/lua/ge/extensions/ui/liveryEditor/camera.lua
    local switchOrder = {"right", "front", "left", "back"}
    local startsWithTop = string.sub(orthographicView, 1, 3) == "top"
      if startsWithTop and y == -1 then
        local view = string.sub(orthographicView, 4)
        M.setOrthographicView(view)
@/lua/ge/extensions/ui/uiMods.lua
      end
      local relPath = filepath:sub(#modDir + #modname + 2)
      table.insert(mods[modname].files, relPath)
@/lua/vehicle/controller/vehicleController/shiftLogic/cvtGearbox2.lua
    modePrefix = "S"
  elseif string.sub(automaticHandling.mode, 1, 1) == "M" then
    modePrefix = "M"
  local manualModeIndex
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  end
  for i = 1, modeCount do
    local mode = modes:sub(i, i)
    if automaticHandling.availableModeLookup[mode] then
@/lua/ge/extensions/editor/flowgraph/references.lua
    if not pos2 then
      im.Text(label:sub(pos1))
      break
    elseif pos1 < pos2 then
      im.Text(label:sub(pos1, pos2 - 1))
      im.SameLine()
    local pos3 = pos2 + highlightLowerLen
    im.TextColored(matchColor, label:sub(pos2, pos3))
    im.SameLine()
@/lua/vehicle/partCondition.lua
        result[partId] = getCondition(partId)
        --log("I", "partCondition.getConditions", string.format("Got condition for partId %25s: ", partId) .. string.sub(serialize(result[partId]), 1, 100))
      end,
@/lua/common/extensions/ui/flowgraph/editor.lua
  elseif tpe == 'string' or tpe == 'bool' or tpe == 'boolean' then
    return (tostring(value):sub(0, 10) .. (tostring(value):len() > 10 and "..." or ""))
  elseif tpe == 'number' then
@/lua/ge/extensions/core/remoteController.lua
    --log('D', logTag, "got '" .. tostring(data) .. "' from "..tostring(ip) .. ":" .. tostring(listenPort))
    if(data:sub(0, 6) == 'beamng') then -- new device trying to connect
      local args = split(data, '|')
@/lua/ge/extensions/flowgraph/nodes/ui/contextTranslation.lua
        for v in string.gmatch(translationString, "{{%a+}}") do
          self:createPin('in', 'string', v:sub(3, -3), nil, '')
        end
@/lua/ge/extensions/core/modmanager.lua
    if string.startswith(path, "/vehicles/") and not string.startswith(path, "/vehicles/mod_info") then
    vehicles[string.sub(path, 20)] = 1
    end
      local tmp = e:gsub(filename, "")
      if tmp:sub(1,1) ~= "/" then tmp = "/"..tmp end
      filesInZIP[#filesInZIP+1] = tmp
                local needManualAction = true
                if string.sub(oldFilepath,1,11) == "/mods/repo/" then
                  zip:close()
    local path, filename, ext = path.split(v)
    local infofile = path .. string.sub(filename, 0, -string.len(ext)-2) .. '.json'
    local data = jsonReadFile(infofile)
      local tmp = e:gsub(mods[modname].unpackedPath, "")
      if tmp:sub(1,1) ~= "/" then tmp = "/"..tmp end
      mountedFilesChange[i] = {filename = tmp, type = reason }
    if zipPath:startswith(mods[modname].unpackedPath) then
      zipPath = string.sub(zipPath, string.len(mods[modname].unpackedPath) + 1)
      if string.startswith(zipPath, '/') then
      if string.startswith(zipPath, '/') then
        zipPath = string.sub(zipPath, 2)
      end
  if string.startswith(realPath, userPath) then
    local modPath = realPath:sub(string.len(userPath))
    modPath = modPath:gsub("\\", "/")
    if zipPos then
      modPath = modPath:sub(1, zipPos + 3)
    else
@/lua/ge/extensions/flowgraph/nodes/mission/getCustomVehicleData.lua
  while s <= #str do
    while str:sub(e, e) ~= "," and e <= #str do
      e = e + 1
    end
    wps[i] = str:sub(s, e - 1)
    e = e + 1
@/lua/ge/extensions/scenario/scenariosLoader.lua
      scenarioData.sourceFile = scenarioFilename
      scenarioData.official = isOfficialContentVPath(string.sub(scenarioFilename, 0))
      scenarioData.levelName = string.gsub(scenarioFilename, "(.*/)(.*)/scenarios/(.*)%.json", "%2")
        if string.startswith(p, scenarioData.directory) then
          local imageFilename = string.sub(p, string.len(scenarioData.directory) + 2, string.len(p) - 4)
          local foundClash = false
@/lua/ge/extensions/editor/assetBrowser.lua
      if file.type == "image" then
        local textureName = string.sub(file.fileName, 1, #file.fileName-2)
        local textureType = string.sub(file.fileName, -2)
        local textureName = string.sub(file.fileName, 1, #file.fileName-2)
        local textureType = string.sub(file.fileName, -2)
        if string.sub(textureType,1,1) == "_" then
        local textureType = string.sub(file.fileName, -2)
        if string.sub(textureType,1,1) == "_" then
          textureType = string.sub(textureType,2,2)
        if string.sub(textureType,1,1) == "_" then
          textureType = string.sub(textureType,2,2)
          if textureType == "n" or textureType == "d" or textureType == "s" then
        -- TODO: check if filetype is present
        fileName = string.sub(fileName, 1, #fileName - #fileType)
        -- Remove the `.` from the filetype
        -- Remove the `.` from the filetype
        fileType = #fileType > 0 and string.lower(string.sub(fileType, 2)) or fileType
              -- TODO: check if filetype is present
              fileName = string.sub(fileName, 1, #fileName - #fileType)
              -- Remove the `.` from the filetype
              -- Remove the `.` from the filetype
              fileType = #fileType > 0 and string.lower(string.sub(fileType, 2)) or fileType
  local filename = string.match(filepath, "[^/]*$")
  local fileDir = string.sub(filepath, 1, #filepath - #filename)
  local dir = getDirByPath(fileDir, root, true)
    local simpleFileType = string.lower(string.match(filename, "[^.]*$"))
    local fileNameNoExt = string.sub(filename, 1, #filename - (#filetype+1))
    local file = newFile(dir, dir.path..filename, fileNameNoExt, filetype, simpleFileType)
      if levelName and string.lower(levelName) == string.lower(var.levelName) then
        levelFilepath = string.sub(levelFilepath, 1, #levelFilepath - #filename)
        dir = getDirByPath(levelFilepath, var.root)
      elseif artFilepath then
        artFilepath = string.sub(artFilepath, 1, #artFilepath - #filename)
        dir = getDirByPath(artFilepath, var.commonArt)
@/lua/common/libs/lunajson/lunajson/sax.lua
  local function f_nul()
    if sub(json, pos, pos+2) == 'ull' then
      pos = pos+3
  local function f_fls()
    if sub(json, pos, pos+3) == 'alse' then
      pos = pos+4
  local function f_tru()
    if sub(json, pos, pos+2) == 'rue' then
      pos = pos+3
        end
        str = str .. sub(json, pos, jsonlen)
        if pos2 == jsonlen+2 then
    end
    str = str .. sub(json, pos, newpos-1)
    pos = newpos+1
    local pos2 = (pos-1) + n
    local str = sub(json, pos, pos2)
    while pos2 > jsonlen and jsonlen ~= 0 do
      pos2 = pos2 - (jsonlen - (pos-1))
      str = str .. sub(json, pos, pos2)
    end
@/lua/common/libs/luasocket/socket/mbox.lua
        if not i then break end
        local message = string.sub(mbox_s, j, i-1)
        table.insert(mbox, message)
@/lua/ge/extensions/editor/flowgraph/nodelibrary.lua
    if match:find(t..": ") ~= nil then
      return t, string.sub(match, #t+3)
    end
    if match:find(t..":") ~= nil then
      return t, string.sub(match, #t+2)
    end
    if not pos2 then
      im.Text(label:sub(pos1))
      break
    elseif pos1 < pos2 then
      im.Text(label:sub(pos1, pos2 - 1))
      im.SameLine()
    local pos3 = pos2 + highlightLowerLen
    im.TextColored(matchColor, label:sub(pos2, pos3))
    im.SameLine()
@/lua/ge/extensions/editor/raceEditor.lua
              table.insert(allFiles,{
                name = string.sub(filename,1,-11),
                file = f
@/lua/ge/extensions/flowgraph/nodes/vehicle/ai/scriptAI/pathFromFile.lua
    for _, fileName in pairs(self.files) do
      local fnShort = string.sub(fileName, string.len(trackFilePath) + 1)
      fnShort = string.sub(fnShort, 1, string.len(fnShort) - string.len(trackFileExt))
      local fnShort = string.sub(fileName, string.len(trackFilePath) + 1)
      fnShort = string.sub(fnShort, 1, string.len(fnShort) - string.len(trackFileExt))
      if im.Selectable1(fnShort, fnShort==self.fnShort) then
  if self.fileName and self.fileName ~= "" then
    local fnShort = string.sub(self.fileName, string.len(trackFilePath) + 1)
    self.fnShort = string.sub(fnShort, 1, string.len(fnShort) - string.len(trackFileExt))
    local fnShort = string.sub(self.fileName, string.len(trackFilePath) + 1)
    self.fnShort = string.sub(fnShort, 1, string.len(fnShort) - string.len(trackFileExt))
  end
@/lua/ge/extensions/editor/tech/roadArchitect/import.lua
    if not ni then break end
    local text = string.sub(s, i, ni - 1)
    if not string.find(text, "^%s*$") then
  end
  local text = string.sub(s, i)
  if not string.find(text, "^%s*$") then
@/lua/ge/extensions/ui/vehicleSelector/vehicleSpecifications.lua
      local start = math.max(1, i - 2)
      table.insert(parts, 1, integerPart:sub(start, i))
    end
@/lua/ge/extensions/util/procTrack.lua
  while i*5 < #word do
    local w = string.sub(word, 1+ i*5, 5+i*5)
@/lua/common/libs/lunajson/lunajson/decoder.lua
  local function f_nul()
    if sub(json, pos, pos+2) == 'ull' then
      pos = pos+3
  local function f_fls()
    if sub(json, pos, pos+3) == 'alse' then
      pos = pos+4
  local function f_tru()
    if sub(json, pos, pos+2) == 'rue' then
      pos = pos+3

    local str = sub(json, pos, tmppos)
    pos = newpos
@/lua/vehicle/controller/driveModes.lua
  for k, v in pairs(jbeamData) do
    if k:sub(1, #"modes") == "modes" then
      tableMergeRecursive(modeData, v)

    if k:sub(1, #"enabledModes") == "enabledModes" then
      for _, modeKey in pairs(v) do
@/lua/ge/extensions/gameplay/missions/proceduralMissionGenerators/timeTrialMissions.lua

            local isRaceJson = string.sub(raceFile,#raceFile-9,#raceFile) == '.race.json'
@/lua/vehicle/input.lua
  --print(string.format("/  Splitting '%10s' into long: '%5s', side: '%5s' .", wheelName, long, side))
  long = long and long:sub(1, 1) or long
  side = side and side:sub(1, 1) or side
  long = long and long:sub(1, 1) or long
  side = side and side:sub(1, 1) or side
  --print(string.format("\\_ Splitting '%10s' into long: '%5s', side: '%5s' .", wheelName, long, side))
@/lua/ge/extensions/editor/assemblySpline/molecule.lua
  for _, anchorName in ipairs(anchorNames) do
    if anchorName:sub(1, 5) == anchorPrefixStrWithDot then
      local parts = {}
@/ui/ui-vue/dist/index.js
    
`,_sfc_main$70={__name:`OthersView`,props:{addons:Object},emits:[`changeView`],setup(__props,{emit:__emit}){let{lua}=useBridge(),emit$1=__emit,inGarage=sysInfo_default.gameState.value===`garage`,navigate$1=(...state)=>{let stateName=state[0];window.bngVue.gotoGameState(stateName,{params:{mode:`mainMenuOthers`},tryAngularJS:!0,blankAngularJS:!0})},startGarage=()=>lua.extensions.gameplay_garageMode.start(),startTrackBuilder=()=>lua.freeroam_freeroam.startTrackBuilder(`glow_city`);async function rallyDisclaimer(){await openExperimental($translate.instant(`ui.rally.experimentalTitle`),htmlBody,[{label:$translate.instant(`ui.common.back`),value:!1,isCancel:!0,extras:{accent:ACCENTS.secondary}},{label:$translate.instant(`ui.common.understood`),value:!0,default:!0}])&&openGameplaySelector(`openRallySelector`)}function runAction(action){switch(typeof action){case`function`:nextTick(action);break;case`string`:navigate$1(action);break;case`object`:Array.isArray(action)?navigate$1(...action):navigate$1(action.state,action.params);break}}function openGameplaySelector(action){lua.ui_gameplaySelector_general[action]()}return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$62,[createBaseVNode(`div`,_hoisted_2$51,[createVNode(unref(bngScreenHeading_default),{class:`header`,divider:!0,type:`line`},{default:withCtx(()=>[..._cache[13]||=[createTextVNode(` More `,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_3$44,[createVNode(BackAside_default,{onClick:_cache[0]||=$event=>emit$1(`changeView`,null)}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`rallyHelmet`,onClick:_cache[1]||=$event=>rallyDisclaimer(),tag:_ctx.$t(`ui.career.experimental.name`),"tag-red":``},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.rally`)),1)]),_:1},8,[`tag`]),createVNode(MenuButton_default,{size:`medium`,"icon-id":`gamepad`,tag:`New!`,onClick:_cache[2]||=$event=>openGameplaySelector(`openGameplaySelector`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`Gameplay Selector`)),1)]),_:1}),createVNode(MenuButton_default,{"bng-scoped-nav-autofocus":``,size:`medium`,"icon-id":`flag`,tag:`Gameplay Filter`,onClick:_cache[3]||=$event=>openGameplaySelector(`openChallengesSelector`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.options.userInterface.showMissionMarkers`)),1)]),_:1}),createVNode(MenuButton_default,{"bng-scoped-nav-autofocus":``,size:`medium`,"icon-id":`star`,tag:`Gameplay Filter`,onClick:_cache[4]||=$event=>openGameplaySelector(`openCampaignsSelector`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.campaigns`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`clapperboard`,tag:`Gameplay Filter`,onClick:_cache[5]||=$event=>openGameplaySelector(`openScenariosSelector`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.scenarios`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`stopwatchArrows02`,onClick:_cache[6]||=$event=>navigate$1(`menu.quickraceOverview`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.quickrace`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,disabled:inGarage,highlighted:inGarage,"icon-id":`carDealer`,onClick:_cache[7]||=$event=>startGarage()},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.mainmenu.garage`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`bus`,onClick:_cache[8]||=$event=>navigate$1(`menu.busRoutes`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.bus`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`lightrunner`,onClick:_cache[9]||=$event=>navigate$1(`menu.lightrunnerOverview`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.lightRunner`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,disabled:inGarage,"icon-id":`autobahn`,onClick:_cache[10]||=$event=>startTrackBuilder()},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.playmodes.trackBuilder`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`movieCamera`,onClick:_cache[11]||=$event=>navigate$1(`menu.replay`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.dashboard.replay`)),1)]),_:1}),createVNode(MenuButton_default,{size:`medium`,"icon-id":`chartBars`,onClick:_cache[12]||=$event=>navigate$1(`menu.options.stats`)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.statspage.title`)),1)]),_:1}),(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.addons,(item,idx)=>(openBlock(),createBlock(MenuButton_default,{key:idx,size:`medium`,"icon-id":item.iconId,icon:item.icon,onClick:$event=>runAction(item.action),tag:_ctx.$t(`ui.mainmenu.mod`),"tag-dark-green":``},{default:withCtx(()=>[createTextVNode(toDisplayString(item.title),1)]),_:2},1032,[`icon-id`,`icon`,`onClick`,`tag`]))),128))])])]))}},OthersView_default=__plugin_vue_export_helper_default(_sfc_main$70,[[`__scopeId`,`data-v-4c4dfed6`]]),Storage=class{constructor(name,values={}){this.storage=window.localStorage,this.name=name,this.assign(values)}assign(values={}){this._values||(this._values={},this.values=reactive({}));let keys=Object.keys(values);for(let key in this._values)delete this.values[key];if(this._values={},keys.length===0){this._listener&&=(window.removeEventListener(`storage`,this._listener),null);return}let that=this;for(let key in values)this._values[key]={exists:this.has(key),value:this.get(key,values[key]),defaultValue:values[key]},Object.defineProperty(this.values,key,{get(){let item=that._values[key];return item.exists?item.value:that.evalDefaultValue(item.defaultValue)},set(value){let item=that._values[key];value!==item.value&&(item.exists=!0,item.value=value,that.set(key,value))},enumerable:!0,configurable:!0});this._listener||(this._listener=()=>{for(let key in this._values){let item=this._values[key],newExists=that.has(key),newValue=that.get(key,item.defaultValue);(item.exists!==newExists||item.value!==newValue)&&(item.exists=newExists,item.value=newValue,that.values[key]=newValue)}},window.addEventListener(`storage`,this._listener))}evalDefaultValue(defaultValue){return typeof defaultValue==`function`?defaultValue():defaultValue}getKey(key){return this.name+`:`+key}has(key){return this.storage.getItem(this.getKey(key))!==null}get(key,defaultValue=void 0){let data=this.storage.getItem(this.getKey(key));try{return data===null?this.evalDefaultValue(defaultValue):JSON.parse(data)}catch(error){return console.warn(`Error parsing storage data for key: ${key}\n`,error),this.evalDefaultValue(defaultValue)}}set(key,value){let data=JSON.stringify(value);this.storage.setItem(this.getKey(key),data)}del(key){this.storage.removeItem(this.getKey(key))}};const useDiscoverStore=defineStore(`discover`,()=>{let{lua,events:events$3}=useBridge(),discoverPages=ref([]),loaded=ref(!1),enabled=ref(!1),descShow=ref(!1),descText=ref(null),descriptions=ref({hover:null,focus:null}),pageDescription=ref(null),currentPage=ref(0),descTimer=null,storage=new Storage(`discover`,{lastSelected:0,lastStarted:void 0}).values;function setDescription(type,card=void 0){descTimer&&clearTimeout(descTimer),descriptions.value[type]=card?.description,card?(descShow.value=!0,descText.value=card.description):type===`hover`&&descriptions.value.focus?descText.value=descriptions.value.focus:descTimer=setTimeout(()=>{descShow.value=!1,descTimer=setTimeout(()=>{descText.value=null,descTimer=null},200)},100)}async function loadDiscoverPages(){loaded.value=!1,enabled.value=!1,discoverPages.value=[],await lua.extensions.load(`gameplay_discover`),discoverPages.value=await lua.gameplay_discover.getDiscoverPages(),loaded.value=!0,enabled.value=!0,console.log(`discoverPages`,discoverPages.value,`lastStartedDiscoverId`,storage.lastStarted)}async function startDiscover(discoverId){let cardIndex=allCards.value.findIndex(card=>card.discoverId===discoverId);if(cardIndex===-1){console.warn(`startDiscover: card not found: ${discoverId}`);return}storage.lastSelected=cardIndex,storage.lastStarted=discoverId,enabled.value=!1,events$3.emit(`LoadingScreen`,{active:!0}),await startLoading$1(async()=>{await waitForLoadingScreenFadeIn$1(),await lua.gameplay_discover.startDiscover(discoverId)})}let sections=computed(()=>{let baseSections=[],stamp=Date.now();if(discoverPages.value&&Array.isArray(discoverPages.value)&&discoverPages.value.length>0){let page=discoverPages.value[currentPage.value];if(page&&page.sections){for(let section of page.sections)if(section.cards&§ion.cards.length>0){let isFreeroam=section.type===`freeroam`,sectionConfig={title:section.title||(isFreeroam?`Freeroam Experiences`:`Showcase Challenges`),cards:[],placeholders:isFreeroam?5:10,size:isFreeroam?`big`:`medium`,style:isFreeroam?{}:{"--button-height":`4.5em`},key:stamp++,type:section.type};for(let card of section.cards){let cardWithHandlers={...card,onClick:()=>startDiscover(card.discoverId),onFocus:()=>setDescription(`focus`,card),onHover:()=>setDescription(`hover`,card),onBlur:()=>setDescription(`focus`),onMouseLeave:()=>setDescription(`hover`)};sectionConfig.cards.push(cardWithHandlers)}baseSections.push(sectionConfig)}}}return baseSections}),allCards=computed(()=>sections.value.flatMap(s=>s.cards)),description=computed(()=>({show:descShow.value,text:descText.value})),lastSelectedIndex=computed({get:()=>storage.lastSelected,set:value=>storage.lastSelected=value}),lastStartedDiscoverId=computed(()=>{if(storage.lastStarted)return storage.lastStarted;for(let section of sections.value)if(section.cards.length>0)return section.cards[0].discoverId}),totalPages=computed(()=>discoverPages.value?.length||0),hasNextPage=computed(()=>currentPage.valuecurrentPage.value>0),pages=computed(()=>!discoverPages.value||!Array.isArray(discoverPages.value)?[]:discoverPages.value.map((page,index)=>({index,name:page.title||`Page ${index+1}`,isActive:index===currentPage.value})));function nextPage(){hasNextPage.value&¤tPage.value++}function prevPage(){hasPrevPage.value&¤tPage.value--}function goToPage(pageIndex){pageIndex>=0&&pageIndex!discoverPages.value||!Array.isArray(discoverPages.value)||currentPage.value>=discoverPages.value.length?`ui.experiences.general.quickStart`:discoverPages.value[currentPage.value].title||`ui.experiences.general.quickStart`);function getSectionsForPage(pageIndex){if(!discoverPages.value||!Array.isArray(discoverPages.value)||pageIndex<0||pageIndex>=discoverPages.value.length)return[];let page=discoverPages.value[pageIndex],baseSections=[],stamp=Date.now();if(page&&page.sections){for(let section of page.sections)if(section.cards&§ion.cards.length>0){let isFreeroam=section.type===`freeroam`,sectionConfig={title:section.title||(isFreeroam?`Freeroam Experiences`:`Showcase Challenges`),cards:[],placeholders:isFreeroam?5:10,size:isFreeroam?`big`:`medium`,style:isFreeroam?{}:{"--button-height":`4.5em`},key:stamp++,type:section.type};for(let card of section.cards){let cardWithHandlers={...card,onClick:()=>startDiscover(card.discoverId),onFocus:()=>setDescription(`focus`,card),onHover:()=>setDescription(`hover`,card),onBlur:()=>setDescription(`focus`),onMouseLeave:()=>setDescription(`hover`)};sectionConfig.cards.push(cardWithHandlers)}baseSections.push(sectionConfig)}}return baseSections}return{loaded,enabled,sections,allCards,description,lastSelectedIndex,lastStartedDiscoverId,currentPage,totalPages,hasNextPage,hasPrevPage,pages,pageDescription,currentPageTitle,discoverPages,nextPage,prevPage,goToPage,getSectionsForPage,loadDiscoverPages}});var _hoisted_1$61={class:`center-wrap`},_hoisted_2$50={class:`exp-wrapper`},_hoisted_3$43={class:`exp-container`},_hoisted_4$32={key:0,class:`exp-card-desc`},_hoisted_5$27={class:`exp-page-description-text`},_sfc_main$69={__name:`DiscoverView`,emits:[`changeView`],setup(__props,{emit:__emit}){let emit$1=__emit,bgRequired=sysInfo_default.mainMenuBackgroundRequired,discover=useDiscoverStore(),focusId=computed(()=>{let allCards=discover.sections.flatMap(section=>section.cards),card=allCards.find(card$1=>discover.lastStartedDiscoverId&&discover.lastStartedDiscoverId===card$1.discoverId);return card||=allCards[0],card?.discoverId}),menuButtonRef=ref(null),setButtonRef=(el,card)=>{card.discoverId===focusId.value&&(menuButtonRef.value=el)},switchPage=left=>{let indexOffset=left?-1:1,newIndex=(discover.currentPage+indexOffset)%discover.pages.length,adjustedIndex=newIndex<0?discover.pages.length+newIndex:newIndex;discover.goToPage(adjustedIndex),nextTick(()=>focusDefaultButton())};onMounted(async()=>{await discover.loadDiscoverPages(),discover.discoverPages&&discover.discoverPages.length>0&&(discover.pageDescription=discover.discoverPages[discover.currentPage]?.description),await nextTick(),focusDefaultButton()});function focusDefaultButton(){if(!menuButtonRef.value)return;let elementToFocus=menuButtonRef.value?.getElement?.();setFocusExternal(elementToFocus)}return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$61,[!unref(discover).loaded||unref(discover).pages.length===0?(openBlock(),createBlock(unref(bngScreenHeading_default),{key:0,divider:``,type:`line`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(`ui.experiences.general.quickStart`)),1)]),_:1})):unref(discover).pages.length===1?(openBlock(),createBlock(unref(bngScreenHeading_default),{key:1,divider:``,type:`line`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(unref(discover).pages[0].name)),1)]),_:1})):(openBlock(),createBlock(unref(bngScreenHeading_default),{key:2,class:`exp-header exp-page-nav`,divider:``,type:`line`,"bng-no-child-nav":`true`},{default:withCtx(()=>[createVNode(unref(bngButton_default),{class:`exp-tab-button exp-tab-nav`,accent:unref(ACCENTS).outlined,"icon-left":unref(icons).arrowSmallLeft,onClick:_cache[0]||=$event=>switchPage(!0)},{default:withCtx(()=>[withDirectives(createVNode(unref(bngBinding_default),{"ui-event":`tab_l`,controller:``},null,512),[[unref(BngOnUiNav_default),()=>switchPage(!0),`tab_l`]])]),_:1},8,[`accent`,`icon-left`]),(openBlock(!0),createElementBlock(Fragment,null,renderList(unref(discover).pages,page=>(openBlock(),createBlock(unref(bngButton_default),{key:page.index,class:normalizeClass([{"exp-page-nav-active":page.index===unref(discover).currentPage},`exp-tab-button`]),accent:unref(ACCENTS).outlined,onClick:$event=>unref(discover).goToPage(page.index)},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(page.name)),1)]),_:2},1032,[`class`,`accent`,`onClick`]))),128)),createVNode(unref(bngButton_default),{class:`exp-tab-button exp-tab-nav`,accent:unref(ACCENTS).outlined,"icon-right":unref(icons).arrowSmallRight,onClick:_cache[1]||=$event=>switchPage(!1)},{default:withCtx(()=>[withDirectives(createVNode(unref(bngBinding_default),{"ui-event":`tab_r`,controller:``},null,512),[[unref(BngOnUiNav_default),()=>switchPage(!1),`tab_r`]])]),_:1},8,[`accent`,`icon-right`])]),_:1})),createBaseVNode(`div`,_hoisted_2$50,[createBaseVNode(`div`,_hoisted_3$43,[createVNode(BackAside_default,{onClick:_cache[2]||=$event=>emit$1(`changeView`,null)}),withDirectives((openBlock(),createBlock(unref(bngCard_default),{class:`exp-content`},{default:withCtx(()=>[unref(bgRequired)?(openBlock(),createBlock(BlurBackground_default,{key:0,class:`corners-big`})):createCommentVNode(``,!0),(openBlock(!0),createElementBlock(Fragment,null,renderList(unref(discover).sections,(section,index)=>(openBlock(),createElementBlock(Fragment,{key:section.key},[index>0?(openBlock(),createElementBlock(`div`,{key:0,class:normalizeClass({"exp-separator":!0,"exp-desc-active":unref(discover).description.show})},[createVNode(Transition,{name:`desc-appear`},{default:withCtx(()=>[unref(discover).description.show?(openBlock(),createElementBlock(`div`,_hoisted_4$32,toDisplayString(_ctx.$tt(unref(discover).description.text)),1)):createCommentVNode(``,!0)]),_:1})],2)):createCommentVNode(``,!0),createBaseVNode(`div`,{class:normalizeClass([`exp-buttons`,{[`exp-buttons-${section.type}`]:section.type,"exp-buttons-mission-with-description":unref(discover).pageDescription&§ion.type===`mission`,[`exp-buttons-${section.cards.length}-missions`]:section.type===`mission`}])},[unref(discover).loaded?(openBlock(),createElementBlock(Fragment,{key:1},[(openBlock(!0),createElementBlock(Fragment,null,renderList(section.cards,card=>(openBlock(),createBlock(MenuButton_default,{key:card.discoverId,ref_for:!0,ref:el=>setButtonRef(el,card),"bng-scoped-nav-autofocus":card.discoverId===focusId.value,size:section.size,"no-blur":``,disabled:!unref(discover).enabled,"bg-img-abs":card.image,"enlarge-on-hover":``,"darkened-image":section.size===`medium`,"text-icon-prefix":section.size==`medium`&&card.icon,style:normalizeStyle(section.style),tag:_ctx.$ctx_t(card.tag),onClick:card.onClick,onMouseenter:card.onHover,onMouseleave:card.onMouseLeave,onFocus:card.onFocus,onBlur:card.onBlur},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(card.name)),1)]),_:2},1032,[`bng-scoped-nav-autofocus`,`size`,`disabled`,`bg-img-abs`,`darkened-image`,`text-icon-prefix`,`style`,`tag`,`onClick`,`onMouseenter`,`onMouseleave`,`onFocus`,`onBlur`]))),128)),section.type===`freeroam`&&unref(discover).pageDescription?(openBlock(),createElementBlock(`div`,{key:0,class:`exp-page-description`,style:normalizeStyle({"grid-column":`span ${5-section.cards.length}`,"--card-count":5-section.cards.length})},[createVNode(unref(bngCardHeading_default),{type:`ribbon`,class:`exp-page-description-title`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$tt(unref(discover).pageDescription.title)),1)]),_:1}),createBaseVNode(`span`,_hoisted_5$27,toDisplayString(_ctx.$tt(unref(discover).pageDescription.description)),1)],4)):createCommentVNode(``,!0)],64)):(openBlock(!0),createElementBlock(Fragment,{key:0},renderList(section.placeholders,i=>(openBlock(),createBlock(MenuButton_default,{key:i,disabled:``,size:section.size,"no-blur":``,"bg-img":section.size===`big`?`/images/mainmenu/freeroam.jpg`:null,style:normalizeStyle(section.style)},{default:withCtx(()=>[createTextVNode(toDisplayString(i===1?_ctx.$tt(`ui.repository.loading`):``),1)]),_:2},1032,[`size`,`bg-img`,`style`]))),128))],2)],64))),128))]),_:1})),[[unref(BngBlur_default),!unref(bgRequired)]])])])]))}},DiscoverView_default=__plugin_vue_export_helper_default(_sfc_main$69,[[`__scopeId`,`data-v-c671ffb6`]]),routes_default$9=[{path:`/menu.mainmenu`,component:MainMenu_default,meta:{infoBar:{visible:!0,showSysInfo:!0},uiApps:{shown:!1},topBar:{visible:!0}},children:[{path:``,name:`menu.mainmenu`,component:MainView_default},{path:`others`,name:`menu.mainmenu.others`,component:OthersView_default,meta:{topBar:{visible:!1}}},{path:`discover`,name:`menu.mainmenu.discover`,component:DiscoverView_default,meta:{topBar:{visible:!1}}}]},{path:`/menu.:sub(.*)?`,name:`menu`,component:layoutEmpty_default,meta:{clickThrough:!0,topBar:{visible:!0},infoBar:{withAngular:!0,visible:!0,showSysInfo:!0}}}];const useMissionDetailsStore=defineStore(`missionDetails`,()=>{let{events:events$3}=useBridge(),missions=ref([]),selectedMissionId=ref(null),preselectedPage=ref(null),userSettingsModel=ref({}),repairOptions=ref(null),startOptionModel=ref(null),activeObjectives=ref({}),context=ref(null),sameUserSettingsAsLast=ref(!1),selectedMission=computed(()=>{if(!missions.value||missions.value.length===0)return null;let missionIndex=missions.value.findIndex(x=>x.id===selectedMissionId.value);if(missionIndex===-1)return null;let data=missions.value[missionIndex];return{id:data.id,name:data.name,description:data.description,missionTypeLabels:[data.missionTypeLabel],images:data.previews,startableDetails:{startable:data.unlocks.startable},order:missionIndex,leagues:data.leagues,hasRules:data.hasRules}}),currentMission=computed(()=>{if(!missions.value||missions.value.length===0)return null;let missionIndex=missions.value.findIndex(x=>x.id===selectedMissionId.value);return missionIndex===-1?null:missions.value[missionIndex]}),entryFee=ref(),missionBasicInfo=computed(()=>currentMission.value?currentMission.value.parentInfo?{id:currentMission.value.id,name:currentMission.value.parentInfo.name,icon:currentMission.value.parentInfo.icon,description:currentMission.value.parentInfo.description,missionTypeLabels:[currentMission.value.parentInfo.missionTypeLabel],images:currentMission.value.parentInfo.previews,additionalAttributes:currentMission.value.parentInfo.additionalAttributes,entryFee:entryFee.value,official:currentMission.value.official,author:currentMission.value.author,date:currentMission.value.parentInfo.date}:{id:currentMission.value.id,name:currentMission.value.name,icon:currentMission.value.icon,description:currentMission.value.description,missionTypeLabels:[currentMission.value.missionTypeLabel],images:currentMission.value.previews,additionalAttributes:currentMission.value.additionalAttributes,entryFee:entryFee.value,official:currentMission.value.official,author:currentMission.value.author,date:currentMission.value.date}:null),missionProgressFromMission=(mission,activeObjectives$1)=>{if(!mission||!mission.formattedProgress||!mission.formattedProgress.unlockedStars||!mission.formattedProgress.unlockedStars.stars||mission.formattedProgress.unlockedStars.disabled)return null;let stars=mission.formattedProgress.unlockedStars.stars;if(!stars||!stars.length||stars.length===0)return null;let activeStars=[];for(let star of stars){let info={enabled:!1,order:star.globalStarIndex,isDefaultStar:star.isDefaultStar,key:star.key,label:star.label,rewards:star.rewards,unlocked:star.unlocked,count:star.count};activeObjectives$1&&activeObjectives$1.starInfo&&activeObjectives$1.starInfo[star.key]&&(info.enabled=activeObjectives$1.starInfo[star.key].enabled,info.message=activeObjectives$1.starInfo[star.key].message,info.visible=activeObjectives$1.starInfo[star.key].visible,info.label=activeObjectives$1.starInfo[star.key].label,info.rewards=activeObjectives$1.starInfo[star.key].rewards),activeStars.push(info)}return{stars:activeStars,message:activeObjectives$1.message,showMessage:activeStars.filter(x=>!x.visible).length>0}},missionProgress=computed(()=>missionProgressFromMission(currentMission.value,activeObjectives.value)),missionSettings=computed(()=>{if(!(!currentMission.value||!currentMission.value.userSettings||currentMission.value.userSettings.length===0))return currentMission.value.userSettings}),missionStartableDetails=computed(()=>{if(!currentMission.value)return null;if(context.value===`availableMissions`){let startable=currentMission.value.unlocks.startable;if(!repairOptions.value&&!startable)return console.log(`no repair ooptions`),null;if(startOptionModel.value===`defaultStart`)return{startableVisible:currentMission.value.unlocks.startable,startableEnabled:!0};let needsRepair=repairOptions.value?repairOptions.value.length>0:!1,repairType=repairOptions.value?repairOptions.value.find(x=>x.type===startOptionModel.value):null;return{needsRepair,repairOptions:repairOptions.value,selectedRepairTypeLabel:repairType?repairType.label:null,selectedRepairType:startOptionModel.value,startableVisible:!0,startableEnabled:!needsRepair||repairType.enabled}}else if(context.value===`ongoingMission`)return{startableVisible:!1,abandonVisible:!0,restartVisible:!0,continueVisible:!0}}),formattedProgress=computed(()=>currentMission.value?currentMission.value.formattedProgress:null),currentProgressKey=ref(),currentProgressKeyTranslation=ref(),currentProgress=ref();events$3.on(`missionProgressKeyChanged`,data=>{currentProgressKey.value=data.progressKey,currentProgressKeyTranslation.value=data.translation,currentProgress.value=data.progress});let availableVehicles=computed(()=>currentMission.value.userSettings&&Array.isArray(currentMission.value.userSettings)?currentMission.value.userSettings.filter(x=>x.isVehicleSelector):void 0);events$3.on(`missionStartingOptionsForUserSettingsReady`,data=>{repairOptions.value=data.options&&Array.isArray(data.options)&&data.options.length>0?data.options.filter(x=>x.type):null,startOptionModel.value=repairOptions.value&&repairOptions.value.length>0?repairOptions.value[0].type:null,entryFee.value=data.options&&data.entryFee?data.entryFee:null});let stopSelectedMissionWatcher=watch(()=>selectedMissionId.value,()=>{if(!currentMission.value)return;let updatedSettings={};currentMission.value.userSettings&¤tMission.value.userSettings.length&¤tMission.value.userSettings.forEach(x=>updatedSettings[x.key]=x.value),userSettingsModel.value=updatedSettings}),stopSettingsWatcher=watch(()=>userSettingsModel.value,async()=>{let settings$1=Object.keys(userSettingsModel.value).map(key=>({key,value:userSettingsModel.value[key]})),activeStars=await Lua_default.extensions.gameplay_missions_missionScreen.getActiveStarsForUserSettings(selectedMissionId.value,settings$1);if(activeObjectives.value={...activeObjectives.value,...activeStars},Lua_default.extensions.gameplay_missions_missionScreen.changeUserSettings(selectedMissionId.value,settings$1),Lua_default.extensions.gameplay_missions_missionScreen.requestStartingOptionsForUserSettings(selectedMissionId.value,settings$1),context.value===`ongoingMission`){for(let key in sameUserSettingsAsLast.value=!0,userSettingsModel.value)sameUserSettingsAsLast.value=sameUserSettingsAsLast.value&¤tMission.value&¤tMission.value.lastUserSettings&&userSettingsModel.value[key]==currentMission.value.lastUserSettings[key];for(let key in currentMission.value.lastUserSettings)sameUserSettingsAsLast.value=sameUserSettingsAsLast.value&¤tMission.value&¤tMission.value.lastUserSettings&&userSettingsModel.value[key]==currentMission.value.lastUserSettings[key]}},{deep:!0}),changeSettings=(key,value)=>{userSettingsModel.value[key]=value,currentMission.value.userSettings&¤tMission.value.userSettings.forEach(x=>{if(x.key===key&&(x.value=value,x.type===`select`)){for(let option of x.values)if(option.v===value){x.currentOption=option;break}}})},changeRepairType=type=>startOptionModel.value=type,selectMission=missionId=>{selectedMissionId.value!==missionId&&(selectedMissionId.value=missionId)},selectPreviousMission=()=>{let index=missions.value.findIndex(x=>x.id===selectedMissionId.value);selectMissionByIndex(index>0?index-1:missions.value.length-1)},selectNextMission=()=>{let index=missions.value.findIndex(x=>x.id===selectedMissionId.value);selectMissionByIndex(index{let settings$1=Object.keys(userSettingsModel.value).map(key=>({key,value:userSettingsModel.value[key]})),startingOptions=startOptionModel.value?{repair:{type:startOptionModel.value}}:{};Lua_default.extensions.gameplay_missions_missionScreen.startMissionById(selectedMissionId.value,settings$1,startingOptions)},abandonMission=()=>{Lua_default.extensions.gameplay_missions_missionScreen.stopMissionById(selectedMissionId.value,!1,!0)},restartMission=()=>{Lua_default.core_recoveryPrompt.buttonPressed(`restartMission`,{type:`none`})},reconfigureMission=()=>{let settings$1=Object.keys(userSettingsModel.value).map(key=>({key,value:userSettingsModel.value[key]}));Lua_default.extensions.gameplay_missions_missionScreen.startFromWithinMission(selectedMissionId.value,settings$1)},missionCards=ref([]),showMissionCards=ref(!1),isTutorialEnabled=ref(!1),customRecoveryOptionsActiveState=ref({}),hideReconfigureButton=ref(!1),hideRecoveryOptions=ref(!1),init$3=async()=>{let data=await Lua_default.extensions.gameplay_missions_missionScreen.getMissionScreenData();context.value=data.context;let preselectedMissionId=null;Array.isArray(data)?missions.value=data:data.hasOwnProperty(`missions`)?(missions.value=data.missions,preselectedMissionId=data.selectedMissionId,preselectedPage.value=data.selectedPage):data.hasOwnProperty(`mission`)&&(missions.value=[data.missions],preselectedMissionId=data.mission.id,preselectedPage.value=data.selectedPage),missions.value&&missions.value.forEach(mission=>{mission.userSettings&&mission.userSettings.length>0&&(mission.userSettings=mission.userSettings.map(setting=>(setting.type===`bool`&&(setting.type=`select`,setting.values=setting.value?[{l:setting.trueLabel||`Enabled`,v:!0},{l:setting.falseLabel||`Disabled`,v:!1}]:[{l:setting.falseLabel||`Disabled`,v:!1},{l:setting.trueLabel||`Enabled`,v:!0}],setting.currentOption={l:setting.value?setting.trueLabel||`Enabled`:setting.falseLabel||`Disabled`,v:setting.value}),setting)))}),isTutorialEnabled.value=data.isTutorialEnabled,missions.value&&(selectedMissionId.value=preselectedMissionId||missions.value[0].id),userSettingsModel.value={},customRecoveryOptionsActiveState.value=data.customRecoveryOptionsActiveState,missionCards.value=data.missionCards,showMissionCards.value=data.showMissionCards,hideReconfigureButton.value=data.hideReconfigureButton,hideRecoveryOptions.value=data.hideRecoveryOptions};function selectMissionByIndex(index){if(index<0||index>missions.value.length-1){console.warn(`Selected mission id not valid`,index);return}selectedMissionId.value=missions.value[index].id}function dispose$2(){stopSelectedMissionWatcher(),stopSettingsWatcher(),events$3.off(`missionStartingOptionsForUserSettingsReady`),missionCards.value=[]}return{missions,context,selectedMission,missionBasicInfo,missionProgressFromMission,missionProgress,missionSettings,sameUserSettingsAsLast,missionStartableDetails,currentProgressKey,currentProgressKeyTranslation,currentProgress,formattedProgress,availableVehicles,userSettingsModel,missionCards,showMissionCards,isTutorialEnabled,customRecoveryOptionsActiveState,hideReconfigureButton,hideRecoveryOptions,preselectedPage,selectMission,selectPreviousMission,selectNextMission,startMission,abandonMission,reconfigureMission,restartMission,changeSettings,changeRepairType,init:init$3,dispose:dispose$2}});var _hoisted_1$60={class:`info-content`},_sfc_main$68={__name:`InfoCard`,props:{header:{type:String,required:!1},headerType:{type:String,required:!1},noBlur:{type:Boolean,default:!1}},setup(__props){let slots=useSlots();return(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(bngCard_default),{class:normalizeClass([`card info-card`,{"no-background":__props.noBlur}])},createSlots({default:withCtx(()=>[unref(slots).header?renderSlot(_ctx.$slots,`header`,{key:0},void 0,!0):__props.header?(openBlock(),createBlock(unref(bngCardHeading_default),{key:1,type:__props.headerType},{default:withCtx(()=>[createTextVNode(toDisplayString(__props.header),1)]),_:1},8,[`type`])):createCommentVNode(``,!0),withDirectives((openBlock(),createElementBlock(`div`,_hoisted_1$60,[renderSlot(_ctx.$slots,`content`,{},void 0,!0)])),[[unref(BngUiNavScroll_default),void 0,void 0,{force:!0}]])]),_:2},[unref(slots).button?{name:`buttons`,fn:withCtx(()=>[renderSlot(_ctx.$slots,`button`,{},void 0,!0)]),key:`0`}:void 0]),1032,[`class`])),[[unref(BngBlur_default),!__props.noBlur]])}},InfoCard_default=__plugin_vue_export_helper_default(_sfc_main$68,[[`__scopeId`,`data-v-6771bedf`]]),_hoisted_1$59={key:0,class:`heading-highlight`},_hoisted_2$49={key:5,class:`stars-container`},_hoisted_3$42={key:0},WOOSH$1=`event:>UI>Career>EndScreen_Whoosh_Ratings`,_sfc_main$67={__name:`Grid`,props:{grid:Object},setup(__props){let{units}=useBridge(),props=__props,isMonospace=td=>td.format===`detailledTime`||td.format===`distance`||td.format===`rallyTimeFormatter`||td.format===`rallyPenaltyFormatter`||td.mono,now$1=Date.now()/1e3,wooshDelays=[];return onMounted(()=>{if(wooshDelays.length=0,props.grid.leaderaboardSoundDelay){let id=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,WOOSH$1)},props.grid.leaderaboardSoundDelay);wooshDelays.push(id)}}),onBeforeUnmount(()=>{for(let id of wooshDelays)clearTimeout(id)}),(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,{class:`grid`,style:normalizeStyle({"--columns":__props.grid.labels.length})},[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.grid.labels,(heading,colIndex)=>(openBlock(),createElementBlock(Fragment,null,[heading===``?createCommentVNode(``,!0):(openBlock(),createElementBlock(`div`,{key:0,class:normalizeClass([`col-heading`,{"first-column":colIndex===0}]),style:normalizeStyle({"--column":colIndex+1})},toDisplayString(_ctx.$t(heading)),7))],64))),256)),__props.grid.labels?(openBlock(),createElementBlock(`div`,_hoisted_1$59)):createCommentVNode(``,!0),(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.grid.rows,(row,rowIndex)=>(openBlock(),createElementBlock(Fragment,null,[(openBlock(!0),createElementBlock(Fragment,null,renderList(row,(td,colIndex)=>(openBlock(),createElementBlock(`div`,{class:normalizeClass([`property`,{monospace:isMonospace(td),"first-column":colIndex===0,"total-td":td.styling?.totalRow}]),style:normalizeStyle({"--row":rowIndex+2,"--column":colIndex+1})},[td.text===`true`?(openBlock(),createBlock(unref(bngIcon_default),{key:0,class:`checkmark`,type:unref(icons).checkmark},null,8,[`type`])):td.text===`false`?(openBlock(),createBlock(unref(bngIcon_default),{key:1,class:`checkmark`,type:unref(icons).abandon},null,8,[`type`])):!td.format||td.format==`detailledTime`||td.format==`rallyTimeFormatter`||td.format==`rallyPenaltyFormatter`?(openBlock(),createElementBlock(Fragment,{key:2},[createTextVNode(toDisplayString(td.text),1)],64)):td.format==`timespan`?(openBlock(),createElementBlock(Fragment,{key:3},[createTextVNode(toDisplayString(unref(formatTime)(unref(now$1)-td.timestamp,1,!0)),1)],64)):td.format==`distance`?(openBlock(),createElementBlock(Fragment,{key:4},[createTextVNode(toDisplayString(unref(units).buildString(`distance`,td.distance,1)),1)],64)):td.format==`simpleStars`?(openBlock(),createElementBlock(`div`,_hoisted_2$49,[td.defaults.length>0?(openBlock(),createBlock(unref(bngMainStars_default),{key:0,individualStars:td.defaults,class:`stars main-stars`,scale:.5},null,8,[`individualStars`])):createCommentVNode(``,!0),td.bonus.length>0?(openBlock(),createBlock(unref(bngMainStars_default),{key:1,individualStars:td.bonus,class:`stars bonus-stars`,scale:.5},null,8,[`individualStars`])):createCommentVNode(``,!0)])):td.format==`replay`?(openBlock(),createElementBlock(Fragment,{key:6},[td.text==`yes`?(openBlock(),createElementBlock(`div`,_hoisted_3$42,[createVNode(unref(bngIcon_default),{type:unref(icons).clapperboard},null,8,[`type`])])):createCommentVNode(``,!0)],64)):(openBlock(),createElementBlock(Fragment,{key:7},[createTextVNode(toDisplayString(td),1)],64))],6))),256)),__props.grid.leaderboardIndex?(openBlock(),createElementBlock(`div`,{key:0,class:normalizeClass([`row-highlight`,{"outline-swoop":__props.grid.leaderboardIndex==rowIndex+1,"row-even":rowIndex%2!=0}]),style:normalizeStyle({"--row":rowIndex+2})},null,6)):(openBlock(),createElementBlock(`div`,{key:1,class:normalizeClass([`row-highlight`,{"row-even":rowIndex%2!=0}]),style:normalizeStyle({"--row":rowIndex+2})},null,6))],64))),256))],4))}},Grid_default=__plugin_vue_export_helper_default(_sfc_main$67,[[`__scopeId`,`data-v-80ca57b4`]]),_hoisted_1$58={key:0,class:`ratings`},_hoisted_2$48={class:`prop-container`},_hoisted_3$41={key:1,class:`table-wrapper`},_hoisted_4$31={class:`replay-visibility`},_hoisted_5$26={key:0,class:`caption`},_hoisted_6$21={key:2},_sfc_main$66={__name:`MissionLeaderboards`,props:{},setup(__props){let{formattedProgress,currentProgress,currentProgressKey,currentProgressKeyTranslation}=storeToRefs(useMissionDetailsStore()),{units}=useBridge(),ratings=computed(()=>currentProgress.value);function valueOf(x){return x.format==`distance`?units.buildString(`distance`,x.distance,1):x.text}return(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{class:`mission-ratings`,header:`Leaderboards`,"header-type":`line`},{content:withCtx(()=>[createTextVNode(` Leaderboard: `+toDisplayString(_ctx.$ctx_t(unref(currentProgressKeyTranslation)))+` `,1),ratings.value?(openBlock(),createElementBlock(`div`,_hoisted_1$58,[createBaseVNode(`div`,_hoisted_2$48,[(openBlock(!0),createElementBlock(Fragment,null,renderList(ratings.value.ownAggregate,(attr,index)=>(openBlock(),createBlock(unref(bngPropVal_default),{class:normalizeClass([`prop`,{"outline-swoop":attr.newBest}]),key:index,"key-label":_ctx.$t(attr.label),"value-label":valueOf(attr.value),style:normalizeStyle({"--animation-delay":attr.animDelay?attr.animDelay:0})},null,8,[`key-label`,`value-label`,`class`,`style`]))),128))])])):createCommentVNode(``,!0),ratings.value&&ratings.value.attempts?(openBlock(),createElementBlock(`div`,_hoisted_3$41,[createBaseVNode(`div`,_hoisted_4$31,[createVNode(unref(bngIcon_default),{class:`replay-icon`,type:unref(icons).clapperboard},null,8,[`type`]),createBaseVNode(`div`,null,toDisplayString(unref($translate).instant(`missions.general.replay.replayVisibility`)),1)]),createVNode(Grid_default,{grid:ratings.value.attempts},null,8,[`grid`]),!Array.isArray(ratings.value.attempts.rows)||ratings.value.attempts.rows.length==0?(openBlock(),createElementBlock(`div`,_hoisted_5$26,` No Attempts yet! `)):createCommentVNode(``,!0)])):(openBlock(),createElementBlock(`div`,_hoisted_6$21,[..._cache[0]||=[createBaseVNode(`div`,{class:`caption`},` No Attempts yet! `,-1)]]))]),_:1}))}},MissionLeaderboards_default=__plugin_vue_export_helper_default(_sfc_main$66,[[`__scopeId`,`data-v-df98c8b2`]]),_hoisted_1$57={class:`icons-wrapper`},_hoisted_2$47={class:`task-description`},_hoisted_3$40={key:0,class:`task-description-message`},_hoisted_4$30={key:1,class:`task-description-message`},DEFAULT_STAR_LOCKED_COLOR=`rgba(var(--bng-ter-yellow-50-rgb), 0.5)`,DEFAULT_STAR_UNLOCKED_COLOR=`var(--bng-ter-yellow-50)`,BONUS_STAR_LOCKED_COLOR=`rgba(var(--bng-add-blue-400-rgb), 0.5)`,BONUS_STAR_UNLOCKED_COLOR=`var(--bng-add-blue-400)`,DEFAULT_STAR_WOOSH=`event:>UI>Career>EndScreen_Whoosh_Main`,DEFAULT_STAR_THUMP=`event:>UI>Career>EndScreen_Star_Main`,BONUS_STAR_WOOSH=`event:>UI>Career>EndScreen_Whoosh_Bonus`,BONUS_STAR_THUMP=`event:>UI>Career>EndScreen_Star_Bonus`,_sfc_main$65={__name:`Objective`,props:{star:{type:Object,required:!0},noRewards:{type:Boolean,default:!1},simple:Boolean},setup(__props,{expose:__expose}){let props=__props,starColor=computed(()=>props.star.isDefaultStar?props.star.unlocked?DEFAULT_STAR_UNLOCKED_COLOR:DEFAULT_STAR_LOCKED_COLOR:props.star.unlocked?BONUS_STAR_UNLOCKED_COLOR:BONUS_STAR_LOCKED_COLOR),starColorLocked=computed(()=>props.star.isDefaultStar?DEFAULT_STAR_LOCKED_COLOR:BONUS_STAR_LOCKED_COLOR),hasRewards=computed(()=>props.star.rewards&&props.star.rewards.length&&props.star.rewards.length>0),starIconType=computed(()=>props.star.unlocked?icons.star:icons.starSecondary),wooshDelay,thumpDelay;return onMounted(()=>{props.star.animationFinished||(props.star.soundDelay&&props.star.soundDelay>0&&(wooshDelay=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,props.star.isDefaultStar?DEFAULT_STAR_WOOSH:BONUS_STAR_WOOSH)},props.star.soundDelay)),props.star.soundDelayThump&&props.star.soundDelayThump>0&&(thumpDelay=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,props.star.isDefaultStar?DEFAULT_STAR_THUMP:BONUS_STAR_THUMP)},props.star.soundDelayThump)))}),onBeforeUnmount(()=>{clearTimeout(wooshDelay),clearTimeout(thumpDelay)}),__expose({cancelSoundDelays(){console.log(`Objective: Cancelling sound delays`,{hadWooshDelay:!!wooshDelay,hadThumpDelay:!!thumpDelay}),clearTimeout(wooshDelay),clearTimeout(thumpDelay),wooshDelay=null,thumpDelay=null}}),(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,{class:normalizeClass([{inactive:!__props.star.enabled,unlocked:__props.star.unlocked&&!__props.star.unlockAttempt,"unlock-attempt":__props.star.unlockAttempt&&!__props.star.animationFinished,"animation-complete":__props.star.animationFinished&&__props.star.unlockAttempt},`task-item`])},[__props.star.unlockAttempt&&!__props.star.animationFinished?(openBlock(),createElementBlock(`div`,{key:0,class:`fill unlock-change-background`,style:normalizeStyle({"--animation-delay":__props.star.animDelay})},null,4)):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_1$57,[__props.star.unlockChange&&!__props.star.animationFinished?(openBlock(),createBlock(unref(bngIcon_default),{key:0,class:`task-icon fill`,type:unref(icons).starSecondary,color:starColorLocked.value},null,8,[`type`,`color`])):createCommentVNode(``,!0),createVNode(unref(bngIcon_default),{class:normalizeClass([`task-icon`,{thump:__props.star.unlockChange&&!__props.star.animationFinished,"unlock-change-star":__props.star.unlockChange&&!__props.star.animationFinished,"animation-complete":__props.star.animationFinished&&__props.star.unlockChange}]),type:starIconType.value,color:starColor.value,style:normalizeStyle({"--animation-delay":__props.star.animDelayThump,"--star-color":starColor.value})},null,8,[`type`,`color`,`style`,`class`])]),createBaseVNode(`div`,null,[createBaseVNode(`span`,_hoisted_2$47,toDisplayString(_ctx.$ctx_t(__props.star.label)),1),__props.star.message?(openBlock(),createElementBlock(`div`,_hoisted_3$40,[createVNode(unref(bngIcon_default),{class:`task-description-message-icon`,type:unref(icons).info},null,8,[`type`]),createBaseVNode(`div`,null,toDisplayString(__props.star.message),1)])):createCommentVNode(``,!0),hasRewards.value&&!__props.noRewards&&!__props.simple?(openBlock(),createElementBlock(`div`,_hoisted_4$30,[createVNode(RewardsPills_default,{class:`tiny-rewards`,rewards:__props.star.rewards},null,8,[`rewards`])])):createCommentVNode(``,!0)])],2))}},Objective_default=__plugin_vue_export_helper_default(_sfc_main$65,[[`__scopeId`,`data-v-48925fbe`]]),_hoisted_1$56={key:1,class:`tasks`},_hoisted_2$46={key:3,class:`tasks`},_hoisted_3$39={key:4,class:`progress-message`},_sfc_main$64={__name:`MissionObjectives`,props:{stars:Array,message:String,showMessage:Boolean,noBlur:Boolean,noRewards:Boolean,noDisabledObjectives:Boolean,cardHeadingType:{String,default:`ribbon`}},setup(__props,{expose:__expose}){let props=__props,objectiveRefs=ref([]),visibleMainStars=computed(()=>{if(!props.stars||!Array.isArray(props.stars))return[];let stars=props.stars.filter(star=>star.isDefaultStar);return props.noDisabledObjectives?stars:stars.filter(star=>star.enabled)}),visibleBonusStars=computed(()=>{if(!props.stars||!Array.isArray(props.stars))return[];let stars=props.stars.filter(star=>!star.isDefaultStar);return props.noDisabledObjectives?stars:stars.filter(star=>star.enabled)});return __expose({cancelSoundDelays(){console.log(`MissionObjectives: Cancelling all sound delays`),objectiveRefs.value&&objectiveRefs.value.length&&objectiveRefs.value.forEach(ref$1=>{ref$1&&ref$1.cancelSoundDelays&&ref$1.cancelSoundDelays()})}}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{class:`mission-progress`,"no-blur":__props.noBlur},{content:withCtx(()=>[visibleMainStars.value.length?(openBlock(),createBlock(unref(bngCardHeading_default),{key:0,type:__props.cardHeadingType,class:`header bonus-header`},{default:withCtx(()=>[..._cache[0]||=[createTextVNode(` Main Objectives `,-1)]]),_:1},8,[`type`])):createCommentVNode(``,!0),visibleMainStars.value.length?(openBlock(),createElementBlock(`div`,_hoisted_1$56,[(openBlock(!0),createElementBlock(Fragment,null,renderList(visibleMainStars.value,star=>(openBlock(),createBlock(Objective_default,{key:star.key,star,"no-rewards":__props.noRewards,ref_for:!0,ref_key:`objectiveRefs`,ref:objectiveRefs},null,8,[`star`,`no-rewards`]))),128))])):createCommentVNode(``,!0),visibleBonusStars.value.length?(openBlock(),createBlock(unref(bngCardHeading_default),{key:2,type:__props.cardHeadingType,class:`bonus-header`},{default:withCtx(()=>[..._cache[1]||=[createTextVNode(` Bonus Objectives `,-1)]]),_:1},8,[`type`])):createCommentVNode(``,!0),visibleBonusStars.value.length?(openBlock(),createElementBlock(`div`,_hoisted_2$46,[(openBlock(!0),createElementBlock(Fragment,null,renderList(visibleBonusStars.value,star=>(openBlock(),createBlock(Objective_default,{key:star.key,star,"no-rewards":__props.noRewards,ref_for:!0,ref_key:`objectiveRefs`,ref:objectiveRefs},null,8,[`star`,`no-rewards`]))),128))])):createCommentVNode(``,!0),__props.message&&__props.showMessage?(openBlock(),createElementBlock(`div`,_hoisted_3$39,` Main Objectives are only available with default settings. `)):createCommentVNode(``,!0)]),_:1},8,[`no-blur`]))}},MissionObjectives_default=__plugin_vue_export_helper_default(_sfc_main$64,[[`__scopeId`,`data-v-4195cf41`]]),_hoisted_1$55={class:`settings-container`},_hoisted_2$45={class:`settings-wrapper`},_hoisted_3$38={key:0,class:`centered`},_hoisted_4$29={class:`setting-row`},_hoisted_5$25={class:`setting-item`},_hoisted_6$20={class:`setting-row`},_hoisted_7$19={class:`input-wrapper`},_sfc_main$63={__name:`MissionSettings`,setup(__props){let store$1=useMissionDetailsStore(),{missionSettings,availableVehicles,selectedMission}=storeToRefs(store$1),hasAnySettings=computed(()=>missionSettings.value&&missionSettings.value.length>0||availableVehicles.value&&availableVehicles.value.length>0);computed(()=>!1);let changeSelectValue=function(value,label,option,setting){store$1.changeSettings(setting.key,value),setting.currentOption=option},changeNumSettingValue=(setting,dir)=>{console.log(`changeNumSettingValue`,dir);let clampedValue=clamp(setting.value+dir,setting.min,setting.max);store$1.changeSettings(setting.key,clampedValue)};return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$55,[createBaseVNode(`div`,_hoisted_2$45,[hasAnySettings.value?createCommentVNode(``,!0):(openBlock(),createElementBlock(`div`,_hoisted_3$38,`Nothing to change here!`)),(openBlock(!0),createElementBlock(Fragment,null,renderList(unref(missionSettings),(setting,index)=>(openBlock(),createBlock(unref(slotSwitcher_default),{slotId:setting.type,key:setting.key+unref(selectedMission).id},{select:withCtx(()=>[createBaseVNode(`div`,{class:normalizeClass([`setting-item`,{"vehicle-setting":setting.currentOption?.thumb}])},[setting.currentOption?.thumb?(openBlock(),createBlock(unref(aspectRatio_default),{key:0,class:`image`,style:normalizeStyle({backgroundImage:`url(`+encodeURI(setting.currentOption.thumb)+`)`})},null,8,[`style`])):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_4$29,[createBaseVNode(`div`,{class:normalizeClass([`setting-item-label`,{"disabled-text":setting.disabled}])},[createTextVNode(toDisplayString(_ctx.$t(setting.label))+` `,1),setting.disabled?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).lockClosed,color:`var(--bng-cool-gray-400)`,class:`locked-icon`},null,8,[`type`])):createCommentVNode(``,!0)],2),createVNode(unref(bngSelect_default),{"bng-scoped-nav-autofocus":index===0,class:`setting-control`,options:setting.values,value:setting.value,config:{label:x=>_ctx.$t(x.l),value:x=>x.v},onValueChanged:(a$1,b,c)=>changeSelectValue(a$1,b,c,setting),loop:!0,disabled:setting.disabled},null,8,[`bng-scoped-nav-autofocus`,`options`,`value`,`config`,`onValueChanged`,`disabled`])])],2)]),int:withCtx(()=>[createBaseVNode(`div`,_hoisted_5$25,[createBaseVNode(`div`,_hoisted_6$20,[createBaseVNode(`div`,{class:normalizeClass([`setting-item-label`,{"disabled-text":setting.disabled}])},[createTextVNode(toDisplayString(_ctx.$t(setting.label))+` `,1),setting.disabled?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).lockClosed,color:`var(--bng-cool-gray-400)`,class:`locked-icon`},null,8,[`type`])):createCommentVNode(``,!0)],2),withDirectives((openBlock(),createElementBlock(`div`,_hoisted_7$19,[createVNode(unref(bngInput_default),{class:`input`,modelValue:setting.value,value:setting.value,min:setting.min,max:setting.max,disabled:setting.disabled,type:`number`,onValueChanged:value=>unref(store$1).changeSettings(setting.key,value)},null,8,[`modelValue`,`value`,`min`,`max`,`disabled`,`onValueChanged`])])),[[unref(BngScopedNav_default)],[unref(BngOnUiNavFocus_default),dir=>changeNumSettingValue(setting,dir),`vertical`,{repeat:!0}]])])])]),_:2},1032,[`slotId`]))),128))])]))}},MissionSettings_default=__plugin_vue_export_helper_default(_sfc_main$63,[[`__scopeId`,`data-v-0b5d169b`]]),_hoisted_1$54=[`onClick`],_hoisted_2$44={class:`setting-label-header`},_hoisted_3$37={class:`setting-label-value`},_hoisted_4$28={class:`setting-background`},_hoisted_5$24=[`onClick`],_hoisted_6$19=[`onClick`],_hoisted_7$18={class:`setting-label-header`},_hoisted_8$14={class:`setting-label-value`},_hoisted_9$12=[`onClick`],_hoisted_10$9={class:`setting-label-header`},_hoisted_11$7={class:`setting-label-value`},_sfc_main$62={__name:`MissionSettingsSimple`,props:{missionSettings:{type:Array,required:!0},noInput:{type:Boolean,default:!1}},setup(__props){let store$1=useMissionDetailsStore(),findOptionValue=(valueToFind,opts)=>Math.max(0,opts.findIndex(opt=>opt.v===valueToFind)),toggleSetting=setting=>{if(console.log(`toggleSetting`,setting),setting.type===`bool`)setting.value=!setting.value,store$1.changeSettings(setting.key,setting.value);else if(setting.type===`int`)setting.value+=1,setting.value>(setting.max||10)&&(setting.value=setting.min||0),store$1.changeSettings(setting.key,setting.value);else if(setting.type===`select`){console.log(`select`,setting);let index=findOptionValue(setting.currentOption.v,setting.values);console.log(`index`,index),index+=1,index>setting.values.length-1&&(index=0),store$1.changeSettings(setting.key,setting.values[index].v),setting.currentOption=setting.values[index]}},incrementSetting=setting=>{console.log(`incrementSetting`,setting),setting.type===`int`&&(console.log(`incrementSetting`,setting.value),setting.value+=setting.step||1,console.log(`incrementSetting`,setting.value),setting.value>(setting.max||10)&&(setting.value=setting.min||0),store$1.changeSettings(setting.key,setting.value))},decrementSetting=setting=>{setting.type===`int`&&(setting.value-=setting.step||1,setting.value<(setting.min||0)&&(setting.value=setting.max||10),store$1.changeSettings(setting.key,setting.value))};return(_ctx,_cache)=>(openBlock(),createBlock(unref(bngCard_default),{class:`mission-settings`,"bng-nav-item":``},{default:withCtx(()=>[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.missionSettings,setting=>(openBlock(),createBlock(unref(slotSwitcher_default),{slotId:setting.type,key:setting.key},{bool:withCtx(()=>[createBaseVNode(`div`,{class:normalizeClass([`mission-setting-pill`,{clickable:!setting.disabled&&!__props.noInput}]),onClick:$event=>!setting.disabled&&!__props.noInput&&toggleSetting(setting)},[createBaseVNode(`div`,{class:normalizeClass([`setting-label`,{"disabled-text":setting.disabled}])},[createBaseVNode(`div`,_hoisted_2$44,[createTextVNode(toDisplayString(_ctx.$ctx_t(setting.label))+` `,1),setting.disabled?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).lockClosed,color:`var(--bng-cool-gray-400)`,class:`locked-icon`},null,8,[`type`])):createCommentVNode(``,!0)]),createBaseVNode(`div`,_hoisted_3$37,[createVNode(unref(bngIcon_default),{type:setting.value?`checkboxOn`:`missionCheckboxCross`},null,8,[`type`])])],2)],10,_hoisted_1$54)]),int:withCtx(()=>[createBaseVNode(`div`,{class:normalizeClass([`mission-setting-pill`,{clickable:!setting.disabled&&!__props.noInput}])},[createBaseVNode(`div`,_hoisted_4$28,[createBaseVNode(`div`,{class:`setting-increment clickable noHover`,onClick:$event=>!setting.disabled&&!__props.noInput&&incrementSetting(setting)},null,8,_hoisted_5$24),createBaseVNode(`div`,{class:`setting-decrement clickable noHover`,onClick:$event=>!setting.disabled&&!__props.noInput&&decrementSetting(setting)},null,8,_hoisted_6$19)]),createBaseVNode(`div`,{class:normalizeClass([`setting-label`,{"disabled-text":setting.disabled}])},[createBaseVNode(`div`,_hoisted_7$18,[createTextVNode(toDisplayString(_ctx.$ctx_t(setting.label))+` `,1),setting.disabled?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).lockClosed,color:`var(--bng-cool-gray-400)`,class:`locked-icon`},null,8,[`type`])):createCommentVNode(``,!0)]),createBaseVNode(`div`,_hoisted_8$14,toDisplayString(setting.value),1)],2)],2)]),select:withCtx(()=>[createBaseVNode(`div`,{class:normalizeClass([`mission-setting-pill`,{clickable:!setting.disabled&&!__props.noInput}]),onClick:$event=>!setting.disabled&&!__props.noInput&&toggleSetting(setting)},[setting.currentOption&&setting.currentOption.thumb?(openBlock(),createBlock(unref(aspectRatio_default),{key:0,class:`image`,style:normalizeStyle({backgroundImage:`url(`+encodeURI(setting.currentOption.thumb)+`)`})},null,8,[`style`])):createCommentVNode(``,!0),createBaseVNode(`div`,{class:normalizeClass([`setting-label`,{"disabled-text":setting.disabled}])},[createBaseVNode(`div`,_hoisted_10$9,[createTextVNode(toDisplayString(_ctx.$ctx_t(setting.label))+` `,1),setting.disabled?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).lockClosed,color:`var(--bng-cool-gray-400)`,class:`locked-icon`},null,8,[`type`])):createCommentVNode(``,!0)]),createBaseVNode(`div`,_hoisted_11$7,toDisplayString(_ctx.$ctx_t(setting.currentOption?.l)),1)],2)],10,_hoisted_9$12)]),_:2},1032,[`slotId`]))),128))]),_:1}))}},MissionSettingsSimple_default=__plugin_vue_export_helper_default(_sfc_main$62,[[`__scopeId`,`data-v-43d094ba`]]),_hoisted_1$53={key:0,class:`background-icon`},_hoisted_2$43={class:`reward-top`},_hoisted_3$36={class:`breakdown`},_hoisted_4$27={class:`breakdown-grid`},_hoisted_5$23={class:`progress-bar-wrapper`},_sfc_main$61=Object.assign({inheritAttrs:!1},{__name:`MissionRewards`,props:{change:{type:Object,required:!1},simple:{type:Boolean,default:!1},noBlur:{type:Boolean,default:!1},animationDelay:{type:String,default:`0s`}},setup(__props,{expose:__expose}){let{units}=useBridge(),props=__props,showBarAnimations=ref(new Map),animatedProgressBars=ref(new Map),animatedRewards=ref(new Map);ref(new Map),ref(new Map);let animatedBreakdownItems=ref(new Map),animatedBreakdownValues=ref(new Map),showProgressBars=ref(new Map),activeTimeouts=ref([]),activeAnimationFrames=ref([]);function startAnimations(){if(!props.change||!props.change.formattedRewards||!props.change.formattedRewards.list)return;let skipAnimations=props.change.skipAnimations===!0,rewardsData=props.change?.formattedRewards?.list||{};(Array.isArray(rewardsData)?rewardsData:Object.values(rewardsData)).forEach((info,index)=>{if(skipAnimations){if(animatedRewards.value.set(index,!0),info.breakdown&&info.breakdown.forEach((bd,bdIndex)=>{animatedBreakdownItems.value.set(`${index}-${bdIndex}`,!0),animatedBreakdownValues.value.set(`${index}-${bdIndex}`,{value:bd.after||0,shouldPulse:!1})}),info.progressBar){showProgressBars.value.set(index,!0),showBarAnimations.value.set(index,!1);let finalAnimation=info.progressBar.animations[info.progressBar.animations.length-1];animatedProgressBars.value.set(index,{level:finalAnimation.level,animValue:Math.floor(finalAnimation.to),min:finalAnimation.min,max:finalAnimation.max})}Lua_default.extensions.gameplay_missions_missionScreen.activateSound(`money`,!1,1);return}let rewardTimeout=setTimeout(()=>{animatedRewards.value.set(index,!0)},info.animDelay||1e3);if(activeTimeouts.value.push(rewardTimeout),info.breakdown&&info.breakdown.forEach((bd,bdIndex)=>{let breakdownTimeout=setTimeout(()=>{animatedBreakdownItems.value.set(`${index}-${bdIndex}`,!0)},bd.animDelayShow||1e3);if(activeTimeouts.value.push(breakdownTimeout),bd.animDelayStartLerp===-1)animatedBreakdownValues.value.set(`${index}-${bdIndex}`,{value:bd.after||0,shouldPulse:!1});else{let lerpTimeout=setTimeout(()=>{console.log(`index`,index,info),bd.soundClass&&Lua_default.extensions.gameplay_missions_missionScreen.activateSound(bd.soundClass,!0,bd.pitch);let startTime=performance.now(),startValue=bd.before||0,endValue=bd.after||0,duration=(bd.duration||1)*1e3;if(bd.tickingOneShots){console.log(`bd.tickingOneShots`,bd.tickingOneShots);let valueDiff=endValue-startValue,timePerIncrement=duration/valueDiff;for(let i=0;i{Lua_default.Engine.Audio.playOnce(`AudioGui`,bd.tickingOneShots)},soundTime-performance.now());activeTimeouts.value.push(soundTimeout)}}let animate=currentTime=>{let elapsed=currentTime-startTime,progress=Math.min(elapsed/duration,1),currentValue=Math.round(startValue+(endValue-startValue)*progress);if(animatedBreakdownValues.value.set(`${index}-${bdIndex}`,{value:currentValue,shouldPulse:progress===1}),progress<1){let animFrame=requestAnimationFrame(animate);activeAnimationFrames.value.push(animFrame)}else bd.soundClass&&Lua_default.extensions.gameplay_missions_missionScreen.activateSound(bd.soundClass,!1,1),bd.endSound&&Lua_default.Engine.Audio.playOnce(`AudioGui`,bd.endSound)},initialFrame=requestAnimationFrame(animate);activeAnimationFrames.value.push(initialFrame)},bd.animDelayStartLerp||1e3);activeTimeouts.value.push(lerpTimeout)}}),info.progressBar){let lastBreakdownLerpDelay=info.breakdown[info.breakdown.length-1]?.animDelayStartLerp||1e3,progressTimeout=setTimeout(()=>{showProgressBars.value.set(index,!0)},lastBreakdownLerpDelay);if(activeTimeouts.value.push(progressTimeout),lastBreakdownLerpDelay===-1){let finalAnimation=info.progressBar.animations[info.progressBar.animations.length-1];animatedProgressBars.value.set(index,{level:finalAnimation.level,animValue:Math.floor(finalAnimation.to),min:finalAnimation.min,max:finalAnimation.max})}else{let barTimeout=setTimeout(()=>{showBarAnimations.value.set(index,!0);let currentAnimationIndex=0,animate=()=>{let animation=info.progressBar.animations[currentAnimationIndex];if(!animation)return;if(animation.to===-1||animation.max===-1){animatedProgressBars.value.set(index,{level:animation.level,animValue:100,min:0,max:100,from:0});return}let startTime=performance.now(),startValue=animation.from,endValue=animation.to,duration=animation.duration*1e3,animateFrame=currentTime=>{let elapsed=currentTime-startTime,progress=Math.min(elapsed/duration,1),currentValue=startValue+(endValue-startValue)*progress;if(animatedProgressBars.value.set(index,{level:animation.level,animValue:Math.floor(currentValue),min:animation.min,max:animation.max,from:startValue}),progress<1){let frame$1=requestAnimationFrame(animateFrame);activeAnimationFrames.value.push(frame$1)}else currentAnimationIndexUI>Career>EndScreen_LevelUp`),currentAnimationIndex++,animate())},frame=requestAnimationFrame(animateFrame);activeAnimationFrames.value.push(frame)};animate()},lastBreakdownLerpDelay);activeTimeouts.value.push(barTimeout)}}})}function clearAllAnimations(){Lua_default.extensions.gameplay_missions_missionScreen.activateSound(`money`,!1,1),activeTimeouts.value.forEach(timeout=>clearTimeout(timeout)),activeTimeouts.value=[],activeAnimationFrames.value.forEach(frame=>cancelAnimationFrame(frame)),activeAnimationFrames.value=[]}return onMounted(()=>{startAnimations()}),__expose({cancelSoundDelays(){console.log(`MissionRewards: Cancelling sound delays`)}}),watch(()=>props.change?.skipAnimations,newValue=>{newValue===!0&&(clearAllAnimations(),animatedRewards.value=new Map,animatedBreakdownItems.value=new Map,animatedBreakdownValues.value=new Map,showProgressBars.value=new Map,animatedProgressBars.value=new Map,showBarAnimations.value=new Map,startAnimations())}),onUnmounted(()=>{clearAllAnimations(),Lua_default.extensions.gameplay_missions_missionScreen.activateSound(`money`,!1,1),Lua_default.extensions.gameplay_missions_missionScreen.activateSound(`progressBar`,!1,1)}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{header:`Rewards`,headerType:`ribbon`,class:`dynamic`,"no-blur":__props.noBlur,style:normalizeStyle({"animation-delay":__props.animationDelay})},{content:withCtx(()=>[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.change?.formattedRewards?.list||[],(info,index)=>(openBlock(),createElementBlock(`div`,{key:index,class:normalizeClass([`rewardInfo`,{"show-reward":animatedRewards.value.get(index),"has-color":info.attributeColor,"unlock-attempt":info.animDelay&&!__props.change.animationFinished,"animation-complete":__props.change.animationFinished}]),style:normalizeStyle([info.attributeColor?{"--attribute-color":info.attributeColor}:void 0])},[info.icon?(openBlock(),createElementBlock(`div`,_hoisted_1$53,[createVNode(unref(bngIcon_default),{type:info.icon},null,8,[`type`])])):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_2$43,[createBaseVNode(`div`,_hoisted_3$36,[createBaseVNode(`div`,_hoisted_4$27,[(openBlock(!0),createElementBlock(Fragment,null,renderList(info.breakdown,(bd,bdIndex)=>(openBlock(),createElementBlock(Fragment,{key:bdIndex},[createBaseVNode(`div`,{class:normalizeClass([`breakdown-label`,{"show-breakdown-item":animatedBreakdownItems.value.get(`${index}-${bdIndex}`),large:bd.large,"show-animation":bd.animDelayShow&&!__props.change.animationFinished&&!__props.change.skipAnimations,"lerp-animation":bd.animDelayStartLerp&&!__props.change.animationFinished&&!__props.change.skipAnimations}]),style:normalizeStyle({"--show-delay":bd.animDelayShow+`ms`,"--lerp-delay":bd.animDelayStartLerp+`ms`})},toDisplayString(_ctx.$ctx_t(bd.label)),7),createBaseVNode(`div`,{class:normalizeClass([`breakdown-pill`,{"show-breakdown-item":animatedBreakdownItems.value.get(`${index}-${bdIndex}`),large:bd.large}])},[createVNode(RewardPill_default,{icon:info.icon,attributeKey:info.attributeKey,rewardAmount:animatedBreakdownValues.value.get(`${index}-${bdIndex}`)?.value??bd.before,class:normalizeClass({"highlight-pulse":animatedBreakdownValues.value.get(`${index}-${bdIndex}`)?.shouldPulse&&bd.large})},null,8,[`icon`,`attributeKey`,`rewardAmount`,`class`])],2)],64))),128)),info.progressBar?(openBlock(),createElementBlock(Fragment,{key:0},[_cache[0]||=createBaseVNode(`div`,null,null,-1),createBaseVNode(`div`,{class:normalizeClass([`level-label`,{"show-breakdown-item":animatedBreakdownItems.value.get(`${index}-${info.breakdown.length-1}`)}])},` Level `+toDisplayString(Math.floor(animatedProgressBars.value.get(index)?.level??info.progressBar.animations[0].level)),3)],64)):createCommentVNode(``,!0)])])]),info.progressBar?(openBlock(),createElementBlock(Fragment,{key:1},[createBaseVNode(`div`,{class:normalizeClass([`progress-level-container`,{"show-breakdown-item":animatedBreakdownItems.value.get(`${index}-${info.breakdown.length-1}`)}])},[createBaseVNode(`div`,_hoisted_5$23,[createVNode(unref(bngProgressBar_default),{class:normalizeClass([`slim`,{"animate-progress":showBarAnimations.value.get(index)}]),value:animatedProgressBars.value.get(index)?.animValue??info.progressBar.animations[0].from,max:animatedProgressBars.value.get(index)?.max??info.progressBar.animations[0].max,min:animatedProgressBars.value.get(index)?.min??info.progressBar.animations[0].min,oldValue:animatedProgressBars.value.get(index)?.from??info.progressBar.animations[0].from,showValueLabel:!1},null,8,[`class`,`value`,`max`,`min`,`oldValue`])])],2),createTextVNode(` `+toDisplayString(info.progressBar.skill),1)],64)):createCommentVNode(``,!0)],6))),128))]),_:1},8,[`no-blur`,`style`]))}}),MissionRewards_default=__plugin_vue_export_helper_default(_sfc_main$61,[[`__scopeId`,`data-v-a34402da`]]),_hoisted_1$52={key:0,class:`ratings`},_hoisted_2$42={key:0,class:`prop-container`},_hoisted_3$35={class:`main-label`},_hoisted_4$26={class:`text-container`},_sfc_main$60={__name:`MissionTextPanel`,props:{panel:{type:Object,required:!0},noBlur:{type:Boolean,default:!1}},setup(__props,{expose:__expose}){let{units}=useBridge(),props=__props,wooshDelays=[],thumpDelays=[];onMounted(()=>{console.log(`Playing sound TextPanel: onMounted`,props.panel.animationFinished),props.panel.animationFinished||props.panel.attempt&&props.panel.attempt.list&&props.panel.attempt.list.filter(item=>item.mainResult).forEach(result=>{if(result.soundDelay&&result.soundDelay>0){let delay=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,`event:>UI>Career>EndScreen_Whoosh_Main`)},result.soundDelay);wooshDelays.push(delay)}if(result.soundDelayThump&&result.soundDelayThump>0){let delay=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,`event:>UI>Career>EndScreen_Star_Main`)},result.soundDelayThump);thumpDelays.push(delay)}})}),onBeforeUnmount(()=>{wooshDelays.forEach(delay=>clearTimeout(delay)),thumpDelays.forEach(delay=>clearTimeout(delay))});function valueOf(x){return x.format==`distance`?units.buildString(`distance`,x.distance,1):x.text}let content=computed(()=>{let txt=props.panel.text;return txt?typeof txt==`string`?parse$1($translate.instant(txt)):Array.isArray(txt)&&txt.length>0?parse$1(txt.map(x=>$translate.contextTranslate(x)).join(``)):parse$1($translate.contextTranslate(txt)):``}),mainResults=computed(()=>!props.panel.attempt||!props.panel.attempt.list?[]:props.panel.attempt.list.filter(item=>item.mainResult)),nonMainResults=computed(()=>!props.panel.attempt||!props.panel.attempt.list?[]:props.panel.attempt.list.filter(item=>!item.mainResult)),translatedHeader=computed(()=>props.panel.header?$translate.instant(props.panel.header):null);return __expose({cancelSoundDelays(){console.log(`MissionTextPanel: Cancelling sound delays`,{hadWooshDelays:wooshDelays.length,hadThumpDelays:thumpDelays.length}),wooshDelays.forEach(delay=>clearTimeout(delay)),thumpDelays.forEach(delay=>clearTimeout(delay)),wooshDelays.length=0,thumpDelays.length=0}}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{header:translatedHeader.value,headerType:`ribbon`,class:normalizeClass([`dynamic`,{experimental:__props.panel.experimental,"full-height":__props.panel.fullHeight}]),"no-blur":__props.noBlur},{content:withCtx(()=>[__props.panel.attempt?(openBlock(),createElementBlock(`div`,_hoisted_1$52,[__props.panel.attempt.list?(openBlock(),createElementBlock(`div`,_hoisted_2$42,[(openBlock(!0),createElementBlock(Fragment,null,renderList(mainResults.value,(result,index)=>(openBlock(),createElementBlock(`div`,{key:index,class:normalizeClass([`main-result`,{"unlock-attempt":result.animDelay&&!__props.panel.animationFinished,"animation-complete":__props.panel.animationFinished}])},[result.animDelay&&!__props.panel.animationFinished?(openBlock(),createElementBlock(`div`,{key:0,class:`fill unlock-change-background`,style:normalizeStyle({"--animation-delay":result.animDelay})},null,4)):createCommentVNode(``,!0),createBaseVNode(`span`,_hoisted_3$35,toDisplayString(_ctx.$t(result.label)),1),result.value.text!==`true`&&result.value.text!==`false`?(openBlock(),createElementBlock(`span`,{key:1,class:normalizeClass([`main-value`,{thump:result.animDelayThump&&!__props.panel.animationFinished,"animation-complete":__props.panel.animationFinished}]),style:normalizeStyle({"--animation-delay":result.animDelayThump})},toDisplayString(valueOf(result.value)),7)):createCommentVNode(``,!0),result.value.text===`true`?(openBlock(),createBlock(unref(bngIcon_default),{key:2,class:normalizeClass([`main-value`,{thump:result.animDelayThump&&!__props.panel.animationFinished,"animation-complete":__props.panel.animationFinished}]),style:normalizeStyle({"--animation-delay":result.animDelayThump}),type:unref(icons).checkmark},null,8,[`class`,`style`,`type`])):createCommentVNode(``,!0),result.value.text===`false`?(openBlock(),createBlock(unref(bngIcon_default),{key:3,class:normalizeClass([`main-value`,{thump:result.animDelayThump&&!__props.panel.animationFinished,"animation-complete":__props.panel.animationFinished}]),style:normalizeStyle({"--animation-delay":result.animDelayThump}),type:unref(icons).mathMultiply},null,8,[`class`,`style`,`type`])):createCommentVNode(``,!0)],2))),128)),(openBlock(!0),createElementBlock(Fragment,null,renderList(nonMainResults.value,(attr,index)=>(openBlock(),createBlock(unref(bngPropVal_default),{class:`prop`,key:index,"key-label":_ctx.$t(attr.label),"value-label":valueOf(attr.value)},null,8,[`key-label`,`value-label`]))),128))])):createCommentVNode(``,!0),__props.panel.attempt.grids?(openBlock(!0),createElementBlock(Fragment,{key:1},renderList(__props.panel.attempt.grids,grid=>(openBlock(),createBlock(Grid_default,{grid},null,8,[`grid`]))),256)):createCommentVNode(``,!0)])):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_4$26,[content.value&&content.value!==``?(openBlock(),createBlock(unref(dynamicComponent_default),{key:0,template:content.value},null,8,[`template`])):createCommentVNode(``,!0)])]),_:1},8,[`header`,`class`,`no-blur`]))}},MissionTextPanel_default=__plugin_vue_export_helper_default(_sfc_main$60,[[`__scopeId`,`data-v-35a314c2`]]),_hoisted_1$51={class:`list`},_hoisted_2$41={class:`setting-item-label`},_sfc_main$59={__name:`MissionDialPanel`,props:{panel:{type:Object,required:!0}},setup(__props){function updateDial(dial){Lua_default.extensions.hook(`onDialSetByDialPanel`,dial)}return(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{class:`dial-card`,header:__props.panel.header,"header-type":`ribbon`},{content:withCtx(()=>[createBaseVNode(`div`,null,toDisplayString(_ctx.$ctx_t(__props.panel.text)),1),createBaseVNode(`div`,_hoisted_1$51,[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.panel.dials,dial=>(openBlock(),createElementBlock(`div`,{key:dial.key,class:`setting-item`},[createBaseVNode(`div`,_hoisted_2$41,toDisplayString(_ctx.$t(dial.label)),1),createVNode(unref(bngInput_default),{class:`input`,modelValue:dial.value,"onUpdate:modelValue":$event=>dial.value=$event,min:0,max:60,suffix:`seconds`,decimals:2,type:`number`,disabled:dial.disabled,step:.01,onValueChanged:$event=>updateDial(dial)},null,8,[`modelValue`,`onUpdate:modelValue`,`disabled`,`onValueChanged`])]))),128))])]),_:1},8,[`header`]))}},MissionDialPanel_default=__plugin_vue_export_helper_default(_sfc_main$59,[[`__scopeId`,`data-v-fe82c7b7`]]),_hoisted_1$50={key:0,class:`replay-container`},_hoisted_2$40={class:`temporary-replay-note`},_hoisted_3$34={class:`replay-items-container`},_hoisted_4$25={class:`replay-info`},_hoisted_5$22={class:`title-container`},_hoisted_6$18={class:`replay-name`},_hoisted_7$17={class:`replay-file`},_hoisted_8$13={class:`replay-actions`},_hoisted_9$11={key:0},_hoisted_10$8={key:1,class:`no-replays`},_sfc_main$58={__name:`MissionReplayPanel`,props:{panel:{type:Object,required:!0}},emits:[`update:panel`],setup(__props,{emit:__emit}){let props=__props,emit$1=__emit,state=ref(`inactive`),loadedReplayFile=ref(``),events$3=useEvents();function onPlayReplay(file$1){Lua_default.core_replay.loadFile(file$1),Lua_default.core_replay.togglePlay()}function onStopReplay(){Lua_default.core_replay.stop()}function saveMissionReplay(file$1){Lua_default.core_replay.saveMissionReplay(file$1)}function removeMissionSavedReplay(file$1){Lua_default.core_replay.removeMissionSavedReplay(file$1)}function openReplayFolder(file$1){Lua_default.core_replay.openMissionReplayFolder(file$1)}onUnmounted(()=>{Lua_default.core_replay.stop(),events$3.off(`replayStateChanged`),events$3.off(`recordingFilesUpdated`)});function setFilesTitles(){props.panel.recordingFiles&&Array.isArray(props.panel.recordingFiles)&&props.panel.recordingFiles.length>0&&props.panel.recordingFiles.forEach(file$1=>{file$1.meta?.time?file$1.title=timeSpan(file$1.meta.time,null,1,!0):file$1.title=file$1.replayFileName})}return onMounted(()=>{setFilesTitles(),events$3.on(`replayStateChanged`,val=>{loadedReplayFile.value=val.loadedFile,state.value=val.state}),events$3.on(`recordingFilesUpdated`,val=>{emit$1(`update:panel`,{...props.panel,recordingFiles:val}),setTimeout(()=>{setFilesTitles()},5)})}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{class:`replay-panel`},{content:withCtx(()=>[__props.panel.recordingFiles&&Array.isArray(__props.panel.recordingFiles)&&__props.panel.recordingFiles.length>0?(openBlock(),createElementBlock(`div`,_hoisted_1$50,[createVNode(bngCardHeading_default,{type:`ribbon`,class:`replay-heading`},{default:withCtx(()=>[..._cache[0]||=[createTextVNode(` Replays `,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_2$40,toDisplayString(unref($translate).instant(`missions.general.replay.temporaryAreNotPermanent`)),1),createBaseVNode(`div`,_hoisted_3$34,[(openBlock(!0),createElementBlock(Fragment,null,renderList([...__props.panel.recordingFiles].reverse(),file$1=>(openBlock(),createElementBlock(`div`,{key:file$1.replayFile,class:normalizeClass([`replay-item`,{"active-replay":file$1.replayFile===loadedReplayFile.value}])},[createBaseVNode(`div`,_hoisted_4$25,[createBaseVNode(`div`,_hoisted_5$22,[createBaseVNode(`div`,_hoisted_6$18,toDisplayString(file$1.title),1),createVNode(unref(bngIcon_default),{type:unref(icons).star,class:normalizeClass([`star-icon`,{saved:file$1.userSaved}])},null,8,[`type`,`class`])]),createBaseVNode(`div`,_hoisted_7$17,toDisplayString(file$1.replayFile),1)]),createBaseVNode(`div`,_hoisted_8$13,[createVNode(unref(bngButton_default),{class:`replay-button`,accent:`custom`,onClick:$event=>file$1.replayFile===loadedReplayFile.value?onStopReplay():onPlayReplay(file$1.replayFile),icon:file$1.replayFile===loadedReplayFile.value?`square`:`play`,disabled:!file$1.replayFile},null,8,[`onClick`,`icon`,`disabled`,`accent`]),createVNode(unref(bngButton_default),{class:`replay-button`,accent:`custom`,onClick:$event=>file$1.userSaved?removeMissionSavedReplay(file$1.replayFile):saveMissionReplay(file$1.replayFile),icon:file$1.userSaved?unref(icons).trashBin1:unref(icons).floppyDisk},null,8,[`onClick`,`icon`,`accent`]),createVNode(unref(bngButton_default),{class:`replay-button`,accent:`custom`,onClick:$event=>openReplayFolder(file$1.replayFile),icon:unref(icons).folder,disabled:!file$1.replayFile},null,8,[`onClick`,`icon`,`disabled`,`accent`])])],2))),128))]),loadedReplayFile.value?(openBlock(),createElementBlock(`div`,_hoisted_9$11,[createVNode(app_default$1,{hideFileControls:!0})])):createCommentVNode(``,!0)])):(openBlock(),createElementBlock(`div`,_hoisted_10$8,toDisplayString(unref($translate).instant(`missions.general.replay.noReplays`)),1))]),_:1}))}},MissionReplayPanel_default=__plugin_vue_export_helper_default(_sfc_main$58,[[`__scopeId`,`data-v-c567d0df`]]),_hoisted_1$49={class:`score-section-container`},_hoisted_2$39={key:0,class:`score-section`},_hoisted_3$33={class:`score-section-title`},_hoisted_4$24={class:`score-earned`},_hoisted_5$21={key:1,class:`score-section`},_hoisted_6$17={class:`score-section-title`},_hoisted_7$16={class:`score-earned`},_hoisted_8$12={key:2,class:`score-section`},_hoisted_9$10={class:`score-section-title`},_hoisted_10$7={class:`score-earned`},_sfc_main$57={__name:`MissionCrashTestStepDetails`,props:{panel:{type:Object,required:!0},noBlur:{type:Boolean,default:!1}},setup(__props){let{units}=useBridge();return onMounted(()=>{}),onBeforeUnmount(()=>{}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{header:_ctx.translatedHeader,headerType:`ribbon`,class:normalizeClass([`dynamic`,{experimental:__props.panel.experimental,"full-height":__props.panel.fullHeight}]),"no-blur":__props.noBlur},{content:withCtx(()=>[createVNode(bngCardHeading_default,{type:`ribbon`,class:`replay-heading`},{default:withCtx(()=>[..._cache[0]||=[createTextVNode(` Stage Score `,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_1$49,[__props.panel.stepScoreData.speedScore?(openBlock(),createElementBlock(`div`,_hoisted_2$39,[createBaseVNode(`span`,_hoisted_3$33,toDisplayString(__props.panel.stepScoreData.speedScore.scoreName),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.speedScore.actualSpeed.text)+` : `+toDisplayString(__props.panel.stepScoreData.speedScore.actualSpeed.value)+` `+toDisplayString(__props.panel.stepScoreData.speedScore.actualSpeed.unit),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.speedScore.targetSpeed.text)+` : `+toDisplayString(__props.panel.stepScoreData.speedScore.targetSpeed.value)+` `+toDisplayString(__props.panel.stepScoreData.speedScore.targetSpeed.unit),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.speedScore.diff.text)+` : `+toDisplayString(__props.panel.stepScoreData.speedScore.diff.value)+` `+toDisplayString(__props.panel.stepScoreData.speedScore.diff.unit),1),createBaseVNode(`span`,_hoisted_4$24,`Score : `+toDisplayString(__props.panel.stepScoreData.speedScore.score)+` / `+toDisplayString(__props.panel.stepScoreData.speedScore.maxScore),1)])):createCommentVNode(``,!0),__props.panel.stepScoreData.timeScore?(openBlock(),createElementBlock(`div`,_hoisted_5$21,[createBaseVNode(`span`,_hoisted_6$17,toDisplayString(__props.panel.stepScoreData.timeScore.scoreName),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.timeScore.timeToImpact.text)+` : `+toDisplayString(__props.panel.stepScoreData.timeScore.timeToImpact.value)+` `+toDisplayString(__props.panel.stepScoreData.timeScore.timeToImpact.unit),1),createBaseVNode(`span`,_hoisted_7$16,`Score : `+toDisplayString(__props.panel.stepScoreData.timeScore.score)+` / `+toDisplayString(__props.panel.stepScoreData.timeScore.maxScore),1)])):createCommentVNode(``,!0),__props.panel.stepScoreData.damageLocationScore?(openBlock(),createElementBlock(`div`,_hoisted_8$12,[createBaseVNode(`span`,_hoisted_9$10,toDisplayString(__props.panel.stepScoreData.damageLocationScore.scoreName),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.damageLocationScore.requiredImpactLocation.text)+` : `+toDisplayString(__props.panel.stepScoreData.damageLocationScore.requiredImpactLocation.value),1),createBaseVNode(`span`,null,toDisplayString(__props.panel.stepScoreData.damageLocationScore.actualImpactLocation.text)+` : `+toDisplayString(__props.panel.stepScoreData.damageLocationScore.actualImpactLocation.value)+` `+toDisplayString(__props.panel.stepScoreData.damageLocationScore.actualImpactLocation.precision),1),createBaseVNode(`span`,_hoisted_10$7,`Score : `+toDisplayString(__props.panel.stepScoreData.damageLocationScore.score)+` / `+toDisplayString(__props.panel.stepScoreData.damageLocationScore.maxScore),1)])):createCommentVNode(``,!0)]),_cache[1]||=createBaseVNode(`span`,{class:`new-score-title`},`New score : `,-1),createVNode(app_default),_ctx.content&&_ctx.content!==``?(openBlock(),createBlock(unref(dynamicComponent_default),{key:0,template:_ctx.content},null,8,[`template`])):createCommentVNode(``,!0)]),_:1},8,[`header`,`class`,`no-blur`]))}},MissionCrashTestStepDetails_default=__plugin_vue_export_helper_default(_sfc_main$57,[[`__scopeId`,`data-v-0ff5c78e`]]),_hoisted_1$48={class:`slip-container`},_sfc_main$56={__name:`MissionTimeSlipPanel`,props:{panel:{type:Object,required:!0}},setup(__props){let{$game}=useLibStore(),{units}=useBridge(),props=__props,screenshot=function(){Lua_default.gameplay_drag_dragBridge.screenshotTimeslip()};return onMounted(()=>{console.log(props.panel)}),(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{header:__props.panel.header,"header-type":`ribbon`,"no-blur":!0},{content:withCtx(()=>[createBaseVNode(`div`,_hoisted_1$48,[createVNode(Timeslip_default,{slip:__props.panel.timeslip},null,8,[`slip`]),createVNode(unref(bngIcon_default),{class:`save`,type:unref(icons).floppyDisk,onClick:screenshot},null,8,[`type`])])]),_:1},8,[`header`]))}},MissionTimeSlipPanel_default=__plugin_vue_export_helper_default(_sfc_main$56,[[`__scopeId`,`data-v-f273ddb7`]]),_hoisted_1$47={class:`ratings`},_hoisted_2$38={class:`prop-container`},_hoisted_3$32={class:`table-wrapper`},_hoisted_4$23={key:0,class:`caption`},WOOSH=`event:>UI>Career>EndScreen_Whoosh_Ratings`,HIGHLIGHT=`event:>UI>Career>EndScreen_Highlight_Ratings`,_sfc_main$55={__name:`MissionRatings`,props:{ratings:{type:Object,required:!1},simple:{type:Boolean,required:!1}},setup(__props){let{units}=useBridge(),props=__props;function valueOf(x){return x.format==`distance`?units.buildString(`distance`,x.distance,1):x.text}let wooshDelays=[];return onMounted(()=>{if(!props.ratings.animationFinished){wooshDelays.length=0;for(let attr of props.ratings.ownAggregate)if(attr.soundDelay){let wooshId=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,WOOSH)},attr.soundDelay);wooshDelays.push(wooshId);let highlightId=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,HIGHLIGHT)},attr.soundDelay+1e3);wooshDelays.push(highlightId)}}}),onBeforeUnmount(()=>{for(let id of wooshDelays)clearTimeout(id)}),Date.now()/1e3,(_ctx,_cache)=>(openBlock(),createBlock(InfoCard_default,{class:`mission-ratings`,header:`Ratings`,"header-type":`ribbon`,"no-blur":__props.simple},{content:withCtx(()=>[createBaseVNode(`div`,_hoisted_1$47,[createBaseVNode(`div`,_hoisted_2$38,[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.ratings.ownAggregate,(attr,index)=>(openBlock(),createBlock(unref(bngPropVal_default),{class:normalizeClass([`prop task-item`,{"animation-complete":attr.newBest}]),key:index,"key-label":_ctx.$t(attr.label),"value-label":valueOf(attr.value),style:normalizeStyle({"--animation-delay":attr.animDelay?attr.animDelay:0})},null,8,[`key-label`,`value-label`,`class`,`style`]))),128))])]),createBaseVNode(`div`,_hoisted_3$32,[createVNode(Grid_default,{grid:__props.ratings.attempts},null,8,[`grid`]),!Array.isArray(__props.ratings.attempts.rows)||__props.ratings.attempts.rows.length==0?(openBlock(),createElementBlock(`div`,_hoisted_4$23,` No Attempts yet! `)):createCommentVNode(``,!0)])]),_:1},8,[`no-blur`]))}},MissionRatings_default=__plugin_vue_export_helper_default(_sfc_main$55,[[`__scopeId`,`data-v-f8219235`]]),_hoisted_1$46={class:`mission-unlocks`},_hoisted_2$37={class:`league-container`},_hoisted_3$31={class:`cards-container`},_sfc_main$54={__name:`MissionUnlocks`,props:{change:{type:Object,required:!1}},setup(__props,{expose:__expose}){return __expose({cancelSoundDelays(){console.log(`MissionUnlocks: Cancelling sound delays`)}}),(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$46,[__props.change&&__props.change.unlockedLeagues&&__props.change.unlockedLeagues.length>0?(openBlock(),createElementBlock(Fragment,{key:0},[createVNode(unref(bngCardHeading_default),{type:`ribbon`},{default:withCtx(()=>[..._cache[0]||=[createTextVNode(`Unlocked Series`,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_2$37,[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.change.unlockedLeagues,league=>(openBlock(),createBlock(LeagueRow_default,{key:league.id,league,vertical:``,nowUnlocked:``,condensed:``,class:`league`},null,8,[`league`]))),128))])],64)):createCommentVNode(``,!0),__props.change&&__props.change.unlockedMissions&&__props.change.unlockedMissions.length>0?(openBlock(),createElementBlock(Fragment,{key:1},[createVNode(unref(bngCardHeading_default),{type:`ribbon`},{default:withCtx(()=>[..._cache[1]||=[createTextVNode(`Unlocked Challenges`,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_3$31,[(openBlock(!0),createElementBlock(Fragment,null,renderList(__props.change.unlockedMissions,elem=>(openBlock(),createElementBlock(Fragment,{key:elem.id},[elem.hidden?createCommentVNode(``,!0):(openBlock(),createBlock(MissionCard_default,{key:0,class:`clickable-card`,mission:elem.formatted},null,8,[`mission`]))],64))),128))])],64)):createCommentVNode(``,!0)]))}},MissionUnlocks_default=__plugin_vue_export_helper_default(_sfc_main$54,[[`__scopeId`,`data-v-fa4ac1f4`]]),_hoisted_1$45={key:0,class:`page-navigation`},_hoisted_2$36={class:`nav-arrow-container nav-left`},_hoisted_3$30={key:0,class:`page-buttons`},_hoisted_4$22={key:0,class:`mandatory-dot`},_hoisted_5$20={class:`nav-arrow-container nav-right`},_hoisted_6$16={class:`button-row`},_hoisted_7$15={key:0,class:`replay-div`},_hoisted_8$11={key:0,class:`replay-warning`},_hoisted_9$9={key:0,class:`fee`},DURATION_SWOOSH=.15,DURATION_STAR_THUMP=.15,DURATION_HIGHSCORE_HIGHLIGHT=.15,DURATION_PANEL_SLIDE=.2,ANIM_START_DELAY=.25,ANIM_GAP=.33,ANIM_GAP_BREAKDOWN=.5,_sfc_main$53={__name:`MissionControl`,props:{mode:{type:String,required:!1,default:`endScreenTest`}},setup(__props){let{events:events$3}=useBridge();useUINavScope(`mission-control`);let exit=()=>{logger_default.debug(`exit`),window.bngVue.gotoGameState(`mission-details`)};useMissionDetailsStore();let layout=ref([]),supportsReplay=ref(!1),simpleStartScreen=ref(!1),buttons=ref([]),header=ref(),props=__props,animationsEndTime=ref(null),animEndTimeout=ref(null),replayRecording=ref(!1);function calculateAnimationTimes(panels){if(![`endScreen`,`test`].includes(props.mode)){logger_default.debug(`calculateAnimationTimes: Skipping - mode is not endScreen or test`);return}animEndTimeout.value&&=(clearTimeout(animEndTimeout.value),null);let animDelay=ANIM_START_DELAY,currentPagePanels=panels.filter(panel=>panel.pages?panel.pages[currentPage.value]:currentPage.value===`main`),anyAnimations=!1;for(let panel of currentPagePanels){if(panel.skipAnimations){logger_default.debug(`calculateAnimationTimes: Skipping animations for panel ${panel.type}`);continue}if(anyAnimations=!0,panel.slideAnimDelay=animDelay+`s`,logger_default.debug(`calculateAnimationTimes: Set slideAnimDelay for panel ${panel.type} to ${panel.slideAnimDelay}`),panel.slideInSound=setTimeout(()=>{Lua_default.Engine.Audio.playOnce(`AudioGui`,`event:>UI>Career>EndScreen_SlideIn`),logger_default.debug(`Playing slide in sound`),panel.slideInSound=null},animDelay*1e3),animDelay+=DURATION_PANEL_SLIDE,[`main`,`rewards`].includes(currentPage.value)){if(animDelay+=ANIM_GAP,panel.type===`rewards`&&panel.change&&panel.change.formattedRewards){let rewardsData=panel.change?.formattedRewards?.list||{},rewardsList=Array.isArray(rewardsData)?rewardsData:Object.values(rewardsData);animDelay+=ANIM_GAP,rewardsList.forEach((reward,index)=>{logger_default.debug(reward),reward.animDelay=animDelay*1e3,animDelay+=ANIM_GAP,reward.breakdown&&reward.breakdown.forEach((bd,bdIndex)=>{bd.animDelayShow=animDelay*1e3,animDelay+=ANIM_GAP,bd.duration>0&&(animDelay+=ANIM_GAP_BREAKDOWN,bd.animDelayStartLerp=animDelay*1e3,animDelay+=bd.duration)}),reward.progressBar&&reward.progressBar.animations&&reward.progressBar.animations.forEach(anim=>{anim.animDelay=animDelay*1e3,animDelay+=anim.duration+ANIM_GAP}),animDelay+=ANIM_GAP})}if(panel.type===`textPanel`&&panel.attempt){let list=panel.attempt.list;if(list&&list.length){let mainResults=list.filter(item=>item.mainResult);for(let mainResult of mainResults)mainResult.animDelay=animDelay+`s`,mainResult.soundDelay=animDelay*1e3,animDelay+=DURATION_SWOOSH,mainResult.animDelayThump=animDelay+`s`,mainResult.soundDelayThump=animDelay*1e3,animDelay+=DURATION_SWOOSH+DURATION_STAR_THUMP+ANIM_GAP}}if(panel.type===`objectives`&&panel.formattedProgress){let stars=panel.formattedProgress.stars;if(stars)for(let star of stars)star.unlockChange?(star.animDelay=animDelay+`s`,star.soundDelay=animDelay*1e3,animDelay+=DURATION_SWOOSH,star.animDelayThump=animDelay+`s`,star.soundDelayThump=animDelay*1e3,animDelay+=DURATION_SWOOSH+DURATION_STAR_THUMP+ANIM_GAP):star.unlockAttempt&&(star.animDelay=animDelay+`s`,star.soundDelay=animDelay*1e3,animDelay+=DURATION_SWOOSH+(DURATION_SWOOSH+DURATION_STAR_THUMP)/2+ANIM_GAP)}if(panel.type===`ratings`&&panel.progress){let formattedProgress=panel.progress.formattedProgress;if(formattedProgress){if(formattedProgress.ownAggregate)for(let agg of formattedProgress.ownAggregate)agg.newBest&&(agg.animDelay=animDelay+`s`,agg.soundDelay=animDelay*1e3,animDelay+=DURATION_HIGHSCORE_HIGHLIGHT+ANIM_GAP);formattedProgress.attempts&&(formattedProgress.attempts.leaderboardAnimDelay=animDelay+`s`,formattedProgress.attempts.leaderaboardSoundDelay=animDelay*1e3,animDelay+=DURATION_SWOOSH+ANIM_GAP)}}animDelay+=ANIM_GAP+ANIM_GAP}}animationsEndTime.value=null,logger_default.debug(`animDelay`,animDelay);let totalDuration=animDelay*1e3,pageInfo=pagesInfo.value[currentPage.value];(!anyAnimations||!pageInfo.mandatory)&&(totalDuration=0),animationsEndTime.value=Date.now()+totalDuration,animEndTimeout.value=setTimeout(()=>{animationsEndTime.value=null,animEndTimeout.value=null},totalDuration)}function resetAndCalculateAnimationTimes(){if(logger_default.debug(props.mode),![`endScreen`,`test`].includes(props.mode)||!layout.value)return;let initializedPanels=layout.value.map(panel=>({...panel,slideAnimDelay:`0s`,skipAnimations:!!visitedPages.value.has(currentPage.value)}));initializedPanels.forEach(panel=>{if(panel.type===`textPanel`&&panel.attempt&&panel.attempt.list&&panel.attempt.list.forEach(item=>{item.mainResult&&(item.animDelay=`-1s`,item.soundDelay=-1,item.animDelayThump=`-1s`,item.soundDelayThump=-1)}),panel.formattedProgress&&panel.formattedProgress.stars&&panel.formattedProgress.stars.forEach(star=>{star.animDelay=`-1s`,star.soundDelay=-1,star.animDelayThump=`-1s`,star.soundDelayThump=-1}),panel.progress&&panel.progress.formattedProgress&&(panel.progress.formattedProgress.ownAggregate.forEach(agg=>{agg.animDelay=`-1s`,agg.soundDelay=-1}),panel.progress.formattedProgress.attempts.leaderboardAnimDelay=`-1s`,panel.progress.formattedProgress.attempts.leaderaboardSoundDelay=-1),panel.type===`textPanel`&&panel.attempt&&(panel.attempt.animDelay=`-1s`,panel.attempt.soundDelay=-1,panel.attempt.animDelayThump=`-1s`,panel.attempt.soundDelayThump=-1),panel.type===`rewards`&&panel.change?.formattedRewards?.list){panel.change.skipAnimations=panel.skipAnimations;let rewardsData=panel.change?.formattedRewards?.list||{},rewardsList=Array.isArray(rewardsData)?rewardsData:Object.values(rewardsData),animDelay=0;rewardsList.forEach((reward,index)=>{reward.animDelay=-1,animDelay+=ANIM_GAP,reward.breakdown&&reward.breakdown.forEach((bd,bdIndex)=>{bd.animDelayShow=-1,bd.animDelayStartLerp=-1}),animDelay+=ANIM_GAP})}}),calculateAnimationTimes(initializedPanels),layout.value=initializedPanels}let pagesInfo=ref({}),dataReady=ref(!1);onBeforeMount(()=>{visitedPages.value=new Set([]),logger_default.debug(props.mode),events$3.on(`onRequestMissionScreenDataReady`,data=>{header.value=data.header,data.pages&&(pagesInfo.value=data.pages),dataReady.value=!0,[`endScreen`,`test`].includes(props.mode)?(layout.value=data.layout,currentPage.value=null,showPage(`main`)):layout.value=data.layout,supportsReplay.value=data.supportsReplay,simpleStartScreen.value=data.simpleStartScreen,buttons.value=data.buttons}),Lua_default.extensions.hook(`onRequestMissionScreenData`,props.mode),props.mode!==`startScreen`&&Lua_default.extensions.gameplay_missions_missionScreen.activateSoundBlur(!0)}),onMounted(()=>{events$3.on(`onReplayRecordingValueRequested`,value=>{replayRecording.value=value}),Lua_default.extensions.hook(`onReplayRecordingValueRequested`)}),onUnmounted(()=>{events$3.off(`onRequestMissionScreenDataReady`),events$3.off(`onReplayRecordingValueRequested`),Lua_default.extensions.gameplay_missions_missionScreen.activateSoundBlur(!1)});let startScreenReplaySwitchClicked=newValue=>{Lua_default.extensions.hook(`onMissionAutoReplayRecordingSettingChanged`,newValue)},buttonClicked=button=>{logger_default.debug(button),Lua_default.extensions.hook(`onMissionScreenButtonClicked`,button)},currentPage=ref(`main`),visitedPages=ref(new Set([`main`])),panelRefs=ref({}),isInputBlocked=ref(!1),columnAdjustmentInterval=ref(null),headerRef=ref(null),wideColumnRef=ref(null),buttonsRef=ref(null),availablePages=computed(()=>{if(!layout.value||layout.value.length===0)return[];if(pagesInfo.value&&Object.keys(pagesInfo.value).length>0)return Object.entries(pagesInfo.value).map(([pageName,pageInfo])=>({name:pageName,order:pageInfo.order,label:pageInfo.label,icon:pageInfo.icon})).sort((a$1,b)=>a$1.order-b.order).map(page=>page.name);let pages=new Set;layout.value.forEach(panel=>{panel.pages&&Object.keys(panel.pages).forEach(page=>{pages.add(page)})});let orderedPages=[];return[`main`,`rewards`,`details`,`empty`].forEach(page=>{pages.has(page)&&(orderedPages.push(page),pages.delete(page))}),pages.forEach(page=>{orderedPages.push(page)}),orderedPages});computed(()=>layout.value?layout.value.filter(panel=>panel.pages?panel.pages[currentPage.value]:currentPage.value===`main`):[]);let pageRandomKey=ref(Math.random()),currentPanels=computed(()=>!layout.value||currentPage.value===`empty`||!layout.value.length||!layout.value[0]?[]:(logger_default.debug(`Layout:`),logger_default.debug(layout),layout.value.filter(panel=>panel.pages?panel.pages[currentPage.value]:currentPage.value===`main`).map(panel=>({...panel,slideAnimDelay:panel.slideAnimDelay||`0s`,visited:visitedPages.value.has(currentPage.value),key:pageRandomKey.value}))));watch(currentPage,()=>{pageRandomKey.value=Math.random(),nextTick(()=>{adjustWideColumn()})}),watch([layout,currentPage],()=>{layout.value&&layout.value.length>0&&adjustWideColumn()},{immediate:!0});let showPageNavigation=computed(()=>!0);function cancelAllSoundDelays(){logger_default.debug(`MissionControl: Cancelling all sound delays`),currentPanels.value.forEach(panel=>{let ref$1=panelRefs.value[panel.type];panel.slideInSound&&=(clearTimeout(panel.slideInSound),null),ref$1&&typeof ref$1.cancelSoundDelays==`function`&&(logger_default.debug(`MissionControl: Cancelling sounds for panel type: ${panel.type}`),ref$1.cancelSoundDelays())})}function showPage(pageName){visitedPages.value.has(pageName)&&Lua_default.Engine.Audio.playOnce(`AudioGui`,`event:>UI>Career>EndScreen_SlideIn`),currentPage.value&&visitedPages.value.add(currentPage.value),cancelAllSoundDelays(),currentPage.value=pageName,logger_default.debug(props.mode),[`endScreen`,`test`].includes(props.mode)&&(animationsEndTime.value=null,resetAndCalculateAnimationTimes()),nextTick(()=>{adjustWideColumn()})}function focusNextPage(){let currentIndex=availablePages.value.indexOf(currentPage.value);currentIndex0?availablePages.value[currentIndex-1]:availablePages.value[availablePages.value.length-1])}function adjustWideColumn(){if(columnAdjustmentInterval.value)return;let maxDuration=2e3;if(layout.value&&layout.value.length>0){let lastPanel=layout.value[layout.value.length-1];lastPanel&&lastPanel.slideAnimDelay&&(maxDuration=parseFloat(lastPanel.slideAnimDelay)*1e3+1e3)}let CHECK_INTERVAL=0,startTime=Date.now();function checkColumnWidth(){if(Date.now()-startTime>maxDuration){clearInterval(columnAdjustmentInterval.value),columnAdjustmentInterval.value=null;return}if(wideColumnRef.value){let wideColumn=wideColumnRef.value,columnLeft=wideColumn.getBoundingClientRect().left;window.innerWidth;let childElements=Array.from(wideColumn.children),maxRowWidth=0,lastTop=-1,currentRowWidth=0;childElements.forEach(child=>{let style=window.getComputedStyle(child);if(style.display!==`none`&&style.visibility!==`hidden`){let childRect=child.getBoundingClientRect(),childTop=Math.round(childRect.top),childRight=childRect.right-columnLeft;lastTop!==-1&&Math.abs(childTop-lastTop)>1?(maxRowWidth=Math.max(maxRowWidth,currentRowWidth),currentRowWidth=childRight):currentRowWidth=Math.max(currentRowWidth,childRight),lastTop=childTop}}),maxRowWidth=Math.max(maxRowWidth,currentRowWidth);let widthInRem=Math.max(25,maxRowWidth/16)+.25;wideColumn.style.width=`${widthInRem}rem`}}checkColumnWidth(),columnAdjustmentInterval.value=setInterval(checkColumnWidth,0)}onBeforeUnmount(()=>{columnAdjustmentInterval.value&&=(clearInterval(columnAdjustmentInterval.value),null),animEndTimeout.value&&=(clearTimeout(animEndTimeout.value),null)});function getPageIcon(page){return!pagesInfo.value||!pagesInfo.value[page]?`questionmark`:pagesInfo.value[page].icon||`questionmark`}let findNextUnvisitedMandatoryPage=()=>{let orderedPages=availablePages.value;for(let page of orderedPages){let pageInfo=pagesInfo.value[page];if(page!==currentPage.value&&pageInfo?.mandatory&&!visitedPages.value.has(page))return page}return null},isPlayingAnimations=computed(()=>!currentPage.value||visitedPages.value.has(currentPage.value)?!1:animationsEndTime.value&&Date.now()dataReady.value?isPlayingAnimations.value?`skip`:findNextUnvisitedMandatoryPage()===null?!1:`continue`:!1),skipAnimations=()=>{currentPage.value&&(animationsEndTime.value=Date.now(),showPage(currentPage.value))},continueToNextPage=()=>{let nextMandatoryPage=findNextUnvisitedMandatoryPage();nextMandatoryPage&&showPage(nextMandatoryPage)},shouldShowMandatoryDot=page=>{if(!dataReady.value)return!1;let pageInfo=pagesInfo.value[page];return page===currentPage.value?pageInfo?.mandatory&&isPlayingAnimations.value:pageInfo?.mandatory&&!visitedPages.value.has(page)};function updatePanel(newPanel){let index=layout.value.findIndex(p$1=>p$1.type===newPanel.type);index!==-1&&(layout.value[index]=newPanel,console.log(newPanel.recordingFiles))}let leftBinding=ref(),rightBinding=ref(),leftIconClass=computed(()=>({"with-binding":leftBinding.value?.displayed})),rightIconClass=computed(()=>({"with-binding":rightBinding.value?.displayed}));return(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(layoutSingle_default),{class:normalizeClass([`mission-control-layout`,{"main-sequence":props.mode===`endScreen`||props.mode===`test`}]),"bng-ui-scope":`mission-control`},{default:withCtx(()=>[header.value?(openBlock(),createElementBlock(`div`,{key:0,class:`top`,ref_key:`headerRef`,ref:headerRef},[createVNode(InfoCard_default,{class:`full-width`},{header:withCtx(()=>[createVNode(bngAdvCardHeading_default,{class:`header`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$ctx_t(header.value.header)),1)]),_:1})]),content:withCtx(()=>[showPageNavigation.value?(openBlock(),createElementBlock(`div`,_hoisted_1$45,[createBaseVNode(`div`,_hoisted_2$36,[availablePages.value.length>1?(openBlock(),createBlock(unref(bngButton_default),{key:0,"bng-no-nav":`true`,accent:unref(ACCENTS).text,class:`page-nav`,onClick:focusPreviousPage},{default:withCtx(()=>[createVNode(unref(bngIcon_default),{type:leftBinding.value?.displayed?unref(icons).arrowSmallLeft:unref(icons).arrowLargeLeft,class:normalizeClass(leftIconClass.value)},null,8,[`type`,`class`]),createVNode(unref(bngBinding_default),{ref_key:`leftBinding`,ref:leftBinding,"ui-event":`tab_l`,controller:``},null,512)]),_:1},8,[`accent`])):createCommentVNode(``,!0)]),simpleStartScreen.value?createCommentVNode(``,!0):(openBlock(),createElementBlock(`div`,_hoisted_3$30,[(openBlock(!0),createElementBlock(Fragment,null,renderList(availablePages.value,page=>(openBlock(),createElementBlock(`div`,{key:page,class:`page-icon-wrapper`},[createVNode(unref(bngIcon_default),{type:getPageIcon(page),onClick:$event=>showPage(page),class:normalizeClass([`page-icon-button`,{"current-page":currentPage.value===page}])},null,8,[`type`,`onClick`,`class`]),shouldShowMandatoryDot(page)?(openBlock(),createElementBlock(`div`,_hoisted_4$22)):createCommentVNode(``,!0)]))),128))])),createBaseVNode(`div`,_hoisted_5$20,[availablePages.value.length>1?(openBlock(),createBlock(unref(bngButton_default),{key:0,"bng-no-nav":`true`,accent:unref(ACCENTS).text,class:`page-nav`,onClick:focusNextPage},{default:withCtx(()=>[createVNode(unref(bngBinding_default),{ref_key:`rightBinding`,ref:rightBinding,"ui-event":`tab_r`,controller:``},null,512),createVNode(unref(bngIcon_default),{type:rightBinding.value?.displayed?unref(icons).arrowSmallRight:unref(icons).arrowLargeRight,class:normalizeClass(rightIconClass.value)},null,8,[`type`,`class`])]),_:1},8,[`accent`])):createCommentVNode(``,!0)])])):createCommentVNode(``,!0)]),_:1})],512)):createCommentVNode(``,!0),layout.value?withDirectives((openBlock(),createElementBlock(`div`,{key:1,class:`columns`,ref_key:`wideColumnRef`,ref:wideColumnRef},[(openBlock(!0),createElementBlock(Fragment,null,renderList(currentPanels.value,panel=>(openBlock(),createBlock(unref(slotSwitcher_default),{key:panel.type,slotId:panel.type},{textPanel:withCtx(()=>[(openBlock(),createBlock(MissionTextPanel_default,{ref_for:!0,ref:el=>panelRefs.value[panel.type]=el,panel,"no-blur":!0,key:panel.key,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`})},null,8,[`panel`,`style`]))]),crashTestStepDetails:withCtx(()=>[(openBlock(),createBlock(MissionCrashTestStepDetails_default,{ref_for:!0,ref:el=>panelRefs.value[panel.type]=el,"no-blur":!0,key:panel.key,panel},null,8,[`panel`]))]),replayPanel:withCtx(()=>[(openBlock(),createBlock(MissionReplayPanel_default,{ref_for:!0,ref:el=>panelRefs.value[panel.type]=el,"no-blur":!0,key:panel.key,panel,"onUpdate:panel":updatePanel,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`})},null,8,[`panel`,`style`]))]),objectives:withCtx(()=>[panel.formattedProgress?(openBlock(),createBlock(MissionObjectives_default,{ref_for:!0,ref:el=>panelRefs.value[panel.type]=el,stars:panel.formattedProgress.stars,"no-blur":!0,key:panel.key,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`})},null,8,[`stars`,`style`])):createCommentVNode(``,!0)]),ratings:withCtx(()=>[(openBlock(),createBlock(MissionRatings_default,{ratings:panel.progress.formattedProgress,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`}),"no-blur":!0,key:panel.key},null,8,[`ratings`,`style`]))]),rewards:withCtx(()=>[(openBlock(),createBlock(MissionRewards_default,{change:panel.change,"no-blur":!0,"animation-delay":panel.slideAnimDelay||`0s`,key:panel.key},null,8,[`change`,`animation-delay`]))]),dragDial:withCtx(()=>[(openBlock(),createBlock(MissionDialPanel_default,{panel,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`}),"no-blur":!0,key:panel.key},null,8,[`panel`,`style`]))]),dragTimeSlip:withCtx(()=>[(openBlock(),createBlock(MissionTimeSlipPanel_default,{panel,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`}),"no-blur":!0,key:panel.key},null,8,[`panel`,`style`]))]),unlocks:withCtx(()=>[(openBlock(),createBlock(MissionUnlocks_default,{ref_for:!0,ref:el=>panelRefs.value[panel.type]=el,change:panel.change,style:normalizeStyle({"animation-delay":panel.slideAnimDelay||`0s`}),key:panel.key},null,8,[`change`,`style`]))]),_:2},1032,[`slotId`]))),128))])),[[unref(BngBlur_default),!0]]):createCommentVNode(``,!0),createBaseVNode(`div`,{class:`bottom`,ref_key:`buttonsRef`,ref:buttonsRef},[createVNode(InfoCard_default,{class:`full-width`},{content:withCtx(()=>[..._cache[2]||=[]]),button:withCtx(()=>[createBaseVNode(`div`,_hoisted_6$16,[supportsReplay.value&&props.mode===`startScreen`?(openBlock(),createElementBlock(`div`,_hoisted_7$15,[replayRecording.value?(openBlock(),createElementBlock(`div`,_hoisted_8$11,[createVNode(unref(bngIcon_default),{type:`danger`}),createTextVNode(` `+toDisplayString(unref($translate).instant(`missions.general.replay.increaseFps`)),1)])):createCommentVNode(``,!0),createVNode(unref(bngSwitch_default),{label:_ctx.$t(`missions.general.replay.enableMissionRecording`),modelValue:replayRecording.value,"onUpdate:modelValue":_cache[0]||=$event=>replayRecording.value=$event,onValueChanged:startScreenReplaySwitchClicked},null,8,[`label`,`modelValue`])])):createCommentVNode(``,!0),showContinueButton.value?(openBlock(),createBlock(unref(bngButton_default),{key:1,class:`large`,onClick:_cache[1]||=$event=>showContinueButton.value===`skip`?skipAnimations():continueToNextPage(),accent:`main`,disabled:isInputBlocked.value},{default:withCtx(()=>[createBaseVNode(`div`,null,toDisplayString(_ctx.$t(showContinueButton.value===`skip`?`ui.common.skip`:`ui.common.next`)),1)]),_:1},8,[`disabled`])):(openBlock(!0),createElementBlock(Fragment,{key:2},renderList(buttons.value,button=>withDirectives((openBlock(),createBlock(unref(bngButton_default),{class:`large`,onClick:$event=>buttonClicked(button),accent:button.main?`main`:`secondary`,disabled:isInputBlocked.value},{default:withCtx(()=>[createBaseVNode(`div`,null,toDisplayString(_ctx.$t(button.label)),1),button.fee?(openBlock(),createElementBlock(`div`,_hoisted_9$9,[_cache[3]||=createTextVNode(` (Pay `,-1),createVNode(RewardsPills_default,{class:`tiny-rewards`,rewards:button.fee},null,8,[`rewards`]),_cache[4]||=createTextVNode(` ) `,-1)])):createCommentVNode(``,!0)]),_:2},1032,[`onClick`,`accent`,`disabled`])),[[unref(BngFocusIf_default),button.focus]])),256))])]),_:1})],512)]),_:1},8,[`class`])),[[unref(BngOnUiNav_default),exit,`menu,back`],[unref(BngOnUiNav_default),focusPreviousPage,`tab_l`],[unref(BngOnUiNav_default),focusNextPage,`tab_r`]])}},MissionControl_default=__plugin_vue_export_helper_default(_sfc_main$53,[[`__scopeId`,`data-v-455699fd`]]),_hoisted_1$44={class:`tile`},_hoisted_2$35={class:`name`},_sfc_main$52={__name:`MissionTile`,props:{card:{type:Object}},setup(__props){return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$44,[createVNode(aspectRatio_default,{externalImage:__props.card.image,class:`image`},null,8,[`externalImage`]),__props.card.expandGroupKey?(openBlock(),createBlock(aspectRatio_default,{key:0,class:`folder`},{default:withCtx(()=>[createVNode(unref(bngIcon_default),{class:`glyph small`,type:__props.card.expanded?unref(icons).BNGFolder:unref(icons).folder},null,8,[`type`])]),_:1})):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_2$35,toDisplayString(_ctx.$tt(__props.card.name)),1)]))}},MissionTile_default=__plugin_vue_export_helper_default(_sfc_main$52,[[`__scopeId`,`data-v-85e164f5`]]),_hoisted_1$43={class:`content-container`},_hoisted_2$34={key:0,class:`grid-list`},_hoisted_3$29={class:`label`},_sfc_main$51={__name:`MissionsGrid`,setup(__props){useUINavScope(`missions-grid`);let data=ref({});onBeforeMount(async()=>{data.value=await Lua_default.core_vehicles.getVehicleTiles()}),onUnmounted(()=>{});function cardClicked(id){let card=data.value.tilesById[id];id&&card.expandGroupKey&&(card.expanded=!card.expanded)}return(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(layoutSingle_default),{class:`layout-content-full flex-column`,"bng-ui-scope":`missions-grid`},{default:withCtx(()=>[createVNode(unref(bngScreenHeading_default),{divider:``},{default:withCtx(()=>[..._cache[0]||=[createTextVNode(` Challenges `,-1)]]),_:1}),createBaseVNode(`div`,_hoisted_1$43,[data.value&&data.value.groupsByKey?(openBlock(),createElementBlock(`div`,_hoisted_2$34,[(openBlock(!0),createElementBlock(Fragment,null,renderList(data.value.groupKeys,groupKey=>(openBlock(),createElementBlock(Fragment,null,[data.value.groupsByKey[groupKey].propName==`Type`?(openBlock(),createElementBlock(Fragment,{key:0},[createBaseVNode(`div`,_hoisted_3$29,toDisplayString(data.value.groupsByKey[groupKey].label),1),(openBlock(!0),createElementBlock(Fragment,null,renderList(data.value.groupsByKey[groupKey].tileIdsUnsorted,id=>(openBlock(),createElementBlock(Fragment,null,[data.value.tilesById[id].expandGroupKey?(openBlock(),createBlock(MissionTile_default,{key:0,class:`card`,card:data.value.tilesById[id],onClick:$event=>cardClicked(id)},null,8,[`card`,`onClick`])):createCommentVNode(``,!0),data.value.tilesById[id].expanded?(openBlock(!0),createElementBlock(Fragment,{key:1},renderList(data.value.groupsByKey[data.value.tilesById[id].expandGroupKey].tileIdsUnsorted,subId=>(openBlock(),createBlock(MissionTile_default,{class:`card`,card:data.value.tilesById[subId],onClick:$event=>cardClicked(subId)},null,8,[`card`,`onClick`]))),256)):createCommentVNode(``,!0)],64))),256))],64)):createCommentVNode(``,!0)],64))),256))])):createCommentVNode(``,!0),_cache[1]||=createBaseVNode(`div`,{class:`details-panel`},` Panel `,-1)])]),_:1})),[[unref(BngBlur_default)]])}},MissionsGrid_default=__plugin_vue_export_helper_default(_sfc_main$51,[[`__scopeId`,`data-v-a6877652`]]),_hoisted_1$42={key:0,"bng-ui-scope":`dragHistory`,class:`drag-history-wrapper`},_hoisted_2$33={key:0,class:`drag-history-container`},_hoisted_3$28={class:`drag-history-filters`},_hoisted_4$21={class:`filter-label`},_hoisted_5$19={class:`filter-active`},_hoisted_6$15={key:0,class:`filter-buttons`},_hoisted_7$14={key:1,class:`no-filters`},_hoisted_8$10={class:`drag-history-list`},_hoisted_9$8=[`onClick`],_hoisted_10$6={class:`drag-history-item-content`},_hoisted_11$6={class:`drag-history-meta`},_hoisted_12$5={class:`drag-history-item-label`},_hoisted_13$5={key:1,class:`drag-history-item`},_hoisted_14$5={class:`drag-history-details`},_hoisted_15$5={key:0,class:`drag-history-slip-wrap`},_hoisted_16$5={key:1,class:`drag-history-empty-message`},_hoisted_17$4={key:1,class:`drag-history-container`},_hoisted_18$4={class:`drag-history-details`},_sfc_main$50={__name:`MissionDragHistory`,props:{id:{type:String,required:!0},name:{type:String,required:!0},level:{type:String,required:!0}},setup(__props){useUINavScope(`dragHistory`);let props=__props,entryId=computed(()=>props.id===void 0?void 0:(``+props.id).replace(/\%/g,`/`)),name=computed(()=>props.name===void 0?void 0:props.name),level$1=computed(()=>props.level===void 0?void 0:props.level),historyData=ref(void 0);ref(null);let filterDefinitions=[{key:`brand`,label:`Brand`},{key:`country`,label:`Country`},{key:`drivetrain`,label:`Drivetrain`},{key:`fuelType`,label:`Fuel Type`},{key:`transmission`,label:`Transmission`},{key:`configType`,label:`Config Type`},{key:`inductionType`,label:`Induction Type`},{key:`tree`,label:`Tree Type`}],selectedFilters=ref({}),activeFilters=ref([]),availableFilterOptions=computed(()=>{if(!historyData.value?.history)return{};let options={};return filterDefinitions.forEach(filter=>{options[filter.key]=new Set}),historyData.value.history.forEach(entry=>{let vehicleInfo=entry.racerInfos[0];filterDefinitions.forEach(filter=>{filter.key===`tree`?entry.tree&&options[filter.key].add(entry.tree):vehicleInfo[filter.key]&&options[filter.key].add(vehicleInfo[filter.key])})}),Object.fromEntries(Object.entries(options).map(([key,values])=>[key,[...values].sort().map(value=>({label:value,value}))]))}),filteredHistory=computed(()=>!historyData.value?.history||activeFilters.value.length===0?historyData.value?.history||[]:historyData.value.history.filter(entry=>{let vehicleInfo=entry.racerInfos[0];return activeFilters.value.some(filter=>filter.type===`tree`?entry.tree===filter.value:vehicleInfo[filter.type]===filter.value)}));function setup$3(data){historyData.value=data,historyData.value&&historyData.value.history&&Array.isArray(historyData.value.history)&&historyData.value.history.length>0&&toggleExpand(historyData.value.history[0])}ref({});let selectedEntry=ref(void 0),toggleExpand=entry=>setTimeout(()=>{selectedEntry.value!==entry&&(selectedEntry.value=entry)},0),handleFilterChange=(filterKey,selectedValue)=>{if(!selectedValue||activeFilters.value.some(f=>f.type===filterKey&&f.value===selectedValue))return;let newFilterIndex=filterDefinitions.findIndex(f=>f.key===filterKey),insertIndex=activeFilters.value.findIndex(f=>filterDefinitions.findIndex(fd=>fd.key===f.type)>newFilterIndex),newFilter={type:filterKey,value:selectedValue};insertIndex===-1?activeFilters.value.push(newFilter):activeFilters.value.splice(insertIndex,0,newFilter),selectedEntry.value=filteredHistory.value[0]},exit=()=>window.bngVue.gotoGameState(`play`),start=()=>{Lua_default.gameplay_drag_dragBridge.getHistory(entryId.value).then(setup$3),filterDefinitions.forEach(filter=>{selectedFilters.value[filter.key]=null})},removeFilter=filterToRemove=>{activeFilters.value=activeFilters.value.filter(f=>!(f.type===filterToRemove.type&&f.value===filterToRemove.value)),selectedFilters.value[filterToRemove.type]=null,selectedEntry.value=filteredHistory.value[0]};return onMounted(start),(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(layoutSingle_default),{class:`drag-history-layout`},{default:withCtx(()=>[historyData.value===void 0?createCommentVNode(``,!0):withDirectives((openBlock(),createElementBlock(`div`,_hoisted_1$42,[createVNode(unref(bngScreenHeading_default),{preheadings:[_ctx.$t(level$1.value)]},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$t(name.value))+` History`,1)]),_:1},8,[`preheadings`]),historyData.value&&historyData.value.history&&historyData.value.history.length>0?(openBlock(),createElementBlock(`div`,_hoisted_2$33,[createBaseVNode(`div`,_hoisted_3$28,[(openBlock(),createElementBlock(Fragment,null,renderList(filterDefinitions,filter=>createBaseVNode(`div`,{key:filter.key,class:`filter-item`},[createBaseVNode(`div`,_hoisted_4$21,toDisplayString(filter.label),1),createVNode(unref(bngDropdown_default),{modelValue:selectedFilters.value[filter.key],"onUpdate:modelValue":[$event=>selectedFilters.value[filter.key]=$event,val=>handleFilterChange(filter.key,val)],items:availableFilterOptions.value[filter.key],"show-search":!0},null,8,[`modelValue`,`onUpdate:modelValue`,`items`]),createBaseVNode(`div`,_hoisted_5$19,[activeFilters.value.some(f=>f.type===filter.key)?(openBlock(),createElementBlock(`div`,_hoisted_6$15,[(openBlock(!0),createElementBlock(Fragment,null,renderList(activeFilters.value.filter(f=>f.type===filter.key),activeFilter=>(openBlock(),createBlock(unref(bngButton_default),{key:activeFilter.value,size:`small`,accent:`orange`,onClick:$event=>removeFilter(activeFilter)},{default:withCtx(()=>[createTextVNode(toDisplayString(activeFilter.value)+` × `,1)]),_:2},1032,[`onClick`]))),128))])):(openBlock(),createElementBlock(`div`,_hoisted_7$14,`No filters selected`))])])),64))]),createBaseVNode(`div`,_hoisted_8$10,[createBaseVNode(`div`,{class:normalizeClass([`drag-history-tab-wrapper`,{"drag-history-empty":filteredHistory.value.length===0}])},[filteredHistory.value.length>0?(openBlock(!0),createElementBlock(Fragment,{key:0},renderList(filteredHistory.value,entry=>withDirectives((openBlock(),createElementBlock(`div`,{"bng-nav-item":``,class:normalizeClass([`drag-history-item`,{selected:selectedEntry.value!==void 0&&selectedEntry.value==entry}]),onClick:$event=>toggleExpand(entry)},[createBaseVNode(`div`,_hoisted_10$6,[createBaseVNode(`div`,_hoisted_11$6,[withDirectives(createBaseVNode(`div`,null,null,512),[[unref(BngRelativeTime_default),entry.stripInfo.dateTime]])]),createBaseVNode(`div`,_hoisted_12$5,toDisplayString(entry.stripInfo.dateTime),1)])],10,_hoisted_9$8)),[[unref(BngSoundClass_default),`bng_click_generic_small`]])),256)):(openBlock(),createElementBlock(`div`,_hoisted_13$5,[..._cache[0]||=[createBaseVNode(`div`,{class:`drag-history-item-content`},[createBaseVNode(`div`,{class:`drag-history-item-label`},`No matches found for current filters`)],-1)]]))],2)]),createBaseVNode(`div`,_hoisted_14$5,[createVNode(unref(bngCard_default),{class:`drag-history-content-card`},{default:withCtx(()=>[createVNode(unref(bngCardHeading_default),{class:`drag-history-heading`,type:`ribbon`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$t(level$1.value))+` - `+toDisplayString(_ctx.$t(name.value)),1)]),_:1}),filteredHistory.value.length>0?(openBlock(),createElementBlock(Fragment,{key:0},[selectedEntry.value?(openBlock(),createElementBlock(`div`,_hoisted_15$5,[createVNode(Timeslip_default,{class:`drag-history-slip-item`,slip:selectedEntry.value},null,8,[`slip`])])):createCommentVNode(``,!0)],64)):(openBlock(),createElementBlock(`div`,_hoisted_16$5,` No timeslips match the selected filters. Try adjusting your filter criteria. `))]),_:1})])])):(openBlock(),createElementBlock(`div`,_hoisted_17$4,[_cache[2]||=createBaseVNode(`div`,{class:`drag-history-list`},[createBaseVNode(`div`,{class:`drag-history-tab-wrapper drag-history-empty`},[createBaseVNode(`div`,{class:`drag-history-item`},[createBaseVNode(`div`,{class:`drag-history-item-content`},[createBaseVNode(`div`,{class:`drag-history-item-label`},`No History Available`)])])])],-1),createBaseVNode(`div`,_hoisted_18$4,[createVNode(unref(bngCard_default),{class:`drag-history-content-card`},{default:withCtx(()=>[createVNode(unref(bngCardHeading_default),{class:`drag-history-heading`,type:`ribbon`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$t(level$1.value))+` - `+toDisplayString(_ctx.$t(name.value)),1)]),_:1}),_cache[1]||=createBaseVNode(`div`,{class:`drag-history-empty-message`},` No drag race history yet. Start a practice run or play a drag race challenge! `,-1)]),_:1})])]))])),[[unref(BngOnUiNav_default),exit,`back,menu`]])]),_:1})),[[unref(BngBlur_default)]])}},MissionDragHistory_default=__plugin_vue_export_helper_default(_sfc_main$50,[[`__scopeId`,`data-v-003bb226`]]),_hoisted_1$41={class:`mission-details-layout-content`},_hoisted_2$32={class:`mission-details-topbar`},_hoisted_3$27={class:`details-pages-container`},_hoisted_4$20={class:`mission-details-content`},_hoisted_5$18={class:`available-missions-container`},_hoisted_6$14={key:0,class:`ongoing-mission-buttons`},_hoisted_7$13={key:1,class:`recovery-options-container`},_hoisted_8$9={class:`recovery-options-list`},_hoisted_9$7={class:`mission-card-container`},_hoisted_10$5={key:0,class:`group-header`},_hoisted_11$5={class:`label`},_hoisted_12$4={class:`mission-card-list`},_hoisted_13$4={key:0,class:`mission-info`},_hoisted_14$4={class:`details-content-container`},_hoisted_15$4={class:`details-content-entry`},_hoisted_16$4={key:0,class:`details-info-container`},_hoisted_17$3={class:`details-info-description`},_hoisted_18$3={key:3,class:`details-objectives-container`},_hoisted_19$2={key:0,class:`ongoing-mission-reconfigure-button`},_hoisted_20$2={key:1,class:`ongoing-mission-text`},_hoisted_21$2={key:2,class:`current-details-buttons`},_hoisted_22$2={key:0,class:`simple-settings-container`},_hoisted_23$2={key:1,class:`entry-fee`},_hoisted_24$1={key:2,class:`repair-item`},AVAILABLE_PAGES=[{value:`info`,label:`Info`,icon:`medal`},{value:`settings`,label:`Settings`,icon:`adjust`},{value:`leaderboards`,label:`Leaderboards`,icon:`chartBars`}],_sfc_main$49={__name:`MissionDetailsNew`,setup(__props){let store$1=useMissionDetailsStore(),{context,missionCards,missionBasicInfo,missionStartableDetails,missionSettings,missionProgress,selectedMission,isTutorialEnabled,hideReconfigureButton,hideRecoveryOptions,sameUserSettingsAsLast,preselectedPage}=storeToRefs(store$1),controls$1=controls_default(),scopedNav=useScopedNav(),tasksStore=useTasksStore(),currentPage=ref(`info`);watch(preselectedPage,newPage=>{newPage&&AVAILABLE_PAGES.some(page=>page.value===newPage)&&(currentPage.value=newPage)},{immediate:!0});let availablePages=computed(()=>AVAILABLE_PAGES.filter(page=>!(page.value===`settings`&&hideReconfigureButton.value))),scopeNavState=reactive({missionDetailsActivated:!1}),uiState=reactive({missionStarted:!1,settingsTriggered:!1}),isGamepadAvailable=controls$1.isGamepadAvailable(!0),showTasks=computed(()=>tasksStore.tasks.length>0&&isTutorialEnabled.value),preheadings=computed(()=>missionBasicInfo.value.missionTypeLabels.map(x=>$translate.contextTranslate(x)));computed(()=>{let showRestart=isGamepadAvailable&&isGamepadAvailable.value||sameUserSettingsAsLast.value;return{label:showRestart?`Restart`:`Reconfigure`,icon:showRestart?icons.restart:icons.reconfigure}});let displayedAuthor=computed(()=>missionBasicInfo.value.author||``),displayedDate=computed(()=>missionBasicInfo.value.date?new Date(missionBasicInfo.value.date*1e3).toLocaleDateString():``),showOfficialIcon=computed(()=>!!missionBasicInfo.value.official),showMissionInfo=computed(()=>displayedAuthor.value||displayedDate.value),missionInfoString=computed(()=>displayedAuthor.value&&displayedDate.value?`${displayedAuthor.value} • ${displayedDate.value}`:displayedAuthor.value?displayedAuthor.value:displayedDate.value?displayedDate.value:``),recoveryOptions=computed(()=>store$1.customRecoveryOptionsActiveState?Object.entries(store$1.customRecoveryOptionsActiveState).filter(([key,option])=>option.isRecoveryOption).map(([key,option])=>({key,...option})):[]),unpauseOnUnmount=!0;provide(`animationSettings`,{animate:!0,animateOnMount:!1,animateOnMountIntervalDelay:.2,animateOnEmptyIntervalDelay:.1,animateOnEmpty:!0,animateNextTask:!0,successCallback:()=>Lua_default.Engine.Audio.playOnce(`AudioGui`,`event:>UI>Career>Checkbox`)}),onMounted(()=>{Lua_default.simTimeAuthority.pause(!0)}),onBeforeMount(async()=>{await store$1.init()}),onUnmounted(()=>{store$1.$dispose(),unpauseOnUnmount&&Lua_default.simTimeAuthority.pause(!1)});let startMission=()=>{uiState.missionStarted=!0,window.bngVue.gotoGameState(`blank`,{tryAngular:!1,blankAngularJS:!0}),store$1.startMission()},selectMission=id=>{scopeNavState.missionDetailsActivated=!0,store$1.selectMission(id)},onDetailScopeChanged=(activated,event)=>{scopeNavState.missionDetailsActivated=activated},navigateToPage=(direction$1=1)=>{let nextIndex=(availablePages.value.findIndex(page=>page.value===currentPage.value)+direction$1+availablePages.value.length)%availablePages.value.length;currentPage.value=availablePages.value[nextIndex].value},handleBack=()=>{window.bngVue.gotoGameState(`play`)},handleContinue=async()=>{if(await Lua_default.extensions.gameplay_missions_missionScreen.isAnyMissionActive()){let isMissionStartOrEndScreen=await Lua_default.extensions.gameplay_missions_missionScreen.isMissionStartOrEndScreenActive();if(isMissionStartOrEndScreen){window.bngVue.gotoGameState(`mission-control`,{params:{mode:isMissionStartOrEndScreen}});return}}window.bngVue.gotoGameState(`play`)},handleMainMenu=()=>{unpauseOnUnmount=!1,gotoMenu()},gotoMenu=()=>{Lua_default.career_career.isActive().then(isActive=>{isActive?window.bngVue.gotoAngularState(`menu.careerPause`):window.bngVue.gotoAngularState(`menu.mainmenu`)})},gotoControl=()=>{Lua_default.extensions.gameplay_missions_missionScreen.isAnyMissionActive().then(isMissionActive=>{isMissionActive&&Lua_default.extensions.gameplay_missions_missionScreen.isMissionStartOrEndScreenActive().then(isMissionStartOrEndScreen=>{if(isMissionStartOrEndScreen){window.bngVue.gotoGameState(`mission-control`,{params:{mode:isMissionStartOrEndScreen}});return}}),window.bngVue.gotoGameState(`play`)})},gotoSettings=()=>{currentPage.value=`settings`,scopeNavState.missionDetailsActivated=!0,uiState.settingsTriggered=!0},onDetailsClick=event=>{scopeNavState.missionDetailsActivated||=!0},handleRecoveryOption=optionKey=>{Lua_default.core_recoveryPrompt.buttonPressed(optionKey,{type:`vehicle`,vehId:0})};async function handleExit(event){event.detail.force||await Lua_default.extensions.gameplay_missions_missionManager.getCurrentTaskdataTypeOrNil()||(context.value===`ongoingMission`?gotoControl():gotoMenu())}return(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(layoutSingle_default),{class:`mission-details-layout`,onDeactivate:handleExit},{default:withCtx(()=>[createBaseVNode(`div`,_hoisted_1$41,[withDirectives((openBlock(),createElementBlock(`div`,_hoisted_2$32,[createVNode(unref(bngButton_default),{accent:unref(ACCENTS).text,"bng-no-nav":`true`,class:`page-nav`,onClick:_cache[0]||=$event=>navigateToPage(-1)},{default:withCtx(()=>[createVNode(unref(bngIcon_default),{class:`arrow-icon`,type:unref(icons).arrowSmallLeft},null,8,[`type`]),createVNode(unref(bngBinding_default),{"ui-event":`tab_l`,deviceMask:`xinput`,style:normalizeStyle({"--page-nav-icon":`'${unref(icons).arrowSmallLeft.glyph}'`}),class:`page-nav-icon`},null,8,[`style`])]),_:1},8,[`accent`]),createBaseVNode(`div`,_hoisted_3$27,[(openBlock(!0),createElementBlock(Fragment,null,renderList(availablePages.value,page=>(openBlock(),createElementBlock(`span`,{key:page.value,class:normalizeClass([`page`,{"current-page":currentPage.value===page.value}])},[createVNode(unref(bngIcon_default),{type:page.icon,class:`page-icon-button`,onClick:$event=>currentPage.value=page.value},null,8,[`type`,`onClick`])],2))),128))]),createVNode(unref(bngButton_default),{accent:unref(ACCENTS).text,"bng-no-nav":`true`,class:`page-nav`,onClick:_cache[1]||=$event=>navigateToPage(1)},{default:withCtx(()=>[createVNode(unref(bngBinding_default),{"ui-event":`tab_r`,deviceMask:`xinput`,style:normalizeStyle({"--page-nav-icon":`'${unref(icons).arrowSmallRight.glyph}'`}),class:`page-nav-icon`},null,8,[`style`]),createVNode(unref(bngIcon_default),{class:`arrow-icon`,type:unref(icons).arrowSmallRight},null,8,[`type`])]),_:1},8,[`accent`])])),[[unref(BngBlur_default)]]),createBaseVNode(`div`,_hoisted_4$20,[createBaseVNode(`div`,_hoisted_5$18,[unref(context)===`ongoingMission`||showTasks.value?(openBlock(),createBlock(InfoCard_default,{key:0},{header:withCtx(()=>[createVNode(unref(bngCardHeading_default),{type:`ribbon`},{default:withCtx(()=>[..._cache[6]||=[createTextVNode(` Ongoing Challenge `,-1)]]),_:1})]),content:withCtx(()=>[createVNode(TaskList_default,{class:`task-list`,header:unref(tasksStore).header,tasks:unref(tasksStore).tasks},null,8,[`header`,`tasks`])]),button:withCtx(()=>[unref(missionStartableDetails)?(openBlock(),createElementBlock(`div`,_hoisted_6$14,[unref(missionStartableDetails).continueVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:0,accent:unref(ACCENTS).secondary,"icon-right":unref(icons).catalog02,label:`Main Menu`,class:`large`,onClick:handleMainMenu},null,8,[`accent`,`icon-right`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0),recoveryOptions.value.length>0&&!unref(isTutorialEnabled)&&!unref(hideRecoveryOptions)?(openBlock(),createElementBlock(`div`,_hoisted_7$13,[_cache[7]||=createBaseVNode(`div`,{class:`recovery-options-header`},`Recovery Options`,-1),createBaseVNode(`div`,_hoisted_8$9,[(openBlock(!0),createElementBlock(Fragment,null,renderList(recoveryOptions.value,option=>withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:option.key,accent:unref(ACCENTS).secondary,"icon-right":unref(icons)[option.icon],label:option.label,disabled:!option.active||!option.enabled,class:`recovery-option-button`,onClick:$event=>handleRecoveryOption(option.key)},null,8,[`accent`,`icon-right`,`label`,`disabled`,`onClick`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]])),128))])])):createCommentVNode(``,!0),unref(missionStartableDetails).restartVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:2,accent:unref(ACCENTS).secondary,"icon-right":unref(icons).restart,label:`Restart`,disabled:!unref(store$1).customRecoveryOptionsActiveState?.restartMission?.active,class:`large`,onClick:unref(store$1).restartMission},null,8,[`accent`,`icon-right`,`disabled`,`onClick`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0),!unref(hideReconfigureButton)&&!unref(isTutorialEnabled)?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:3,accent:unref(ACCENTS).secondary,"icon-right":unref(icons).adjust,label:`Reconfigure`,class:`large`,onClick:gotoSettings},null,8,[`accent`,`icon-right`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0),unref(missionStartableDetails).abandonVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:4,"icon-right":unref(icons).abandon,accent:unref(ACCENTS).attention,label:`Abandon`,class:`large`,onClick:unref(store$1).abandonMission},null,8,[`icon-right`,`accent`,`onClick`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0),unref(missionStartableDetails).continueVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:5,"bng-scoped-nav-autofocus":``,"icon-right":unref(icons).fastTravel,label:`Continue`,class:`large`,onClick:handleContinue},null,8,[`icon-right`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0),!unref(missionStartableDetails).startableVisible&&!unref(missionStartableDetails).continueVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:6,"icon-right":unref(icons).lockClosed,label:`Locked`,class:`large`,disabled:``},null,8,[`icon-right`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):createCommentVNode(``,!0)])):createCommentVNode(``,!0)]),_:1})):(openBlock(),createBlock(InfoCard_default,{key:1},{header:withCtx(()=>[createVNode(unref(bngCardHeading_default),{type:`ribbon`},{default:withCtx(()=>[..._cache[8]||=[createTextVNode(` Available Challenges `,-1)]]),_:1})]),content:withCtx(()=>[createBaseVNode(`div`,_hoisted_9$7,[(openBlock(!0),createElementBlock(Fragment,null,renderList(unref(missionCards).groupKeys,groupKey=>(openBlock(),createElementBlock(`div`,{key:groupKey,class:`mission-group`},[unref(missionCards).groupsByKey[groupKey].label?(openBlock(),createElementBlock(`div`,_hoisted_10$5,[createBaseVNode(`div`,_hoisted_11$5,toDisplayString(_ctx.$ctx_t(unref(missionCards).groupsByKey[groupKey].label)),1),unref(missionCards).groupsByKey[groupKey].meta.formattedLeague?(openBlock(),createBlock(unref(bngMainStars_default),{key:0,"unlocked-stars":unref(missionCards).groupsByKey[groupKey].meta.formattedLeague.totalStarsObtained,"total-stars":unref(missionCards).groupsByKey[groupKey].meta.formattedLeague.totalStarsAvailable,class:`league-stars`,scale:.6,reverse:``,numerical:``},null,8,[`unlocked-stars`,`total-stars`])):createCommentVNode(``,!0)])):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_12$4,[(openBlock(!0),createElementBlock(Fragment,null,renderList(unref(missionCards).groupsByKey[groupKey].tileIdsUnsorted,id=>withDirectives((openBlock(),createBlock(MissionCard_default,{key:id,"data-mission-id":id,"bng-scoped-nav-autofocus":unref(selectedMission).id===id||!unref(selectedMission).id&&id===unref(missionCards).groupsByKey[groupKey].tileIdsUnsorted[0],mission:unref(missionCards).tilesById[id],class:normalizeClass([{highlighted:unref(selectedMission).id===id},`mission-card`]),onClick:withModifiers($event=>selectMission(id),[`stop`]),onFocusin:$event=>unref(store$1).selectMission(id)},null,8,[`data-mission-id`,`bng-scoped-nav-autofocus`,`mission`,`class`,`onClick`,`onFocusin`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]])),128))])]))),128))])]),button:withCtx(()=>[withDirectives((openBlock(),createBlock(unref(bngButton_default),{accent:unref(ACCENTS).attention,"bng-no-nav":`true`,class:`exit-button`,onClick:handleBack},{default:withCtx(()=>[scopeNavState.missionDetailsActivated?createCommentVNode(``,!0):(openBlock(),createBlock(unref(bngBinding_default),{key:0,"ui-event":`back`,deviceMask:`xinput`})),_cache[9]||=createTextVNode(` Back `,-1)]),_:1},8,[`accent`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}],[unref(BngSoundClass_default),`bng_back_generic`]])]),_:1}))]),withDirectives((openBlock(),createElementBlock(`div`,{class:`current-details-container`,onActivate:_cache[4]||=$event=>onDetailScopeChanged(!0,$event),onDeactivate:_cache[5]||=$event=>onDetailScopeChanged(!1,$event)},[unref(missionBasicInfo)?(openBlock(),createBlock(InfoCard_default,{key:0,onClick:onDetailsClick},{header:withCtx(()=>[createVNode(bngAdvCardHeading_default,{mute:``,divider:``,preheadings:preheadings.value,icon:unref(missionBasicInfo).icon,class:`current-details-header`},{default:withCtx(()=>[createTextVNode(toDisplayString(_ctx.$ctx_t(unref(missionBasicInfo).name)),1)]),_:1},8,[`preheadings`,`icon`]),showMissionInfo.value?(openBlock(),createElementBlock(`div`,_hoisted_13$4,[showOfficialIcon.value?(openBlock(),createBlock(unref(bngIcon_default),{key:0,type:unref(icons).beamNG,class:`official-icon`},null,8,[`type`])):createCommentVNode(``,!0),createTextVNode(` `+toDisplayString(missionInfoString.value),1)])):createCommentVNode(``,!0),unref(scopedNav).isGamepadActive&&scopeNavState.missionDetailsActivated?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:1,accent:unref(ACCENTS).attention,"bng-no-nav":`true`,tabindex:`-1`,class:`details-back-binding`,onClick:_cache[2]||=withModifiers($event=>scopeNavState.missionDetailsActivated=!1,[`stop`])},{default:withCtx(()=>[createVNode(unref(bngIcon_default),{type:unref(icons).arrowSmallLeft},null,8,[`type`]),createVNode(unref(bngBinding_default),{"ui-event":`back`,deviceMask:`xinput`}),createTextVNode(` `+toDisplayString(unref(context)===`ongoingMission`?`Back`:`Return to list`),1)]),_:1},8,[`accent`])),[[unref(BngSoundClass_default),`bng_back_generic`]]):createCommentVNode(``,!0)]),content:withCtx(()=>[createBaseVNode(`div`,_hoisted_14$4,[createBaseVNode(`div`,_hoisted_15$4,[currentPage.value===`info`?(openBlock(),createElementBlock(`div`,_hoisted_16$4,[unref(missionBasicInfo).images?(openBlock(),createBlock(unref(aspectRatio_default),{key:0,class:`details-info-preview`},{default:withCtx(()=>[createVNode(unref(bngImageCarousel_default),{images:unref(missionBasicInfo).images,transition:``,external:``},null,8,[`images`])]),_:1})):createCommentVNode(``,!0),createBaseVNode(`div`,_hoisted_17$3,toDisplayString(_ctx.$ctx_t(unref(missionBasicInfo).description)),1)])):currentPage.value===`settings`?(openBlock(),createElementBlock(Fragment,{key:1},[unref(missionSettings)&&!showTasks.value?(openBlock(),createBlock(MissionSettings_default,{key:0,"no-blur":``})):createCommentVNode(``,!0)],64)):currentPage.value===`leaderboards`?(openBlock(),createElementBlock(Fragment,{key:2},[unref(selectedMission)&&!showTasks.value?(openBlock(),createBlock(MissionLeaderboards_default,{key:0,"no-blur":``})):createCommentVNode(``,!0)],64)):createCommentVNode(``,!0),currentPage.value===`info`||currentPage.value===`settings`?(openBlock(),createElementBlock(`div`,_hoisted_18$3,[unref(missionProgress)?(openBlock(),createBlock(MissionObjectives_default,{key:0,stars:unref(missionProgress).stars,message:unref(missionProgress).message,showMessage:!0,noDisabledObjectives:!0,"no-blur":``,"card-heading-type":`line`},null,8,[`stars`,`message`])):createCommentVNode(``,!0)])):createCommentVNode(``,!0)])])]),button:withCtx(()=>[unref(context)===`ongoingMission`&¤tPage.value===`settings`?(openBlock(),createElementBlock(`div`,_hoisted_19$2,[withDirectives(createVNode(unref(bngButton_default),{accent:unref(ACCENTS).secondary,"icon-right":unref(icons).reconfigure,disabled:unref(sameUserSettingsAsLast),label:`Reconfigure and Restart mission`,class:`large`,onClick:unref(store$1).reconfigureMission},null,8,[`accent`,`icon-right`,`disabled`,`onClick`]),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]])])):unref(context)===`ongoingMission`&¤tPage.value!==`settings`?(openBlock(),createElementBlock(`div`,_hoisted_20$2,toDisplayString(_ctx.$t(`missions.missions.general.challengeCurrentlyInProgress`)),1)):unref(context)===`availableMissions`?(openBlock(),createElementBlock(`div`,_hoisted_21$2,[currentPage.value===`info`&&unref(context)===`availableMissions`&&unref(missionSettings)&&unref(missionSettings).length>0?(openBlock(),createElementBlock(`div`,_hoisted_22$2,[withDirectives(createVNode(MissionSettingsSimple_default,{"mission-settings":unref(missionSettings),noInput:!0,onClick:_cache[3]||=()=>currentPage.value=`settings`},null,8,[`mission-settings`]),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]])])):createCommentVNode(``,!0),unref(missionBasicInfo)&&unref(missionBasicInfo).entryFee?(openBlock(),createElementBlock(`div`,_hoisted_23$2,[_cache[10]||=createBaseVNode(`span`,{class:`label`},`Entry Fee:`,-1),createVNode(RewardsPills_default,{class:`tiny-rewards`,rewards:unref(missionBasicInfo).entryFee},null,8,[`rewards`])])):createCommentVNode(``,!0),unref(missionStartableDetails).needsRepair?(openBlock(),createElementBlock(`div`,_hoisted_24$1,[createVNode(unref(bngSelect_default),{loop:``,options:unref(missionStartableDetails).repairOptions,value:unref(missionStartableDetails).selectedRepairType,config:{label:x=>x.optionsLabel,value:x=>x.type},class:`repair-item-control`,onValueChanged:unref(store$1).changeRepairType},null,8,[`options`,`value`,`config`,`onValueChanged`])])):createCommentVNode(``,!0),unref(missionStartableDetails).needsRepair&&unref(missionStartableDetails).startableVisible?withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:3,"bng-scoped-nav-autofocus":``,"icon-left":unref(icons).wrench,disabled:!unref(missionStartableDetails).startableEnabled,label:unref(missionStartableDetails).selectedRepairTypeLabel,class:`large`,onClick:startMission},null,8,[`icon-left`,`disabled`,`label`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]]):withDirectives((openBlock(),createBlock(unref(bngButton_default),{key:4,"bng-scoped-nav-autofocus":``,disabled:!unref(missionStartableDetails).startableEnabled,label:unref(missionStartableDetails).selectedRepairTypeLabel,class:`large`,onClick:startMission},{default:withCtx(()=>[..._cache[11]||=[createTextVNode(` Start Challenge `,-1)]]),_:1},8,[`disabled`,`label`])),[[unref(BngOnUiNav_default),void 0,`ok`,{asMouse:!0,focusRequired:!0}]])])):createCommentVNode(``,!0)]),_:1})):createCommentVNode(``,!0)],32)),[[unref(BngScopedNav_default),{activated:scopeNavState.missionDetailsActivated,type:`container`}]])])])]),_:1})),[[unref(BngScopedNav_default),{activateOnMount:!0,actionsOnSuspend:[unref(ACTIONS_ON_SUSPEND).allowNavigationLastNavItem]}],[unref(BngOnUiNav_default),()=>navigateToPage(-1),`tab_l`],[unref(BngOnUiNav_default),()=>navigateToPage(1),`tab_r`],[unref(BngOnUiNav_default),gotoControl,`menu`]])}},MissionDetailsNew_default=__plugin_vue_export_helper_default(_sfc_main$49,[[`__scopeId`,`data-v-cacd7a66`]]),routes_default$10=[{path:`/mission`,children:[{path:`details`,name:`mission-details`,component:MissionDetailsNew_default,meta:{infoBar:{visible:!0,showSysInfo:!1,hints:CROSSFIRE_HINTS_ALL},uiApps:{shown:!1}}},{path:`mission-control/:mode(\\*?.*?)?`,name:`mission-control`,component:MissionControl_default,meta:{uiApps:{shown:!1}},infoBar:{visible:!0,showSysInfo:!1,hints:CROSSFIRE_HINTS_ALL},props:!0},{path:`grid`,name:`missions-grid`,component:MissionsGrid_default,meta:{uiApps:{shown:!1}}},{path:`dragHistory/:id(\\*?.*?)?:name?/:level?/`,name:`dragHistory`,component:MissionDragHistory_default,meta:{uiApps:{shown:!1},infoBar:{visible:!0,showSysInfo:!1,hints:CROSSFIRE_HINTS_ALL}},props:!0}]}],_hoisted_1$40=[`innerHTML`],_hoisted_2$31=[`innerHTML`],_hoisted_3$26=[`innerHTML`],_sfc_main$48={__name:`OnlineConsentView`,setup(__props){useUINavScope(`consent`);let settings$1=useSettings(),{lua}=useBridge(),onlineFeaturesData=ref({}),telemetryData=ref({}),confirmationData=ref({}),parseDescription=descKey=>parse$1($translate.instant(descKey)),onlineFeaturesHtml=computed(()=>parseDescription(`ui.mainmenu.onlineFeatures.featureDescription`)),telemetryDescription=computed(()=>parseDescription(onlineFeaturesData.value.choice===`enable`?`ui.mainmenu.telemetry.featureDescription`:`ui.mainmenu.telemetryOnlineHint`)),confirmationHtml=computed(()=>parseDescription(`ui.mainmenu.privacyPolicyHint`)),onStepComplete=({stepId,data})=>{stepId===`onlineFeatures`&&(telemetryData.value=data.choice===`enable`?{}:{choice:`disable`})},onFinish=async()=>{try{let settingsToApply={};onlineFeaturesData.value.choice&&(settingsToApply.onlineFeatures=onlineFeaturesData.value.choice),telemetryData.value.choice&&(settingsToApply.telemetry=telemetryData.value.choice),await settings$1.apply(settingsToApply),settingsToApply.telemetry===`enable`?console.log(`Starting telemetry...`):settingsToApply.telemetry===`disable`&&console.log(`Unloading telemetry...`),backToMenu()}catch(error){console.error(`Error applying consent settings:`,error)}},backToMenu=()=>window.bngVue.gotoAngularState(`menu.mainmenu`);return onMounted(async()=>{await settings$1.waitForData();let onlineFeatures=settings$1.values.onlineFeatures;onlineFeatures&&onlineFeatures!==`ask`&&(onlineFeaturesData.value={choice:onlineFeatures});let telemetry=settings$1.values.telemetry;telemetry&&telemetry!==`ask`&&(telemetryData.value={choice:telemetry})}),(_ctx,_cache)=>withDirectives((openBlock(),createBlock(unref(WizardView_default),{title:`ui.mainmenu.onlineFeatures.featureTitle`,preheadings:[`Privacy & Features`],style:{"--wizard-height":`45rem`},"bng-ui-scope":`consent`,onStepComplete,onWizardFinish:onFinish},{default:withCtx(()=>[createVNode(unref(WizardStep_default),{id:`onlineFeatures`,title:`ui.options.onlineFeatures`,type:`choice`,modelValue:onlineFeaturesData.value,"onUpdate:modelValue":_cache[0]||=$event=>onlineFeaturesData.value=$event,choices:[{value:`disable`,label:`ui.common.no`,isNo:!0},{value:`enable`,label:`ui.common.yes`,isYes:!0}]},{description:withCtx(()=>[createBaseVNode(`div`,{innerHTML:onlineFeaturesHtml.value},null,8,_hoisted_1$40)]),_:1},8,[`modelValue`]),createVNode(unref(WizardStep_default),{id:`telemetry`,title:`ui.options.telemetry`,type:`choice`,modelValue:telemetryData.value,"onUpdate:modelValue":_cache[1]||=$event=>telemetryData.value=$event,"auto-skip":!0,"enabled-when":[{step:`onlineFeatures`,value:`enable`}],choices:[{value:`disable`,label:`ui.common.no`,isNo:!0},{value:`enable`,label:`ui.common.yes`,isYes:!0}]},{description:withCtx(()=>[createBaseVNode(`div`,{innerHTML:telemetryDescription.value},null,8,_hoisted_2$31)]),_:1},8,[`modelValue`]),createVNode(unref(WizardStep_default),{id:`confirmation`,title:`ui.consent.confirmation`,type:`confirmation`,modelValue:confirmationData.value,"onUpdate:modelValue":_cache[2]||=$event=>confirmationData.value=$event},{description:withCtx(()=>[createBaseVNode(`div`,{innerHTML:confirmationHtml.value},null,8,_hoisted_3$26)]),default:withCtx(()=>[createVNode(unref(WizardSummary_default))]),_:1},8,[`modelValue`])]),_:1})),[[unref(BngBlur_default)],[unref(BngOnUiNav_default),backToMenu,`menu,back`]])}},OnlineConsentView_default=_sfc_main$48,routes_default$11=[{path:`/online-consent`,name:`menu.onlineFeatures`,component:OnlineConsentView_default,meta:{infoBar:{visible:!0,showSysInfo:!0},uiApps:{shown:!1}}}],_sfc_main$47={__name:`CategoryTop`,props:{index:Number,hasSubcategories:Boolean,icon:String,selected:Boolean,disabled:Boolean,hiddenByCondition:Boolean,debugSettings:Boolean},emits:[`click`],setup(__props,{emit:__emit}){let emit$1=__emit;return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,{class:normalizeClass({"options-category":!0,selected:__props.selected,"has-subcategories":__props.hasSubcategories,"hidden-by-condition":__props.hiddenByCondition})},[createVNode(unref(bngButton_default),{class:normalizeClass({"options-category-button":!0,selected:__props.selected,"no-hover":__props.selected}),accent:unref(ACCENTS).custom,icon:__props.icon||`_empty`,disabled:__props.disabled,"bng-no-nav":``,onClick:_cache[0]||=$event=>emit$1(`click`)},{default:withCtx(()=>[createVNode(unref(textScroller_default),null,{default:withCtx(()=>[createTextVNode(toDisplayString(__props.debugSettings?`🐞`:``),1),renderSlot(_ctx.$slots,`default`,{},void 0,!0)]),_:3})]),_:3},8,[`class`,`accent`,`icon`,`disabled`])],2))}},CategoryTop_default=__plugin_vue_export_helper_default(_sfc_main$47,[[`__scopeId`,`data-v-7d90db8f`]]),_hoisted_1$39={key:0,class:`subcategory-svg-icon`},_hoisted_2$30={key:1,class:`subcategory-deco`},_sfc_main$46={__name:`CategorySide`,props:{index:Number,hasSubcategories:Boolean,subcategory:String,icon:String,selected:Boolean,editable:Boolean,disabled:Boolean,hiddenByCondition:Boolean,debugSettings:Boolean},emits:[`click`,`focus`,`edit-cmd`],setup(__props,{emit:__emit}){let canEdit,EditUI=null,EditFloater=computed(()=>null?.value?.EditFloater),emit$1=__emit,emitEdit=(event,...args)=>void 0;return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,{class:normalizeClass({"options-category":!0,editable:__props.editable,selected:__props.selected,subcategory:__props.subcategory,[`subcategory-${__props.subcategory}`]:__props.subcategory,"has-subcategories":__props.hasSubcategories,"hidden-by-condition":__props.hiddenByCondition})},[__props.hasSubcategories?(openBlock(),createElementBlock(`div`,_hoisted_1$39,[..._cache[2]||=[createBaseVNode(`svg`,{width:`100%`,height:`100%`,viewBox:`0 0 24 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},[createBaseVNode(`path`,{d:`M3 12C3 10.8954 3.89543 10 5 10C6.10457 10 7 10.8954 7 12C7 13.1046 6.10457 14 5 14C3.89543 14 3 13.1046 3 12Z`,fill:`var(--bng-off-white)`}),createBaseVNode(`path`,{d:`M10 12C10 10.8954 10.8954 10 12 10C13.1046 10 14 10.8954 14 12C14 13.1046 13.1046 14 12 14C10.8954 14 10 13.1046 10 12Z`,fill:`var(--bng-off-white)`}),createBaseVNode(`path`,{d:`M17 12C17 10.8954 17.8954 10 19 10C20.1046 10 21 10.8954 21 12C21 13.1046 20.1046 14 19 14C17.8954 14 17 13.1046 17 12Z`,fill:`var(--bng-off-white)`})],-1)]])):createCommentVNode(``,!0),__props.subcategory&&__props.subcategory!==`none`?(openBlock(),createElementBlock(`div`,_hoisted_2$30)):createCommentVNode(``,!0),createVNode(unref(bngButton_default),{class:normalizeClass({"options-category-button":!0,selected:__props.selected,"no-hover":__props.selected}),accent:unref(ACCENTS).custom,icon:__props.icon||`_empty`,disabled:__props.disabled,onClick:_cache[0]||=$event=>emit$1(`click`),onFocus:_cache[1]||=$event=>emit$1(`focus`)},{default:withCtx(()=>[createTextVNode(toDisplayString(__props.debugSettings?`🐞`:``),1),renderSlot(_ctx.$slots,`default`,{},void 0,!0)]),_:3},8,[`class`,`accent`,`icon`,`disabled`]),unref(void 0)&&__props.editable?(openBlock(),createBlock(resolveDynamicComponent(EditFloater.value),{key:2,class:`options-edit`,"no-menu":``,onEmitEditCmd:emitEdit},null,32)):createCommentVNode(``,!0)],2))}},CategorySide_default=__plugin_vue_export_helper_default(_sfc_main$46,[[`__scopeId`,`data-v-2403a7c6`]]),_hoisted_1$38={class:`options-settings-list`},_hoisted_2$29={class:`options-settings-list-header`},_hoisted_3$25={class:`options-settings-list-items`},_hoisted_4$19=[`onClick`],_sfc_main$45={__name:`SettingsList`,setup(__props){let settingsList=inject(`settingsList`),goToSetting=inject(`goToSetting`),settingsMode=reactive({assigned:!0,unassigned:!1}),search$1=ref(``),settingsListView=computed(()=>{if(!settingsMode.assigned&&!settingsMode.unassigned)return[];let res=Object.entries(settingsList.value).map(([name,setting])=>({name,...setting})).sort((a$1,b)=>a$1.name.localeCompare(b.name));return(!settingsMode.assigned||!settingsMode.unassigned)&&(res=res.filter(setting=>setting.assigned===settingsMode.assigned)),search$1.value&&(res=res.filter(setting=>setting.name.toLowerCase().includes(search$1.value.toLowerCase()))),res});return(_ctx,_cache)=>(openBlock(),createElementBlock(`div`,_hoisted_1$38,[createBaseVNode(`div`,_hoisted_2$29,[createBaseVNode(`div`,null,[(openBlock(!0),createElementBlock(Fragment,null,renderList(settingsMode,(val,name)=>(openBlock(),createBlock(unref(bngPillCheckbox_default),{key:name,modelValue:settingsMode[name],"onUpdate:modelValue":$event=>settingsMode[name]=$event},{default:withCtx(()=>[createTextVNode(toDisplayString(name),1)]),_:2},1032,[`modelValue`,`onUpdate:modelValue`]))),128))]),createVNode(unref(bngInput_default),{modelValue:search$1.value,"onUpdate:modelValue":_cache[0]||=$event=>search$1.value=$event,"floating-label":`Search`,"leading-icon":unref(icons).search},null,8,[`modelValue`,`leading-icon`])]),withDirectives((openBlock(),createElementBlock(`div`,_hoisted_3$25,[(openBlock(!0),createElementBlock(Fragment,null,renderList(settingsListView.value,setting=>(openBlock(),createElementBlock(`div`,{class:`options-settings-list-item`,key:setting.name},[createBaseVNode(`div`,null,toDisplayString(setting.name),1),createBaseVNode(`div`,null,[(openBlock(!0),createElementBlock(Fragment,null,renderList(setting.assignedIn,(cat,index)=>(openBlock(),createElementBlock(Fragment,{key:index},[index>0?(openBlock(),createElementBlock(Fragment,{key:0},[createTextVNode(`, `)],64)):createCommentVNode(``,!0),createBaseVNode(`span`,{class:`options-goto`,onClick:$event=>unref(goToSetting)(cat[1],cat[2])},toDisplayString(_ctx.$tt(cat[0])),9,_hoisted_4$19)],64))),128))])]))),128))])),[[unref(BngUiNavScroll_default),void 0,void 0,{force:!0}]])]))}},SettingsList_default=__plugin_vue_export_helper_default(_sfc_main$45,[[`__scopeId`,`data-v-f1159da1`]]),_hoisted_1$37={class:`options-licenses-text`},_hoisted_2$28={class:`options-licenses-text`},file=`licenses.txt`,_sfc_main$44={__name:`Licenses`,setup(__props){let licenses=ref([]);return onMounted(async()=>{try{let resp=await getFile(getURL(`/${file}`));try{let lines=(resp||``).split(` `);if(lines.length<=1)throw Error(`No lines`);let res=[],cur={label:``,text:``};for(let line of lines)line=line.trimEnd(),line.startsWith(`===`)?line.charAt(4)!==`=`&&(cur={label:line.substring(3),text:``},res.push(cur)):cur.text+=line+`
@/lua/ge/extensions/ui/topBar.lua
      for _, substate in pairs(item.substates) do
        if string.sub(M.state.currentUIState, 1, #substate) == substate then
          M.state.activeItem = item.id
  -- -- remove leading slash from state
  -- if type(state) == "string" and string.sub(state, 1, 1) == "/" then
  --   state = string.sub(state, 2)
  -- if type(state) == "string" and string.sub(state, 1, 1) == "/" then
  --   state = string.sub(state, 2)
  -- end
  -- -- TODO: popup check is a hack for now. maybe we can check popup state from lua instead
  -- if not opened or M.state.currentUIState == state or (type(state) == "string" and string.sub(state, 1, 5) == "popup") then
  --   return
@/lua/ge/extensions/editor/materialEditor.lua
            local filepath = currentMaterial:getField(k, i)
            if tmp ~= "" and string.sub(filepath, 1, 1) ~= '/' then
              filepath = "/"..filepath
@/lua/ge/extensions/util/docCreator.lua
    if out.pidvid then
      out.pid = out.pidvid:sub(1, 4)
      out.vid = out.pidvid:sub(5, 8)
      out.pid = out.pidvid:sub(1, 4)
      out.vid = out.pidvid:sub(5, 8)
    end
      if info.vendorName then
        if string.lower(string.sub(name, 1, string.len(info.vendorName))) == string.lower(info.vendorName) then
          name = string.sub(name, string.len(info.vendorName) + 1)
        if string.lower(string.sub(name, 1, string.len(info.vendorName))) == string.lower(info.vendorName) then
          name = string.sub(name, string.len(info.vendorName) + 1)
          name = name:gsub("^%s+", "") -- strip whitespaces
@/lua/ge/extensions/ui/uiNavi.lua
    if minimapImage:startswith("/") then
      minimapImage = minimapImage:sub(2)
    end
@/lua/ge/extensions/gameplay/drift/saveLoad.lua
      local dir, _, _ = path.split(file)
      local spotId = level .."/".. string.sub(dir, #levelSpotsDir+1, -2)
      -- main data
@/lua/common/jit/v.lua
      local oidx = 6 * info
      info = sub(vmdef.bcnames, oidx+1, oidx+6)
    end
@/gameplay/missionTypes/busMode/constructor.lua
  if hex:len() == 3 then
    return {(tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255, 1}
  else
  if hex:len() == 3 then
    return {(tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255, 1}
  else
  if hex:len() == 3 then
    return {(tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255, 1}
  else
  else
    return {tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255, 1}
  end
  else
    return {tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255, 1}
  end
  else
    return {tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255, 1}
  end
@/lua/ge/extensions/editor/preferences.lua
  if string.len(defVal) > 100 then
    defVal = string.sub(defVal, 1, 100) .. "..."
  end
@/lua/ge/extensions/career/modules/inventory.lua
    local dir, filename, ext = path.split(files[i])
    local fileNameNoExt = string.sub(filename, 1, -6)
    local inventoryId = tonumber(fileNameNoExt)
@/lua/vehicle/extensions/inputAnalyzer.lua
      if inputLength >= is.stringLength then
        local subStr = inputString:sub(inputLength - is.stringLength + 1)
        if subStr == is.string then
    if inputLength > 16 then
      inputString = inputString:sub(2)
    end
@/lua/common/libs/luasec/ssl.lua
      local len = str:byte(i)
      array[#array + 1] = str:sub(i + 1, i + len)
      i = i + len + 1
@/lua/common/libs/LuLPeg/lulpeg.lua
local function patt_error (s, i)
  local msg = (#s < i + 20) and s:sub(i)
                             or s:sub(i,i+20) .. "..."
  local msg = (#s < i + 20) and s:sub(i)
                             or s:sub(i,i+20) .. "..."
  msg = ("pattern error near '%s'"):format(msg)
  local e = #c + i
  if s:sub(i, e - 1) == c then return e else return nil end
end
@/lua/common/utils/pixellib.lua
  for i = 1, string.len(text) do
    local c = string.sub(text, i, i)
    if c == ' ' then
        for dx = 1, string.len(cl[dy]) do
          local cf = string.sub(cl[dy], dx, dx)
          if cf ~= ' ' then
@/flowgraphEditor/Tower/customNodes/towerNode.lua
    local _, fn, ext = path.split(room.file, true)
    local name = generateObjectNameForClass('Prefab', string.format("%s - %d - ", string.sub(fn, 1, string.len(fn) - string.len(ext)-1), i))
    local scenetreeObject = spawnPrefab(name , self.mgr.savedDir .. room.file, "0 0 0", "0 0 1 0", "1 1 1", false)
@/lua/common/jsonDebug.lua
    local infend = si + 6
    if sub(s, si, infend) == "1#INF00" then
      return math.huge, infend + 1
      local pm = byte(s, si - 1)
      jsonError(string.format("Invalid number: '%s'", sub(s, si - ((pm == 45 or pm == 43) and 1 or 0), infend)), si)
    end
    end
    r = tonumber(sub(s, si, i - 1))
    if r == nil then
      local pm = byte(s, si - 1)
      jsonError(string.format("Invalid number: '%s'", sub(s, si - ((pm == 45 or pm == 43) and 1 or 0), i-1)), si)
    end
  if ch == 34 then -- "
    return sub(s, si1, i - 2), i
  end
    i = i - 1
    key = sub(s, si, i)
@/lua/common/jsonPrettyEncoderCustom.lua
  -- collapse anything below bindings that has less than 4 items
  return path:sub(1,10) == '/bindings/' and tableSize(item) < 4
end
@/lua/ge/extensions/scenario/scenarios.lua
    for _, wp in ipairs(scenario.lapConfig) do
      if wp:sub(1,12) ~= '__generated_' then -- only process non-generated WPs
        if scenario.nodes[wp] == nil then
      if type(entry) == 'string' then
        if not tableContains(triggers, entry) and not tableContains(waypoints, entry) and entry:sub(1,12) ~= '__generated_' then
          log('E', logTag, 'Lapconfig entry is Invalid! It should be either a Trigger or Waypoint: '..entry)
@/lua/ge/extensions/editor/api/dynamicDecals.lua
    local rdnNumber = math.random(1, #randomStringChars)
    res = res .. string.sub(randomStringChars, rdnNumber, rdnNumber)
  end
    local _, filename, extension = path.split(layerData.decalColorTexturePath)
    colorMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
  elseif layerData.type == M.layerTypes.textureFill then
    if filename ~= "" then
      colorMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
    end
    if filename ~= "" then
      normalMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
    end
    if filename ~= "" then
      metallicMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
    end
    if filename ~= "" then
      roughnessMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
    end
    if filename ~= "" then
      alphaMapTextureString = string.sub(filename, 1, #filename - (#extension + 1))
    end
@/lua/ge/extensions/gameplay/missions/missions.lua
    while string.endswith(missionData.description, "\n") do
      missionData.description = string.sub(missionData.description, 1, -2)
    end
  --dump(missionId)
  missionId = string.sub(missionDir, #missionsDir+1)
  missionData.id = missionId
      local missionDir, _, _ = path.split(missionInfo)
      missionDir = string.sub(missionDir,0,-2)
      local missionData = loadMission(missionDir)
  for _, file in ipairs(files) do
    local gen = require(file:sub(0,-5))
    gen.generate = gen.generate or nop
@/lua/ge/extensions/editor/flowgraph/examples.lua
      local dirname, fn, e = path.splitWithoutExt(filename, true)
      local path = dirname:sub(string.len(stateTemplatePath) + 1)
        local moduleName = fn
        --local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
        local lectionData = {}
      if not pos2 then
        im.Text(label:sub(pos1))
        break
      elseif pos1 < pos2 then
        im.Text(label:sub(pos1, pos2 - 1))
        im.SameLine()
      local pos3 = pos2 + highlightLowerLen
      im.TextColored(matchColor, label:sub(pos2, pos3))
      im.SameLine()
@/lua/ge/extensions/editor/assetManagementTool.lua

  if string.sub(path, 1, size) == newPathNotSetString then
    return false
  for hash, asset in pairs(assetsByHash) do
    if string.sub(asset.targetPath, 1, size) == newPathNotSetString then
      return false
@/lua/vehicle/controller/vehicleController/shiftLogic/dctGearbox.lua
    modePrefix = "S"
  elseif string.sub(automaticHandling.mode, 1, 1) == "M" then
    modePrefix = "M"
  local manualModeIndex
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  end
    if string.find(automaticHandling.mode, "M") then
      local gearIndex = tonumber(string.sub(automaticHandling.mode, 2))
      gearRatio = gearbox.gearRatios[gearIndex]
    if string.find(automaticHandling.mode, "M") then
      local gearIndex = tonumber(string.sub(automaticHandling.mode, 2))
      gearRatio = gearbox.gearRatios[gearIndex]

  local isManualMode = string.sub(automaticHandling.mode, 1, 1) == "M"
  --enforce things like L and M modes
  for i = 1, modeCount do
    local mode = modes:sub(i, i)
    if automaticHandling.availableModeLookup[mode] then
@/lua/ge/extensions/freeroam/bigMapMode.lua
  if not mission then
    mission = gameplay_missions_missions.getMissionById(string.sub(missionId, 1, -3))
  end
@/lua/ge/extensions/util/compileMeshes.lua
        local src = f
        local dst = dir1 .. filename:sub(1, -4) .. 'cdae'
        local dstData = '' -- dir1 .. filename:sub(1, -4) .. 'meshes.json' -- do not use this feature for now
        local dst = dir1 .. filename:sub(1, -4) .. 'cdae'
        local dstData = '' -- dir1 .. filename:sub(1, -4) .. 'meshes.json' -- do not use this feature for now
        local cacheFilename = nil
@/lua/vehicle/controller/drivingDynamics/actuators/electronicSplitShaftLock.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/editor/tech/roadArchitect/utilities.lua
  if lastSeparator then
    return path:sub(1, lastSeparator)
  end
@/lua/vehicle/controller/vehicleController/shiftLogic/electricMotor.lua
  for i = 1, modeCount do
    local mode = modes:sub(i, i)
    if automaticHandling.availableModeLookup[mode] then
@/lua/vehicle/controller/propAnimation/dualAxisLever.lua
local function handleMSModes(desiredMode)
  local firstLetter = desiredMode:sub(1, 1)
  if firstLetter == "S" then
  elseif firstLetter == "M" then
    local gearIndex = desiredMode:sub(2, desiredMode:len())
    desiredMode = "M"
      --get the base this mode relates to
      local modeBaseName = impulseMode.modeName:sub(1, modeNameLength - 1)
      --we need to actually have the base mode for this to work
@/lua/common/libs/lua-luaepnf/epnf.lua
local string, io = assert( string ), assert( io )
local V = string.sub( assert( _VERSION ), -4 )
local _G = assert( _G )
  for i = 1, p do
    if string.sub( s, i, i ) == "\n" then
      lno = lno + 1
  for i = sol, #s do
    if string.sub( s, i, i ) == "\n" then
      eol = i - 1
  end
  return string.sub( s, sol, eol ), lno, sol
end
  if #line > clen then
    line = string.sub( line, 1, clen ) .. "..."
  end
    local _,lno = string.gsub( s, "\n", "\n" )
    if string.sub( s, -1, -1 ) ~= "\n" then lno = lno + 1 end
    local msg = ": parse error at "
function epnf.parsestring( g, str, ... )
  local s = string.sub( str, 1, 20 )
  if #s < #str then s = s .. "..." end
@/lua/vehicle/controller/gauges/genericGauges.lua
  for k, v in pairs(jbeamData) do
    if k:sub(1, #"configuration_") == "configuration_" then
      tableMergeRecursive(configData, v)
@/lua/vehicle/powertrain.lua
        local _, file, _ = path.split(filePath)
        local fileName = file:sub(1, -5)
        if not factoryBlackList[fileName] then
        local v = deviceJbeamData[device.name][k]
        if k:sub(1, 12) == "deformGroups" then --check for magic prefix
          local delim = "_" --underscore is used as the delim (eg "deformGroups_turbo")
@/lua/ge/extensions/core/input/actions.lua
    if string.startswith(actionName, prefix) then
      actionName = string.sub(actionName, 1+string.len(prefix))
    else
@/lua/ge/extensions/editor/vizHelper.lua
  for k, v in ipairs(vizHelper) do
    vizHelper[k] = string.sub(v, string.len(artPath) + 1)
  end
@/lua/vehicle/protocols.lua
    local filename = filepath:match("[^/]*.lua$")
    local name = filename:sub(0, #filename - 4)
    local enabled = false
@/lua/ge/extensions/scenario/quickRaceLoader.lua
  --   local _, fn, e = path.split(file)
  --   local name = fn:sub(1,#fn - #e - 1)
  --   local read = jsonReadFile(name)
      local _, fn, e = path.split(file)
      editorTracks[i] = fn:sub(1,#fn - #e - 1)
  end
@/lua/ge/server/server.lua
  local levelDir = path.dirname(levelPath)
  if string.sub(levelDir, -1) ~= '/' then
    levelDir = levelDir.."/"
@/lua/ge/extensions/campaign/campaignsLoader.lua
  campaign.previews = {
    imageExistsDefault(campaign.sourcePath..'/'..campaign.sourcePath:sub(index)..'.jpg')
  }
@/lua/common/jbeam/sections/meshs.lua
    return ColorF(v.r / 255, v.g / 255, v.b / 255, v.a / 255)
  elseif type(v) == 'string' and string.len(v) > 7 and v:sub(1,1) == '#' then
    v = v:gsub("#","")
    v = v:gsub("#","")
    return ColorF(tonumber("0x"..v:sub(1,2)) / 255, tonumber("0x"..v:sub(3,4)) / 255, tonumber("0x"..v:sub(5,6)) / 255, tonumber("0x"..v:sub(7,8)) / 255)
  end
    v = v:gsub("#","")
    return ColorF(tonumber("0x"..v:sub(1,2)) / 255, tonumber("0x"..v:sub(3,4)) / 255, tonumber("0x"..v:sub(5,6)) / 255, tonumber("0x"..v:sub(7,8)) / 255)
  end
    v = v:gsub("#","")
    return ColorF(tonumber("0x"..v:sub(1,2)) / 255, tonumber("0x"..v:sub(3,4)) / 255, tonumber("0x"..v:sub(5,6)) / 255, tonumber("0x"..v:sub(7,8)) / 255)
  end
    v = v:gsub("#","")
    return ColorF(tonumber("0x"..v:sub(1,2)) / 255, tonumber("0x"..v:sub(3,4)) / 255, tonumber("0x"..v:sub(5,6)) / 255, tonumber("0x"..v:sub(7,8)) / 255)
  end
@/lua/common/utils.lua
    return color(v.r, v.g, v.b, v.a)
  elseif type(v) == 'string' and string.len(v) > 7 and v:sub(1,1) == '#' then
    v = v:gsub("#","")
    v = v:gsub("#","")
    return color(tonumber("0x"..v:sub(1,2)), tonumber("0x"..v:sub(3,4)), tonumber("0x"..v:sub(5,6)), tonumber("0x"..v:sub(7,8)))
  elseif v == nil then
    v = v:gsub("#","")
    return color(tonumber("0x"..v:sub(1,2)), tonumber("0x"..v:sub(3,4)), tonumber("0x"..v:sub(5,6)), tonumber("0x"..v:sub(7,8)))
  elseif v == nil then
    v = v:gsub("#","")
    return color(tonumber("0x"..v:sub(1,2)), tonumber("0x"..v:sub(3,4)), tonumber("0x"..v:sub(5,6)), tonumber("0x"..v:sub(7,8)))
  elseif v == nil then
    v = v:gsub("#","")
    return color(tonumber("0x"..v:sub(1,2)), tonumber("0x"..v:sub(3,4)), tonumber("0x"..v:sub(5,6)), tonumber("0x"..v:sub(7,8)))
  elseif v == nil then
function string.startswith(String,Start)
  return string.sub(String,1,string.len(Start))==Start
end
function string.endswith(String,End)
  return End=='' or string.sub(String,-string.len(End))==End
end
  local result = str:gsub("([A-Z])", " %1")
  return string.upper(result:sub(1, 1)) .. result:sub(2)
end
  local result = str:gsub("([A-Z])", " %1")
  return string.upper(result:sub(1, 1)) .. result:sub(2)
end
  for k, expectedType in ipairs(expectedTypes) do
    local isOptional = expectedType:sub(0,9) == "optional:"
    local sanitizedExpectedType = isOptional and expectedType:sub(10, #expectedType) or expectedType
    local isOptional = expectedType:sub(0,9) == "optional:"
    local sanitizedExpectedType = isOptional and expectedType:sub(10, #expectedType) or expectedType
    local actualType = type(data[k])
  while true do
    if filename == "" or string.sub(filename, -1) == "/" then
      break
    end
    filename = string.sub(filename, 1, -2)
  end
  for _, lvlPath in ipairs(FS:findFiles('/levels/', '*', 0, false, true)) do
    table.insert(ret, string.lower(lvlPath:sub(9)))
  end
    if string.len(line) > 0 then
      local firstChar = string.sub(line, 1, 1)
      if firstChar ~= '#' and firstChar ~= ';' and firstChar ~= '/' then
@/inspector/External/three.js/three.js

                console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
                return this.subVectors( v, w );

                console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
                return this.subVectors( v, w );

                return this.sub( v1 );

                return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );

                console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
                return this.subVectors( v, w );

                this.min.copy( center ).sub( halfSize );
                this.max.copy( center ).add( halfSize );

            this.min.sub( vector );
            this.max.add( vector );
                var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
                return clampedPoint.sub( point ).length();

                target.sub( this.center ).normalize();
                target.multiplyScalar( this.radius ).add( this.center );

            this.direction.copy( v ).sub( this.origin ).normalize();
                segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
                segDir.copy( v1 ).sub( v0 ).normalize();
                diff.copy( this.origin ).sub( segCenter );
                segDir.copy( v1 ).sub( v0 ).normalize();
                diff.copy( this.origin ).sub( segCenter );
                    vector3.setFromMatrixPosition( light.target.matrixWorld );
                    uniforms.direction.sub( vector3 );
                    uniforms.direction.transformDirection( viewMatrix );
                    vector3.setFromMatrixPosition( light.target.matrixWorld );
                    uniforms.direction.sub( vector3 );
                    uniforms.direction.transformDirection( viewMatrix );

            var vec = pt2.clone().sub( pt1 );
            return vec.normalize();

            point.copy( this.v2 ).sub( this.v1 );
            point.multiplyScalar( t ).add( this.v1 );

        var tangent = this.v2.clone().sub( this.v1 );

            point.copy( this.v2 ).sub( this.v1 );
            point.multiplyScalar( t ).add( this.v1 );
                this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
                this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
                var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
                this.min.copy( center ).sub( halfSize );
                this.max.copy( center ).add( halfSize );

            this.min.sub( vector );
            this.max.add( vector );
                var clampedPoint = v1.copy( point ).clamp( this.min, this.max );
                return clampedPoint.sub( point ).length();

            this.cone.lookAt( vector2.sub( vector ) );
@/lua/vehicle/energyStorage.lua
        local _, fileNameWithExt, _ = path.split(file)
        local fileName = fileNameWithExt:sub(1, -5)
        local storageFactoryPath = "energyStorage/" .. fileName
@/lua/common/extensions/ui/imgui_custom_luaintf.lua
        if not pos2 then
          M.Text(label:sub(pos1))
          break
        elseif pos1 < pos2 then
          M.Text(label:sub(pos1, pos2 - 1))
          M.SameLine()
        local pos3 = pos2 + highlightLowerLen
        M.TextColored(matchColor, label:sub(pos2, pos3))
        M.SameLine()
@/lua/ge/extensions/editor/barriersEditor.lua
      local scenetreeObject = spawnPrefab("prefab_temp_" .. filename ..os.time(), f, "0 0 0 ", "0 0 1", "1 1 1")
      local short = f:sub(levelPartLength)
      local dirInLevel, _,_ = path.splitWithoutExt(short)
@/lua/ge/extensions/editor/undoHistory.lua
  for s in actionData:gmatch("[^\n]+") do
    table.insert(lines, s:sub(1, toolTipMaxWidth)) -- limit width
  end
@/lua/ge/extensions/core/quickAccess.lua
  end
  if string.sub(args.level, string.len(args.level)) ~= '/' then args.level = args.level .. '/' end -- make sure there is always a trailing slash in the level
@/lua/common/csvlib.lua
    for i = 1, headercount do
      header[i] = #header[i] > 0 and tostring(header[i]):sub(1, 1) or "_"
    end
  filename = filename or self.headernym or format
  if filename:sub(-4, -4) ~= '.' then
    filename = string.format("%s_%s.%s", filename, os.date("%Y-%m-%dT%H_%M_%S"), format)
      until (c == 34 and byte(s, i+1) ~= 34) or c == nil -- "
      val = sub(s, si+1, i - 1):gsub('""', '"')
      repeat i=i+1; c = byte(s,i) until c~=32 and c~=9 -- space tab
      end
      val = sub(s, si, i - 1)
      if testnum then val = tonumber(val) or val end
@/lua/ge/extensions/editor/roadNetworkExporter.lua
            local filename = data.filepath
            extensions.tech_openDriveExporter.export(filename:sub(1, -(#".xodr" + 1)))
            exportedFilename = FS:virtual2Native(filename)
            local filename = data.filepath
            extensions.tech_openStreetMapExporter.export(filename:sub(1, -(#".osm" + 1)))
            osmExportedFilename = FS:virtual2Native(filename)
            sumo_filename = filename
            extensions.tech_sumoExporter.export(sumo_filename:sub(1, -(#".xml" + 1)))
            sumoExportedFilename = FS:virtual2Native(sumo_filename)
@/lua/common/jbeam/expressionParser.lua
  __index = function(tbl, key)
    local val = varWrapper.vars['$' .. key:sub(5)]
    if type(val) == "table" then return val.val else return val end
  --strip leading "$=" from expression and replace all occurences of "$" with "_" (as these are used for lua variable names)
  expr = expr:sub(3):gsub('%$', 'var_')
  --strip leading "$=" from expression and replace all occurences of "$" with "_" (as these are used for lua variable names)
  expr = expr:sub(3):gsub('%$', 'var_')
    __index = function(tbl, key)
      local val = varWrapper.vars['$' .. key:sub(5)]
      if type(val) == "table" then return val.val else return val end
  --strip leading "$=" from expression and replace all occurences of "$" with "_" (as these are used for lua variable names)
  expr = expr:sub(3):gsub('%$', 'var_')
@/lua/ge/extensions/editor/flowgraph/main.lua
          }}
          local fn =self.mgr.savedDir.. self.mgr.savedFilename:sub(0,-10)..'json'
          jsonWriteFile(fn, scenarioJson, true, 20)
                  local nodeData = readFile('/lua/ge/extensions/flowgraph/newNodeTemplate.lua')
                  nodeData = nodeData:gsub("New Node Template", data.filename:sub(1,-5)) -- change name
                  data.filepath = data.filepath:gsub(".lua","Node.lua") -- add Node for customNodes system
@/lua/ge/extensions/util/export.lua
local function _isTextureCookerFilepath(filepath)
  if not string.sub(filepath, -4) == ".png" then return false end
  return string.match(filepath, "%.color%.png$") or string.match(filepath, "%.normal%.png$") or string.match(filepath, "%.data%.png$")
  if not FS:fileExists(filepath) then
    if filepath:sub(1, 1) == '@' then
      local filepathIn = filepath
    elseif _isTextureCookerFilepath(filepath) then
      filepath = string.sub(filepath, 1, -5) .. ".dds"
    else
  local dir, filename, ext = path.splitWithoutExt(filepath)
  if filename:endswith(".dds") then filename = filename:sub(1, -5) end
@/lua/ge/extensions/editor/assemblySpline/import.lua
  for _, anchorName in ipairs(obj:getAnchorNames()) do -- Check if any anchor points have the nail prefix.
    if anchorName:sub(1, 5) == anchorPrefixStr .. '.' then
      return true
@/lua/ge/extensions/editor/particleEditor.lua
    if particleDataName then
      stringList = stringList:sub(last+1)
      local particleData = scenetree.findObject(particleDataName)
    if particleDataName then
      stringList = stringList:sub(last+1)
    else
  local first, last, _ = string.find(particles, "(" .. particle:getName() .. ")")
  local newParticles = string.sub(particles, 1, first-1)
  newParticles = newParticles .. string.sub(particles, last+1)
  local newParticles = string.sub(particles, 1, first-1)
  newParticles = newParticles .. string.sub(particles, last+1)
  newParticles = cleanTabs(newParticles)
@/lua/ge/extensions/core/flowgraphManager.lua
local function reInitOnFileChange(filename)
  local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
  log("I","flowgraphManager","Reloading Node: " .. tostring(requireFilename))
  -- check basic nodes
  if filename:sub(1, string.len(nodePath)) == nodePath then
    reInitOnFileChange(filename)
  -- check custom nodes
  if filename:sub(string.len(filename)-7,string.len(filename)) == 'Node.lua' then
    for _,manager in ipairs(managers) do
      local dirname, fn, e = path.split(filename)
      local path = dirname:sub(string.len(nodePath) + 1)
      local pathArgs = split(path, '/')
      end
      local moduleName = string.sub(fn, 1, string.len(fn) - 4)
      local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
      local moduleName = string.sub(fn, 1, string.len(fn) - 4)
      local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
      local dirname, fn, e = path.splitWithoutExt(filename, true)
      local path = dirname:sub(string.len(stateTemplatePath) + 1)
      if path ~= "" then
        local moduleName = fn
        --local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
        local stateData = {}
@/lua/ge/extensions/gameplay/rally/notebook/structured/textCompositor.lua
    -- separate digits if not a multiple of rounding threshold
    distStr = distStr:sub(1, 1) .. " " .. distStr:sub(2)
  end
    -- separate digits if not a multiple of rounding threshold
    distStr = distStr:sub(1, 1) .. " " .. distStr:sub(2)
  end
@/lua/common/json-ast.lua
  while true do
    c = ctx.str:sub(ctx.pos, ctx.pos)
    if c ~= chr or not c or c == '' then
  while true do
    c = ctx.str:sub(ctx.pos, ctx.pos)
    ctx.pos = ctx.pos + 1
  }
  if num_str:sub(1, 1) == '+' then
    node.prefixPlus = true
  end
  node.addPostfixDot = num_str:sub(num_len, num_len) == '.'
  _addNode(ctx, node)
  while true do
    c = ctx.str:sub(ctx.pos, ctx.pos)
    ctx.pos = ctx.pos + 1
    end
    local nextChar = ctx.str:sub(ctx.pos, ctx.pos)
    if c == '\n' then
  while true do
    c = ctx.str:sub(ctx.pos, ctx.pos)
    ctx.pos = ctx.pos + 1
    end
    if c == '*' and ctx.str:sub(ctx.pos, ctx.pos) == '/' then
      ctx.pos = ctx.pos + 1

    local chr = ctx.str:sub(ctx.pos, ctx.pos)
    local posSaved = ctx.pos
      ctx.pos = ctx.pos + 1
    elseif chr == 't' and ctx.str:sub(ctx.pos, ctx.pos + 3) == 'true' then
      _addNode(ctx, {'bool', true})
      ctx.pos = ctx.pos + 4
    elseif chr == 'f' and ctx.str:sub(ctx.pos, ctx.pos + 4) == 'false' then
      _addNode(ctx, {'bool', false})
      ctx.pos = ctx.pos + 1
    elseif chr == '\r' and ctx.str:sub(ctx.pos + 1, ctx.pos + 1) == '\n' then
      _addNode(ctx, {'newline_windows'})
      ctx.pos = ctx.pos + 1
    elseif chr == '/' and ctx.str:sub(ctx.pos + 1, ctx.pos + 1) == '/' then
      _parse_comment(ctx)
      _parse_comment(ctx)
    elseif chr == '/' and ctx.str:sub(ctx.pos + 1, ctx.pos + 1) == '*' then
      _parse_comment_multiline(ctx)
@/lua/vehicle/controller/drivingDynamics/actuators/electronicDiffLock.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/editor/util/editorElementHelper.lua
        if key ~= "fieldName" and string.startswith(key, "fieldName") then
          table.insert(ret, {label = string.sub(key, 10), fieldName = elem[key], elemLabel = elem.label})
        end
@/lua/ge/extensions/editor/flowgraph/search.lua
    if not pos2 then
      im.Text(label:sub(pos1))
      break
    elseif pos1 < pos2 then
      im.Text(label:sub(pos1, pos2 - 1))
      im.SameLine()
    local pos3 = pos2 + highlightLowerLen
    im.TextColored(matchColor, label:sub(pos2, pos3))
    im.SameLine()
    if match:find(t..": ") ~= nil then
      return t, string.sub(match, #t+3)
    end
    if match:find(t..":") ~= nil then
      return t, string.sub(match, #t+2)
    end
@/ui/ui-vue/src/modules/mainmenu/routes.js
  { // this state is used to display top/info-bar in menus
    path: "/menu.:sub(.*)?",
    name: "menu",
@/lua/ge/extensions/flowgraph/nodes/ui/multiDescription.lua
    if txt:len() > 10 then
      im.Text(txt:sub(1,10).."...")
    else
@/lua/common/jbeam/loader.lua
  -- the directory needs a leading and trailing slash
  if vehicleDir:sub(1, 1) ~= '/' then
    vehicleDir = '/' .. vehicleDir
  end
  if vehicleDir:sub(-1, -1) ~= '/' then
    vehicleDir = vehicleDir .. '/'
@/lua/vehicle/main.lua
  if j then
    local m = _G[string.sub(funName, 1, j - 1)]
    if type(m) == "table" then
    if type(m) == "table" then
      f = m[string.sub(funName, j + 1)]
    end
@/lua/ge/extensions/career/branches.lua
  local infoDir, _, _ = path.split(filePath)
  branch.dir = string.sub(infoDir, 1, -1)  -- Remove trailing '/'
  branch.id = ""
  local folders = {'domains'}
  for folder in string.gmatch(string.sub(infoDir, #branchesDir, -2), "[^/]+") do
      table.insert(folders, folder)
  local folders = {'domains'}
  for folder in string.gmatch(string.sub(infoDir, #branchesDir, -2), "[^/]+") do
      table.insert(folders, folder)
@/lua/common/libs/luasocket/socket/url.lua
local function absolute_path(base_path, relative_path)
    if string.sub(relative_path, 1, 1) == "/" then return relative_path end
    local path = string.gsub(base_path, "[^/]*$", "")
    end
    if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
    if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
    if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
    if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
    return parsed
@/lua/ge/extensions/core/vehicles.lua
    if dir and filename and ext and string.lower(ext) == "pc" then
      local pcfn = filename:sub(1, #filename - 3)
      res.configs[pcfn] = { Configuration = pcfn}
    for _, filename in ipairs(jfiles) do
      if string.lower(filename:sub(-18)) == '.paintlibrary.json' then
        table.insert(filesPaints, filename)
        table.insert(filesPaints, filename)
      elseif string.lower(filename:sub(-5)) == '.json' then
        table.insert(filesJson, filename)
        table.insert(filesJson, filename)
      elseif string.lower(filename:sub(-3)) == '.pc' then
        table.insert(filesPC, filename)
        table.insert(filesPC, filename)
      elseif string.lower(filename:sub(-4)) == '.png' or string.lower(filename:sub(-4)) == '.jpg' then
        filesImages[filename] = true
        table.insert(filesPC, filename)
      elseif string.lower(filename:sub(-4)) == '.png' or string.lower(filename:sub(-4)) == '.jpg' then
        filesImages[filename] = true
    for _, filename in ipairs(jfiles) do
      if string.lower(filename:sub(-18)) == '.paintlibrary.json' then
        table.insert(filesPaints, filename)
        table.insert(filesAll, filename)
      elseif string.lower(filename:sub(-5)) == '.json' then
        table.insert(filesJson, filename)
        table.insert(filesAll, filename)
      elseif string.lower(filename:sub(-3)) == '.pc' then
        table.insert(filesPC, filename)
        table.insert(filesAll, filename)
      elseif string.lower(filename:sub(-4)) == '.png' or string.lower(filename:sub(-4)) == '.jpg' then
        filesImages[filename] = true
        table.insert(filesAll, filename)
      elseif string.lower(filename:sub(-4)) == '.png' or string.lower(filename:sub(-4)) == '.jpg' then
        filesImages[filename] = true
  local vehicleDirectory = path or '/vehicles/' .. model .. '/'
  if string.sub(vehicleDirectory, -1) ~= '/' then vehicleDirectory = vehicleDirectory .. '/' end
  local res = FS:findFiles(vehicleDirectory, '*.jbeam', -1, false, false) -- recursive search
    return 'BeamNG - Official'
  elseif string.sub(path, -3) == '.pc' then
    return 'Custom'
    local fLower = string.lower(filename)
    if string.sub(fLower, -5) == '.json'
    or string.sub(fLower, -6) == '.jbeam'
    if string.sub(fLower, -5) == '.json'
    or string.sub(fLower, -6) == '.jbeam'
    or string.sub(fLower, -3) == '.pc'
    or string.sub(fLower, -6) == '.jbeam'
    or string.sub(fLower, -3) == '.pc'
    or string.sub(fLower, -4) == '.jpg'
    or string.sub(fLower, -3) == '.pc'
    or string.sub(fLower, -4) == '.jpg'
    or string.sub(fLower, -4) == '.png' then
    or string.sub(fLower, -4) == '.jpg'
    or string.sub(fLower, -4) == '.png' then
      anyCacheFileModified = true
@/lua/ge/extensions/core/environment.lua
    if string.len(k) > 31 then
      local newk = string.sub(k, 1, 30)
      log('E', 'ge.environment.reloadGroundModels', 'Ground model name too long: "' .. tostring(k) .. '" is longer than the supported 31 characters. It will be cut to "' .. tostring(newk) .. '")')
@/lua/ge/extensions/editor/assetDeduplicator.lua
          local e = ext:lower()
          if e:sub(1,1) ~= "." then e = "." .. e end
          extBlacklist[e] = true
            local spath = stockMatches[i]
            if spath:sub(1, #currentLevelRoot) ~= currentLevelRoot then
              filtered[#filtered + 1] = spath
            local spath = modMatches[i]
            if spath:sub(1, #currentLevelRoot) ~= currentLevelRoot then
              filtered[#filtered + 1] = spath
@/lua/vehicle/controller/gauges/analogOdometer.lua
  for k, v in pairs(jbeamData) do
    if k:sub(1, #"configuration_") == "configuration_" then
      tableMergeRecursive(configData, v)
@/lua/vehicle/controller/vehicleController/shiftLogic/cvtGearbox.lua
  local manualModeIndex
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  if string.sub(automaticHandling.mode, 1, 1) == "M" then
    manualModeIndex = string.sub(automaticHandling.mode, 2)
  end
  for i = 1, modeCount do
    local mode = modes:sub(i, i)
    if automaticHandling.availableModeLookup[mode] then
@/lua/common/json.lua
    local infend = si + 6
    if sub(s, si, infend) == "1#INF00" then
      return math.huge, infend + 1
      local pm = byte(s, si - 1)
      jsonError(string.format("Invalid number: '%s'", sub(s, si - ((pm == 45 or pm == 43) and 1 or 0), infend)), si)
    end
    end
    r = tonumber(sub(s, si, i - 1))
    if r == nil then
      local pm = byte(s, si - 1)
      jsonError(string.format("Invalid number: '%s'", sub(s, si - ((pm == 45 or pm == 43) and 1 or 0), i-1)), si)
    end
  if ch == 34 then -- "
    return sub(s, si1, i - 2), i
  end
    i = i - 1
    key = sub(s, si, i)
@/lua/vehicle/controller.lua
  for _, v in pairs(loadedControllers) do
    if v.typeName:sub(1, #path) == path then
      table.insert(controllers, v)
@/lua/ge/extensions/gameplay/missions/missionScreen.lua
  local previewFile = m.previewFile
  if previewFile:sub(1, 1) == "/" then
      previewFile = previewFile:sub(2)
  if previewFile:sub(1, 1) == "/" then
      previewFile = previewFile:sub(2)
  end
@/lua/ge/extensions/career/modules/playerAttributes.lua
    if attributeName:endswith("Reputation") then
      local orgId = attributeName:sub(1, -11)
      career_career.interactWithOrganization(orgId)
@/lua/vehicle/extensions/tech/CANBus/ProjectBavariaKombi.lua

  local state = gearStateLookup[string.sub(electrics.values.gear or "", 1, 1)] or 0
  if electrics.values.ignitionLevel <= 0 then
@/lua/vehicle/extensions/tech/CANBus/ProjectBavariaShifter.lua
local function applyInputs(leverState, parkButtonState)
  local gear = string.sub(electrics.values.gear or "", 1, 1)
local function updateHardwareState(dt)
  local state = gearStateLookup[string.sub(electrics.values.gear or "", 1, 1)] or 0
  if electrics.values.ignitionLevel <= 0 then
@/lua/ge/extensions/core/levels.lua
  if levelPath:find('main.level.json') and not FS:fileExists(levelPath) then
    local newName = levelPath:sub(0, levelPath:find('main.level.json') - 1)
    if FS:directoryExists(newName) then
@/lua/ge/extensions/editor/scriptAIManager.lua

          local fn_short = string.sub(filename, string.len(trackFilePath) + 1)
          fn_short = string.sub(fn_short, 1, string.len(fn_short) - string.len(trackFileExt))
          local fn_short = string.sub(filename, string.len(trackFilePath) + 1)
          fn_short = string.sub(fn_short, 1, string.len(fn_short) - string.len(trackFileExt))
          if im.Button(fn_short) then
@/lua/ge/extensions/editor/decalEditor.lua
  local _, _, ext = path.split(fileName)
  local fileNameNoExt = string.sub(fileName, 1, -(ext:len() + 1))
  if not FS:fileExists(fileNameNoExt .. "png") and not FS:fileExists(fileNameNoExt .. "dds") then
@/lua/ge/extensions/career/saveSystem.lua
    else
      local newPath = string.sub(folders[i], oldNameLength + 2)
      newPath = newName .. newPath
@/lua/ge/extensions/flowgraph/nodes/input/blacklistAction.lua
    if not pos2 then
      im.Text(label:sub(pos1))
      break
    elseif pos1 < pos2 then
      im.Text(label:sub(pos1, pos2 - 1))
      im.SameLine()
    local pos3 = pos2 + highlightLowerLen
    im.TextColored(matchColor, label:sub(pos2, pos3))
    im.SameLine()
@/lua/ge/extensions/flowgraph/nodes/activity/activityFlow.lua
  im.Text("Activity: "..(self.mgr.activity and "yes" or "no"))
  im.TextColored(self.mgr.activity and colorEnabled or colorDisabled, self.mgr.activity and ("..."..self.mgr.activity.id:sub(-15)) or "(standalone)")
end
@/lua/ge/extensions/editor/fileDialog.lua
  fileCache = {}
  if currentPath:sub(1,1) ~= "/" then currentPath = "/" .. currentPath end
  if currentPath:sub(-1) ~= "/" then currentPath = currentPath.."/" end
  if currentPath:sub(1,1) ~= "/" then currentPath = "/" .. currentPath end
  if currentPath:sub(-1) ~= "/" then currentPath = currentPath.."/" end
  currentPath = currentPath:gsub("/+", "/")   -- Reducing multiple slashes to avoid trimmed list names
    local s = FS:stat(fn)
    s.name = string.sub(fn, pathLen)
    s.name = string.gsub(s.name, "/(.*)", "%1") -- strip leading /
        if lastSep then
          parentFolder = currentPath:sub(1, currentPath:len()-lastSep+1 )
        end
@/lua/ge/extensions/flowgraph/nodes/types/string.lua
    if #self.string > 10 then
      im.Text(self.string:sub(1,10).. "...")
    else
@/lua/ge/extensions/flowgraph/nodes/string/format.lua
    if txt:len() > 16 then
      im.Text(txt:sub(1,16).."...")
    else
@/lua/common/libs/lua-websockets/websocket/client_ev.lua
            end
          until response:sub(#response-3) == '\r\n\r\n'
          read_io:stop(loop)
@/lua/ge/extensions/ui/liveryEditor/userData.lua
  local _, fn, e = path.split(file)
  return fn:sub(1, #fn - #dynDecalsExtension)
end
@/lua/ge/extensions/editor/dynamicDecals/brushes.lua
    local dir, fileName, fileExt = path.split(decalColorTexturePath)
    name = string.sub(fileName, 1, #fileName - (#fileExt + 1))
  end
@/lua/common/libs/StackTracePlus/StackTracePlus.lua
  --print("guessing function name")
  if type(info.source) == "string" and info.source:sub(1,1) == "@" then
    local file, err = io_open(info.source:sub(2), "r")
  if type(info.source) == "string" and info.source:sub(1,1) == "@" then
    local file, err = io_open(info.source:sub(2), "r")
    if not file then
      if _M.max_string_output_len > 0 and stringlen > _M.max_string_output_len then
        self:add_f("%s%s = string[%d/%d]: %q (more...)\n", prefix, name, _M.max_string_output_len, stringlen, string.sub(tostring(value), 1, _M.max_string_output_len))
      else
        local source = info.source
        if source:sub(2,7) == "string" then
          source = source:sub(9)    -- uno m�s, por el espacio que viene (string "Baragent.Main", por ejemplo)
        if source:sub(2,7) == "string" then
          source = source:sub(9)    -- uno m�s, por el espacio que viene (string "Baragent.Main", por ejemplo)
        end
      local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name
      if source:sub(2, 7) == "string" then
        source = source:sub(9)
      if source:sub(2, 7) == "string" then
        source = source:sub(9)
      end
      local function_type = (info.namewhat == "") and "function" or info.namewhat
      if info.source and info.source:sub(1, 1) == "@" then
        dumper:add_f("\n(%d) %s:%d %s (%s)", level_to_show, info.source:sub(2), info.currentline, function_name, function_type)
      if info.source and info.source:sub(1, 1) == "@" then
        dumper:add_f("\n(%d) %s:%d %s (%s)", level_to_show, info.source:sub(2), info.currentline, function_name, function_type)
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("\n(%d) %s:%d %s (%s)", level_to_show, info.source:sub(2), info.currentline, function_name, function_type)
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("\n(%d) Lua %s '%s' at template '%s:%d'%s", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("\n(%d) Lua %s '%s' at template '%s:%d'%s", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      else
      else
        dumper:add_f("\n(%d) %s:%d: %s", level_to_show, source:sub(2, -3), info.currentline, function_name)
      end
      local function_name = m_user_known_functions[info.func] or m_known_functions[info.func] or info.name
      if source:sub(2, 7) == "string" then
        source = source:sub(9)
      if source:sub(2, 7) == "string" then
        source = source:sub(9)
      end
      local function_type = (info.namewhat == "") and "function" or info.namewhat
      if info.source and info.source:sub(1, 1) == "@" then
        dumper:add_f("(%d) Lua %s '%s' at file '%s:%d'%s\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      if info.source and info.source:sub(1, 1) == "@" then
        dumper:add_f("(%d) Lua %s '%s' at file '%s:%d'%s\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("(%d) Lua %s '%s' at file '%s:%d'%s\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("(%d) Lua %s '%s' at template '%s:%d'%s\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      elseif info.source and info.source:sub(1,1) == '#' then
        dumper:add_f("(%d) Lua %s '%s' at template '%s:%d'%s\n", level_to_show, function_type, function_name, info.source:sub(2), info.currentline, was_guessed and " (best guess)" or "")
      else
@/lua/vehicle/controller/lineLock.lua
  end
  wheelNamesString = wheelNamesString:sub(0, wheelNamesString:len() - 2)
@/lua/ge/extensions/telemetry/core.lua
    -- Validate event name format: must start with lowercase and be camelCase
    local firstChar = event.name:sub(1, 1)
    if firstChar:upper() == firstChar then
@/lua/ge/extensions/editor/resourceChecker.lua
                                    local stringend = ", "
                                    txtstring = string.sub(txtstring, 1, #txtstring - #stringend)
                                  end
@/lua/ge/extensions/editor/perfProfiler.lua
  local dir, fn, ext = path.split(file, true)
  fn = fn:sub(0,fn:len()-ext:len()-1)
@/lua/ge/extensions/freeroam/facilities/fuelPrice.lua
        for i=1, #v2.displayObjects  do
          local char = priceStr:sub(i, i)
          -- force 9/10 in US signs
@/inspector/Views/Layers3DContentView.js
        let delta = new THREE.Vector3;
        this._boundingBox.clampPoint(this._controls.target, delta).setZ(0).sub(this._controls.target);
        this._controls.target.add(delta);
@/lua/ge/extensions/editor/dynamicDecals/history.lua
  for s in actionData:gmatch("[^\n]+") do
    table.insert(lines, s:sub(1, toolTipMaxWidth)) -- limit width
  end
@/lua/common/jbeam/tableSchema.lua
      -- is it a node material?
      if valuePart:sub(1,3) == "NM_" then
        ival = particles.getMaterialIDByName(materials, valuePart:sub(4))
      if valuePart:sub(1,3) == "NM_" then
        ival = particles.getMaterialIDByName(materials, valuePart:sub(4))
        --log('D', "jbeam.replaceSpecialValues", "replaced "..valuePart.." with "..ival)
@/lua/vehicle/electricsCustomValueParser.lua
  --   --   --if it's not in either table, it's forbidden and we abort parsing
  --   s = s:sub(1, (s:find("%.") or (s:len() + 1)) - 1)
  --   if not (customElectricsEnv[s] or keyworkdWhiteListLookup[s]) then
@/lua/ge/extensions/gameplay/sites/sitesManager.lua
    local _, siteName = path.split(site)
    if name == string.sub(siteName, 0, -12) then
      return site
@/lua/ge/extensions/gameplay/rally/util.lua
  local str = hashStringSHA1(s)
  return str:sub(1, 16)
end

  if thepath:sub(-1) == "/" then
    thepath = thepath:sub(1, -2)
  if thepath:sub(-1) == "/" then
    thepath = thepath:sub(1, -2)
  end

  if dirname:sub(-1) == "/" then
    dirname = dirname:sub(1, -2)
  if dirname:sub(-1) == "/" then
    dirname = dirname:sub(1, -2)
  end
  local hash = hashStringSHA1(randomStr)
  return string.sub(hash, 1, 8)
end
@/lua/ge/extensions/scenario/busdriver.lua
  if hex:len() == 3 then
    return (tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255
  else
  if hex:len() == 3 then
    return (tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255
  else
  if hex:len() == 3 then
    return (tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255
  else
  else
    return tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255
  end
  else
    return tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255
  end
  else
    return tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255
  end
@/lua/ge/extensions/tech/utils.lua
  else
    local _,level,_ = path.split(path.split(levelPath):sub(1, -2))
    M.level = level
@/lua/ge/extensions/editor/missionEditor/conditions.lua
  for _, file in ipairs(files) do
    local aConds = require(file:sub(0,-5))
    for key, value in pairs(aConds) do
@/lua/ge/extensions/editor/sidewalkSpline/kit.lua
    local anchorName = anchorNames[i]
    if anchorName:sub(1, 9) == anchorPrefixStrWithDot then
      table.clear(tmpParts) -- Clear the reusable table.
@/lua/common/libs/xlsxlib/xlsxlib.lua
  for i = 1, #col do
    local char = col:sub(i, i):byte()
    if char < 65 or char > 90 then
@/lua/ge/extensions/util/inputSystemUtils.lua
  -- collapse anything below bindings that has less than 4 items
  return path:sub(1,10) == '/bindings/' and tableSize(item) < 4
end
        info.vidpid = filename:upper()
        vendorId = filename:upper():sub(5, 8)
      else
      else
        vendorId = info.vidpid:upper():sub(5, 8)
      end
@/lua/common/libs/slaxml/slaxml.lua
    if first>textStart and self._call.text then
      local text = sub(xml,textStart,first-1)
      if options.stripWhitespace then
@/lua/ge/extensions/tech/techCore.lua
      sourceFile = fgMgr.savedDir .. name .. '.json'
      if string.sub(sourceFile, 1, 1) ~= '/' then
        sourceFile = '/' .. sourceFile
@/lua/ge/extensions/util/nodeBeamExport.lua
  local dir = vdata.vehicleDirectory
  if string.sub(dir, -1) ~= '/' then dir = dir .. '/' end
@/lua/ge/extensions/trackbuilder/trackBuilder.lua
  for _, file in pairs(FS:findFiles(materialSettings.directory, "*.dds", -1, true, false)) do
    local fileWithoutExtension = string.sub(file, 1, string.len(file) - 4)
    local textureType = string.sub(fileWithoutExtension, string.len(fileWithoutExtension) - 1, string.len(fileWithoutExtension))
    local fileWithoutExtension = string.sub(file, 1, string.len(file) - 4)
    local textureType = string.sub(fileWithoutExtension, string.len(fileWithoutExtension) - 1, string.len(fileWithoutExtension))
    local path = {}
    local path = {}
    for str in string.gmatch(string.sub(fileWithoutExtension, 1, string.len(fileWithoutExtension) - 2), "([^'/']+)") do
      table.insert( path, str )
   else -- glow map
      local texType = string.sub(fileWithoutExtension, string.len(fileWithoutExtension) - 4, string.len(fileWithoutExtension))
      if texType == "decal" then
        local path = {}
        for str in string.gmatch(string.sub(fileWithoutExtension, 1, string.len(fileWithoutExtension) - 6), "([^'/']+)") do
          table.insert( path, str )
  if editor.uiIconImageButton(editor.icons.undo, im.ImVec2(16,16), style.buttonColorBase, nil, nil, "resetMaterialButton") then
    local materialLetter = string.sub(materials.matNames[materialSettings.selectedMaterial[0]+1],14,14)
    tb.materialUtil.resetMaterialsToDefault(materialLetter)
    local mat = tb.getPieceInfo(index, sub).materialInfo.centerMesh or 'track_editor_A_center'
    mat = string.sub(mat, 0, 15)
    materialSettings.selectedMaterial[0] = indexOf(materials.matNames,mat)-1
    local mat = tb.getIntersection(name).centerMat or 'track_editor_A_center'
    mat = string.sub(mat, 0, 15)
    materialSettings.selectedMaterial[0] = indexOf(materials.matNames,mat)-1
@/lua/ge/extensions/flowgraph/manager.lua
    -- TODO: clear up hack with filepaths (issue when loading a FG as a mission)
    local path = dirname:sub(string.len(customNodePath) + string.find(dirname, customNodePath, 1, true))
    local pathArgs = split(path, '/')
    end
    local moduleName = string.sub(fn, 1, string.len(fn) - 4)
    local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
    local moduleName = string.sub(fn, 1, string.len(fn) - 4)
    local requireFilename = string.sub(filename, 1, string.len(filename) - 4)
    local status, node = pcall(rerequire, requireFilename)
@/lua/common/libs/luasocket/ltn12.lua
        return function()
            local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1)
            i = i + _M.BLOCKSIZE
@/lua/ge/extensions/editor/dynamicDecals/fonts.lua
    local dir, filename, ext = path.split(file)
    local fontName = string.sub(filename, 1, #filename - #fontAtlasJsonExtension)
    local success = false
    local path, filename, ext = path.split(fontPath)
    local fontName = string.sub(filename, 1, #filename - (#ext + 1))
    if not tableContains(generatedFontAtlases, fontName) then
@/lua/ge/extensions/editor/api/valueInspector.lua
  elseif fieldTypeName == "TypeCommand" then
    if imgui.Button(fieldValue:sub(1,20)) then
      editor.newTextEditorInstance(self.selectedIds, fieldName)
@/lua/vehicle/controller/drivingDynamics/actuators/activeDiffBias.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/ge_utils.lua
function replace_char(pos, str, r)
  return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
function replace_char(pos, str, r)
  return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
function isPlayerVehConfig(vpath)
  local osSep = package.config:sub(1,1)
  if not shipping_build and FS:getGamePath() == FS:getUserPath() then return false end --make sure you don't delete official config
    local k = math.random(1, sl)
    res = res .. string.sub(ascii, k, k)
  end
@/lua/vehicle/controller/drivingDynamics/actuators/activeDiffLock.lua
  if slashPos then
    nameString = nameString:sub(slashPos + 1)
  end
@/lua/ge/extensions/flowgraph/nodes/util/closestRoad.lua
    if index == 1 then
      local short = string.sub(name,length+1,string.len(name))
      local underscoreIndex = string.find(short,"_")
      if underscoreIndex and underscoreIndex >= 0 then
        local rdId = tonumber(string.sub(short,1,underscoreIndex-1))
        if not idId then
        if not idId then
          local obj = scenetree.findObject(string.sub(short,1,underscoreIndex-1))
          if obj then
        end
        local rdIdx = tonumber(string.sub(short,underscoreIndex+1,string.len(short)))
        return rdId, rdIdx
@/lua/ge/extensions/util/richPresence.lua
    M.state.levelName = M.state.levelName:gsub("_", " ")
    M.state.levelName = string.gsub(" "..M.state.levelName, "%W%l", string.upper):sub(2)
    msgFormat()
@/lua/ge/extensions/editor/engineAudioDebug.lua
        local dataString = jsonEncodePretty(data)
        dataString = dataString:sub(3, dataString:len() - 2)
        setClipboard(dataString)
@/lua/ge/extensions/editor/terrainMaterialsEditor.lua
  if im.InputText("##MaterialNameInput", terrainMtlCopyProxy.nameInput, nil, im.flags(im.InputTextFlags_CharsNoBlank)) then
    local firstChar = tonumber(string.sub(ffi.string(terrainMtlCopyProxy.nameInput), 1, 1))
    if firstChar and type(firstChar) == "number" then
@/lua/common/lpack.lua
    end
    r = tonumber(sub(s, seridx + 1, i - 1))
  end
  seridx = strs + strlen
  return sub(s, strs, seridx-1), byte(s, seridx), seridx
end
@/lua/ge/extensions/editor/dataBlockEditor.lua
      resultTable[name] = {}
      stringList = stringList:sub(last+1)
    else
@/lua/common/libs/lua-websockets/websocket/tools.lua
  for j=1,#msg,64 do
    local chunk = msg:sub(j,j+63)
    assert(#chunk==64,#chunk)
@/lua/common/libs/luasec/options.lua
  for k, option in ipairs(options) do
    local name = string.lower(string.sub(option, 8))
    print(string.format([[#if defined(%s)]], option))
@/lua/ge/extensions/flowgraph/states.lua
    for k, func in pairs(node) do
      if string.sub(k, 1, 2) == 'on' and type(func) == 'function' then
        self.hookExists[k] = true
@/lua/vehicle/controller/vehicleController/vehicleController.lua
  local vehicleSpeed = electrics.values.wheelspeed or 0
  local speedLimit = (type(gearName) == "string" and gearName:sub(1, 1) == "R") and topSpeedLimitReverse or topSpeedLimit
  if speedLimit > 0 then
@/lua/common/extensions.lua
      local s = d.source
      if s:sub(1,1) == '@' then s = s:sub(2) end
      if not s:find(extPath) and s ~= 'lua/ge/extensions/core/jobsystem.lua' and s ~= 'lua/common/luaCore.lua' and s ~= '=[C]' then
      local s = d.source
      if s:sub(1,1) == '@' then s = s:sub(2) end
      if not s:find(extPath) and s ~= 'lua/ge/extensions/core/jobsystem.lua' and s ~= 'lua/common/luaCore.lua' and s ~= '=[C]' then
      extPath = extName
      if string.sub(extPath, 1, 1) == '/' then -- strip leading '/' if present
        extPath = string.gsub(extPath, "/(.*)", "%1")

  if string.sub(extPath, 1, 1) == '/' then
    extPath = string.gsub(extPath, "/(.*)", "%1") -- strip leading '/' if present
  for _,luaFilename in pairs(luaFiles) do
    load(luaFilename:sub(1,-5))  -- strip '.lua'
  end
      -- without it, vehicle extensions like custom_input would come out as custom/input which is wrong
      loadAtRoot(file:sub(1,-5), "")
    end
          -- grab specified root
          root = string.sub(extName, 1, string.find(extName, "_") - 1)
        end
    for k, func in pairs(m) do
      if string.sub(k, 1, 2) == 'on' and type(func) == 'function' then
        if not hookLists[k] then hookLists[k] = {} end
@/lua/ge/extensions/editor/gen/mesh.lua
--			lo('?? for_INST:'..tostring(k.parent.attr.name))
		local s = string.sub(k.attr.url,2)
		if dgeo[s] then
--				U.dump(k.attr,'?? for_ATTR:'..tostring(k.attr.semantic))
			dsem[k.attr['source']:sub(2)] = k.attr.semantic
		end
--			lo('?? kid_name:'..i..':'..tostring(k.name)..':'..tostring(k.attr.semantic))
			dsem[k.attr['source']:sub(2)] = k.attr.semantic
		end