Fresh start: replace with naxIO/netfox-cs-sample foundation

Complete replacement of the tactical-shooter project with the
netfox-cs-sample (MIT) — a CS 1.6 inspired multiplayer FPS built
with Godot 4 and netfox.

## What's new
- Full CS-style gameplay: teams (T/CT), rounds, economy, buy menu
- 6 weapons: Knife, Glock, USP, AK-47, M4A1, AWP
- Bomb plant/defuse with 2 bombsites
- Flashbang & smoke grenades
- Proper netfox rollback netcode at 64 tick
- Network popup UI for host/join
- HUD, crosshair, round timer, scoreboard
- All netfox singletons registered as autoloads (works in exported builds)

## Architecture
- Listen-server (host from client, no dedicated server binary)
- Multiplayer-fps game lives at examples/multiplayer-fps/
- Netfox addons registered as autoloads for exported build compat
- Godot 4.7 with Forward+ renderer

## Removed
- Old headless-server architecture (client_main, server_main, player.gd, etc.)
- Custom netfox bootstrap with ENet fallback
- Old ChaffGames FPS template (2,420 lines, 844 KB)
- SimulationServer GDExtension stub
- Godot-jolt physics (netfox sample uses default Godot physics)
- Duplicate weapon_data.gd, anti_cheat.gd, round_manager.gd, etc.
- Server browser API Python venv (87 MB)
- test_range map and modular assets

## Preserved
- Git history
- Server config at config/default_server_config.cfg
- Windows export preset
- Build directory (gitignored)

Co-authored-by: naxIO <naxIO@users.noreply.github.com>
This commit is contained in:
2026-07-02 20:55:20 -04:00
parent ce39b237c3
commit b0c83af092
4416 changed files with 57418 additions and 902676 deletions
+18
View File
@@ -0,0 +1,18 @@
Copyright 2025 Gálffy Tamás
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+100
View File
@@ -0,0 +1,100 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/gather-suite-mixin.gd
extends "res://addons/vest/test/vest-test-base.gd"
# Automatically gathers tests defined in the test class
func _get_ignored_methods() -> Array[String]:
return [
"get_suite_name",
"before_suite", "before_case", "before_benchmark", "before_each",
"after_suite", "after_case", "after_benchmark", "after_each"
]
func _get_suite_name() -> String:
# Check if callback is implemented
if has_method("get_suite_name"):
return call("get_suite_name")
# Check if class_name is set
var script := get_script() as Script
var pattern := RegEx.create_from_string("class_name\\s+([^\n\\s]+)")
var hit := pattern.search(script.source_code)
if hit:
return hit.get_string(1)
# Fall back to script path
return script.resource_path
func _get_suite() -> VestDefs.Suite:
var script := get_script() as Script
var ignored_methods := _get_ignored_methods()
var inherited_methods := (script.get_base_script()
.get_script_method_list()
.map(func(it): return it["name"])
)
var methods := (script.get_script_method_list()
.filter(func(it): return not it["name"].begins_with("_"))
.filter(func(it): return not inherited_methods.has(it["name"]))
.filter(func(it): return not ignored_methods.has(it["name"]))
)
var define_methods: Array[Dictionary] = []
var case_methods: Array[Dictionary] = []
var parametric_methods: Array[Dictionary] = []
for method in methods:
if method["name"].begins_with("suite"):
define_methods.append(method)
elif method["name"].begins_with("test") and not method["default_args"].is_empty() and method["default_args"][0] is String:
parametric_methods.append(method)
elif method["name"].begins_with("test"):
case_methods.append(method)
return await define(_get_suite_name(), func():
for method in define_methods:
await call(method["name"])
for method in case_methods:
var method_name := method["name"] as String
var test_name := method_name.trim_prefix("test").trim_suffix("__only").capitalize()
var callback := func(): await call(method["name"])
var is_only := _is_only(method_name)
test(test_name, callback, is_only, method_name)
for method in parametric_methods:
var method_name := method["name"] as String
var test_name := method_name.trim_prefix("test").trim_suffix("__only").capitalize()
var is_only := _is_only(method_name)
var param_provider_name := method["default_args"][0] as String
if not has_method(param_provider_name):
push_warning(
"Can't run parametrized test \"%s\", provider method \"%s\" is missing!" % \
[method["name"], param_provider_name]
)
var params = await call(param_provider_name)
if not params is Array or not params.all(func(it): return it is Array):
push_warning(
"Can't run parametrized test \"%s\", provider \"%s\" didn't return array or arrays: %s" % \
[method["name"], param_provider_name, params]
)
for i in range(params.size()):
test(
"%s#%d %s" % [test_name, i+1, params[i]],
func(): await callv(method["name"], params[i]),
is_only,
method_name
)
)
func _is_only(name: String) -> bool:
return name.ends_with("__only")
@@ -0,0 +1 @@
uid://mm20mdmsc5ii
+129
View File
@@ -0,0 +1,129 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/expect-mixin.gd
extends "res://addons/vest/_generated-mixins/1-8182042.gd"
## Mixin for asserting test requirement
##
## @tutorial(Assertions): https://foxssake.github.io/vest/latest/user-guide/assertions/
## Expect a [param condition] to be true.
func expect(condition: bool, p_message: String = "") -> void:
if condition:
ok()
else:
fail(p_message)
## Expect a [param condition] to be false.
func expect_not(condition: bool, p_message: String = "") -> void:
if not condition:
ok()
else:
fail(p_message)
## Expect two values to be equal.
## [br][br]
## If [param actual] has an [code]equals()[/code] method, it will be used.
func expect_equal(actual: Variant, expected: Variant, p_message: String = "Actual value differs from expected!") -> void:
if Vest.__.Matchers.is_equal(actual, expected):
ok()
else:
fail(p_message, { "expect": expected, "got": actual })
## Expect two values not to be equal.
## [br][br]
## If [param actual] has an [code]equals()[/code] method, it will be used.
func expect_not_equal(actual: Variant, expected: Variant, p_message: String = "Actual value equals expected!") -> void:
if Vest.__.Matchers.is_equal(actual, expected):
fail(p_message, { "expect": expected, "got": actual })
else:
ok()
## Expect a [param condition] to be true.
## [br][br]
## Synonim of [method expect], aimed at better readability for asserting bools.
func expect_true(condition: bool, p_message: String = "") -> void:
expect(condition, p_message)
## Expect a [param condition] to be false.
## [br][br]
## Synonim of [method expect_not], aimed at better readability for asserting
## bools.
func expect_false(condition: bool, p_message: String = "") -> void:
expect_not(condition, p_message)
## Expect an [param object] to be empty.
## [br][br]
## If it's a custom type implementing [code]is_empty()[/code], that method will
## be used.
func expect_empty(object: Variant, p_message: String = "Object was not empty!") -> void:
match Vest.__.Matchers.is_empty(object):
true:
ok()
false:
fail(p_message)
ERR_METHOD_NOT_FOUND:
fail("Object has no is_empty() method!", { "object": object })
ERR_CANT_RESOLVE:
fail("Unknown object, can't be checked for emptiness!", { "object": object })
## Expect an [param object] to not be empty.
## [br][br]
## If it's a custom type implementing [code]is_empty()[/code], that method will
## be used.
func expect_not_empty(object: Variant, p_message: String = "Object was empty!") -> void:
match Vest.__.Matchers.is_empty(object):
true:
fail(p_message)
false:
ok()
ERR_METHOD_NOT_FOUND:
fail("Object has no is_empty() method!", { "object": object })
ERR_CANT_RESOLVE:
fail("Unknown object, can't be checked for emptiness!", { "object": object })
## Expect an [param object] to contain [param item].
## [br][br]
## If it's a custom type implementing [code]has()[/code], that method will be
## used.
func expect_contains(object: Variant, item: Variant, p_message: String = "Item is missing from collection!") -> void:
match Vest.__.Matchers.contains(object, item):
true:
ok()
false:
fail(p_message, { "got": object, "missing": item })
ERR_METHOD_NOT_FOUND:
fail("Object has no has() method!", { "object": object })
ERR_CANT_RESOLVE:
fail("Unknown object, can't be checked if it contains item!", { "object": object })
## Expect an [param object] to not contain [param item].
## [br][br]
## If it's a custom type implementing [code]has()[/code], that method will be
## used.
func expect_does_not_contain(object: Variant, item: Variant, p_message: String = "Item is in collection!") -> void:
match Vest.__.Matchers.contains(object, item):
true:
fail(p_message, { "got": object, "excess": item })
false:
ok()
ERR_METHOD_NOT_FOUND:
fail("Object has no has() method!", { "object": object })
ERR_CANT_RESOLVE:
fail("Unknown object, can't be checked if it contains item!", { "object": object })
## Expect a [param value] to be null.
func expect_null(value: Variant, p_message: String = "Item is not null!") -> void:
if value == null:
ok()
else:
fail(p_message, { "got": value })
## Expect a [param value] to not be null.
func expect_not_null(value: Variant, p_message: String = "Item is null!") -> void:
if value != null:
ok()
else:
fail(p_message)
@@ -0,0 +1 @@
uid://caf7owv25i7op
@@ -0,0 +1,85 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/assert-that-mixin.gd
extends "res://addons/vest/_generated-mixins/2-ffc90559.gd"
func assert_that(value: Variant) -> _Assertion:
return _Assertion.new(self, value)
class _Assertion:
var _test: VestTest
var _value: Variant
func _init(p_test: Variant, p_value: Variant):
assert(p_test is VestTest, "assert_that mixin used from outside of VestTest!")
_test = p_test
_value = p_value
## Expect a [param condition] about the asserted value to be true.
func passes(condition: Callable, p_message: String = "") -> _Assertion:
_test.expect(condition.call(_value), p_message)
return self
## Expect a [param condition] about the asserted value to be false.
func fails(condition: Callable, p_message: String = "") -> _Assertion:
_test.expect_not(condition.call(_value), p_message)
return self
## Expect the asserted value to be equal to [param expected].
## [br][br]
## If [param actual] has an [code]equals()[/code] method, it will be used.
func is_equal_to(expected: Variant, p_message: String = "Actual value differs from expected!") -> _Assertion:
_test.expect_equal(_value, expected, p_message)
return self
## Expect the asserted value to not be equal to [param expected].
## [br][br]
## If [param actual] has an [code]equals()[/code] method, it will be used.
func is_not_equal_to(expected: Variant, p_message: String = "Actual value equals expected!") -> _Assertion:
_test.expect_not_equal(_value, expected, p_message)
return self
## Expect the asserted value to be empty.
## [br][br]
## If it's a custom type implementing [code]is_empty()[/code], that method will
## be used.
func is_empty(p_message: String = "Object was not empty!") -> _Assertion:
_test.expect_empty(_value, p_message)
return self
## Expect the asserted value to not be empty.
## [br][br]
## If it's a custom type implementing [code]is_empty()[/code], that method will
## be used.
func is_not_empty(p_message: String = "Object was empty!") -> _Assertion:
_test.expect_not_empty(_value, p_message)
return self
## Expect the asserted value to contain [param item].
## [br][br]
## If it's a custom type implementing [code]has()[/code], that method will be
## used.
func contains(item: Variant, p_message: String = "Item is missing from collection!") -> _Assertion:
_test.expect_contains(_value, item, p_message)
return self
## Expect the asserted value to not contain [param item].
## [br][br]
## If it's a custom type implementing [code]has()[/code], that method will be
## used.
func does_not_contain(item: Variant, p_message: String = "Item is in collection!") -> _Assertion:
_test.expect_does_not_contain(_value, item, p_message)
return self
## Expect the asserted value to be null.
func is_null(p_message: String = "Item is not null!") -> _Assertion:
_test.expect_null(_value, p_message)
return self
## Expect the asserted value to not be null.
func is_not_null(p_message: String = "Item is null!") -> _Assertion:
_test.expect_not_null(_value, p_message)
return self
@@ -0,0 +1 @@
uid://d3mmot6r5ycm6
@@ -0,0 +1,86 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/mock-mixin.gd
extends "res://addons/vest/_generated-mixins/3-27f38ba0.gd"
## Provides mocking for tests
##
## @tutorial(Mocks): https://foxssake.github.io/vest/latest/user-guide/mocks/
# TODO: Fail test case if there's unhandled calls
var _mock_generator := VestMockGenerator.new()
var _mock_handler := VestMockHandler.new()
# Maps Scripts to their mocked counterparts
var _mock_script_cache := {}
## Create a mocked instance of a given script
func mock(script: Script):
var mocked_script := _get_mock_script(script)
var mocked_object = mocked_script.new()
_mock_handler.take_over(mocked_object)
return mocked_object
## Get calls of a mock object's method
func get_calls_of(method: Callable) -> Array[Array]:
var result: Array[Array] = []
for call_data in _mock_handler.get_calls():
if call_data.method != method:
continue
result.append(call_data.args)
return result
## Start specifying an answer for a mocked method call
func when(method: Callable) -> AnswerBuilder:
return AnswerBuilder._of(method, self)
func _get_mock_script(script: Script) -> Script:
if _mock_script_cache.has(script):
return _mock_script_cache.get(script)
else:
var mocked_script := _mock_generator.generate_mock_script(script)
_mock_script_cache[script] = mocked_script
return mocked_script
## Builder for specifying [VestMockDefs.Answer] objects
class AnswerBuilder:
var _test
var _args: Array = []
var _method: Callable
## Set expected arguments
func with_args(p_args: Array) -> AnswerBuilder:
_args = p_args
return self
## Answer by calling a custom method
## [br][br]
## The method will received the passed arguments as an array.
func then_answer(p_answer_method: Callable) -> void:
var answer := VestMockDefs.Answer.new()
answer.expected_method = _method
answer.expected_args = _args
answer._answer_method = p_answer_method
_test._mock_handler.add_answer(answer)
## Answer with a fixed value
func then_return(p_answer_value: Variant) -> void:
var answer := VestMockDefs.Answer.new()
answer.expected_method = _method
answer.expected_args = _args
answer._answer_value = p_answer_value
_test._mock_handler.add_answer(answer)
static func _of(p_method: Callable, p_test):
var builder := AnswerBuilder.new()
builder._method = p_method
builder._test = p_test
return builder
@@ -0,0 +1 @@
uid://v3npn3goh4em
@@ -0,0 +1,84 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/capture-signal-mixin.gd
extends "res://addons/vest/_generated-mixins/4-795b469a.gd"
## Mixin for capturing and asserting signals
##
## @tutorial(Capturing signals): https://foxssake.github.io/vest/latest/user-guide/capturing-signals/
# Maps signals to an array of recorded emissions
# Each array item is an individual array containing the emission params
var _signal_captures := {}
# Array of [signal, recorder, is_persistent] tuples
var _signal_recorders: Array[Array] = []
## Capture all emissions of a signal.
## [br][br]
## Mark the capture as [param persistent] if you want the capture to persist
## between test cases.
func capture_signal(what: Signal, arg_count: int = 0, persistent: bool = false):
# Reset captures
_signal_captures[what] = []
# Add listener
var recorder = _get_signal_recorder(what, arg_count)
if not recorder:
push_warning("Can't capture signal with %d arguments!" % arg_count)
return
what.connect(recorder)
_signal_recorders.append([what, recorder, persistent])
## Get the captured signal emissions for a given signal.
## [br][br]
## Note that the captured emissions are reset between test cases. [br]
## Returns an array of signal emission parameters for each captured emission.
func get_signal_emissions(what: Signal) -> Array:
return _signal_captures.get(what, [])
func _init():
super()
on_case_begin.connect(func(__):
# Remove non-persistent recorders
_cleanup_recorders()
# Clear captures
_signal_captures.clear()
)
func _cleanup_recorders():
var filtered_recorders: Array[Array] = []
for recorder_tuple in _signal_recorders:
var recorded_signal := recorder_tuple[0] as Signal
var recorder := recorder_tuple[1] as Callable
var persistent := recorder_tuple[2] as bool
if persistent:
filtered_recorders.append(recorder_tuple)
else:
recorded_signal.disconnect(recorder)
_signal_recorders = filtered_recorders
func _get_signal_recorder(what: Signal, arg_count: int):
match(arg_count):
0: return func(): _record_emission(what, [])
1: return func(a1): _record_emission(what, [a1])
2: return func(a1, a2): _record_emission(what, [a1, a2])
3: return func(a1, a2, a3): _record_emission(what, [a1, a2, a3])
4: return func(a1, a2, a3, a4): _record_emission(what, [a1, a2, a3, a4])
5: return func(a1, a2, a3, a4, a5): _record_emission(what, [a1, a2, a3, a4, a5])
6: return func(a1, a2, a3, a4, a5, a6): _record_emission(what, [a1, a2, a3, a4, a5, a6])
7: return func(a1, a2, a3, a4, a5, a6, a7): _record_emission(what, [a1, a2, a3, a4, a5, a6, a7])
8: return func(a1, a2, a3, a4, a5, a6, a7, a8): _record_emission(what, [a1, a2, a3, a4, a5, a6, a7, a8])
_: return null
func _record_emission(what: Signal, args: Array):
if not _signal_captures.has(what):
_signal_captures[what] = []
_signal_captures[what].append(args)
@@ -0,0 +1 @@
uid://c8oa5ooaqwi11
@@ -0,0 +1,18 @@
# This file is generated by Vest!
# Do not modify!
# source: res://addons/vest/test/mixins/logging-mixin.gd
extends "res://addons/vest/_generated-mixins/5-96ae432f.gd"
# Manages logs added using [method Vest.message]
func _init():
super()
on_case_finish.connect(func(_case):
var messages := Vest._get_messages()
if not messages.is_empty():
_result.data["messages"] = messages
Vest._clear_messages()
)
@@ -0,0 +1 @@
uid://dqqt1ecooeqdd
+93
View File
@@ -0,0 +1,93 @@
extends RefCounted
class_name VestCLIRunner
## Implements functionality to run tests
var _peer: StreamPeerTCP = null
## Run tests with [Params]
func run(params: VestCLI.Params) -> int:
var validation_errors := params.validate()
if not validation_errors.is_empty():
for error in validation_errors:
OS.alert(error)
push_error(error)
return 1
await _connect(params)
var results := await _run_tests(params)
_report(params, results)
_send_results_over_network(params, results)
_disconnect()
if results.get_aggregate_status() == VestResult.TEST_PASS:
print_rich("All tests [color=green]passed[/color]!")
return 0
else:
print_rich("There are test [color=red]failures[/color]!")
return 1
func _run_tests(params: VestCLI.Params) -> VestResult.Suite:
var runner := VestLocalRunner.new()
runner.on_partial_result.connect(func(result: VestResult.Suite):
if _peer != null:
if result != null:
_peer.put_var(result._to_wire(), true)
else:
_peer.put_var(result, true)
)
var results: VestResult.Suite
if params.run_file:
results = await runner.run_script_at(params.run_file, params.only_mode)
elif params.run_glob:
results = await runner.run_glob(params.run_glob, params.only_mode)
return results
func _report(params: VestCLI.Params, results: VestResult.Suite):
var report := TAPReporter.report(results)
if params.report_format:
if params.report_file in ["", "-"]:
print(report)
else:
var fa := FileAccess.open(params.report_file, FileAccess.WRITE)
fa.store_string(report)
fa.close()
func _connect(params: VestCLI.Params):
if not params.host and params.port == -1:
return
var host := params.host
var port := params.port
if not host: host = "127.0.0.1"
if port == -1: port = 54932
var peer := StreamPeerTCP.new()
var err := peer.connect_to_host(host, port)
if err != OK:
push_warning("Couldn't connect on port %d! %s" % [port, error_string(err)])
return
await Vest.until(func(): peer.poll(); return peer.get_status() != StreamPeerTCP.STATUS_CONNECTING)
if peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
push_warning("Connection failed! Socket status: %d" % [peer.get_status()])
return
peer.set_no_delay(true)
_peer = peer
func _disconnect():
if _peer != null:
_peer.disconnect_from_host()
func _send_results_over_network(params: VestCLI.Params, results: VestResult.Suite):
if not _peer:
return
_peer.put_var(results._to_wire(), true)
+1
View File
@@ -0,0 +1 @@
uid://bw0ajf5t50wi0
+21
View File
@@ -0,0 +1,21 @@
[gd_scene load_steps=2 format=3 uid="uid://dopwc3211i1ce"]
[sub_resource type="GDScript" id="GDScript_de1pc"]
script/source = "extends Node
# Used to run tests in debug mode
func _ready():
Vest._register_scene_tree(get_tree())
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
var params := Vest.__.LocalSettings.run_params
var runner := VestCLIRunner.new()
var exit_code := await runner.run(params)
get_tree().quit(exit_code)
"
[node name="vest-cli-scene" type="Node"]
script = SubResource("GDScript_de1pc")
+110
View File
@@ -0,0 +1,110 @@
extends SceneTree
class_name VestCLI
## Class for running vest from the CLI
## [br][br]
## See [VestCLI.Params]
## Vest CLI parameters
class Params:
## Which test script file to run
var run_file: String = ""
## Which test glob to run
var run_glob: String = "res://*.test.gd"
## Reporting format - currently only TAP is supported
var report_format: String = ""
## Path for saving the report
var report_file: String = ""
## How to handle tests marked as `only`
var only_mode: int = Vest.__.ONLY_DISABLED
## Host to connect to for sending results
var host: String = ""
## Port to connect to for sending results
var port: int = -1
## Validate parameters.
## [br][br]
## Returns an array of error messages, or an empty array of the parameters
## are valid.
func validate() -> Array[String]:
var result: Array[String] = []
if not run_file and not run_glob:
result.append("No tests specified!")
if report_format not in ["", "tap"]:
result.append("Unknown report format \"%s\"!" % report_format)
if port != -1 and port < 0 or port > 65535:
result.append("Specified port %d is invalid!" % port)
return result
## Convert to an array of CLI parameters.
func to_args() -> Array[String]:
var result: Array[String] = []
if run_file: result.append_array(["--vest-file", run_file])
if run_glob: result.append_array(["--vest-glob", run_glob])
if report_format: result.append_array(["--vest-report-format", report_format])
if report_file: result.append_array(["--vest-report-file", report_file])
if host: result.append_array(["--vest-host", host])
if port != -1: result.append_array(["--vest-port", str(port)])
match only_mode:
Vest.__.ONLY_DISABLED: result.append("--no-only")
Vest.__.ONLY_AUTO: result.append("--auto-only")
Vest.__.ONLY_ENABLED: result.append("--only")
return result
## Parse an array of CLI parameters.
## [br][br]
## See [method OS.get_cmdline_args].
static func parse(args: Array[String]) -> Params:
var result := Params.new()
for i in range(args.size()):
var arg := args[i]
var val := args[i+1] if i+1 < args.size() else ""
if arg == "--vest-file": result.run_file = val
elif arg == "--vest-glob": result.run_glob = val
elif arg == "--vest-report-file": result.report_file = val
elif arg == "--vest-report-format": result.report_format = val
elif arg == "--vest-port": result.port = val.to_int()
elif arg == "--vest-host": result.host = val
elif arg == "--no-only": result.only_mode = Vest.__.ONLY_DISABLED
elif arg == "--only": result.only_mode = Vest.__.ONLY_ENABLED
elif arg == "--auto-only": result.only_mode = Vest.__.ONLY_AUTO
return result
## Run vest CLI with parameters.
## [br][br]
## Returns the spawned process' ID.
static func run(params: Params) -> int:
var args = ["--headless", "-s", (VestCLI as Script).resource_path]
return OS.create_instance(args + params.to_args())
## Run vest in debug mode.
static func debug(params: Params):
Vest.__.LocalSettings.run_params = params
Vest.__.LocalSettings.flush()
Vest._get_editor_interface()\
.play_custom_scene(preload("res://addons/vest/cli/vest-cli-scene.tscn").resource_path)
func _init():
Vest._register_scene_tree(self)
# Wait a frame for autoloads to register
await process_frame
var params := Params.parse(OS.get_cmdline_args())
var runner := VestCLIRunner.new()
var exit_code := await runner.run(params)
quit(exit_code)
+1
View File
@@ -0,0 +1 @@
uid://dnchvsa0ahjd4
@@ -0,0 +1,74 @@
@tool
extends Node
static var _instance: Vest.__.CreateTestCommand = null
static func find():
return _instance
static func execute() -> void:
if _instance:
_instance.create_test()
else:
push_warning("No instance of Create Test command found!")
func create_test():
var editor := Vest._get_editor_interface()
var edited_script := editor.get_script_editor().get_current_script() as Script
if not edited_script:
editor.get_script_editor().open_script_create_dialog("VestTest", "")
return
var script_path := edited_script.resource_path
var script_directory := script_path.get_base_dir()
var script_filename := script_path.get_file()
if Vest.get_test_name_patterns().any(func(it): return it.matches(script_filename)):
# Script is already a test
return
var preferred_pattern := Vest.get_test_name_patterns()[0]
var test_filename := preferred_pattern.substitute(script_filename)
var test_directory := get_test_directory(script_directory)
var test_path := test_directory.path_join(test_filename)
editor.get_script_editor().open_script_create_dialog("VestTest", test_path)
func get_test_directory(script_dir: String) -> String:
match Vest.get_new_test_location_preference():
Vest.NEW_TEST_MIRROR_DIR_STRUCTURE:
return get_mirrored_test_dir(script_dir)
Vest.NEW_TEST_NEXT_TO_SOURCE:
return script_dir
Vest.NEW_TEST_IN_ROOT:
return Vest.get_tests_root()
return script_dir
func get_mirrored_test_dir(script_dir: String) -> String:
# TODO: Class for managing paths?
if not script_dir.ends_with("/"):
script_dir += "/"
if script_dir.begins_with(Vest.get_sources_root()):
var relative_to_src_root := script_dir.substr(Vest.get_sources_root().length())
return Vest.get_tests_root() + relative_to_src_root
else:
var relative_to_root := script_dir.replace("res://", "")
return Vest.get_tests_root() + relative_to_root
func _ready():
_instance = self
var editor := Vest._get_editor_interface()
editor.get_command_palette().add_command("Create test", "vest/create-test", create_test, "Ctrl+Shift+T")
func _exit_tree():
var editor := Vest._get_editor_interface()
editor.get_command_palette().remove_command("vest/create-test")
func _shortcut_input(event):
if event is InputEventKey:
if event.is_command_or_control_pressed() and event.shift_pressed and event.key_label == KEY_T and event.is_pressed():
create_test()
get_viewport().set_input_as_handled()
@@ -0,0 +1 @@
uid://cmda0loe05f5y
+101
View File
@@ -0,0 +1,101 @@
@tool
extends Node
static var _instance: Vest.__.GoToTestCommand = null
static func find() -> Vest.__.GoToTestCommand:
return _instance
func go_to_test():
var editor := Vest._get_editor_interface()
var edited_script := editor.get_script_editor().get_current_script() as Script
if not edited_script:
# No script is being edited
return
var script_path := edited_script.resource_path
var script_filename := script_path.get_file()
var target_filenames := get_search_filenames(script_filename, Vest.get_test_name_patterns())
var hits := find_matching_scripts(script_path, target_filenames)
if hits.size() == 1:
# Single hit, navigate to script asap
editor.edit_script(load(hits.front()))
else:
# Multiple hits, let user choose which one to open
show_popup(hits)
func get_search_filenames(script_filename: String, patterns: Array[FilenamePattern]) -> Array[String]:
var result := [] as Array[String]
# Check if currently open script is a test, in which case guess implementation's filename
for pattern in patterns:
if pattern.matches(script_filename):
result.append(pattern.reverse(script_filename))
# Currently open script is not a test, figure out possible test names
if result.is_empty():
result.append_array(patterns.map(func(it): return it.substitute(script_filename)))
return result
func find_matching_scripts(script_path: String, search_filenames: Array[String]) -> Array[String]:
var result := [] as Array[String]
Vest.traverse_directory("res://", func(path: String):
if path == script_path:
return
if path.get_file() not in search_filenames:
return
result.append(path)
)
return result
func show_popup(matching_script_paths: Array[String]):
var editor := Vest._get_editor_interface()
var popup := PopupMenu.new()
popup.min_size = Vector2(0, 0)
popup.size = Vector2(0, 0)
# Add options for matches
for idx in range(matching_script_paths.size()):
var script_path := matching_script_paths[idx]
popup.add_icon_item(Vest.Icons.jump_to, script_path)
popup.set_item_icon_max_width(popup.item_count - 1, VestUI.get_icon_size())
# Add option to create
popup.add_icon_item(Vest.Icons.lightbulb, "Create test")
popup.set_item_icon_max_width(popup.item_count - 1, VestUI.get_icon_size())
# Show popup at mouse pos
editor.popup_dialog(popup, Rect2i(
get_viewport().get_mouse_position(),
Vector2.ZERO
))
popup.set_focused_item(0)
popup.index_pressed.connect(func(idx: int):
if idx < matching_script_paths.size():
editor.edit_script(load(matching_script_paths[idx]))
else:
Vest.__.CreateTestCommand.execute()
)
func _ready():
_instance = self
var editor := Vest._get_editor_interface()
editor.get_command_palette().add_command("Go to test", "vest/go-test", go_to_test, "Ctrl+T")
func _exit_tree():
var editor := Vest._get_editor_interface()
editor.get_command_palette().remove_command("vest/go-test")
func _shortcut_input(event):
if event is InputEventKey:
if event.is_command_or_control_pressed() and not event.shift_pressed and event.key_label == KEY_T and event.is_pressed():
go_to_test()
get_viewport().set_input_as_handled()
@@ -0,0 +1 @@
uid://btsb4tdggfvfg
+53
View File
@@ -0,0 +1,53 @@
@tool
extends Node
func run_test():
_run(false, Vest.__.ONLY_AUTO)
func debug_test():
_run(true, Vest.__.ONLY_AUTO)
func _run(is_debug: bool, only_mode: int) -> void:
var editor_interface := Vest._get_editor_interface()
var script_editor := editor_interface.get_script_editor() as ScriptEditor
var edited_script := script_editor.get_current_script()
if not edited_script:
# TODO: Polyfilled toast mechanism so user can see these warns
push_warning("No script to run! Open a script in the script editor.")
return
if not _is_ancestor_of(VestTest, edited_script):
push_warning("Currently open script is not a test! Extend VestTest.")
return
print_verbose("Running test \"%s\"" % [edited_script.resource_path])
var vest_ui := VestUI._get_ui()
vest_ui.run_script(edited_script, is_debug, only_mode)
func _is_ancestor_of(base_script: Script, script: Script) -> bool:
for i in range(128): # Prevent runaway loops
if script == null: break
if base_script == script: return true
script = script.get_base_script()
return false
func _ready():
var editor := Vest._get_editor_interface()
editor.get_command_palette().add_command("Run test", "vest/run-test", run_test, "F7")
editor.get_command_palette().add_command("Debug test", "vest/debug-test", debug_test, "Ctrl+F7")
func _exit_tree():
var editor := Vest._get_editor_interface()
editor.get_command_palette().remove_command("vest/run-test")
editor.get_command_palette().remove_command("vest/debug-test")
func _shortcut_input(event):
if event is InputEventKey:
if event.key_label == KEY_F7 and not event.shift_pressed and event.is_pressed():
if event.is_command_or_control_pressed():
debug_test()
else:
run_test()
get_viewport().set_input_as_handled()
@@ -0,0 +1 @@
uid://owfqf5cu1gju
+30
View File
@@ -0,0 +1,30 @@
@tool
extends RefCounted
class_name FilenamePattern
var _pattern: String
var _reverse_pattern: RegEx
func _init(p_pattern: String):
_pattern = p_pattern
_reverse_pattern = RegEx.create_from_string("^" + p_pattern.replace("*", "(.*)") + "$")
func matches(filename: String) -> bool:
return filename.match(_pattern)
func reverse(filename: String) -> String:
if not matches(filename):
return ""
var reverse_result := _reverse_pattern.search(filename)
if not reverse_result: return ""
if reverse_result.get_group_count() < 1: return ""
return reverse_result.get_string(1) + ".gd"
func substitute(filename: String) -> String:
return _pattern.replace("*", filename.get_file().get_basename())
func _to_string():
return "FilenamePattern(\"%s\")" % [_pattern]
+1
View File
@@ -0,0 +1 @@
uid://bql0s3vbq7u3x
+122
View File
@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="benchmark-fail.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="22.627417"
inkscape:cx="9.5901357"
inkscape:cy="10.783378"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><inkscape:path-effect
effect="powermask"
id="path-effect2"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2"><path
id="mask-powermask-path-effect2_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path2"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><filter
id="mask-powermask-path-effect2_inverse"
inkscape:label="filtermask-powermask-path-effect2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect2_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect2_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" /></mask><inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect8"><g
id="g8"
style=""><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 4,4 8,8"
id="path7" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 12,4 4,12"
id="path8" /></g></mask></defs><path
style="fill:#fc7f7f;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect2)"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z"
inkscape:path-effect="#path-effect2"
inkscape:original-d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" /></svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c1cdr1khuiy2f"
path="res://.godot/imported/benchmark-fail.svg-b20a3c22c391ea7bcebd7f59f83ca9d5.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/benchmark-fail.svg"
dest_files=["res://.godot/imported/benchmark-fail.svg-b20a3c22c391ea7bcebd7f59f83ca9d5.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+94
View File
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="benchmark-pass.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="22.627417"
inkscape:cx="9.5901357"
inkscape:cy="10.783378"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><inkscape:path-effect
effect="powermask"
id="path-effect2"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2"><path
id="mask-powermask-path-effect2_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path2"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><filter
id="mask-powermask-path-effect2_inverse"
inkscape:label="filtermask-powermask-path-effect2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect2_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect2_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" /></mask></defs><path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect2)"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z"
inkscape:path-effect="#path-effect2"
inkscape:original-d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" /></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bt8iem8l0pq4s"
path="res://.godot/imported/benchmark-pass.svg-7479ef55a95006e5fb1a614e003877eb.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/benchmark-pass.svg"
dest_files=["res://.godot/imported/benchmark-pass.svg-7479ef55a95006e5fb1a614e003877eb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+86
View File
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="benchmark.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="22.627417"
inkscape:cx="9.5901357"
inkscape:cy="10.783378"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><inkscape:path-effect
effect="powermask"
id="path-effect2"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2"><path
id="mask-powermask-path-effect2_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path2"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><filter
id="mask-powermask-path-effect2_inverse"
inkscape:label="filtermask-powermask-path-effect2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect2_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect2_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter></defs><path
style="fill:#ffca5f;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect2)"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z"
inkscape:path-effect="#path-effect2"
inkscape:original-d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" /></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b6yh8aylojfgt"
path="res://.godot/imported/benchmark.svg-b9f24369bdd89bc588a152cef6f09c00.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/benchmark.svg"
dest_files=["res://.godot/imported/benchmark.svg-b9f24369bdd89bc588a152cef6f09c00.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+92
View File
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="clear.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="11.313708"
inkscape:cx="0.44194174"
inkscape:cy="7.1594562"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" /></mask><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3-6"><path
id="mask-powermask-path-effect3_box-2"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-9" /></mask><filter
id="mask-powermask-path-effect3_inverse-1"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-2"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-7"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter></defs><path
style="fill:none;fill-opacity:1;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 3.049804,13.3885 h 9.900392"
id="path13"
sodipodi:nodetypes="cc" /><g
id="g13"
transform="rotate(-45,0.50609483,-10.265212)"
style="fill:none;stroke:#e0e0e0;stroke-opacity:1;stroke-width:2;stroke-dasharray:none"><path
id="rect12"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1;stroke-dasharray:none"
d="m -2.800869,4.6381863 -7.999145,4e-7 -1e-6,2.9996797 2.9996796,2.9996796 0.9998938,-1e-6 4.0009536,0.0014 z" /><rect
style="fill:none;fill-opacity:1;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="rect13"
width="1.9990958"
height="6.0000587"
x="-4.7999649"
y="4.6381865" /></g></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ctdipwc8sklwo"
path="res://.godot/imported/clear.svg-c74aed6190d9cab6b3b5d7c8ad724085.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/clear.svg"
dest_files=["res://.godot/imported/clear.svg-c74aed6190d9cab6b3b5d7c8ad724085.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+68
View File
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="collapse.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="true"
inkscape:zoom="45.254834"
inkscape:cx="8.6178639"
inkscape:cy="8.7393979"
inkscape:window-width="2560"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
enabled="true"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path2"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 11,3.0000414 -3,3 -3,-3"
sodipodi:nodetypes="ccc" />
<path
id="path3"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 11,12.999959 8,9.9999586 5,12.999959"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cv8va2smpv1lf"
path="res://.godot/imported/collapse.svg-9b497d9ee40a464a0f26821fb8538f0b.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/collapse.svg"
dest_files=["res://.godot/imported/collapse.svg-9b497d9ee40a464a0f26821fb8538f0b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+85
View File
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="debug.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="16"
inkscape:cx="-1.75"
inkscape:cy="15.375"
inkscape:window-width="1920"
inkscape:window-height="1048"
inkscape:window-x="2560"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" /></mask><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter></defs><ellipse
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path1"
cx="8"
cy="8"
rx="3"
ry="4" /><path
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle1"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="4"
sodipodi:rx="3"
sodipodi:ry="4"
sodipodi:start="0.52359878"
sodipodi:end="2.6179939"
sodipodi:arc-type="arc"
d="M 10.598076,6 A 3,4 0 0 1 8,8 3,4 0 0 1 5.4019238,5.9999999"
sodipodi:open="true" /><path
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 5.4019238,5.9999999 3.9877102,4.5857863 2.5734966,5.9999999"
id="path6" /><path
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 5.4019238,10 3.9877102,8.5857869 2.5734966,10"
id="path8" /><path
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 10.598076,6 12.012289,4.5857864 13.426503,6"
id="path9" /><path
style="fill:none;stroke:#ffca5f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 10.598076,9.9999997 1.414213,-1.414213 1.414214,1.414213"
id="path10" /></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dwhlyf5eyiect"
path="res://.godot/imported/debug.svg-10ec6677d3bd3a64aea2006222e97a3c.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/debug.svg"
dest_files=["res://.godot/imported/debug.svg-10ec6677d3bd3a64aea2006222e97a3c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+68
View File
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="expand.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="true"
inkscape:zoom="45.254834"
inkscape:cx="8.6178639"
inkscape:cy="8.7393979"
inkscape:window-width="2560"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
enabled="true"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path2"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 11,6 8,3 5,6"
sodipodi:nodetypes="ccc" />
<path
id="path3"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 11,10 8,13 5,10"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://sx0233b14cll"
path="res://.godot/imported/expand.svg-6ad1f463c41f73d2aadcc7559e7670ff.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/expand.svg"
dest_files=["res://.godot/imported/expand.svg-6ad1f463c41f73d2aadcc7559e7670ff.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+112
View File
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="fail.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="11.313708"
inkscape:cx="26.649087"
inkscape:cy="5.833631"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect8">
<path
id="mask-powermask-path-effect8_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<g
id="g8"
style="">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 4,4 8,8"
id="path7" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 12,4 4,12"
id="path8" />
</g>
</mask>
<filter
id="mask-powermask-path-effect8_inverse"
inkscape:label="filtermask-powermask-path-effect8"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect8_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect8_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#fc7f7f;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect8)"
inkscape:path-effect="#path-effect8"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:rx="8"
sodipodi:ry="8"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://de5ileacgwme1"
path="res://.godot/imported/fail.svg-fb1453c71ffec14739e9280d33cb8120.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/fail.svg"
dest_files=["res://.godot/imported/fail.svg-fb1453c71ffec14739e9280d33cb8120.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M2 8a6.21 6.21 0 0 0 6 4.657 6.21 6.21 0 0 0 6.006-4.678" style="fill:none;fill-opacity:1;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/></svg>

After

Width:  |  Height:  |  Size: 302 B

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://buuq6qptg3vll"
path="res://.godot/imported/hidden.svg-58af1b7fb82759e99e9f427f659b9a32.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/hidden.svg"
dest_files=["res://.godot/imported/hidden.svg-58af1b7fb82759e99e9f427f659b9a32.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+90
View File
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="jump-to.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4"
inkscape:cx="-107.5"
inkscape:cy="5.25"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs1">
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3">
<path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" />
</mask>
<filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none"
id="path4"
sodipodi:type="arc"
sodipodi:cx="9.689312"
sodipodi:cy="-5.2496619"
sodipodi:rx="3"
sodipodi:ry="3"
sodipodi:start="0.78539816"
sodipodi:end="3.1415927"
sodipodi:open="true"
sodipodi:arc-type="arc"
d="M 11.810632,-3.1283416 A 3,3 0 0 1 8.5412616,-2.4780233 3,3 0 0 1 6.689312,-5.2496619"
transform="rotate(90)" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none"
d="M 5.249662,6.6893122 H 9.2496609"
id="path5"
sodipodi:nodetypes="cc" />
<path
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none"
d="m 8.249662,4.1893122 v 5 l 5.5,-2.5 z"
id="path6"
sodipodi:nodetypes="cccc" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://beoxvhp204wuv"
path="res://.godot/imported/jump-to.svg-c9add894b2d5164c6f4e6837154c4f30.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/jump-to.svg"
dest_files=["res://.godot/imported/jump-to.svg-c9add894b2d5164c6f4e6837154c4f30.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+377
View File
@@ -0,0 +1,377 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="lightbulb.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="5.6568545"
inkscape:cx="-62.932501"
inkscape:cy="8.485281"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><inkscape:path-effect
effect="powermask"
id="path-effect6"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect6"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect2"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><inkscape:path-effect
effect="powermask"
id="path-effect2-5"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2-5"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse-3"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-5"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-6"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2"><path
id="mask-powermask-path-effect2_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path2"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><filter
id="mask-powermask-path-effect2_inverse"
inkscape:label="filtermask-powermask-path-effect2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect2_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect2_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-2" /></mask><inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect8"><g
id="g8"
style=""><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 4,4 8,8"
id="path7" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 12,4 4,12"
id="path8" /></g></mask><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2-5"><path
id="path9"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path10"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><inkscape:path-effect
effect="powermask"
id="path-effect2-7"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect2-7"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect3_inverse-0"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-9"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-3"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2-6"><path
id="mask-powermask-path-effect2_box-0"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path2-6"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><filter
id="mask-powermask-path-effect2_inverse-2"
inkscape:label="filtermask-powermask-path-effect2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect2_primitive1-6"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect2_primitive2-1"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3-8"><path
id="mask-powermask-path-effect3_box-7"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-9" /></mask><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect2-7"><path
id="path11"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
id="path12"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.99983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
inkscape:transform-center-y="-0.65213837"
d="M 8,3.9995283 5.9997641,8.666745 H 8 v 3.333727 L 10.000236,7.3332546 H 8 Z"
sodipodi:nodetypes="ccccccc" /></mask><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3-7"><path
id="mask-powermask-path-effect3_box-5"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-92" /></mask><filter
id="mask-powermask-path-effect3_inverse-2"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-8"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-9"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3-6"><path
id="mask-powermask-path-effect3_box-2"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-9-7" /></mask><filter
id="mask-powermask-path-effect3_inverse-1"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-2"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-7"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><inkscape:path-effect
effect="powermask"
id="path-effect26"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect26"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect21"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect21"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect12"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect12"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect8-2"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><inkscape:path-effect
effect="powermask"
id="path-effect3-9"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" /><filter
id="mask-powermask-path-effect25_inverse"
inkscape:label="filtermask-powermask-path-effect25"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect25_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect25_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect26"><g
id="g26"
transform="translate(-0.36644319,-9.7040383e-4)"
style=""><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path25"
sodipodi:type="arc"
sodipodi:cx="-8.0006008"
sodipodi:cy="6.5"
sodipodi:rx="2.5"
sodipodi:ry="2.5"
sodipodi:start="1.5707963"
sodipodi:end="5.4977871"
sodipodi:open="true"
sodipodi:arc-type="arc"
transform="scale(-1,1)" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 8.0006008,9 8,9.5"
id="path26"
sodipodi:nodetypes="cc" /><circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle26"
cx="8"
cy="12"
r="1" /></g></mask></defs><path
style="fill:none;fill-opacity:1;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path5"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="13"
sodipodi:rx="2"
sodipodi:ry="2"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:arc-type="arc"
d="m 10,13 a 2,2 0 0 1 -1,1.732051 2,2 0 0 1 -2.0000001,0 A 2,2 0 0 1 6,13"
sodipodi:open="true" /><circle
style="fill:#ffca5f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-miterlimit:6"
id="path3"
mask="none"
cx="8"
cy="6"
r="6" /><circle
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-miterlimit:6"
id="circle6"
cx="6"
cy="4"
r="2" /><circle
style="fill:#ffca5f;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-miterlimit:6"
id="circle1"
mask="none"
cx="8"
cy="10"
r="4" /></svg>

After

Width:  |  Height:  |  Size: 15 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ckxkehgmjtjcx"
path="res://.godot/imported/lightbulb.svg-f4f05ab673622fe0cb66314541b2eac4.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/lightbulb.svg"
dest_files=["res://.godot/imported/lightbulb.svg-f4f05ab673622fe0cb66314541b2eac4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3">
<path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" />
</mask>
<filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
id="layer1">
<path
style="fill:#8eef97;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect3)"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmqjme87oq3xx"
path="res://.godot/imported/pass.svg-527f701477d1793b7212aa92a3d53194.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/pass.svg"
dest_files=["res://.godot/imported/pass.svg-527f701477d1793b7212aa92a3d53194.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+114
View File
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="refresh.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="5.71875"
inkscape:cy="6.71875"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs1">
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3">
<path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" />
</mask>
<filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
id="path1"
sodipodi:type="arc"
sodipodi:cx="-8"
sodipodi:cy="7.9999995"
sodipodi:rx="4"
sodipodi:ry="4"
sodipodi:start="0"
sodipodi:end="2.3561945"
sodipodi:arc-type="arc"
d="M -4,7.9999995 A 4,4 0 0 1 -6.4692663,11.695518 4,4 0 0 1 -10.828427,10.828427"
sodipodi:open="true"
transform="rotate(-90)" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
d="M 7.9999997,3.9999997 10,2.9999997"
id="path2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
d="m 7.9999997,3.9999997 2.0000003,1"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
id="path5"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="-8"
sodipodi:rx="4"
sodipodi:ry="4"
sodipodi:start="0"
sodipodi:end="2.3561945"
sodipodi:arc-type="arc"
d="M 12,-8 A 4,4 0 0 1 9.5307337,-4.3044819 4,4 0 0 1 5.1715728,-5.1715729"
sodipodi:open="true"
transform="rotate(90)" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
d="m 7.9999995,12 -2,1"
id="path6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
d="m 7.9999995,12 -2,-1"
id="path7"
sodipodi:nodetypes="cc" />
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dt75n55vr4kq0"
path="res://.godot/imported/refresh.svg-08b8d1fd09107d0faa0c33acbadb6352.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/refresh.svg"
dest_files=["res://.godot/imported/refresh.svg-08b8d1fd09107d0faa0c33acbadb6352.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="run-save.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><path
id="rect7"
style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
d="m 12.4375,4 v 8 h -7 V 7.5 l 3.5,-3.5 z" /><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="16"
inkscape:cx="5.5"
inkscape:cy="14.4375"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><defs
id="defs1"><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3"><path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" /></mask><filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter><mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3-5"><path
id="mask-powermask-path-effect3_box-3"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3-5" /></mask><filter
id="mask-powermask-path-effect3_inverse-6"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50"><feColorMatrix
id="mask-powermask-path-effect3_primitive1-2"
values="1"
type="saturate"
result="fbSourceGraphic" /><feColorMatrix
id="mask-powermask-path-effect3_primitive2-9"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" /></filter></defs><path
sodipodi:type="star"
style="fill:none;stroke:#8eef97;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path4-1"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:r1="5"
sodipodi:r2="2.5"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 13,8 -7.5,4.330127 0,-8.660254 z"
inkscape:transform-center-x="-0.62499999"
transform="matrix(0.5,0,0,0.5,0.8125,4)" /></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c711af0y1s2ct"
path="res://.godot/imported/run-save.svg-284dc56c3fcbb3decae07a3263265580.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/run-save.svg"
dest_files=["res://.godot/imported/run-save.svg-284dc56c3fcbb3decae07a3263265580.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+83
View File
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="run.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="26.4375"
inkscape:cx="3.7446808"
inkscape:cy="5.4846336"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs1">
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect3">
<path
id="mask-powermask-path-effect3_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 3.7573597,9.0606809 5.87868,11.182001 12.24264,4.8180402"
id="path3" />
</mask>
<filter
id="mask-powermask-path-effect3_inverse"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect3_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect3_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<path
sodipodi:type="star"
style="fill:none;stroke:#8eef97;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-opacity:1"
id="path4"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:r1="5"
sodipodi:r2="2.5"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 13,8 -7.5,4.330127 0,-8.660254 z"
inkscape:transform-center-x="-1.25"
transform="translate(-1.24995)" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://r4y6ihamgino"
path="res://.godot/imported/run.svg-b6532e07a4db7efc49be28be04360e08.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/run.svg"
dest_files=["res://.godot/imported/run.svg-b6532e07a4db7efc49be28be04360e08.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="11.314" cy="-1.423" r="5" style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" transform="rotate(45)"/><path d="m5.47 10.53-3.05 3.05" style="fill:none;stroke:#e0e0e0;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none"/></svg>

After

Width:  |  Height:  |  Size: 409 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cl6im4a1uj6nq"
path="res://.godot/imported/search.svg-f595f7d0e550dfff682417fb006673bc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/search.svg"
dest_files=["res://.godot/imported/search.svg-f595f7d0e550dfff682417fb006673bc.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="skip.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="22.627417"
inkscape:cx="13.810679"
inkscape:cy="9.1039998"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<inkscape:path-effect
effect="powermask"
id="path-effect12"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect12"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect12">
<path
id="mask-powermask-path-effect12_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<g
id="g12"
transform="translate(2.0707143e-5)"
style="">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 4,5 7,8 4,11"
id="path11"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 9,5 3,3 -3,3"
id="path12"
sodipodi:nodetypes="ccc" />
</g>
</mask>
<filter
id="mask-powermask-path-effect12_inverse"
inkscape:label="filtermask-powermask-path-effect12"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect12_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect12_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect12)"
inkscape:path-effect="#path-effect12"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:rx="8"
sodipodi:ry="8"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cx4htkmtgdk5l"
path="res://.godot/imported/skip.svg-05ed8ec36ac4803550bae54821df0a30.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/skip.svg"
dest_files=["res://.godot/imported/skip.svg-05ed8ec36ac4803550bae54821df0a30.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
sodipodi:docname="spinner.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="32"
inkscape:cx="6.28125"
inkscape:cy="7.515625"
inkscape:window-width="2560"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid8"
units="px"
originx="0"
originy="0"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
enabled="true"
visible="false" />
</sodipodi:namedview>
<defs
id="defs1">
<linearGradient
id="swatch6"
inkscape:swatch="solid">
<stop
style="stop-color:#e0e0e0;stop-opacity:1;"
offset="0"
id="stop6" />
</linearGradient>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path6"
cx="8"
cy="3"
r="2" />
<circle
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle14"
cx="8"
cy="13"
r="1" />
<circle
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle15"
cx="8"
cy="-13"
transform="rotate(90)"
r="1.4142135" />
<ellipse
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle16"
cx="8"
cy="-3"
transform="rotate(90)"
rx="0.70710677"
ry="0.70700002" />
<ellipse
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle18"
cx="11.313708"
cy="-5"
transform="rotate(45)"
rx="1.6817929"
ry="1.682" />
<ellipse
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle19"
cx="11.313708"
cy="5"
transform="rotate(45)"
rx="0.84089643"
ry="0.84100002" />
<circle
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle20"
cx="1.7763568e-15"
cy="-16.313709"
transform="rotate(135)"
r="1.1892071" />
<ellipse
style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle21"
cx="1.7763568e-15"
cy="-6.3137083"
transform="rotate(135)"
rx="0.59460354"
ry="0.59500003" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://csfyamlc15vp0"
path="res://.godot/imported/spinner.svg-2fba1cd10beb909105907ca61911cf40.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/spinner.svg"
dest_files=["res://.godot/imported/spinner.svg-2fba1cd10beb909105907ca61911cf40.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+160
View File
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="todo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="11.313708"
inkscape:cx="26.47231"
inkscape:cy="19.887378"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<inkscape:path-effect
effect="powermask"
id="path-effect21"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect21"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect12"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect12"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect21">
<path
id="mask-powermask-path-effect21_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<g
id="g21"
style="">
<rect
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="rect17"
width="1"
height="1"
x="4"
y="4"
d="M 4,4 H 5 V 5 H 4 Z" />
<rect
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="rect18"
width="1"
height="1"
x="4"
y="11"
d="m 4,11 h 1 v 1 H 4 Z" />
<rect
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="rect19"
width="1"
height="1"
x="4"
y="7.5"
d="m 4,7.5 h 1 v 1 H 4 Z" />
<path
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 8,8 h 4"
id="path19" />
<path
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 8,4.5 h 4"
id="path20" />
<path
style="fill:#ffca5f;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="m 8,11.5 h 4"
id="path21" />
</g>
</mask>
<filter
id="mask-powermask-path-effect21_inverse"
inkscape:label="filtermask-powermask-path-effect21"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect21_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect21_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#ffca5f;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect21)"
inkscape:path-effect="#path-effect21"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:rx="8"
sodipodi:ry="8"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://meh1sny670to"
path="res://.godot/imported/todo.svg-2340992753f3f9d2c971234e5e126d95.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/todo.svg"
dest_files=["res://.godot/imported/todo.svg-2340992753f3f9d2c971234e5e126d95.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+27
View File
@@ -0,0 +1,27 @@
extends Object
# Results
const result_void: Texture2D = preload("res://addons/vest/icons/void.svg")
const result_skip: Texture2D = preload("res://addons/vest/icons/skip.svg")
const result_todo: Texture2D = preload("res://addons/vest/icons/todo.svg")
const result_fail: Texture2D = preload("res://addons/vest/icons/fail.svg")
const result_pass: Texture2D = preload("res://addons/vest/icons/pass.svg")
# Benchmark
const benchmark: Texture2D = preload("res://addons/vest/icons/benchmark.svg")
const benchmark_pass: Texture2D = preload("res://addons/vest/icons/benchmark-pass.svg")
const benchmark_fail: Texture2D = preload("res://addons/vest/icons/benchmark-fail.svg")
# Actions and buttons
const run: Texture2D = preload("res://addons/vest/icons/run.svg")
const debug: Texture2D = preload("res://addons/vest/icons/debug.svg")
const run_on_save: Texture2D = preload("res://addons/vest/icons/run-save.svg")
const clear: Texture2D = preload("res://addons/vest/icons/clear.svg")
const jump_to: Texture2D = preload("res://addons/vest/icons/jump-to.svg")
const refresh: Texture2D = preload("res://addons/vest/icons/refresh.svg")
const lightbulb: Texture2D = preload("res://addons/vest/icons/lightbulb.svg")
const visible: Texture2D = preload("res://addons/vest/icons/visibility.svg")
const hidden: Texture2D = preload("res://addons/vest/icons/hidden.svg")
const expand: Texture2D = preload("res://addons/vest/icons/expand.svg")
const collapse: Texture2D = preload("res://addons/vest/icons/collapse.svg")
+1
View File
@@ -0,0 +1 @@
uid://g2skerjwbr71
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><defs><mask id="a" maskUnits="userSpaceOnUse"><path d="M1 2.343h14.006v11.314H1Z" style="fill:#fff;fill-opacity:1"/><circle cx="8" cy="8" r="2" style="fill:#000;fill-opacity:1;stroke:none;stroke-width:.2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"/></mask></defs><path d="M8 3.343A6.21 6.21 0 0 0 2 8a6.21 6.21 0 0 0 6 4.657 6.21 6.21 0 0 0 6.006-4.678A6.21 6.21 0 0 0 8 3.343" mask="url(#a)" style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:.155246;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"/></svg>

After

Width:  |  Height:  |  Size: 639 B

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bpyua1ic4p47h"
path="res://.godot/imported/visibility.svg-2226fcfdff15944d56e68e7df764b325.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/visibility.svg"
dest_files=["res://.godot/imported/visibility.svg-2226fcfdff15944d56e68e7df764b325.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+179
View File
@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="void.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="22.627417"
inkscape:cx="15.932"
inkscape:cy="9.4575532"
inkscape:window-width="2560"
inkscape:window-height="1048"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<inkscape:path-effect
effect="powermask"
id="path-effect26"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect26"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect21"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect21"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect12"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect12"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect8"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect8"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect3"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect3"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<filter
id="mask-powermask-path-effect25_inverse"
inkscape:label="filtermask-powermask-path-effect25"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect25_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect25_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect26">
<path
id="mask-powermask-path-effect26_box"
style="fill:#ffffff;fill-opacity:1"
d="M -1,-1 H 17 V 17 H -1 Z" />
<g
id="g26"
transform="translate(-0.36644319,-9.7040383e-4)"
style="">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="path25"
sodipodi:type="arc"
sodipodi:cx="-8.0006008"
sodipodi:cy="6.5"
sodipodi:rx="2.5"
sodipodi:ry="2.5"
sodipodi:start="1.5707963"
sodipodi:end="5.4977871"
sodipodi:open="true"
sodipodi:arc-type="arc"
d="M -8.0006008,9 A 2.5,2.5 0 0 1 -10.415415,7.1470477 2.5,2.5 0 0 1 -9.2506009,4.3349365 2.5,2.5 0 0 1 -6.2328339,4.732233"
transform="scale(-1,1)" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
d="M 8.0006008,9 8,9.5"
id="path26"
sodipodi:nodetypes="cc" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6;stroke-dasharray:none;stroke-opacity:1"
id="circle26"
cx="8"
cy="12"
r="1"
d="M 9,12 A 1,1 0 0 1 8,13 1,1 0 0 1 7,12 1,1 0 0 1 8,11 1,1 0 0 1 9,12 Z" />
</g>
</mask>
<filter
id="mask-powermask-path-effect26_inverse"
inkscape:label="filtermask-powermask-path-effect26"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect26_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect26_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#8da5f0;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:6"
id="path1"
mask="url(#mask-powermask-path-effect26)"
inkscape:path-effect="#path-effect26"
sodipodi:type="arc"
sodipodi:cx="8"
sodipodi:cy="8"
sodipodi:rx="8"
sodipodi:ry="8"
d="M 16,8 A 8,8 0 0 1 8,16 8,8 0 0 1 0,8 8,8 0 0 1 8,0 8,8 0 0 1 16,8 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

+44
View File
@@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ci8hqm6meom3h"
path="res://.godot/imported/void.svg-dedfa2bc2d4e3cbf7106ebb34fd16279.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/vest/icons/void.svg"
dest_files=["res://.godot/imported/void.svg-dedfa2bc2d4e3cbf7106ebb34fd16279.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=2.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
+20
View File
@@ -0,0 +1,20 @@
extends VestMeasure
## Measures the average of a metric.
var _sum: Variant
var _count: int = 0
func _init(p_metric: StringName):
super(p_metric)
func get_measure_name() -> String:
return "average"
func get_value() -> Variant:
return _sum / _count
func ingest(value: Variant) -> void:
_sum = _sum + value if _count else value
_count += 1
@@ -0,0 +1 @@
uid://df6rp7biyybqa
+20
View File
@@ -0,0 +1,20 @@
extends VestMeasure
## Measures the maximum of a metric.
var _max: Variant
var _has: bool = false
func _init(p_metric: StringName):
super(p_metric)
func get_measure_name() -> String:
return "max"
func get_value() -> Variant:
return _max
func ingest(value: Variant) -> void:
_max = max(_max, value) if _has else value
_has = true
+1
View File
@@ -0,0 +1 @@
uid://dkd237tw7ixyw
+38
View File
@@ -0,0 +1,38 @@
class_name VestMeasure
## Base class for implementing measures.
##
## During benchmarks, the benchmarked code may emit custom metrics. Measures
## listen to these metrics, and aggregate the many emitted values into a single
## value, that can be included in the test report.
## [br][br]
## For example, a measure may simply count the number of emissions, calculate
## the average of the emitted values, or keep track of the minimum and maximum
## value emitted.
var _metric: StringName = &""
func _init(p_metric: StringName):
_metric = p_metric
## Get the name of the metric this measure tracks.
func get_metric_name() -> StringName:
return _metric
## Get the name of the measure.
## [br][br]
## [i]override[/i]
func get_measure_name() -> String:
return ""
## Get the value of the measure.
## [br][br]
## [i]override[/i]
func get_value() -> Variant:
return null
## Ingest an emitted metric value.
## [br][br]
## [i]override[/i]
func ingest(_value: Variant) -> void:
pass
+1
View File
@@ -0,0 +1 @@
uid://ds6pfq1623j80
+20
View File
@@ -0,0 +1,20 @@
extends VestMeasure
## Measures the minimum of a metric.
var _min: Variant
var _has: bool = false
func _init(p_metric: StringName):
super(p_metric)
func get_measure_name() -> String:
return "min"
func get_value() -> Variant:
return _min
func ingest(value: Variant) -> void:
_min = min(_min, value) if _has else value
_has = true
+1
View File
@@ -0,0 +1 @@
uid://c8kvrmiyl1hph
+20
View File
@@ -0,0 +1,20 @@
extends VestMeasure
## Measures the sum of a metric.
var _sum: Variant
var _has: bool = false
func _init(p_metric: StringName):
super(p_metric)
func get_measure_name() -> String:
return "sum"
func get_value() -> Variant:
return _sum
func ingest(value: Variant) -> void:
_sum = _sum + value if _has else value
_has = true
+1
View File
@@ -0,0 +1 @@
uid://dbmj156egy6v
+18
View File
@@ -0,0 +1,18 @@
extends VestMeasure
## Measures the value of a metric, retaining only the last emitted value.
var _value: Variant = null
func _init(p_metric: StringName):
super(p_metric)
func get_measure_name() -> String:
return "value"
func get_value() -> Variant:
return _value
func ingest(value: Variant) -> void:
_value = value
@@ -0,0 +1 @@
uid://k53m1xtcmsvh
+68
View File
@@ -0,0 +1,68 @@
extends Object
class_name VestMockDefs
## Grouping class for mock definition primitives.
##
## See [VestMockDefs.Answer][br]
## See [VestMockDefs.Call][br]
## Mock answer definition
##
## Each answer manages a mock method. When this method is called, instead of
## running the underlying code, the answer provides a response.
class Answer:
## The method this instance provides the answers for
var expected_method: Callable
## The expected arguments for providing the answers.
## [br][br]
## May be empty, in which case any and all parameters are accepted.
var expected_args: Array = []
var _answer_value: Variant
var _answer_method: Callable
func _get_specificity() -> int:
return expected_args.size()
func _is_answering(method: Callable, args: Array) -> bool:
if method != expected_method:
return false
if method.get_object() != expected_method.get_object():
return false
if expected_args.is_empty():
return true
if args.size() != expected_args.size():
return false
if args == expected_args:
return true
# Do a lenient check, so users don't trip on unexpected diffs, like
# [2, 4] != [2., 4.]
var lenient_actual := args.map(func(it): return _map_lenient(it))
var lenient_expected := expected_args.map(func(it): return _map_lenient(it))
if lenient_actual == lenient_expected:
return true
return false
func _get_answer(args: Array) -> Variant:
if _answer_method:
return _answer_method.call(args)
else:
return _answer_value
func _map_lenient(value: Variant) -> String:
if typeof(value) == TYPE_INT or typeof(value) == TYPE_FLOAT:
return "%.8f" % [value]
return str(value)
func _to_string() -> String:
return "Answer { %s.%s(%s) }" % [expected_method.get_object(), expected_method.get_method(), expected_args]
## A recorded method call
class Call:
## The method that was called
var method: Callable
## The arguments used for calling the method
var args: Array = []
+1
View File
@@ -0,0 +1 @@
uid://ct7m62cddavyk
+3
View File
@@ -0,0 +1,3 @@
extends Object
# Dummy class to serve as a base for mocks
+1
View File
@@ -0,0 +1 @@
uid://crbyd7o5c3qvh
+48
View File
@@ -0,0 +1,48 @@
extends RefCounted
class_name VestMockGenerator
## Generates mocks for existing scripts
##
## @tutorial(Mocks): https://foxssake.github.io/vest/latest/user-guide/mocks/
# TODO: Support getters and setters?
## Generate a mocked version of a script
func generate_mock_script(script: Script) -> Script:
var dummy_script := preload("res://addons/vest/mocks/vest-mock-dummy.gd") as Script
var mock_script := dummy_script.duplicate() as Script
mock_script.source_code = generate_mock_source(script)
mock_script.reload()
return mock_script
## Generate the source code for mocking a script
func generate_mock_source(script: Script) -> String:
var mock_source := PackedStringArray()
mock_source.append("extends \"%s\"\n\n" % [script.resource_path])
mock_source.append("var __vest_mock_handler: VestMockHandler\n\n")
for method in script.get_script_method_list():
var method_name := method["name"] as String
var method_args = method["args"]
if method_name.begins_with("@"):
# Getter or setter, don't generate as method
continue
var arg_defs := []
for arg in method_args:
var arg_name = arg["name"]
arg_defs.append(arg_name)
var arg_def_string := ", ".join(arg_defs)
mock_source.append(
("func %s(%s):\n" +
"\treturn __vest_mock_handler._handle(self.%s, [%s])\n\n") %
[method_name, arg_def_string, method_name, arg_def_string]
)
return "".join(mock_source)
@@ -0,0 +1 @@
uid://cawk4xgh75woy
+42
View File
@@ -0,0 +1,42 @@
extends RefCounted
class_name VestMockHandler
## Manages mock instances
var _answers: Array[VestMockDefs.Answer] = []
var _calls: Array[VestMockDefs.Call] = []
var _unhandled_calls: Array[VestMockDefs.Call] = []
## Take over a mock instance, recording its calls and providing its answers
func take_over(what: Object):
what.__vest_mock_handler = self
## Register an answer
func add_answer(answer: VestMockDefs.Answer):
_answers.append(answer)
## Get all recorded mock calls
func get_calls() -> Array[VestMockDefs.Call]:
return _calls
## Get all recorded mock calls to which there were no registered answers
func get_unhandled_calls() -> Array[VestMockDefs.Call]:
return _unhandled_calls
func _handle(method: Callable, args: Array):
var call_data := VestMockDefs.Call.new()
call_data.method = method
call_data.args = args
var possible_answers = _answers\
.filter(func(it): return it._is_answering(method, args))
possible_answers.sort_custom(func(a, b): return a._get_specificity() > b._get_specificity())
if possible_answers.is_empty():
_unhandled_calls.append(call_data)
return
var answer := possible_answers.front() as VestMockDefs.Answer
_calls.append(call_data)
return answer._get_answer(args)
@@ -0,0 +1 @@
uid://0yq06hbkdt46
+7
View File
@@ -0,0 +1,7 @@
[plugin]
name="vest"
description="A unit testing library for Godot"
author="Tamás Gálffy and contributors"
version="1.10.4"
script="plugin.gd"
+93
View File
@@ -0,0 +1,93 @@
@tool
extends EditorPlugin
var bottom_control: Control
static var SETTINGS := [
{
"name": "vest/runner_timeout",
"value": 8.0,
"type": TYPE_FLOAT
},
{
"name": "vest/sources_root",
"value": "res://",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_DIR
},
{
"name": "vest/tests_root",
"value": "res://tests/",
"type": TYPE_STRING,
"hint": PROPERTY_HINT_DIR
},
{
"name": "vest/test_name_patterns",
"value": PackedStringArray(["*.test.gd", "test_*.gd"]),
"type": TYPE_PACKED_STRING_ARRAY,
"hint": PROPERTY_HINT_DIR
},
{
"name": "vest/new_test_location",
"value": Vest.NEW_TEST_MIRROR_DIR_STRUCTURE,
"type": TYPE_INT,
"hint": PROPERTY_HINT_ENUM,
"hint_string": ",".join([
"Mirror directory structure",
"Next to source",
"In tests root"
])
}
] as Array[Dictionary]
func _enter_tree():
Vest._register_scene_tree(get_tree())
Vest._register_editor_interface_provider(get_editor_interface)
# Manually trigger local settings init?
Vest.__.LocalSettings._static_init()
bottom_control = (preload("res://addons/vest/ui/vest-ui.tscn") as PackedScene).instantiate()
resource_saved.connect(bottom_control.handle_resource_saved)
add_control_to_bottom_panel(bottom_control, "Vest")
add_settings(SETTINGS)
# Create commands
for command in Vest.__.create_commands():
add_child(command)
func _exit_tree():
resource_saved.disconnect(bottom_control.handle_resource_saved)
remove_control_from_bottom_panel(bottom_control)
bottom_control.queue_free()
remove_settings(SETTINGS)
func add_settings(settings: Array):
for setting in settings:
add_setting(setting)
func add_setting(setting: Dictionary):
if ProjectSettings.has_setting(setting.name):
return
ProjectSettings.set_setting(setting.name, setting.value)
ProjectSettings.set_initial_value(setting.name, setting.value)
ProjectSettings.add_property_info({
"name": setting.get("name"),
"type": setting.get("type"),
"hint": setting.get("hint", PROPERTY_HINT_NONE),
"hint_string": setting.get("hint_string", "")
})
func remove_settings(settings: Array):
for setting in settings:
remove_setting(setting)
func remove_setting(setting: Dictionary):
if not ProjectSettings.has_setting(setting.name):
return
ProjectSettings.clear(setting.name)
+1
View File
@@ -0,0 +1 @@
uid://wgil432yj8k1
+19
View File
@@ -0,0 +1,19 @@
extends RefCounted
signal on_partial_result(result: VestResult.Suite)
func run_script(_script: Script, _only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
# OVERRIDE
return VestResult.Suite.new()
func run_glob(_p_glob: String, _only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
# OVERRIDE
return VestResult.Suite.new()
func run_script_at(path: String, only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
var test_script := load(path)
if not test_script or not test_script is Script:
return null
return await run_script(test_script, only_mode)
@@ -0,0 +1 @@
uid://f1gd7s4rxrh1
+114
View File
@@ -0,0 +1,114 @@
extends "res://addons/vest/runner/vest-base-runner.gd"
class_name VestDaemonRunner
## Runs tests in a separate, background process
var _server: TCPServer
var _port: int
var _peer: StreamPeerTCP
var _is_debug_run := false
## Enable debug mode for the next run
func with_debug() -> VestDaemonRunner:
_is_debug_run = true
return self
## Run a test script
func run_script(script: Script, only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
var params := VestCLI.Params.new()
params.run_file = script.resource_path
params.only_mode = only_mode
return await _run_with_params(params)
## Run test scripts matching glob
## [br][br]
## See [method String.match]
func run_glob(glob: String, only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
var params := VestCLI.Params.new()
params.run_glob = glob
params.only_mode = only_mode
return await _run_with_params(params)
func _run_with_params(params: VestCLI.Params) -> VestResult.Suite:
var timeout := Vest.timeout(Vest.get_runner_timeout())
# Start host
if _start(-1) != OK:
push_error("Couldn't start vest host!")
return null
# Start process
params.host = "127.0.0.1"
params.port = _port
if not _is_debug_run:
VestCLI.run(params)
else:
_is_debug_run = false
VestCLI.debug(params)
# Wait for agent to connect
if await timeout.until(func(): return _server.is_connection_available()) != OK:
push_error("Agent didn't connect in time!")
return null
_peer = _server.take_connection()
var results = null
while true:
await Vest.sleep()
_peer.poll()
if _peer.get_status() != StreamPeerTCP.STATUS_CONNECTED:
break
if _peer.get_available_bytes() <= 0:
# No data, wait some more
continue
var message = _peer.get_var(true)
if message is Dictionary:
results = message
on_partial_result.emit(VestResult.Suite._from_wire(results))
_stop()
if results == null:
push_error("Test run failed!")
return null
elif results is Dictionary:
var suite_result = VestResult.Suite._from_wire(results)
return suite_result
else:
push_error("Unrecognized test result data! %s" % [results])
return null
func _start(port: int = -1):
# Start host
_server = TCPServer.new()
# Find random port for host
if port < 0:
for i in range(32):
port = randi_range(49152, 65535)
if _server.listen(port, "127.0.0.1") == OK:
break
else:
_server.listen(port, "127.0.0.1")
_port = port
if not _server.is_listening():
push_error("Failed to find available port!")
return ERR_CANT_CREATE
return OK
func _stop():
_peer.disconnect_from_host()
_server.stop()
_peer = null
_server = null
_port = -1
@@ -0,0 +1 @@
uid://btopw8r6n6fp1
+122
View File
@@ -0,0 +1,122 @@
extends "res://addons/vest/runner/vest-base-runner.gd"
class_name VestLocalRunner
var _result_buffer: VestResult.Suite
## Run a test script
func run_script(script: Script, only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
var _result_buffer = VestResult.Suite.new()
if not script:
return null
var test_instance = script.new()
if not test_instance is VestTest:
test_instance.free()
return null
var test := test_instance as VestTest
var suite = await test._get_suite()
var run_only := false
match only_mode:
Vest.__.ONLY_DISABLED: run_only = false
Vest.__.ONLY_AUTO: run_only = suite.has_only()
Vest.__.ONLY_ENABLED: run_only = true
await test._begin(test_instance)
_result_buffer = await _run_suite(_result_buffer, suite, test, run_only)
await test._finish(test)
test.free()
return _result_buffer
## Run test scripts matching glob
## [br][br]
## See [method String.match]
func run_glob(glob: String, only_mode: int = Vest.__.ONLY_DEFAULT) -> VestResult.Suite:
_result_buffer = VestResult.Suite.new()
_result_buffer.suite = VestDefs.Suite.new()
_result_buffer.suite.name = "Glob suite \"%s\"" % [glob]
# Gather suites
var suites := [] as Array[VestDefs.Suite]
var test_instances := [] as Array[VestTest]
var has_only = false
for test_file in Vest.glob(glob):
var test := _load_test(test_file)
if not test: continue
var subsuite := await test._get_suite()
test_instances.append(test)
suites.append(subsuite)
has_only = has_only or subsuite.has_only()
# Figure out only mode
var run_only := false
match only_mode:
Vest.__.ONLY_DISABLED: run_only = false
Vest.__.ONLY_AUTO: run_only = has_only
Vest.__.ONLY_ENABLED: run_only = true
# Run suites
for i in range(suites.size()):
var suite_result := VestResult.Suite.new()
_result_buffer.subsuites.append(suite_result)
var response := await _run_suite(suite_result, suites[i], test_instances[i], run_only)
if not response:
_result_buffer.subsuites.erase(suite_result)
# Cleanup
for test in test_instances:
test.free()
return _result_buffer
func _load_test(path: String) -> VestTest:
var script := load(path)
if not script or not script is Script:
return null
var test_instance = (script as Script).new()
if not test_instance is VestTest:
return null
return test_instance as VestTest
func _run_case(case: VestDefs.Case, test_instance: VestTest, run_only: bool, is_parent_only: bool = false) -> VestResult.Case:
if run_only and not case.is_only and not is_parent_only:
return null
await test_instance._begin(case)
await case.callback.call()
await test_instance._finish(case)
on_partial_result.emit(_result_buffer)
return test_instance._get_result()
func _run_suite(result: VestResult.Suite, suite: VestDefs.Suite, test_instance: VestTest, run_only: bool, is_parent_only: bool = false) -> VestResult.Suite:
if run_only and not suite.has_only() and not is_parent_only:
return null
result.suite = suite
await test_instance._begin(suite)
for subsuite in suite.suites:
var suite_result := VestResult.Suite.new()
suite_result = await _run_suite(suite_result, subsuite, test_instance, run_only, is_parent_only or suite.is_only)
if suite_result != null:
result.subsuites.append(suite_result)
for case in suite.cases:
var case_result := await _run_case(case, test_instance, run_only, is_parent_only or suite.is_only)
if case_result != null:
result.cases.append(case_result)
await test_instance._finish(suite)
return result
@@ -0,0 +1 @@
uid://bteqiowekiut
+90
View File
@@ -0,0 +1,90 @@
extends Object
class_name TAPReporter
## Generates reports in the Test Anything Protocol format
##
## See [url]https://testanything.org/[/url]
const INDENT_SIZE := 2
## Generate a report from test suite results
static func report(suite: VestResult.Suite) -> String:
var lines := PackedStringArray()
lines.append("TAP version 14")
_report_suite(suite, lines, 0)
return "\n".join(lines)
static func _report_suite(suite: VestResult.Suite, lines: PackedStringArray, indent: int = 0):
var indent_prefix := " ".repeat(indent)
var test_count := suite.plan_size()
var test_id := 1
lines.append(indent_prefix + "1..%d" % [test_count])
for subsuite in suite.subsuites:
lines.append(indent_prefix + "# Subtest: %s" % [subsuite.suite.name])
_report_suite(subsuite, lines, indent + INDENT_SIZE)
_report_subsuite_results(test_id, subsuite, lines, indent)
test_id += 1
for case in suite.cases:
_report_case(test_id, case, lines, indent)
test_id += 1
static func _report_case(test_id: int, case: VestResult.Case, lines: PackedStringArray, indent: int = 0):
var indent_prefix := " ".repeat(indent)
var test_point := "ok"
if case.status == VestResult.TEST_FAIL:
test_point = "not ok"
var description := case.case.description
var directive = ""
match case.status:
VestResult.TEST_TODO: directive = "\t# TODO"
VestResult.TEST_SKIP: directive = "\t# SKIP"
lines.append(indent_prefix + "%s %d - %s%s" % [test_point, test_id, description, directive])
var yaml_data = {}
if case.status == VestResult.TEST_FAIL:
yaml_data["severity"] = "fail"
yaml_data["assert_source"] = case.assert_file
yaml_data["assert_line"] = case.assert_line
if not case.messages.is_empty():
yaml_data["message"] = case.messages[0]
if case.messages.size() > 1:
yaml_data["messages"] = case.messages
if case.data: yaml_data["data"] = case.data
if not yaml_data.is_empty():
_report_yaml(yaml_data, lines, indent + INDENT_SIZE)
static func _report_subsuite_results(test_id: int, subsuite: VestResult.Suite, lines: PackedStringArray, indent: int = 0):
var indent_prefix := " ".repeat(indent)
var test_point = "ok"
if subsuite.get_count_by_status(VestResult.TEST_FAIL) > 0:
test_point = "not ok"
lines.append(indent_prefix + "%s %d - %s" % [test_point, test_id, subsuite.suite.name])
if test_point != "ok":
var yaml_data = {
"pass": subsuite.get_count_by_status(VestResult.TEST_PASS),
"fail": subsuite.get_count_by_status(VestResult.TEST_FAIL),
"skip": subsuite.get_count_by_status(VestResult.TEST_SKIP),
"todo": subsuite.get_count_by_status(VestResult.TEST_TODO)
}
_report_yaml(yaml_data, lines, indent + INDENT_SIZE)
static func _report_yaml(data: Dictionary, lines: PackedStringArray, indent: int = 0):
var indent_prefix := " ".repeat(indent)
lines.append(indent_prefix + "---")
lines.append(YAMLWriter.stringify(data, indent))
lines.append(indent_prefix + "...")

Some files were not shown because too many files have changed in this diff Show More