Copy disabled (too large)
Download .txt
Showing preview only (11,254K chars total). Download the full file to get everything.
Repository: safing/portmaster
Branch: development
Commit: 368822a17eff
Files: 1599
Total size: 10.4 MB
Directory structure:
gitextract_qc0_tm9o/
├── .angulardoc.json
├── .earthlyignore
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ ├── report-bug.md
│ │ ├── report-compatibility.md
│ │ └── suggest-feature.md
│ ├── dependabot.yml
│ ├── label-actions.yml
│ └── workflows/
│ ├── angular.yml
│ ├── go.yml
│ ├── issues-first-greet.yml
│ ├── issues-label-actions.yml
│ ├── issues-stale.yml
│ ├── kext.yml
│ ├── release.yml
│ ├── tauri.yml
│ └── windows-dll.yml
├── .gitignore
├── .golangci.yml
├── .travis.yml
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── Earthfile
├── LICENSE
├── README.md
├── TESTING.md
├── TRADEMARKS
├── assets/
│ ├── data/
│ │ ├── favicons/
│ │ │ ├── browserconfig.xml
│ │ │ ├── head.html
│ │ │ └── manifest.json
│ │ ├── fonts/
│ │ │ ├── Roboto-300/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-300italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-500/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-500italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-700/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-700italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-regular/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── roboto-slimfix.css
│ │ │ └── roboto.css
│ │ ├── icons/
│ │ │ ├── README.md
│ │ │ └── generate_ico.sh
│ │ ├── img/
│ │ │ └── flags/
│ │ │ └── LICENSE.txt
│ │ └── world-50m.json
│ ├── icons.go
│ ├── icons_default.go
│ └── icons_windows.go
├── base/
│ ├── .gitignore
│ ├── README.md
│ ├── api/
│ │ ├── api_bridge.go
│ │ ├── auth_wrapper.go
│ │ ├── authentication.go
│ │ ├── authentication_test.go
│ │ ├── client/
│ │ │ ├── api.go
│ │ │ ├── client.go
│ │ │ ├── const.go
│ │ │ ├── message.go
│ │ │ └── websocket.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── endpoints.go
│ │ ├── endpoints_config.go
│ │ ├── endpoints_debug.go
│ │ ├── endpoints_meta.go
│ │ ├── endpoints_test.go
│ │ ├── enriched-response.go
│ │ ├── init_test.go
│ │ ├── main.go
│ │ ├── module.go
│ │ ├── request.go
│ │ ├── router.go
│ │ └── testclient/
│ │ ├── root/
│ │ │ └── index.html
│ │ └── serve.go
│ ├── apprise/
│ │ └── notify.go
│ ├── config/
│ │ ├── basic_config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── expertise.go
│ │ ├── get-safe.go
│ │ ├── get.go
│ │ ├── get_test.go
│ │ ├── init_test.go
│ │ ├── main.go
│ │ ├── module.go
│ │ ├── option.go
│ │ ├── persistence.go
│ │ ├── persistence_test.go
│ │ ├── perspective.go
│ │ ├── registry.go
│ │ ├── registry_test.go
│ │ ├── release.go
│ │ ├── set.go
│ │ ├── set_test.go
│ │ ├── validate.go
│ │ └── validity.go
│ ├── container/
│ │ ├── container.go
│ │ ├── container_test.go
│ │ ├── doc.go
│ │ └── serialization.go
│ ├── database/
│ │ ├── accessor/
│ │ │ ├── accessor-json-bytes.go
│ │ │ ├── accessor-json-string.go
│ │ │ ├── accessor-struct.go
│ │ │ ├── accessor.go
│ │ │ └── accessor_test.go
│ │ ├── boilerplate_test.go
│ │ ├── controller.go
│ │ ├── controllers.go
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── dbmodule/
│ │ │ ├── db.go
│ │ │ └── maintenance.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── hook.go
│ │ ├── hookbase.go
│ │ ├── interface.go
│ │ ├── interface_cache.go
│ │ ├── interface_cache_test.go
│ │ ├── iterator/
│ │ │ └── iterator.go
│ │ ├── main.go
│ │ ├── maintenance.go
│ │ ├── migration/
│ │ │ ├── error.go
│ │ │ └── migration.go
│ │ ├── query/
│ │ │ ├── README.md
│ │ │ ├── condition-and.go
│ │ │ ├── condition-bool.go
│ │ │ ├── condition-error.go
│ │ │ ├── condition-exists.go
│ │ │ ├── condition-float.go
│ │ │ ├── condition-int.go
│ │ │ ├── condition-not.go
│ │ │ ├── condition-or.go
│ │ │ ├── condition-regex.go
│ │ │ ├── condition-string.go
│ │ │ ├── condition-stringslice.go
│ │ │ ├── condition.go
│ │ │ ├── condition_test.go
│ │ │ ├── operators.go
│ │ │ ├── operators_test.go
│ │ │ ├── parser.go
│ │ │ ├── parser_test.go
│ │ │ ├── query.go
│ │ │ └── query_test.go
│ │ ├── record/
│ │ │ ├── base.go
│ │ │ ├── base_test.go
│ │ │ ├── key.go
│ │ │ ├── meta-bench_test.go
│ │ │ ├── meta-gencode.go
│ │ │ ├── meta-gencode_test.go
│ │ │ ├── meta.colf
│ │ │ ├── meta.gencode
│ │ │ ├── meta.go
│ │ │ ├── record.go
│ │ │ ├── record_test.go
│ │ │ ├── wrapper.go
│ │ │ └── wrapper_test.go
│ │ ├── registry.go
│ │ ├── storage/
│ │ │ ├── badger/
│ │ │ │ ├── badger.go
│ │ │ │ └── badger_test.go
│ │ │ ├── bbolt/
│ │ │ │ ├── bbolt.go
│ │ │ │ └── bbolt_test.go
│ │ │ ├── errors.go
│ │ │ ├── fstree/
│ │ │ │ ├── fstree.go
│ │ │ │ └── fstree_test.go
│ │ │ ├── hashmap/
│ │ │ │ ├── map.go
│ │ │ │ └── map_test.go
│ │ │ ├── injectbase.go
│ │ │ ├── interface.go
│ │ │ ├── sinkhole/
│ │ │ │ └── sinkhole.go
│ │ │ ├── sqlite/
│ │ │ │ ├── bobgen.yaml
│ │ │ │ ├── dberrors/
│ │ │ │ │ ├── bob_errors.bob.go
│ │ │ │ │ ├── bob_main.bob_test.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── dbinfo/
│ │ │ │ │ ├── bob_types.bob.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── factory/
│ │ │ │ │ ├── bobfactory_context.bob.go
│ │ │ │ │ ├── bobfactory_main.bob.go
│ │ │ │ │ ├── bobfactory_main.bob_test.go
│ │ │ │ │ ├── bobfactory_random.bob.go
│ │ │ │ │ ├── bobfactory_random.bob_test.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── migrations/
│ │ │ │ │ ├── 0_settings.sql
│ │ │ │ │ └── 1_initial.sql
│ │ │ │ ├── migrations_config.yml
│ │ │ │ ├── models/
│ │ │ │ │ ├── bob_joins.bob.go
│ │ │ │ │ ├── bob_loaders.bob.go
│ │ │ │ │ ├── bob_types.bob_test.go
│ │ │ │ │ ├── bob_where.bob.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── prepared.go
│ │ │ │ ├── prepared_test.go
│ │ │ │ ├── schema.go
│ │ │ │ ├── sqlite.go
│ │ │ │ └── sqlite_test.go
│ │ │ └── storages.go
│ │ └── subscription.go
│ ├── info/
│ │ └── version.go
│ ├── log/
│ │ ├── formatting.go
│ │ ├── formatting_unix.go
│ │ ├── formatting_windows.go
│ │ ├── input.go
│ │ ├── logging.go
│ │ ├── logging_test.go
│ │ ├── output.go
│ │ ├── slog.go
│ │ ├── trace.go
│ │ ├── trace_test.go
│ │ └── writer.go
│ ├── metrics/
│ │ ├── api.go
│ │ ├── config.go
│ │ ├── metric.go
│ │ ├── metric_counter.go
│ │ ├── metric_counter_fetching.go
│ │ ├── metric_export.go
│ │ ├── metric_gauge.go
│ │ ├── metric_histogram.go
│ │ ├── metrics_host.go
│ │ ├── metrics_info.go
│ │ ├── metrics_logs.go
│ │ ├── metrics_runtime.go
│ │ ├── module.go
│ │ └── persistence.go
│ ├── notifications/
│ │ ├── cleaner.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── module-mirror.go
│ │ ├── module.go
│ │ └── notification.go
│ ├── rng/
│ │ ├── doc.go
│ │ ├── entropy.go
│ │ ├── entropy_test.go
│ │ ├── fullfeed.go
│ │ ├── fullfeed_test.go
│ │ ├── get.go
│ │ ├── get_test.go
│ │ ├── osfeeder.go
│ │ ├── rng.go
│ │ ├── rng_test.go
│ │ └── tickfeeder.go
│ ├── runtime/
│ │ ├── module.go
│ │ ├── provider.go
│ │ ├── registry.go
│ │ ├── registry_test.go
│ │ ├── singe_record_provider.go
│ │ ├── storage.go
│ │ └── trace_provider.go
│ ├── template/
│ │ └── module.go
│ └── utils/
│ ├── atomic.go
│ ├── broadcastflag.go
│ ├── call_limiter.go
│ ├── call_limiter2.go
│ ├── call_limiter_test.go
│ ├── debug/
│ │ ├── debug.go
│ │ ├── debug_android.go
│ │ └── debug_default.go
│ ├── fs.go
│ ├── mimetypes.go
│ ├── onceagain.go
│ ├── onceagain_test.go
│ ├── osdetail/
│ │ ├── colors_windows.go
│ │ ├── command.go
│ │ ├── dnscache_windows.go
│ │ ├── errors.go
│ │ ├── service_windows.go
│ │ ├── shell_windows.go
│ │ ├── svchost_windows.go
│ │ ├── version_windows.go
│ │ └── version_windows_test.go
│ ├── permissions.go
│ ├── permissions_windows.go
│ ├── renameio/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── doc.go
│ │ ├── example_test.go
│ │ ├── symlink_test.go
│ │ ├── tempfile.go
│ │ ├── tempfile_linux_test.go
│ │ ├── writefile.go
│ │ └── writefile_test.go
│ ├── safe.go
│ ├── safe_test.go
│ ├── slices.go
│ ├── slices_test.go
│ ├── stablepool.go
│ ├── stablepool_test.go
│ ├── structure.go
│ ├── structure_test.go
│ ├── uuid.go
│ └── uuid_test.go
├── cmds/
│ ├── cmdbase/
│ │ ├── service.go
│ │ ├── service_linux.go
│ │ ├── service_windows.go
│ │ ├── update.go
│ │ └── version.go
│ ├── integrationtest/
│ │ ├── main.go
│ │ └── netstate.go
│ ├── trafficgen/
│ │ ├── main.go
│ │ └── pack
│ └── winkext-test/
│ ├── main.go
│ ├── main_linux.go
│ └── pack
├── desktop/
│ ├── angular/
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ ├── .vscode/
│ │ │ ├── launch.json
│ │ │ └── tasks.json
│ │ ├── README.md
│ │ ├── angular.json
│ │ ├── browser-extension-dev.config.ts
│ │ ├── browser-extension.config.ts
│ │ ├── docker.sh
│ │ ├── e2e/
│ │ │ ├── protractor.conf.js
│ │ │ ├── src/
│ │ │ │ ├── app.e2e-spec.ts
│ │ │ │ └── app.po.ts
│ │ │ └── tsconfig.json
│ │ ├── karma.conf.js
│ │ ├── package.json
│ │ ├── projects/
│ │ │ ├── portmaster-chrome-extension/
│ │ │ │ ├── karma.conf.js
│ │ │ │ ├── src/
│ │ │ │ │ ├── app/
│ │ │ │ │ │ ├── app-routing.module.ts
│ │ │ │ │ │ ├── app.component.html
│ │ │ │ │ │ ├── app.component.scss
│ │ │ │ │ │ ├── app.component.ts
│ │ │ │ │ │ ├── app.module.ts
│ │ │ │ │ │ ├── domain-list/
│ │ │ │ │ │ │ ├── domain-list.component.html
│ │ │ │ │ │ │ ├── domain-list.component.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── header/
│ │ │ │ │ │ │ ├── header.component.html
│ │ │ │ │ │ │ ├── header.component.scss
│ │ │ │ │ │ │ ├── header.component.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── interceptor.ts
│ │ │ │ │ │ ├── request-interceptor.service.ts
│ │ │ │ │ │ └── welcome/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── intro.component.html
│ │ │ │ │ │ ├── intro.component.ts
│ │ │ │ │ │ └── welcome.module.ts
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ ├── background/
│ │ │ │ │ │ ├── commands.ts
│ │ │ │ │ │ ├── tab-tracker.ts
│ │ │ │ │ │ └── tab-utils.ts
│ │ │ │ │ ├── background.ts
│ │ │ │ │ ├── environments/
│ │ │ │ │ │ ├── environment.prod.ts
│ │ │ │ │ │ └── environment.ts
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── main.ts
│ │ │ │ │ ├── manifest.json
│ │ │ │ │ ├── polyfills.ts
│ │ │ │ │ ├── styles.scss
│ │ │ │ │ └── test.ts
│ │ │ │ ├── tsconfig.app.json
│ │ │ │ └── tsconfig.spec.json
│ │ │ ├── safing/
│ │ │ │ ├── portmaster-api/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── karma.conf.js
│ │ │ │ │ ├── ng-package.json
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── src/
│ │ │ │ │ │ ├── lib/
│ │ │ │ │ │ │ ├── app-profile.service.ts
│ │ │ │ │ │ │ ├── app-profile.types.ts
│ │ │ │ │ │ │ ├── config.service.ts
│ │ │ │ │ │ │ ├── config.types.ts
│ │ │ │ │ │ │ ├── core.types.ts
│ │ │ │ │ │ │ ├── debug-api.service.ts
│ │ │ │ │ │ │ ├── features.ts
│ │ │ │ │ │ │ ├── meta-api.service.ts
│ │ │ │ │ │ │ ├── module.ts
│ │ │ │ │ │ │ ├── netquery.service.ts
│ │ │ │ │ │ │ ├── network.types.ts
│ │ │ │ │ │ │ ├── platform-specific/
│ │ │ │ │ │ │ │ ├── tauri/
│ │ │ │ │ │ │ │ │ ├── tauri-http-interceptor.ts
│ │ │ │ │ │ │ │ │ └── tauri-websocket-subject.ts
│ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ ├── portapi.service.ts
│ │ │ │ │ │ │ ├── portapi.types.ts
│ │ │ │ │ │ │ ├── spn.service.ts
│ │ │ │ │ │ │ ├── spn.types.ts
│ │ │ │ │ │ │ ├── utils.ts
│ │ │ │ │ │ │ └── websocket.service.ts
│ │ │ │ │ │ ├── public-api.ts
│ │ │ │ │ │ └── test.ts
│ │ │ │ │ ├── tsconfig.lib.json
│ │ │ │ │ ├── tsconfig.lib.prod.json
│ │ │ │ │ └── tsconfig.spec.json
│ │ │ │ └── ui/
│ │ │ │ ├── .eslintrc.json
│ │ │ │ ├── README.md
│ │ │ │ ├── karma.conf.js
│ │ │ │ ├── ng-package.json
│ │ │ │ ├── package.json
│ │ │ │ ├── src/
│ │ │ │ │ ├── lib/
│ │ │ │ │ │ ├── accordion/
│ │ │ │ │ │ │ ├── accordion-group.html
│ │ │ │ │ │ │ ├── accordion-group.ts
│ │ │ │ │ │ │ ├── accordion.html
│ │ │ │ │ │ │ ├── accordion.module.ts
│ │ │ │ │ │ │ ├── accordion.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── animations/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── dialog/
│ │ │ │ │ │ │ ├── _confirm.dialog.scss
│ │ │ │ │ │ │ ├── _dialog.scss
│ │ │ │ │ │ │ ├── confirm.dialog.html
│ │ │ │ │ │ │ ├── confirm.dialog.ts
│ │ │ │ │ │ │ ├── dialog.animations.ts
│ │ │ │ │ │ │ ├── dialog.container.ts
│ │ │ │ │ │ │ ├── dialog.module.ts
│ │ │ │ │ │ │ ├── dialog.ref.ts
│ │ │ │ │ │ │ ├── dialog.service.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── dropdown/
│ │ │ │ │ │ │ ├── dropdown.html
│ │ │ │ │ │ │ ├── dropdown.module.ts
│ │ │ │ │ │ │ ├── dropdown.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── overlay-stepper/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── overlay-stepper-container.html
│ │ │ │ │ │ │ ├── overlay-stepper-container.ts
│ │ │ │ │ │ │ ├── overlay-stepper.module.ts
│ │ │ │ │ │ │ ├── overlay-stepper.ts
│ │ │ │ │ │ │ ├── refs.ts
│ │ │ │ │ │ │ ├── step-outlet.ts
│ │ │ │ │ │ │ └── step.ts
│ │ │ │ │ │ ├── pagination/
│ │ │ │ │ │ │ ├── _pagination.scss
│ │ │ │ │ │ │ ├── dynamic-items-paginator.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pagination.html
│ │ │ │ │ │ │ ├── pagination.module.ts
│ │ │ │ │ │ │ ├── pagination.ts
│ │ │ │ │ │ │ └── snapshot-paginator.ts
│ │ │ │ │ │ ├── select/
│ │ │ │ │ │ │ ├── _select.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── item.ts
│ │ │ │ │ │ │ ├── select.html
│ │ │ │ │ │ │ ├── select.module.ts
│ │ │ │ │ │ │ └── select.ts
│ │ │ │ │ │ ├── tabs/
│ │ │ │ │ │ │ ├── _tab-group.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── tab-group.html
│ │ │ │ │ │ │ ├── tab-group.ts
│ │ │ │ │ │ │ ├── tab.ts
│ │ │ │ │ │ │ └── tabs.module.ts
│ │ │ │ │ │ ├── tipup/
│ │ │ │ │ │ │ ├── _tipup.scss
│ │ │ │ │ │ │ ├── anchor.ts
│ │ │ │ │ │ │ ├── clone-node.ts
│ │ │ │ │ │ │ ├── css-utils.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── safe.pipe.ts
│ │ │ │ │ │ │ ├── tipup-component.ts
│ │ │ │ │ │ │ ├── tipup.html
│ │ │ │ │ │ │ ├── tipup.module.ts
│ │ │ │ │ │ │ ├── tipup.ts
│ │ │ │ │ │ │ ├── translations.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── toggle-switch/
│ │ │ │ │ │ │ ├── _toggle-switch.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── toggle-switch.html
│ │ │ │ │ │ │ ├── toggle-switch.ts
│ │ │ │ │ │ │ └── toggle.module.ts
│ │ │ │ │ │ ├── tooltip/
│ │ │ │ │ │ │ ├── _tooltip-component.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── tooltip-component.html
│ │ │ │ │ │ │ ├── tooltip-component.ts
│ │ │ │ │ │ │ ├── tooltip.module.ts
│ │ │ │ │ │ │ └── tooltip.ts
│ │ │ │ │ │ └── ui.module.ts
│ │ │ │ │ ├── public-api.ts
│ │ │ │ │ └── test.ts
│ │ │ │ ├── theming.scss
│ │ │ │ ├── tsconfig.lib.json
│ │ │ │ ├── tsconfig.lib.prod.json
│ │ │ │ └── tsconfig.spec.json
│ │ │ └── tauri-builtin/
│ │ │ ├── src/
│ │ │ │ ├── app/
│ │ │ │ │ ├── app.component.html
│ │ │ │ │ ├── app.component.ts
│ │ │ │ │ └── app.config.ts
│ │ │ │ ├── index.html
│ │ │ │ ├── main.ts
│ │ │ │ └── styles.scss
│ │ │ └── tsconfig.app.json
│ │ ├── proxy.json
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── app-routing.module.ts
│ │ │ │ ├── app.component.html
│ │ │ │ ├── app.component.scss
│ │ │ │ ├── app.component.spec.ts
│ │ │ │ ├── app.component.ts
│ │ │ │ ├── app.module.ts
│ │ │ │ ├── integration/
│ │ │ │ │ ├── browser.ts
│ │ │ │ │ ├── electron.ts
│ │ │ │ │ ├── factory.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── integration.ts
│ │ │ │ │ └── taur-app.ts
│ │ │ │ ├── intro/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── intro.module.ts
│ │ │ │ │ ├── step-1-welcome/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-1-welcome.html
│ │ │ │ │ │ └── step-1-welcome.ts
│ │ │ │ │ ├── step-2-trackers/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-2-trackers.html
│ │ │ │ │ │ └── step-2-trackers.ts
│ │ │ │ │ ├── step-3-dns/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-3-dns.html
│ │ │ │ │ │ └── step-3-dns.ts
│ │ │ │ │ ├── step-4-tipups/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-4-tipups.html
│ │ │ │ │ │ └── step-4-tipups.ts
│ │ │ │ │ └── step.scss
│ │ │ │ ├── layout/
│ │ │ │ │ ├── navigation/
│ │ │ │ │ │ ├── navigation.html
│ │ │ │ │ │ ├── navigation.scss
│ │ │ │ │ │ └── navigation.ts
│ │ │ │ │ └── side-dash/
│ │ │ │ │ ├── side-dash.html
│ │ │ │ │ ├── side-dash.scss
│ │ │ │ │ └── side-dash.ts
│ │ │ │ ├── package.json
│ │ │ │ ├── pages/
│ │ │ │ │ ├── app-view/
│ │ │ │ │ │ ├── app-insights/
│ │ │ │ │ │ │ ├── app-insights.component.html
│ │ │ │ │ │ │ └── app-insights.component.ts
│ │ │ │ │ │ ├── app-view.html
│ │ │ │ │ │ ├── app-view.scss
│ │ │ │ │ │ ├── app-view.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── merge-profile-dialog/
│ │ │ │ │ │ │ ├── merge-profile-dialog.component.html
│ │ │ │ │ │ │ └── merge-profile-dialog.component.ts
│ │ │ │ │ │ ├── overview.html
│ │ │ │ │ │ ├── overview.scss
│ │ │ │ │ │ ├── overview.ts
│ │ │ │ │ │ ├── qs-history/
│ │ │ │ │ │ │ ├── qs-history.component.html
│ │ │ │ │ │ │ ├── qs-history.component.scss
│ │ │ │ │ │ │ └── qs-history.component.ts
│ │ │ │ │ │ ├── qs-internet/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── qs-internet.html
│ │ │ │ │ │ │ └── qs-internet.ts
│ │ │ │ │ │ ├── qs-select-exit/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── qs-select-exit.html
│ │ │ │ │ │ │ ├── qs-select-exit.scss
│ │ │ │ │ │ │ └── qs-select-exit.ts
│ │ │ │ │ │ └── qs-use-spn/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── qs-use-spn.html
│ │ │ │ │ │ └── qs-use-spn.ts
│ │ │ │ │ ├── dashboard/
│ │ │ │ │ │ ├── dashboard-widget/
│ │ │ │ │ │ │ ├── dashboard-widget.component.html
│ │ │ │ │ │ │ └── dashboard-widget.component.ts
│ │ │ │ │ │ ├── dashboard.component.html
│ │ │ │ │ │ ├── dashboard.component.scss
│ │ │ │ │ │ ├── dashboard.component.ts
│ │ │ │ │ │ └── feature-card/
│ │ │ │ │ │ ├── feature-card.component.html
│ │ │ │ │ │ ├── feature-card.component.scss
│ │ │ │ │ │ └── feature-card.component.ts
│ │ │ │ │ ├── monitor/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── monitor.html
│ │ │ │ │ │ ├── monitor.scss
│ │ │ │ │ │ └── monitor.ts
│ │ │ │ │ ├── page.scss
│ │ │ │ │ ├── settings/
│ │ │ │ │ │ ├── settings.html
│ │ │ │ │ │ ├── settings.scss
│ │ │ │ │ │ └── settings.ts
│ │ │ │ │ ├── spn/
│ │ │ │ │ │ ├── country-details/
│ │ │ │ │ │ │ ├── country-details.html
│ │ │ │ │ │ │ ├── country-details.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── country-overlay/
│ │ │ │ │ │ │ ├── country-overlay.html
│ │ │ │ │ │ │ ├── country-overlay.scss
│ │ │ │ │ │ │ ├── country-overlay.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── map-legend/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── map-legend.html
│ │ │ │ │ │ │ └── map-legend.ts
│ │ │ │ │ │ ├── map-renderer/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── map-renderer.ts
│ │ │ │ │ │ │ └── map-style.scss
│ │ │ │ │ │ ├── map.service.ts
│ │ │ │ │ │ ├── node-icon/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── node-icon.html
│ │ │ │ │ │ │ ├── node-icon.scss
│ │ │ │ │ │ │ └── node-icon.ts
│ │ │ │ │ │ ├── pin-details/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-details.html
│ │ │ │ │ │ │ └── pin-details.ts
│ │ │ │ │ │ ├── pin-list/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-list.html
│ │ │ │ │ │ │ └── pin-list.ts
│ │ │ │ │ │ ├── pin-overlay/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-overlay.html
│ │ │ │ │ │ │ ├── pin-overlay.scss
│ │ │ │ │ │ │ └── pin-overlay.ts
│ │ │ │ │ │ ├── pin-route/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-route.html
│ │ │ │ │ │ │ ├── pin-route.scss
│ │ │ │ │ │ │ └── pin-route.ts
│ │ │ │ │ │ ├── spn-feature-carousel/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── spn-feature-carousel.html
│ │ │ │ │ │ │ ├── spn-feature-carousel.scss
│ │ │ │ │ │ │ └── spn-feature-carousel.ts
│ │ │ │ │ │ ├── spn-page.html
│ │ │ │ │ │ ├── spn-page.scss
│ │ │ │ │ │ ├── spn-page.ts
│ │ │ │ │ │ ├── spn.module.ts
│ │ │ │ │ │ └── utils.ts
│ │ │ │ │ └── support/
│ │ │ │ │ ├── form/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── support-form.html
│ │ │ │ │ │ ├── support-form.scss
│ │ │ │ │ │ └── support-form.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── pages.ts
│ │ │ │ │ ├── progress-dialog/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── progress-dialog.html
│ │ │ │ │ │ └── progress-dialog.ts
│ │ │ │ │ ├── support.html
│ │ │ │ │ ├── support.scss
│ │ │ │ │ └── support.ts
│ │ │ │ ├── prompt-entrypoint/
│ │ │ │ │ ├── prompt-entrypoint.ts
│ │ │ │ │ └── prompt.html
│ │ │ │ ├── services/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── notifications.service.spec.ts
│ │ │ │ │ ├── notifications.service.ts
│ │ │ │ │ ├── notifications.types.ts
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── session-data.service.ts
│ │ │ │ │ ├── status.service.spec.ts
│ │ │ │ │ ├── status.service.ts
│ │ │ │ │ ├── status.types.ts
│ │ │ │ │ ├── supporthub.service.ts
│ │ │ │ │ ├── ui-state.service.ts
│ │ │ │ │ └── virtual-notification.ts
│ │ │ │ └── shared/
│ │ │ │ ├── action-indicator/
│ │ │ │ │ ├── action-indicator.module.ts
│ │ │ │ │ ├── action-indicator.service.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── indicator.html
│ │ │ │ │ ├── indicator.scss
│ │ │ │ │ └── indicator.ts
│ │ │ │ ├── animations.ts
│ │ │ │ ├── app-icon/
│ │ │ │ │ ├── app-icon-resolver.ts
│ │ │ │ │ ├── app-icon.html
│ │ │ │ │ ├── app-icon.module.ts
│ │ │ │ │ ├── app-icon.scss
│ │ │ │ │ ├── app-icon.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── config/
│ │ │ │ │ ├── basic-setting/
│ │ │ │ │ │ ├── basic-setting.html
│ │ │ │ │ │ ├── basic-setting.scss
│ │ │ │ │ │ ├── basic-setting.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── config-settings.html
│ │ │ │ │ ├── config-settings.scss
│ │ │ │ │ ├── config-settings.ts
│ │ │ │ │ ├── config.module.ts
│ │ │ │ │ ├── export-dialog/
│ │ │ │ │ │ ├── export-dialog.component.html
│ │ │ │ │ │ └── export-dialog.component.ts
│ │ │ │ │ ├── filter-lists/
│ │ │ │ │ │ ├── filter-list.html
│ │ │ │ │ │ ├── filter-list.scss
│ │ │ │ │ │ ├── filter-list.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── generic-setting/
│ │ │ │ │ │ ├── generic-setting.html
│ │ │ │ │ │ ├── generic-setting.scss
│ │ │ │ │ │ ├── generic-setting.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── import-dialog/
│ │ │ │ │ │ ├── cursor.ts
│ │ │ │ │ │ ├── import-dialog.component.html
│ │ │ │ │ │ ├── import-dialog.component.ts
│ │ │ │ │ │ └── selection.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── ordererd-list/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── item.html
│ │ │ │ │ │ ├── item.scss
│ │ │ │ │ │ ├── item.ts
│ │ │ │ │ │ ├── ordered-list.html
│ │ │ │ │ │ ├── ordered-list.scss
│ │ │ │ │ │ └── ordered-list.ts
│ │ │ │ │ ├── rule-list/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── list-item.html
│ │ │ │ │ │ ├── list-item.scss
│ │ │ │ │ │ ├── list-item.ts
│ │ │ │ │ │ ├── rule-list.html
│ │ │ │ │ │ ├── rule-list.scss
│ │ │ │ │ │ └── rule-list.ts
│ │ │ │ │ ├── safe.pipe.ts
│ │ │ │ │ └── subsystems.ts
│ │ │ │ ├── count-indicator/
│ │ │ │ │ ├── count-indicator.html
│ │ │ │ │ ├── count-indicator.module.ts
│ │ │ │ │ ├── count-indicator.scss
│ │ │ │ │ ├── count-indicator.ts
│ │ │ │ │ ├── count.pipe.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── country-flag/
│ │ │ │ │ ├── country-flag.ts
│ │ │ │ │ ├── country.module.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── edit-profile-dialog/
│ │ │ │ │ ├── edit-profile-dialog.html
│ │ │ │ │ ├── edit-profile-dialog.scss
│ │ │ │ │ ├── edit-profile-dialog.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── exit-screen/
│ │ │ │ │ ├── exit-screen.html
│ │ │ │ │ ├── exit-screen.scss
│ │ │ │ │ ├── exit-screen.ts
│ │ │ │ │ ├── exit.service.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── expertise/
│ │ │ │ │ ├── expertise-directive.ts
│ │ │ │ │ ├── expertise-switch.html
│ │ │ │ │ ├── expertise-switch.scss
│ │ │ │ │ ├── expertise-switch.ts
│ │ │ │ │ ├── expertise.module.ts
│ │ │ │ │ ├── expertise.service.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── external-link.directive.ts
│ │ │ │ ├── feature-scout/
│ │ │ │ │ ├── feature-scout.html
│ │ │ │ │ ├── feature-scout.scss
│ │ │ │ │ ├── feature-scout.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── focus/
│ │ │ │ │ ├── focus.directive.ts
│ │ │ │ │ ├── focus.module.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── fuzzySearch/
│ │ │ │ │ ├── fuse.service.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── search-pipe.ts
│ │ │ │ ├── loading/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── loading.html
│ │ │ │ │ ├── loading.scss
│ │ │ │ │ └── loading.ts
│ │ │ │ ├── menu/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── menu-group.scss
│ │ │ │ │ ├── menu-item.scss
│ │ │ │ │ ├── menu-trigger.html
│ │ │ │ │ ├── menu-trigger.scss
│ │ │ │ │ ├── menu.html
│ │ │ │ │ ├── menu.module.ts
│ │ │ │ │ └── menu.ts
│ │ │ │ ├── multi-switch/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── multi-switch.html
│ │ │ │ │ ├── multi-switch.module.ts
│ │ │ │ │ ├── multi-switch.scss
│ │ │ │ │ ├── multi-switch.ts
│ │ │ │ │ ├── switch-item.scss
│ │ │ │ │ └── switch-item.ts
│ │ │ │ ├── netquery/
│ │ │ │ │ ├── .eslintrc.json
│ │ │ │ │ ├── add-to-filter/
│ │ │ │ │ │ ├── add-to-filter.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── circular-bar-chart/
│ │ │ │ │ │ └── circular-bar-chart.component.ts
│ │ │ │ │ ├── combined-menu.pipe.ts
│ │ │ │ │ ├── connection-details/
│ │ │ │ │ │ ├── conn-details.html
│ │ │ │ │ │ ├── conn-details.scss
│ │ │ │ │ │ ├── conn-details.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── connection-helper.service.ts
│ │ │ │ │ ├── connection-row/
│ │ │ │ │ │ ├── conn-row.html
│ │ │ │ │ │ ├── conn-row.scss
│ │ │ │ │ │ ├── conn-row.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── line-chart/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── line-chart.ts
│ │ │ │ │ ├── netquery.component.html
│ │ │ │ │ ├── netquery.component.ts
│ │ │ │ │ ├── netquery.module.ts
│ │ │ │ │ ├── pipes/
│ │ │ │ │ │ ├── can-show.pipe.ts
│ │ │ │ │ │ ├── can-use-rules.pipe.ts
│ │ │ │ │ │ ├── country-name.pipe.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── is-blocked.pipe.ts
│ │ │ │ │ │ └── location.pipe.ts
│ │ │ │ │ ├── scope-label/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── scope-label.html
│ │ │ │ │ │ └── scope-label.ts
│ │ │ │ │ ├── search-overlay/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── search-overlay.html
│ │ │ │ │ │ └── search-overlay.ts
│ │ │ │ │ ├── searchbar/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── searchbar.html
│ │ │ │ │ │ └── searchbar.ts
│ │ │ │ │ ├── tag-bar/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── tag-bar.html
│ │ │ │ │ │ └── tag-bar.ts
│ │ │ │ │ ├── textql/
│ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── input.ts
│ │ │ │ │ │ ├── lexer.ts
│ │ │ │ │ │ ├── parser.ts
│ │ │ │ │ │ └── token.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── network-scout/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── network-scout.html
│ │ │ │ │ ├── network-scout.scss
│ │ │ │ │ └── network-scout.ts
│ │ │ │ ├── notification/
│ │ │ │ │ ├── notification.html
│ │ │ │ │ ├── notification.scss
│ │ │ │ │ └── notification.ts
│ │ │ │ ├── notification-list/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── notification-list.component.html
│ │ │ │ │ ├── notification-list.component.scss
│ │ │ │ │ └── notification-list.component.ts
│ │ │ │ ├── pipes/
│ │ │ │ │ ├── bytes.pipe.ts
│ │ │ │ │ ├── common-pipes.module.ts
│ │ │ │ │ ├── duration.pipe.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── round.pipe.ts
│ │ │ │ │ ├── time-ago.pipe.ts
│ │ │ │ │ ├── to-profile.pipe.ts
│ │ │ │ │ └── to-seconds.pipe.ts
│ │ │ │ ├── process-details-dialog/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── process-details-dialog.html
│ │ │ │ │ ├── process-details-dialog.scss
│ │ │ │ │ └── process-details-dialog.ts
│ │ │ │ ├── prompt-list/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── prompt-list.component.html
│ │ │ │ │ ├── prompt-list.component.scss
│ │ │ │ │ └── prompt-list.component.ts
│ │ │ │ ├── security-lock/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── security-lock.html
│ │ │ │ │ ├── security-lock.scss
│ │ │ │ │ └── security-lock.ts
│ │ │ │ ├── spn-account-details/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-account-details.html
│ │ │ │ │ ├── spn-account-details.scss
│ │ │ │ │ └── spn-account-details.ts
│ │ │ │ ├── spn-login/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-login.html
│ │ │ │ │ ├── spn-login.scss
│ │ │ │ │ └── spn-login.ts
│ │ │ │ ├── spn-network-status/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-network-status.html
│ │ │ │ │ ├── spn-network-status.scss
│ │ │ │ │ └── spn-network-status.ts
│ │ │ │ ├── spn-status/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-status.html
│ │ │ │ │ └── spn-status.ts
│ │ │ │ ├── text-placeholder/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── placeholder.scss
│ │ │ │ │ └── placeholder.ts
│ │ │ │ └── utils.ts
│ │ │ ├── electron-app.d.ts
│ │ │ ├── environments/
│ │ │ │ ├── environment.prod.ts
│ │ │ │ └── environment.ts
│ │ │ ├── i18n/
│ │ │ │ ├── helptexts.yaml
│ │ │ │ └── helptexts.yaml.d.ts
│ │ │ ├── index.html
│ │ │ ├── main.ts
│ │ │ ├── polyfills.ts
│ │ │ ├── styles.scss
│ │ │ ├── test.ts
│ │ │ ├── theme/
│ │ │ │ ├── _breadcrumbs.scss
│ │ │ │ ├── _button.scss
│ │ │ │ ├── _card.scss
│ │ │ │ ├── _colors.scss
│ │ │ │ ├── _dialog.scss
│ │ │ │ ├── _drag-n-drop.scss
│ │ │ │ ├── _inputs.scss
│ │ │ │ ├── _markdown.scss
│ │ │ │ ├── _pill.scss
│ │ │ │ ├── _scroll.scss
│ │ │ │ ├── _search.scss
│ │ │ │ ├── _table.scss
│ │ │ │ ├── _tailwind.scss
│ │ │ │ ├── _trust-level.scss
│ │ │ │ ├── _typography.scss
│ │ │ │ ├── _verdict.scss
│ │ │ │ └── mixins/
│ │ │ │ └── _pill.scss
│ │ │ └── theme.less
│ │ ├── tailwind.config.js
│ │ ├── tsconfig.app.json
│ │ ├── tsconfig.json
│ │ └── tsconfig.spec.json
│ └── tauri/
│ ├── .cargo/
│ │ └── config.toml
│ ├── .vscode/
│ │ ├── launch.json
│ │ └── tasks.json
│ └── src-tauri/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── Cross.toml
│ ├── README.md
│ ├── build.rs
│ ├── capabilities/
│ │ └── default.json
│ ├── src/
│ │ ├── cli.rs
│ │ ├── commands/
│ │ │ ├── mod.rs
│ │ │ └── tauri_http.rs
│ │ ├── config.rs
│ │ ├── main.rs
│ │ ├── portapi/
│ │ │ ├── client.rs
│ │ │ ├── message.rs
│ │ │ ├── mod.rs
│ │ │ ├── models/
│ │ │ │ ├── config.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── notification.rs
│ │ │ │ ├── spn.rs
│ │ │ │ └── system_status_types.rs
│ │ │ └── types.rs
│ │ ├── portmaster/
│ │ │ ├── commands.rs
│ │ │ ├── mod.rs
│ │ │ ├── notifications.rs
│ │ │ └── websocket.rs
│ │ ├── service/
│ │ │ ├── manager.rs
│ │ │ ├── mod.rs
│ │ │ ├── status.rs
│ │ │ ├── systemd.rs
│ │ │ └── windows_service.rs
│ │ ├── traymenu.rs
│ │ ├── window.rs
│ │ └── xdg/
│ │ └── mod.rs
│ ├── tauri.conf.json5
│ └── templates/
│ ├── NSIS_Simple_Service_Plugin_Unicode_1.30/
│ │ ├── License.txt
│ │ ├── Readme.txt
│ │ └── Source/
│ │ ├── LSASecurityControl.pas
│ │ ├── NSIS Plugins.groupproj
│ │ ├── NSIS.pas
│ │ ├── ServiceControl.pas
│ │ ├── SimpleSC.dpr
│ │ ├── SimpleSC.dproj
│ │ └── SimpleSC.res
│ ├── nsis/
│ │ └── install_hooks.nsh
│ └── wix/
│ ├── CheckServiceStatus.vbs
│ ├── Migration.vbs
│ ├── files.wxs
│ ├── main.wxs
│ ├── main_original.wxs
│ ├── migration.wxs
│ └── old_service_check.wxs
├── go.mod
├── go.sum
├── packaging/
│ ├── README.md
│ ├── linux/
│ │ ├── dev_helpers/
│ │ │ └── build_tauri.sh
│ │ ├── portmaster-autostart.desktop
│ │ ├── portmaster.desktop
│ │ ├── portmaster.service
│ │ ├── postinst
│ │ ├── postrm
│ │ └── readme.md
│ └── windows/
│ ├── .gitkeep
│ ├── dev_helpers/
│ │ ├── build_angular.ps1
│ │ └── build_tauri.ps1
│ ├── generate_windows_installers.ps1
│ └── sign_binaries_in_dist.ps1
├── runtime/
│ └── .gitkeep
├── service/
│ ├── broadcasts/
│ │ ├── api.go
│ │ ├── data.go
│ │ ├── install_info.go
│ │ ├── module.go
│ │ ├── notify.go
│ │ └── state.go
│ ├── compat/
│ │ ├── api.go
│ │ ├── callbacks.go
│ │ ├── debug_default.go
│ │ ├── debug_linux.go
│ │ ├── debug_windows.go
│ │ ├── iptables.go
│ │ ├── iptables_test.go
│ │ ├── module.go
│ │ ├── notify.go
│ │ ├── selfcheck.go
│ │ ├── wfpstate.go
│ │ └── wfpstate_test.go
│ ├── config.go
│ ├── configure/
│ │ └── updates.go
│ ├── control/
│ │ ├── api.go
│ │ ├── module.go
│ │ └── pause.go
│ ├── core/
│ │ ├── api.go
│ │ ├── base/
│ │ │ ├── databases.go
│ │ │ ├── logs.go
│ │ │ ├── module.go
│ │ │ └── profiling.go
│ │ ├── config.go
│ │ ├── core.go
│ │ ├── events.go
│ │ ├── os_default.go
│ │ ├── os_windows.go
│ │ ├── update_config.go
│ │ └── update_versions.go
│ ├── debug.go
│ ├── debug_test.go
│ ├── detection/
│ │ └── dga/
│ │ ├── lms.go
│ │ └── lms_test.go
│ ├── firewall/
│ │ ├── api.go
│ │ ├── bypassing.go
│ │ ├── config.go
│ │ ├── dns.go
│ │ ├── inspection/
│ │ │ └── inspection.go
│ │ ├── interception/
│ │ │ ├── dnsmonitor/
│ │ │ │ ├── etwlink_windows.go
│ │ │ │ ├── eventlistener.go
│ │ │ │ ├── eventlistener_linux.go
│ │ │ │ ├── eventlistener_windows.go
│ │ │ │ ├── module.go
│ │ │ │ └── varlinktypes.go
│ │ │ ├── ebpf/
│ │ │ │ ├── bandwidth/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── interface.go
│ │ │ │ ├── connection_listener/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── worker.go
│ │ │ │ ├── exec/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── exec.go
│ │ │ │ └── programs/
│ │ │ │ ├── bandwidth.c
│ │ │ │ ├── bpf/
│ │ │ │ │ ├── bpf_core_read.h
│ │ │ │ │ ├── bpf_helper_defs.h
│ │ │ │ │ ├── bpf_helpers.h
│ │ │ │ │ └── bpf_tracing.h
│ │ │ │ ├── exec.c
│ │ │ │ ├── monitor.c
│ │ │ │ ├── update.sh
│ │ │ │ └── vmlinux-x86.h
│ │ │ ├── interception_default.go
│ │ │ ├── interception_linux.go
│ │ │ ├── interception_windows.go
│ │ │ ├── introspection.go
│ │ │ ├── module.go
│ │ │ ├── nfq/
│ │ │ │ ├── conntrack.go
│ │ │ │ ├── nfq.go
│ │ │ │ └── packet.go
│ │ │ ├── nfqueue_linux.go
│ │ │ ├── packet_tracer.go
│ │ │ ├── windowskext/
│ │ │ │ ├── bandwidth_stats.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── handler.go
│ │ │ │ ├── kext.go
│ │ │ │ ├── packet.go
│ │ │ │ ├── service.go
│ │ │ │ └── syscall.go
│ │ │ └── windowskext2/
│ │ │ ├── doc.go
│ │ │ ├── handler.go
│ │ │ ├── kext.go
│ │ │ ├── packet.go
│ │ │ └── service.go
│ │ ├── master.go
│ │ ├── module.go
│ │ ├── packet_handler.go
│ │ ├── preauth.go
│ │ ├── prompt.go
│ │ └── tunnel.go
│ ├── instance.go
│ ├── integration/
│ │ ├── etw_windows.go
│ │ ├── integration.go
│ │ ├── integration_windows.go
│ │ └── module.go
│ ├── intel/
│ │ ├── block_reason.go
│ │ ├── customlists/
│ │ │ ├── config.go
│ │ │ ├── lists.go
│ │ │ └── module.go
│ │ ├── entity.go
│ │ ├── entity_test.go
│ │ ├── filterlists/
│ │ │ ├── bloom.go
│ │ │ ├── cache_version.go
│ │ │ ├── database.go
│ │ │ ├── decoder.go
│ │ │ ├── index.go
│ │ │ ├── keys.go
│ │ │ ├── lookup.go
│ │ │ ├── module.go
│ │ │ ├── module_test.go
│ │ │ ├── record.go
│ │ │ └── updater.go
│ │ ├── geoip/
│ │ │ ├── country_info.go
│ │ │ ├── country_info_test.go
│ │ │ ├── database.go
│ │ │ ├── init_test.go
│ │ │ ├── location.go
│ │ │ ├── location_test.go
│ │ │ ├── lookup.go
│ │ │ ├── lookup_test.go
│ │ │ ├── module.go
│ │ │ ├── regions.go
│ │ │ └── regions_test.go
│ │ └── resolver.go
│ ├── interop/
│ │ ├── api.go
│ │ ├── ivpn/
│ │ │ ├── ivpn.go
│ │ │ └── notification.go
│ │ ├── module.go
│ │ └── verdict_handler.go
│ ├── mgr/
│ │ ├── doc.go
│ │ ├── events.go
│ │ ├── group.go
│ │ ├── group_ext.go
│ │ ├── group_module.go
│ │ ├── manager.go
│ │ ├── sleepyticker.go
│ │ ├── sleepyticker_test.go
│ │ ├── states.go
│ │ ├── worker.go
│ │ ├── worker_info.go
│ │ ├── worker_test.go
│ │ ├── workermgr.go
│ │ └── workermgr_test.go
│ ├── nameserver/
│ │ ├── config.go
│ │ ├── conflict.go
│ │ ├── failing.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── nameserver.go
│ │ ├── nsutil/
│ │ │ └── nsutil.go
│ │ └── response.go
│ ├── netenv/
│ │ ├── addresses_test.go
│ │ ├── adresses.go
│ │ ├── api.go
│ │ ├── dbus_linux.go
│ │ ├── dbus_linux_test.go
│ │ ├── dialing.go
│ │ ├── environment.go
│ │ ├── environment_default.go
│ │ ├── environment_linux.go
│ │ ├── environment_linux_test.go
│ │ ├── environment_test.go
│ │ ├── environment_windows.go
│ │ ├── environment_windows_test.go
│ │ ├── icmp_listener.go
│ │ ├── init_test.go
│ │ ├── location.go
│ │ ├── location_default.go
│ │ ├── location_test.go
│ │ ├── location_windows.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── network-change.go
│ │ ├── notes.md
│ │ ├── online-status.go
│ │ ├── online-status_test.go
│ │ ├── os_android.go
│ │ └── os_default.go
│ ├── netquery/
│ │ ├── active_chart_handler.go
│ │ ├── bandwidth_chart_handler.go
│ │ ├── database.go
│ │ ├── manager.go
│ │ ├── module_api.go
│ │ ├── orm/
│ │ │ ├── decoder.go
│ │ │ ├── decoder_test.go
│ │ │ ├── encoder.go
│ │ │ ├── encoder_test.go
│ │ │ ├── query_runner.go
│ │ │ ├── schema_builder.go
│ │ │ └── schema_builder_test.go
│ │ ├── query.go
│ │ ├── query_handler.go
│ │ ├── query_request.go
│ │ ├── query_test.go
│ │ └── runtime_query_runner.go
│ ├── network/
│ │ ├── api.go
│ │ ├── api_test.go
│ │ ├── clean.go
│ │ ├── connection.go
│ │ ├── connection_android.go
│ │ ├── connection_handler.go
│ │ ├── connection_store.go
│ │ ├── database.go
│ │ ├── dns.go
│ │ ├── iphelper/
│ │ │ ├── get.go
│ │ │ ├── iphelper.go
│ │ │ ├── tables.go
│ │ │ └── tables_test.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── multicast.go
│ │ ├── netutils/
│ │ │ ├── address.go
│ │ │ ├── dns.go
│ │ │ ├── dns_test.go
│ │ │ ├── ip.go
│ │ │ ├── ip_test.go
│ │ │ └── tcpassembly.go
│ │ ├── packet/
│ │ │ ├── bandwidth.go
│ │ │ ├── const.go
│ │ │ ├── info_only.go
│ │ │ ├── packet.go
│ │ │ ├── packetinfo.go
│ │ │ └── parse.go
│ │ ├── ports.go
│ │ ├── proc/
│ │ │ ├── findpid.go
│ │ │ ├── pids_by_user.go
│ │ │ ├── tables.go
│ │ │ └── tables_test.go
│ │ ├── reference/
│ │ │ ├── ports.go
│ │ │ └── protocols.go
│ │ ├── socket/
│ │ │ └── socket.go
│ │ ├── state/
│ │ │ ├── exists.go
│ │ │ ├── info.go
│ │ │ ├── lookup.go
│ │ │ ├── system_default.go
│ │ │ ├── system_linux.go
│ │ │ ├── system_windows.go
│ │ │ ├── tcp.go
│ │ │ └── udp.go
│ │ └── status.go
│ ├── process/
│ │ ├── api.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── executable.go
│ │ ├── find.go
│ │ ├── module.go
│ │ ├── process.go
│ │ ├── process_default.go
│ │ ├── process_linux.go
│ │ ├── process_windows.go
│ │ ├── profile.go
│ │ ├── special.go
│ │ ├── tags/
│ │ │ ├── appimage_unix.go
│ │ │ ├── flatpak_unix.go
│ │ │ ├── interpreter_unix.go
│ │ │ ├── net.go
│ │ │ ├── snap_unix.go
│ │ │ ├── svchost_windows.go
│ │ │ └── winstore_windows.go
│ │ └── tags.go
│ ├── profile/
│ │ ├── active.go
│ │ ├── api.go
│ │ ├── binmeta/
│ │ │ ├── convert.go
│ │ │ ├── find_default.go
│ │ │ ├── find_linux.go
│ │ │ ├── find_linux_test.go
│ │ │ ├── find_windows.go
│ │ │ ├── find_windows_test.go
│ │ │ ├── icon.go
│ │ │ ├── icons.go
│ │ │ ├── ignore.go
│ │ │ ├── locations_linux.go
│ │ │ ├── name.go
│ │ │ └── name_test.go
│ │ ├── config-update.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── endpoints/
│ │ │ ├── annotations.go
│ │ │ ├── endpoint-any.go
│ │ │ ├── endpoint-asn.go
│ │ │ ├── endpoint-continent.go
│ │ │ ├── endpoint-country.go
│ │ │ ├── endpoint-domain.go
│ │ │ ├── endpoint-ip.go
│ │ │ ├── endpoint-iprange.go
│ │ │ ├── endpoint-lists.go
│ │ │ ├── endpoint-scopes.go
│ │ │ ├── endpoint.go
│ │ │ ├── endpoint_test.go
│ │ │ ├── endpoints.go
│ │ │ ├── endpoints_test.go
│ │ │ └── reason.go
│ │ ├── fingerprint.go
│ │ ├── fingerprint_test.go
│ │ ├── framework.go
│ │ ├── framework_test.go
│ │ ├── get.go
│ │ ├── merge.go
│ │ ├── meta.go
│ │ ├── migrations.go
│ │ ├── module.go
│ │ ├── profile-layered-provider.go
│ │ ├── profile-layered.go
│ │ ├── profile.go
│ │ └── special.go
│ ├── resolver/
│ │ ├── api.go
│ │ ├── block-detection.go
│ │ ├── compat.go
│ │ ├── config.go
│ │ ├── doc.go
│ │ ├── failing.go
│ │ ├── ipinfo.go
│ │ ├── ipinfo_test.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── metrics.go
│ │ ├── namerecord.go
│ │ ├── namerecord_test.go
│ │ ├── resolve.go
│ │ ├── resolver-env.go
│ │ ├── resolver-https.go
│ │ ├── resolver-mdns.go
│ │ ├── resolver-plain.go
│ │ ├── resolver-tcp.go
│ │ ├── resolver.go
│ │ ├── resolver_test.go
│ │ ├── resolvers.go
│ │ ├── resolvers_test.go
│ │ ├── reverse.go
│ │ ├── reverse_test.go
│ │ ├── rr_context.go
│ │ ├── rrcache.go
│ │ ├── rrcache_test.go
│ │ ├── scopes.go
│ │ └── test/
│ │ └── resolving.bash
│ ├── status/
│ │ ├── module.go
│ │ ├── notifications.go
│ │ ├── security_level.go
│ │ └── status.go
│ ├── sync/
│ │ ├── module.go
│ │ ├── profile.go
│ │ ├── setting_single.go
│ │ ├── settings.go
│ │ └── util.go
│ ├── ui/
│ │ ├── api.go
│ │ ├── module.go
│ │ └── serve.go
│ └── updates/
│ ├── downloader.go
│ ├── index.go
│ ├── index_scan.go
│ ├── module.go
│ ├── updates_test.go
│ └── upgrade.go
├── spn/
│ ├── TESTING.md
│ ├── TRADEMARKS
│ ├── access/
│ │ ├── account/
│ │ │ ├── auth.go
│ │ │ ├── client.go
│ │ │ ├── types.go
│ │ │ └── view.go
│ │ ├── api.go
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── database.go
│ │ ├── features.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── notify.go
│ │ ├── op_auth.go
│ │ ├── storage.go
│ │ ├── token/
│ │ │ ├── errors.go
│ │ │ ├── module_test.go
│ │ │ ├── pblind.go
│ │ │ ├── pblind_gen_test.go
│ │ │ ├── pblind_test.go
│ │ │ ├── registry.go
│ │ │ ├── request.go
│ │ │ ├── request_test.go
│ │ │ ├── scramble.go
│ │ │ ├── scramble_gen_test.go
│ │ │ ├── scramble_test.go
│ │ │ ├── token.go
│ │ │ └── token_test.go
│ │ └── zones.go
│ ├── cabin/
│ │ ├── config-public.go
│ │ ├── database.go
│ │ ├── identity.go
│ │ ├── identity_test.go
│ │ ├── keys.go
│ │ ├── keys_test.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── verification.go
│ │ └── verification_test.go
│ ├── captain/
│ │ ├── api.go
│ │ ├── bootstrap.go
│ │ ├── client.go
│ │ ├── config.go
│ │ ├── establish.go
│ │ ├── exceptions.go
│ │ ├── gossip.go
│ │ ├── hooks.go
│ │ ├── intel.go
│ │ ├── module.go
│ │ ├── navigation.go
│ │ ├── op_gossip.go
│ │ ├── op_gossip_query.go
│ │ ├── op_publish.go
│ │ ├── piers.go
│ │ ├── public.go
│ │ └── status.go
│ ├── conf/
│ │ ├── map.go
│ │ ├── mode.go
│ │ ├── networks.go
│ │ └── version.go
│ ├── crew/
│ │ ├── connect.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── op_connect.go
│ │ ├── op_connect_test.go
│ │ ├── op_ping.go
│ │ ├── op_ping_test.go
│ │ ├── policy.go
│ │ └── sticky.go
│ ├── debug.go
│ ├── docks/
│ │ ├── bandwidth_test.go
│ │ ├── controller.go
│ │ ├── crane.go
│ │ ├── crane_establish.go
│ │ ├── crane_init.go
│ │ ├── crane_netstate.go
│ │ ├── crane_terminal.go
│ │ ├── crane_test.go
│ │ ├── crane_verify.go
│ │ ├── cranehooks.go
│ │ ├── hub_import.go
│ │ ├── measurements.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── op_capacity.go
│ │ ├── op_capacity_test.go
│ │ ├── op_expand.go
│ │ ├── op_latency.go
│ │ ├── op_latency_test.go
│ │ ├── op_sync_state.go
│ │ ├── op_whoami.go
│ │ ├── op_whoami_test.go
│ │ ├── terminal_expansion.go
│ │ └── terminal_expansion_test.go
│ ├── hub/
│ │ ├── database.go
│ │ ├── errors.go
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── hub.go
│ │ ├── hub_test.go
│ │ ├── intel.go
│ │ ├── intel_override.go
│ │ ├── measurements.go
│ │ ├── status.go
│ │ ├── transport.go
│ │ ├── transport_test.go
│ │ ├── truststores.go
│ │ ├── update.go
│ │ └── update_test.go
│ ├── instance.go
│ ├── navigator/
│ │ ├── api.go
│ │ ├── api_route.go
│ │ ├── costs.go
│ │ ├── database.go
│ │ ├── findnearest.go
│ │ ├── findnearest_test.go
│ │ ├── findroutes.go
│ │ ├── findroutes_test.go
│ │ ├── intel.go
│ │ ├── map.go
│ │ ├── map_stats.go
│ │ ├── map_test.go
│ │ ├── measurements.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── optimize.go
│ │ ├── optimize_region.go
│ │ ├── optimize_test.go
│ │ ├── options.go
│ │ ├── pin.go
│ │ ├── pin_export.go
│ │ ├── region.go
│ │ ├── route.go
│ │ ├── routing-profiles.go
│ │ ├── sort.go
│ │ ├── sort_test.go
│ │ ├── state.go
│ │ ├── state_test.go
│ │ └── update.go
│ ├── patrol/
│ │ ├── domains.go
│ │ ├── domains_test.go
│ │ ├── http.go
│ │ └── module.go
│ ├── ships/
│ │ ├── connection_test.go
│ │ ├── http.go
│ │ ├── http_info.go
│ │ ├── http_info_page.html.tmpl
│ │ ├── http_info_test.go
│ │ ├── http_shared.go
│ │ ├── http_shared_test.go
│ │ ├── kcp.go
│ │ ├── launch.go
│ │ ├── masking.go
│ │ ├── module.go
│ │ ├── mtu.go
│ │ ├── pier.go
│ │ ├── registry.go
│ │ ├── ship.go
│ │ ├── tcp.go
│ │ ├── testship.go
│ │ ├── testship_test.go
│ │ └── virtual_network.go
│ ├── sluice/
│ │ ├── module.go
│ │ ├── packet_listener.go
│ │ ├── request.go
│ │ ├── sluice.go
│ │ ├── sluices.go
│ │ └── udp_listener.go
│ ├── spn.go
│ ├── terminal/
│ │ ├── control_flow.go
│ │ ├── defaults.go
│ │ ├── errors.go
│ │ ├── fmt.go
│ │ ├── init.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── msg.go
│ │ ├── msgtypes.go
│ │ ├── operation.go
│ │ ├── operation_base.go
│ │ ├── operation_counter.go
│ │ ├── permission.go
│ │ ├── rate_limit.go
│ │ ├── session.go
│ │ ├── session_test.go
│ │ ├── terminal.go
│ │ ├── terminal_test.go
│ │ ├── testing.go
│ │ └── upstream.go
│ ├── test
│ ├── testing/
│ │ ├── README.md
│ │ └── simple/
│ │ ├── README.md
│ │ ├── clientsim.sh
│ │ ├── config-template.json
│ │ ├── docker-compose.yml
│ │ ├── entrypoint.sh
│ │ ├── inject-intel.sh
│ │ ├── intel-client.yaml
│ │ ├── intel-testnet.json
│ │ ├── join.sh
│ │ ├── reset-databases.sh
│ │ ├── run.sh
│ │ └── stop.sh
│ ├── tools/
│ │ ├── Dockerfile
│ │ ├── container-init.sh
│ │ ├── install.sh
│ │ ├── install.v2.sh
│ │ ├── start-checksum.txt
│ │ └── sysctl.conf
│ └── unit/
│ ├── doc.go
│ ├── scheduler.go
│ ├── scheduler_stats.go
│ ├── scheduler_test.go
│ ├── unit.go
│ ├── unit_debug.go
│ └── unit_test.go
├── windows_core_dll/
│ ├── build.ps1
│ ├── dllmain.cpp
│ ├── framework.h
│ ├── pch.cpp
│ ├── pch.h
│ ├── windows_core_dll.sln
│ ├── windows_core_dll.vcxproj
│ ├── windows_core_dll.vcxproj.filters
│ └── windows_core_dll.vcxproj.user
└── windows_kext/
├── .gitignore
├── PacketFlow.md
├── PortmasterKext64.inf
├── README.md
├── c_helper/
│ ├── ARM64/
│ │ └── c_helper.lib
│ ├── c_helper.filters
│ ├── c_helper.sln
│ ├── c_helper.vcxproj
│ ├── helper.c
│ └── x64/
│ └── c_helper.lib
├── driver/
│ ├── .cargo/
│ │ └── config.toml
│ ├── Cargo.toml
│ ├── Makefile.toml
│ ├── README.md
│ ├── rust-toolchain
│ └── src/
│ ├── ale_callouts.rs
│ ├── array_holder.rs
│ ├── bandwidth.rs
│ ├── callouts.rs
│ ├── common.rs
│ ├── connection.rs
│ ├── connection_cache.rs
│ ├── connection_map.rs
│ ├── device.rs
│ ├── entry.rs
│ ├── id_cache.rs
│ ├── lib.rs
│ ├── logger.rs
│ ├── packet_callouts.rs
│ ├── packet_util.rs
│ └── stream_callouts.rs
├── kextinterface/
│ ├── command.go
│ ├── info.go
│ ├── ioctl.go
│ ├── kext.go
│ ├── kext_file.go
│ ├── kext_file_test.go
│ ├── protocol_test.go
│ └── version.txt
├── link-dev.ps1
├── protocol/
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ ├── command.rs
│ ├── info.rs
│ └── lib.rs
├── test/
│ ├── BUILD_DEBUG.md
│ ├── README.md
│ └── build_test.ps1
├── test_protocol.sh
└── wdk/
├── .cargo/
│ └── config.toml
├── Cargo.toml
├── README.md
├── build.rs
├── rust-analyzer.cargo.target
├── rust-toolchain
└── src/
├── allocator.rs
├── attributes.rs
├── consts.rs
├── debug.rs
├── driver.rs
├── error.rs
├── fast_mutex.rs
├── ffi.rs
├── filter_engine/
│ ├── callout.rs
│ ├── callout_data.rs
│ ├── classify.rs
│ ├── connect_request.rs
│ ├── ffi.rs
│ ├── layer.rs
│ ├── metadata.rs
│ ├── mod.rs
│ ├── net_buffer.rs
│ ├── packet.rs
│ ├── stream_data.rs
│ └── transaction.rs
├── interface.rs
├── ioqueue.rs
├── irp_helpers.rs
├── lib.rs
├── rw_spin_lock.rs
├── spin_lock.rs
└── utils.rs
================================================
FILE CONTENTS
================================================
================================================
FILE: .angulardoc.json
================================================
{
"repoId": "8f466ce7-4b75-4048-8b8a-cad5bf173aa0",
"lastSync": 0
}
================================================
FILE: .earthlyignore
================================================
# Ignore angular outputs.
desktop/angular/node_modules
desktop/angular/dist
desktop/angular/dist-lib
desktop/angular/dist-extension
desktop/angular/.angular
# Ignore tauri outputs.
desktop/tauri/src-tauri/target
#######################
# Copy from .gitignore:
# Compiled binaries
# *.exe
# dist/
# Dist dir
# dist
# Custom dev deops
go.mod.*
# vendor dir
vendor
# testing
testing
spn/testing/simple/testdata
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# OS specifics
.DS_Store
# Custom dev scripts
win_dev_*
go.work
go.work.sum
================================================
FILE: .gitattributes
================================================
# Treat all Go files in this repo as binary, with no git magic updating
# line endings. Windows users contributing to Go will need to use a
# modern version of git and editors capable of LF line endings.
*.go -text diff=golang
================================================
FILE: .github/FUNDING.yml
================================================
github: safing
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
blank_issues_enabled: true # default: true
contact_links:
- name: "Ask Questions on Discord"
url: https://safing.io/discord
about: Get help from our great community
- name: "Wiki and FAQ"
url: https://wiki.safing.io/
about: Learn more about Portmaster in our Wiki
- name: "Contribution Guideline"
url: https://docs.safing.io/portmaster/guides/contribute
about: Learn how to best contribute and make sure your work is aligned with Safing’s current goals and focus
- name: "Code of Conduct"
url: https://docs.safing.io/community/code-of-conduct
about: Be nice to other community members
================================================
FILE: .github/ISSUE_TEMPLATE/report-bug.md
================================================
---
name: "🐞 Report a Bug"
about: Report a bug encountered while using the Portmaster
labels: bug
---
<!--
Please disclose security related issues privately to support@safing.io.
-->
**Pre-Submit Checklist**:
- Check applicable sources for existing issues:
- [Windows Known Issues](https://docs.safing.io/portmaster/install/windows#known-issues)
- [Linux Known Issues](https://docs.safing.io/portmaster/install/linux#compatibility)
- [Github Issues](https://github.com/safing/portmaster/issues?q=is%3Aissue+label%3Abug)
**What happened**:
**What did you expect to happen?**:
**How did you reproduce it?**:
**Debug Information**:
<!--
Paste debug information below:
- General issue: Click on "Copy Debug Information" on the Settings page.
- App related issue: Click on "Copy Debug Information" in the dropdown menu of an app in the Monitor view.
⚠ Please remove sensitive/private information from the "Unexpected Logs" and "Network Connections" sections.
This is easiest to do in the preview mode.
Additional logs can be found here:
- Linux: `/var/lib/portmaster/log`
- Windows: `%PROGRAMDATA%\Portmaster\logs`
-->
================================================
FILE: .github/ISSUE_TEMPLATE/report-compatibility.md
================================================
---
name: "📝 Make a Compatibility Report"
about: Report Portmaster in/compatibility with Linux Distros, VPN Clients or general Software
labels: "in/compatibility"
---
**Pre-Submit Checklist**:
- Check applicable sources for existing issues:
- [Linux Compatibility](https://docs.safing.io/portmaster/install/linux#compatibility)
- [VPN Compatibility](https://docs.safing.io/portmaster/install/status/vpn-compatibility)
- [Github Issues](https://github.com/safing/portmaster/issues?q=is%3Aissue+label%3Ain%2Fcompatibility)
**What worked?**
**What did not work?**
**Debug Information**:
<!--
Paste debug information below if reporting a problem:
- General issue: Click on "Copy Debug Information" on the Settings page.
- App related issue: Click on "Copy Debug Information" in the dropdown menu of an app in the Monitor view.
⚠ Please remove sensitive/private information from the "Unexpected Logs" and "Network Connections" sections.
This is easiest to do in the preview mode.
If needed, additional logs can be found here:
- Linux: `/var/lib/portmaster/log`
- Windows: `%PROGRAMDATA%\Portmaster\logs`
-->
================================================
FILE: .github/ISSUE_TEMPLATE/suggest-feature.md
================================================
---
name: "💡 Suggest an Improvement or Feature"
about: Suggest an enhancement or a new feature for the Portmaster
labels: suggestion
---
**What would you like to add or change?**:
**Why do you and others need this?**:
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/desktop/angular"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/desktop/tauri"
schedule:
interval: "daily"
================================================
FILE: .github/label-actions.yml
================================================
# Configuration for Label Actions - https://github.com/dessant/label-actions
community support:
comment: |
Hey @{issue-author}, thank you for raising this issue with us.
After a first review we noticed that this does not seem to be a technical issue, but rather a configuration issue or general question about how Portmaster works.
Thus, we invite the community to help with configuration and/or answering this questions.
If you are in a hurry or haven't received an answer, a good place to ask is in [our Discord community](https://discord.gg/safing).
If your problem or question has been resolved or answered, please come back and give an update here for other users encountering the same and then close this issue.
If you are a paying subscriber and want this issue to be checked out by Safing, please send us a message [on Discord](https://discord.gg/safing) or [via Email](mailto:support@safing.io) with your username and the link to this issue, so we can prioritize accordingly.
needs debug info:
comment: |
Hey @{issue-author}, thank you for raising this issue with us.
After a first review we noticed that we will require the Debug Info for further investigation. However, you haven't supplied any Debug Info in your report.
Please [collect Debug Info](https://wiki.safing.io/en/FAQ/DebugInfo) from Portmaster _while_ the reported issue is present.
in/compatibility:
comment: |
Hey @{issue-author}, thank you for reporting on a compatibility.
We keep a list of compatible software and user provided guides for improving compatibility [in the wiki - please have a look there](https://wiki.safing.io/en/Portmaster/App/Compatibility).
If you can't find your software in the list, then a good starting point is our guide on [How do I make software compatible with Portmaster](https://wiki.safing.io/en/FAQ/MakeSoftwareCompatibleWithPortmaster).
If you have managed to establish compatibility with an application, please share your findings here. This will greatly help other users encountering the same issues.
fixed:
comment: |
This issue has been fixed by the recently referenced commit or PR.
However, the fix is not released yet.
It is expected to go into the [Beta Release Channel](https://wiki.safing.io/en/FAQ/SwitchReleaseChannel) for testing within the next two weeks and will be available for everyone within the next four weeks. While this is the typical timeline we work with, things are subject to change.
================================================
FILE: .github/workflows/angular.yml
================================================
name: Angular
on:
push:
paths:
- 'desktop/angular/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
pull_request:
paths:
- 'desktop/angular/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
defaults:
run:
working-directory: desktop/angular
steps:
- name: Check out code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3
with:
node-version: 18
- run: npm install
- uses: sibiraj-s/action-eslint@bcf41bb9abce43cdbad51ab9b3da2eddaa17eab3 # v3
with:
annotations: true
extensions: 'ts,html'
working-directory: desktop/angular
test:
name: Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build angular projects
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +angular-ci
================================================
FILE: .github/workflows/go.yml
================================================
name: Go
on:
push:
paths:
- '**.go'
- 'cmds/**'
- 'runtime/**'
- 'service/**'
- 'spn/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
pull_request:
paths:
- '**.go'
- 'cmds/**'
- 'runtime/**'
- 'service/**'
- 'spn/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
jobs:
lint:
name: Linter
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '^1.21'
cache: false
- name: Run golangci-lint
uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6
with:
version: v1.64.6
only-new-issues: true
args: -c ./.golangci.yml --timeout 15m
- name: Run go vet
run: go vet ./...
test:
name: Test & Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run Go Tests & Build
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +go-ci
================================================
FILE: .github/workflows/issues-first-greet.yml
================================================
# This workflow responds to first time posters with a greeting message.
# Docs: https://github.com/actions/first-interaction
name: Greet New Users
# This workflow is triggered when a new issue is created.
on:
issues:
types: opened
permissions:
contents: read
issues: write
jobs:
greet:
runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@2ec0f0fd78838633cd1c1342e4536d49ef72be54 # v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Respond to first time issue raisers.
issue-message: |
Greetings and welcome to our community! As this is the first issue you opened here, we wanted to share some useful infos with you:
- 🗣️ Our community on [Discord](https://discord.gg/safing) is super helpful and active. We also have an AI-enabled support bot that knows Portmaster well and can give you immediate help.
- 📖 The [Wiki](https://wiki.safing.io/) answers all common questions and has many important details. If you can't find an answer there, let us know, so we can add anything that's missing.
================================================
FILE: .github/workflows/issues-label-actions.yml
================================================
# This workflow responds with a message when certain labels are added to an issue or PR.
# Docs: https://github.com/dessant/label-actions
name: Label Actions
# This workflow is triggered when a label is added to an issue.
on:
issues:
types: labeled
permissions:
contents: read
issues: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/label-actions@ade7bcd4c1b30de6ba8e556cc31301fd4f79ca65 # v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
config-path: ".github/label-actions.yml"
process-only: "issues"
================================================
FILE: .github/workflows/issues-stale.yml
================================================
# This workflow warns and then closes stale issues and PRs.
# Docs: https://github.com/actions/stale
name: Close Stale Issues
on:
schedule:
- cron: "17 5 * * 1-5" # run at 5:17 (UTC) on Monday to Friday
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Increase max operations.
# When using GITHUB_TOKEN, the rate limit is 1,000 requests per hour per repository.
operations-per-run: 500
# Handle stale issues
stale-issue-label: 'stale'
# Exemptions
exempt-all-issue-assignees: true
exempt-issue-labels: 'support,dependencies,pinned,security'
# Mark as stale
days-before-issue-stale: 63 # 2 months / 9 weeks
stale-issue-message: |
This issue has been automatically marked as inactive because it has not had activity in the past two months.
If no further activity occurs, this issue will be automatically closed in one week in order to increase our focus on active topics.
# Close
days-before-issue-close: 7 # 1 week
close-issue-message: |
This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.
If the issue has not been resolved, you can [find more information in our Wiki](https://wiki.safing.io/) or [continue the conversation on our Discord](https://discord.gg/safing).
# TODO: Handle stale PRs
days-before-pr-stale: 36500 # 100 years - effectively disabled.
================================================
FILE: .github/workflows/kext.yml
================================================
name: Windows Kernel Extension
on:
push:
paths:
- 'windows_kext/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
pull_request:
paths:
- 'windows_kext/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Kernel Extension
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +kext-ci
================================================
FILE: .github/workflows/release.yml
================================================
name: Release v2.X
on:
push:
branches:
- main
- development
tags:
- v*
workflow_dispatch:
jobs:
release-prep:
name: Prep
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build all artifacts
run: earthly --remote-cache=ghcr.io/safing/build-cache --push +release-prep
- name: Upload Dist
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
path: ./dist/
if-no-files-found: error
installer-linux:
#JOB DISABLED FOR NOW
if: false
name: Installer linux
runs-on: ubuntu-latest
needs: release-prep
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build linux installers
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +installer-linux
# --ci include --no-output flag
- name: Upload Installers
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
path: ./dist/linux_amd64/
if-no-files-found: error
installer-windows:
#JOB DISABLED FOR NOW
if: false
name: Installer windows
runs-on: windows-latest
needs: release-prep
steps:
- name: Checkout Repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Download Dist
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
path: dist/
- name: Build windows artifacts
run: powershell -NoProfile -File ./packaging/windows/generate_windows_installers.ps1
- name: Upload Installers
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
path: ./dist/windows_amd64/
if-no-files-found: error
================================================
FILE: .github/workflows/tauri.yml
================================================
name: Tauri
on:
push:
paths:
- 'desktop/tauri/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
pull_request:
paths:
- 'desktop/tauri/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build tauri project
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +tauri-ci
lint:
name: Linter
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@43211c7a0eae5344d6d79fb4aaf209c8f8866203 # v1
with:
version: v0.8.0
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build tauri project
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +tauri-lint
================================================
FILE: .github/workflows/windows-dll.yml
================================================
name: Windows Portmaster Core DLL
on:
push:
paths:
- 'windows_core_dll/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
pull_request:
paths:
- 'windows_core_dll/**'
branches:
- main
- development
- v1-legacy
- v1-legacy-develop
workflow_dispatch:
jobs:
build:
name: Build
runs-on: windows-latest
steps:
- name: Checkout Repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2
- name: Build DLL
run: msbuild windows_core_dll\windows_core_dll.sln -t:rebuild -property:Configuration=Release
- name: Verify DLL
shell: powershell
run: |
if (!(Test-Path "windows_core_dll/x64/Release/portmaster-core.dll")) {
Write-Error "DLL build failed: portmaster-core.dll not found"
exit 1
}
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: portmaster-core-dll
path: windows_core_dll/x64/Release/portmaster-core.dll
================================================
FILE: .gitignore
================================================
# Compiled binaries
*.exe
dist/
# Dist dir
dist
packaging/_precompiled/
# Custom dev deops
go.mod.*
# vendor dir
vendor
# testing
testdata
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# OS specifics
.DS_Store
# Custom dev scripts
win_dev_*
go.work
go.work.sum
# Kext releases
windows_kext/release/kext_release_*.zip
windows_core_dll/.vs/windows_core_dll
#windows_core_dll
windows_core_dll/x64/
windows_core_dll/portmaster-core/x64/
#Tauri-generated files
desktop/tauri/src-tauri/gen/
#Binaries used for installer gereneration for Windows
desktop/tauri/src-tauri/binary/
desktop/tauri/src-tauri/intel/
windows_kext/test/_testcert/
windows_kext/test/_out/
windows_kext/test/_delme/
================================================
FILE: .golangci.yml
================================================
# Docs:
# https://golangci-lint.run/usage/linters/
linters:
enable-all: true
disable:
- containedctx
- contextcheck
- cyclop
- depguard
- exhaustruct
- forbidigo
- funlen
- gochecknoglobals
- gochecknoinits
- gocognit
- gocyclo
- gomoddirectives
- interfacebloat
- ireturn
- lll
- mnd
- musttag
- nestif
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- perfsprint # TODO(ppacher): we should re-enanble this one to avoid costly fmt.* calls in the hot-path
- revive
- tagliatelle
- testifylint
- testpackage
- varnamelen
- whitespace
- wrapcheck
- wsl
- gci
- tenv # Deprecated
linters-settings:
revive:
# See https://github.com/mgechev/revive#available-rules for details.
enable-all-rules: true
goimports:
local-prefixes: github.com/safing
godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging
keywords:
- FIXME
gosec:
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
excludes:
- G204 # Variables in commands.
- G304 # Variables in file paths.
- G505 # We need crypto/sha1 for non-security stuff. Using `nolint:` triggers another linter.
issues:
exclude-use-default: false
exclude-rules:
- text: "a blank import .*"
linters:
- golint
- text: "ST1000: at least one file in a package should have a package comment.*"
linters:
- stylecheck
================================================
FILE: .travis.yml
================================================
language: go
go:
- 1.x
os:
- linux
- windows
branches:
only:
- master
- develop
- /^feature\/travis\/.+$/ # feature/travis/*
- /^fix\/travis\/.+$/ # fix/travis/*
addons:
apt:
update: true
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -y install libnetfilter-queue-dev; fi
install:
- go get -d -u github.com/golang/dep
- go install github.com/golang/dep/cmd/dep
- ./.ci-inject-internal-deps.sh
- dep ensure
- ./test install
script: ./test --scripted
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "portmaster-core",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmds/portmaster-core",
"windows": {
"args": ["--bin-dir=C:\\Program Files\\Portmaster", "--log-stdout", "--log", "trace"]
},
"linux": {
"console": "integratedTerminal", // required to debug as root
"asRoot": true, // required to debug as root
"args": ["--bin-dir=/usr/lib/portmaster", "--log-stdout", "--log", "trace"]
},
},
{
"name": "portmaster-core (NO INTERCEPTION)",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmds/portmaster-core",
"windows": {
"args": ["--bin-dir=C:\\Program Files\\Portmaster", "--log-stdout", "--log", "trace", "--disable-interception=true"]
},
"linux": {
"console": "integratedTerminal", // required to debug as root
"asRoot": true, // required to debug as root
"args": ["--bin-dir=/usr/lib/portmaster", "--log-stdout", "--log", "trace", "--disable-interception=true"]
},
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"cSpell.words": [
"netenv",
"safing",
"Warningf"
]
}
================================================
FILE: AUTHORS
================================================
All files in this repository (unless otherwise noted) are authored, owned and copyrighted by Safing ICS Technologies GmbH (Austria).
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at coc@safing.io. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: Earthfile
================================================
VERSION 0.8
# Custom argument: "custom_version" to manually set the version of the build (and ignore Git Tag value)
# Usage example: earthly --build-arg custom_version="1.2.3" +<target>
ARG --global custom_version = ""
ARG --global go_version = 1.24
ARG --global node_version = 18
ARG --global rust_version = 1.89
ARG --global tauri_version = "2.2.5"
ARG --global golangci_lint_version = 1.64.6
ARG --global go_builder_image = "golang:${go_version}-alpine"
ARG --global node_builder_image = "node:${node_version}"
ARG --global rust_builder_image = "rust:${rust_version}-bookworm"
ARG --global work_image = "alpine"
ARG --global outputDir = "./dist"
# Architectures:
# The list of rust targets we support. They will be automatically converted
# to GOOS, GOARCH and GOARM when building go binaries. See the +RUST_TO_GO_ARCH_STRING
# helper method at the bottom of the file.
#
# Linux:
# x86_64-unknown-linux-gnu
# aarch64-unknown-linux-gnu
# armv7-unknown-linux-gnueabihf
# arm-unknown-linux-gnueabi
#
# Windows:
# x86_64-pc-windows-gnu
# aarch64-pc-windows-gnu
#
# Mac:
# x86_64-apple-darwin
# aarch64-apple-darwin
# Import the earthly rust lib since it already provides some useful
# build-targets and methods to initialize the rust toolchain.
IMPORT github.com/earthly/lib/rust:3.0.2 AS rust
build:
# Build all Golang binaries:
# ./dist/linux_amd64/portmaster-core
# ./dist/linux_amd64/portmaster-start
# ./dist/linux_arm64/portmaster-core
# ./dist/linux_arm64/portmaster-start
# ./dist/windows_amd64/portmaster-core.exe
# ./dist/windows_amd64/portmaster-start.exe
# ./dist/windows_arm64/portmaster-core.exe
# ./dist/windows_arm64/portmaster-start.exe
BUILD +go-build --GOOS="linux" --GOARCH="amd64"
BUILD +go-build --GOOS="linux" --GOARCH="arm64"
BUILD +go-build --GOOS="windows" --GOARCH="amd64"
BUILD +go-build --GOOS="windows" --GOARCH="arm64"
# Build the Angular UI:
# ./dist/all/portmaster-ui.zip
BUILD +angular-release
# Build Tauri app binaries:
# ./dist/linux_amd64/portmaster-app
# ./dist/windows_amd64/portmaster-app
BUILD +tauri-build --target="x86_64-unknown-linux-gnu"
BUILD +tauri-build --target="x86_64-pc-windows-gnu"
# TODO(vladimir): Build bundles
# ./dist/linux_amd64/Portmaster-0.1.0-1.x86_64.rpm
# ./dist/linux_amd64/Portmaster_0.1.0_amd64.deb
# Bild Tauri bundle for Windows:
# Build UI assets:
# ./dist/all/assets.zip
BUILD +assets
build-spn:
BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="amd64"
BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="arm64"
# TODO: Add other platforms
go-ci:
BUILD +go-build --GOOS="linux" --GOARCH="amd64"
BUILD +go-build --GOOS="linux" --GOARCH="arm64"
BUILD +go-build --GOOS="windows" --GOARCH="amd64"
BUILD +go-build --GOOS="windows" --GOARCH="arm64"
BUILD +go-test
angular-ci:
BUILD +angular-release
tauri-ci:
BUILD +tauri-build --target="x86_64-unknown-linux-gnu"
BUILD +tauri-build --target="x86_64-pc-windows-gnu"
kext-ci:
BUILD +kext-build
release:
LOCALLY
IF ! git diff --quiet
RUN echo -e "\033[1;31m Refusing to release a dirty git repository. Please commit your local changes first! \033[0m" ; exit 1
END
BUILD +build
go-deps:
FROM ${go_builder_image}
WORKDIR /go-workdir
# We need the git cli to extract version information for go-builds
RUN apk add git
# These cache dirs will be used in later test and build targets
# to persist cached go packages.
#
# NOTE: cache only gets persisted on successful builds. A test
# failure will prevent the go cache from being persisted.
ENV GOCACHE = "/.go-cache"
ENV GOMODCACHE = "/.go-mod-cache"
# Copying only go.mod and go.sum means that the cache for this
# target will only be busted when go.mod/go.sum change. This
# means that we can cache the results of 'go mod download'.
COPY go.mod .
COPY go.sum .
RUN go mod download
# Explicitly cache here.
SAVE IMAGE --cache-hint
go-base:
FROM +go-deps
# Copy the full repo, as Go embeds whether the state is clean.
COPY . .
# Set version information: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer
DO +SET_VERSION_INFO
# Explicitly cache here.
SAVE IMAGE --cache-hint
# updates all go dependencies and runs go mod tidy, saving go.mod and go.sum locally.
go-update-deps:
FROM +go-base
RUN go get -u ./..
RUN go mod tidy
SAVE ARTIFACT --keep-ts go.mod AS LOCAL go.mod
SAVE ARTIFACT --keep-ts --if-exists go.sum AS LOCAL go.sum
# mod-tidy runs 'go mod tidy', saving go.mod and go.sum locally.
mod-tidy:
FROM +go-base
RUN go mod tidy
SAVE ARTIFACT --keep-ts go.mod AS LOCAL go.mod
SAVE ARTIFACT --keep-ts --if-exists go.sum AS LOCAL go.sum
# go-build runs 'go build ./cmds/...', saving artifacts locally.
# If --CMDS is not set, it defaults to building portmaster-start, portmaster-core and hub
go-build:
FROM +go-base
# Arguments for cross-compilation.
ARG GOOS=linux
ARG GOARCH=amd64
ARG GOARM
ARG CMDS=portmaster-core
CACHE --sharing shared "$GOCACHE"
CACHE --sharing shared "$GOMODCACHE"
RUN mkdir /tmp/build
# Fall back to build all binaries when none is specified.
IF [ "${CMDS}" = "" ]
LET CMDS=$(ls -1 "./cmds/")
END
# Build all go binaries from the specified in CMDS
FOR bin IN $CMDS
# Add special build options.
IF [ "${GOOS}" = "windows" ] && [ "${bin}" = "portmaster-start" ]
# Windows, portmaster-start
ENV CGO_ENABLED = "1"
ENV EXTRA_LD_FLAGS = "-H windowsgui"
ELSE
# Defaults
ENV CGO_ENABLED = "0"
ENV EXTRA_LD_FLAGS = ""
END
RUN --no-cache go build -ldflags="${EXTRA_LD_FLAGS} -X github.com/safing/portmaster/base/info.version=${VERSION} -X github.com/safing/portmaster/base/info.buildSource=${SOURCE} -X github.com/safing/portmaster/base/info.buildTime=${BUILD_TIME}" -o "/tmp/build/" ./cmds/${bin}
END
DO +GO_ARCH_STRING --goos="${GOOS}" --goarch="${GOARCH}" --goarm="${GOARM}"
FOR bin IN $(ls -1 "/tmp/build/")
SAVE ARTIFACT --keep-ts "/tmp/build/${bin}" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/${bin}"
END
SAVE ARTIFACT --keep-ts "/tmp/build/" ./output
spn-image:
# Use minimal image as base.
FROM alpine
# Copy the static executable.
COPY (+go-build/output/portmaster-start --GOARCH=amd64 --GOOS=linux --CMDS=portmaster-start) /init/portmaster-start
# Copy the init script
COPY spn/tools/container-init.sh /init.sh
# Run the hub.
ENTRYPOINT ["/init.sh"]
# Get version.
LET version = "$(/init/portmaster-start version --short | tr ' ' -)"
RUN echo "Version: ${version}"
# Save dev image
SAVE IMAGE "spn:latest"
SAVE IMAGE "spn:${version}"
SAVE IMAGE "ghcr.io/safing/spn:latest"
SAVE IMAGE "ghcr.io/safing/spn:${version}"
# Test one or more go packages.
# Test are always run as -short, as "long" tests require a full desktop system.
# Run `earthly +go-test` to test all packages
# Run `earthly +go-test --PKG="service/firewall"` to only test a specific package.
# Run `earthly +go-test --TESTFLAGS="-args arg1"` to add custom flags to go test (-args in this case)
go-test:
FROM +go-base
ARG GOOS=linux
ARG GOARCH=amd64
ARG GOARM
ARG TESTFLAGS
ARG PKG="..."
CACHE --sharing shared "$GOCACHE"
CACHE --sharing shared "$GOMODCACHE"
FOR pkg IN $(go list -e "./${PKG}")
RUN --no-cache go test -cover -short ${pkg} ${TESTFLAGS}
END
go-test-all:
FROM ${work_image}
ARG --required architectures
FOR arch IN ${architectures}
DO +RUST_TO_GO_ARCH_STRING --rustTarget="${arch}"
BUILD +go-test --GOARCH="${GOARCH}" --GOOS="${GOOS}" --GOARM="${GOARM}"
END
go-lint:
FROM +go-base
RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v${golangci_lint_version}
RUN golangci-lint run -c ./.golangci.yml --timeout 15m --show-stats
# Builds portmaster-start, portmaster-core, hub and notifier for all supported platforms
go-release:
FROM ${work_image}
ARG --required architectures
FOR arch IN ${architectures}
DO +RUST_TO_GO_ARCH_STRING --rustTarget="${arch}"
IF [ -z GOARCH ]
RUN echo "Failed to extract GOARCH for ${arch}"; exit 1
END
IF [ -z GOOS ]
RUN echo "Failed to extract GOOS for ${arch}"; exit 1
END
BUILD +go-build --GOARCH="${GOARCH}" --GOOS="${GOOS}" --GOARM="${GOARM}"
END
# Builds all binaries from the cmds/ folder for linux/windows AMD64
# Most utility binaries are never needed on other platforms.
go-build-utils:
BUILD +go-build --CMDS="" --GOARCH=amd64 --GOOS=linux
BUILD +go-build --CMDS="" --GOARCH=amd64 --GOOS=windows
# Prepares the angular project by installing dependencies
angular-deps:
FROM ${node_builder_image}
WORKDIR /app/ui
RUN apt update && apt install zip
COPY desktop/angular/package.json .
COPY desktop/angular/package-lock.json .
RUN npm install
# Copies the UI folder into the working container
# and builds the shared libraries in the specified configuration (production or development)
angular-base:
FROM +angular-deps
ARG configuration="production"
COPY desktop/angular/ .
# Remove symlink and copy assets directly.
RUN rm ./assets
# COPY assets/data ./assets # Do not include the assets folder into portmaster.zip, we use the assets.zip instead
IF [ "${configuration}" = "production" ]
RUN --no-cache npm run build-libs
ELSE
RUN --no-cache npm run build-libs:dev
END
# Explicitly cache here.
SAVE IMAGE --cache-hint
# Build an angualr project, zip it and save artifacts locally
angular-project:
ARG --required project
ARG --required dist
ARG configuration="production"
ARG baseHref="/"
FROM +angular-base --configuration="${configuration}"
IF [ "${configuration}" = "production" ]
ENV NODE_ENV="production"
END
RUN --no-cache ./node_modules/.bin/ng build --configuration ${configuration} --base-href ${baseHref} "${project}"
RUN --no-cache cwd=$(pwd) && cd "${dist}" && zip -r "${cwd}/${project}.zip" ./
SAVE ARTIFACT --keep-ts "${dist}" "./output/${project}"
# Save portmaster UI as local artifact.
IF [ "${project}" = "portmaster" ]
SAVE ARTIFACT --keep-ts "./${project}.zip" AS LOCAL ${outputDir}/all/${project}-ui.zip
SAVE ARTIFACT --keep-ts "./${project}.zip" output/${project}.zip
END
# Build the angular projects (portmaster-UI and tauri-builtin) in dev mode
angular-dev:
BUILD +angular-project --project=portmaster --dist=./dist --configuration=development --baseHref=/ui/modules/portmaster/
BUILD +angular-project --project=tauri-builtin --dist=./dist/tauri-builtin --configuration=development --baseHref=/
# Build the angular projects (portmaster-UI and tauri-builtin) in production mode
angular-release:
BUILD +angular-project --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/
BUILD +angular-project --project=tauri-builtin --dist=./dist/tauri-builtin --configuration=production --baseHref=/
assets:
FROM ${work_image}
RUN apk add zip
WORKDIR /app/assets
COPY --keep-ts ./assets/data .
RUN zip -r -9 -db -X assets.zip *
SAVE ARTIFACT --keep-ts "assets.zip" AS LOCAL "${outputDir}/all/assets.zip"
# A base target for rust to prepare the build container
rust-base:
FROM ${rust_builder_image}
RUN apt-get update -qq
# Tools and libraries required for cross-compilation
RUN apt-get install --no-install-recommends -qq \
autoconf \
autotools-dev \
libtool-bin \
clang \
cmake \
bsdmainutils \
gcc-multilib \
linux-libc-dev \
linux-libc-dev-amd64-cross \
build-essential \
curl \
wget \
file \
libsoup-3.0-dev \
libwebkit2gtk-4.1-dev \
gcc-mingw-w64-x86-64 \
zip
# Install library dependencies for all supported architectures
# required for succesfully linking.
RUN apt-get install --no-install-recommends -qq \
libsoup-3.0-0 \
libwebkit2gtk-4.1-0 \
libssl3 \
libayatana-appindicator3-1 \
librsvg2-bin \
libgtk-3-0 \
libjavascriptcoregtk-4.1-0 \
libssl-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libgtk-3-dev \
libjavascriptcoregtk-4.1-dev
# Add some required rustup components
RUN rustup component add clippy
RUN rustup component add rustfmt
DO rust+INIT --keep_fingerprints=true
# For now we need tauri-cli 2.0.0 for bulding
DO rust+CARGO --args="install tauri-cli --version 2.2.7 --locked"
# Explicitly cache here.
SAVE IMAGE --cache-hint
tauri-src:
FROM +rust-base
WORKDIR /app/tauri
# --keep-ts is necessary to ensure that the timestamps of the source files
# are preserved such that Rust's incremental compilation works correctly.
COPY --keep-ts ./desktop/tauri/ .
COPY assets/data ./../../assets/data
COPY packaging ./../../packaging
COPY (+angular-project/output/tauri-builtin --project=tauri-builtin --dist=./dist/tauri-builtin --configuration=production --baseHref="/") ./../angular/dist/tauri-builtin
WORKDIR /app/tauri/src-tauri
# Explicitly cache here.
SAVE IMAGE --cache-hint
tauri-build:
FROM +tauri-src
ARG --required target
ARG output=".*/release/([^\./]+|([^\./]+\.(dll|exe)))"
DO +RUST_TO_GO_ARCH_STRING --rustTarget="${target}"
RUN echo "GOOS=${GOOS} GOARCH=${GOARCH} GOARM=${GOARM} GO_ARCH_STRING=${GO_ARCH_STRING}"
DO rust+SET_CACHE_MOUNTS_ENV
RUN rustup target add "${target}"
# Build
RUN --mount=$EARTHLY_RUST_TARGET_CACHE cargo tauri build --ci --target="${target}" --no-bundle
DO rust+COPY_OUTPUT --output="${output}"
# BUG(cross-compilation):
#
# The above command seems to correctly compile for all architectures we want to support but fails during
# linking since the target libaries are not available for the requested platforms. Maybe we need to download
# the, manually ...
#
# The earthly rust lib also has support for using cross-rs for cross-compilation but that fails due to the
# fact that cross-rs base docker images used for building are heavily outdated (latest = ubunut:16.0, main = ubuntu:20.04)
# which does not ship recent enough glib versions (our glib dependency needs glib>2.70 but ubunut:20.04 only ships 2.64)
#
# The following would use the CROSS function from the earthly lib, this
# DO rust+CROSS --target="${target}"
RUN echo output: $(ls -R "target/${target}/release")
# Binaries
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/portmaster"
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster.exe" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/portmaster.exe"
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/WebView2Loader.dll" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/WebView2Loader.dll"
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster" ./output/portmaster
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/portmaster.exe" ./output/portmaster.exe
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/WebView2Loader.dll" ./output/WebView2Loader.dll
tauri-release:
FROM ${work_image}
ARG --required architectures
FOR arch IN ${architectures}
BUILD +tauri-build --target="${arch}"
END
tauri-lint:
FROM +rust-base
ARG target="x86_64-unknown-linux-gnu"
WORKDIR /app
# Copy static files that are embedded inside the executable.
COPY --keep-ts ./assets ./assets
# Copy all the rust code
COPY --keep-ts ./desktop/tauri ./desktop/tauri
# Create a empty ui dir so it will satisfy the build.
RUN mkdir -p ./desktop/angular/dist/tauri-builtin
SAVE IMAGE --cache-hint
# Run the linter.
WORKDIR /app/desktop/tauri/src-tauri
RUN --mount=$EARTHLY_RUST_TARGET_CACHE cargo clippy --all-targets --all-features -- -D warnings
release-prep:
FROM +rust-base
WORKDIR /app
# Linux specific
COPY (+tauri-build/output/portmaster --target="x86_64-unknown-linux-gnu") ./output/binary/linux_amd64/portmaster
COPY (+go-build/output/portmaster-core --GOARCH=amd64 --GOOS=linux --CMDS=portmaster-core) ./output/binary/linux_amd64/portmaster-core
# Windows specific
COPY (+tauri-build/output/portmaster.exe --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/portmaster.exe
COPY (+tauri-build/output/WebView2Loader.dll --target="x86_64-pc-windows-gnu") ./output/binary/windows_amd64/WebView2Loader.dll
COPY (+go-build/output/portmaster-core.exe --GOARCH=amd64 --GOOS=windows --CMDS=portmaster-core) ./output/binary/windows_amd64/portmaster-core.exe
# All platforms
COPY (+assets/assets.zip) ./output/binary/all/assets.zip
COPY (+angular-project/output/portmaster.zip --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/) ./output/binary/all/portmaster.zip
# Build update manager
COPY (+go-build/output/updatemgr --GOARCH=amd64 --GOOS=linux --CMDS=updatemgr) ./updatemgr
# Get "portmaster-kext.sys" and "portmaster-core.dll" from current stable release
RUN mkdir -p ./output/downloaded/windows_amd64 && ./updatemgr download https://updates.safing.io/stable.v3.json --platform windows_amd64 ./output/downloaded/windows_amd64
RUN find ./output/downloaded/windows_amd64 -type f ! -name "portmaster-kext.sys" ! -name "portmaster-core.dll" -delete # We are only interested in the KEXT and core DLL. Remove the rest.
# Get intel artifacts
RUN mkdir -p ./output/intel && ./updatemgr download https://updates.safing.io/intel.v3.json ./output/intel
# Save all artifacts to output folder (on host)
SAVE ARTIFACT --keep-ts "output/binary/all/*" AS LOCAL "${outputDir}/binary/all/"
SAVE ARTIFACT --keep-ts "output/binary/linux_amd64/*" AS LOCAL "${outputDir}/binary/linux_amd64/"
SAVE ARTIFACT --keep-ts "output/binary/windows_amd64/*" AS LOCAL "${outputDir}/binary/windows_amd64/"
SAVE ARTIFACT --keep-ts "output/intel/*" AS LOCAL "${outputDir}/intel/"
SAVE ARTIFACT --keep-ts "output/downloaded/*" AS LOCAL "${outputDir}/downloaded/" # KEXT and core DLL: artifacts from the current stable release
# Save all artifacts to the container output folder so other containers can access it.
SAVE ARTIFACT --keep-ts "output/binary/all/*" "output/binary/all/"
SAVE ARTIFACT --keep-ts "output/binary/linux_amd64/*" "output/binary/linux_amd64/"
SAVE ARTIFACT --keep-ts "output/binary/windows_amd64/*" "output/binary/windows_amd64/"
SAVE ARTIFACT --keep-ts "output/intel/*" "output/intel/"
SAVE ARTIFACT --keep-ts "output/downloaded/*" "output/downloaded/"
# IMPORTANT: COPYING PRECOMPILED LOCAL FILES!
# If "packaging/_precompiled" foledr exists, it's contents has priority to be used; it's files will overwrite the ones from the build!
# Expected structure:
# - packaging/_precompiled/binary/...
# - packaging/_precompiled/intel
# Careful! If there are any files in the '_precompiled/intel' folder, the final 'intel/index.json' may be broken due to incorrect hash values!
COPY --if-exists --keep-ts ./packaging/_precompiled/binary ./packaging/precompiled/binary
COPY --if-exists --keep-ts ./packaging/_precompiled/intel ./packaging/precompiled/intel
IF --no-cache [ -d ./packaging/precompiled ]
RUN --no-cache echo "[ !!! ATTENTION !!! ] PRECOMPILED FILES IN USE:" && find ./packaging/precompiled -type f;
IF --no-cache [ -d ./packaging/precompiled/intel ]
RUN --no-cache echo "[!!! ATTENTION !!!] ENSURE THAT 'intel/index.json' CONTAINS THE CORRECT HASHES!"
END
RUN --no-cache echo "Script paused. Press Enter to continue..." && read
SAVE ARTIFACT --if-exists --keep-ts "packaging/precompiled/intel/*" AS LOCAL "${outputDir}/intel/" # save to host
SAVE ARTIFACT --if-exists --keep-ts "packaging/precompiled/binary/*" AS LOCAL "${outputDir}/binary/" # save to host
SAVE ARTIFACT --if-exists --keep-ts "packaging/precompiled/intel/*" "output/intel/" # save to container (so other containers can access it)
SAVE ARTIFACT --if-exists --keep-ts "packaging/precompiled/binary/*" "output/binary/" # save to container (so other containers can access it)
END
installer-linux:
FROM +rust-base
# ARG --required target
ARG target="x86_64-unknown-linux-gnu"
WORKDIR /app/tauri
COPY --keep-ts ./desktop/tauri/ .
COPY assets/data ./../../assets/data
COPY packaging ./../../packaging
WORKDIR /app/tauri/src-tauri
SAVE IMAGE --cache-hint
DO +RUST_TO_GO_ARCH_STRING --rustTarget="${target}"
# Build and copy the binaries
RUN mkdir -p target/${target}/release
COPY (+release-prep/output/binary/linux_amd64/portmaster) ./target/${target}/release/portmaster
RUN mkdir -p binary
COPY (+release-prep/output/binary/linux_amd64/portmaster-core) ./binary/portmaster-core
COPY (+release-prep/output/binary/all/portmaster.zip) ./binary/portmaster.zip
COPY (+release-prep/output/binary/all/assets.zip) ./binary/assets.zip
# Download the intel data
RUN mkdir -p intel
COPY (+release-prep/output/intel/*) ./intel/
# Init version information: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer
DO +SET_VERSION_INFO
# Set version in Cargo.toml if it's a valid SemVer (required for using in the installer file names)
RUN if [ -n "$VERSION_SemVer" ]; then sed -i 's/^version = ".*"/version = "'"$VERSION_SemVer"'"/g' Cargo.toml; fi
# build the installers
RUN cargo tauri bundle --ci --target="${target}"
# Installers
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/bundle/deb/*.deb" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/"
SAVE ARTIFACT --if-exists --keep-ts "target/${target}/release/bundle/rpm/*.rpm" AS LOCAL "${outputDir}/${GO_ARCH_STRING}/"
all-artifacts:
BUILD +release-prep
BUILD +installer-linux
kext-build:
FROM ${rust_builder_image}
# Install architecture target
DO rust+INIT --keep_fingerprints=true
# Build kext
WORKDIR /app/kext
# --keep-ts is necessary to ensure that the timestamps of the source files
# are preserved such that Rust's incremental compilation works correctly.
COPY --keep-ts ./windows_kext/ .
# Add target architecture
RUN rustup target add x86_64-pc-windows-msvc
# Build using special earthly lib
WORKDIR /app/kext/release
DO rust+CARGO --args="run"
SAVE ARTIFACT --keep-ts "portmaster-kext-release-bundle.zip" AS LOCAL "${outputDir}/windows_amd64/portmaster-kext-release-bundle.zip"
# Takes GOOS, GOARCH and optionally GOARM and creates a string representation for file-names.
# in the form of ${GOOS}_{GOARCH} if GOARM is empty, otherwise ${GOOS}_${GOARCH}v${GOARM}.
# Thats the same format as expected and served by our update server.
#
# The result is available as GO_ARCH_STRING environment variable in the build context.
GO_ARCH_STRING:
FUNCTION
ARG --required goos
ARG --required goarch
ARG goarm
LET result = "${goos}_${goarch}"
IF [ "${goarm}" != "" ]
SET result = "${goos}_${goarch}v${goarm}"
END
ENV GO_ARCH_STRING="${result}"
# Takes a rust target (--rustTarget) and extracts architecture and OS and arm version
# and finally calls GO_ARCH_STRING.
#
# The result is available as GO_ARCH_STRING environment variable in the build context.
# It also exports GOOS, GOARCH and GOARM environment variables.
RUST_TO_GO_ARCH_STRING:
FUNCTION
ARG --required rustTarget
LET goos=""
IF [ -z "${rustTarget##*linux*}" ]
SET goos="linux"
ELSE IF [ -z "${rustTarget##*windows*}" ]
SET goos="windows"
ELSE IF [ -z "${rustTarget##*darwin*}" ]
SET goos="darwin"
ELSE
RUN echo "GOOS not detected"; \
exit 1;
END
LET goarch=""
LET goarm=""
IF [ -z "${rustTarget##*x86_64*}" ]
SET goarch="amd64"
ELSE IF [ -z "${rustTarget##*arm*}" ]
SET goarch="arm"
SET goarm="6"
IF [ -z "${rustTarget##*v7*}" ]
SET goarm="7"
END
ELSE IF [ -z "${rustTarget##*aarch64*}" ]
SET goarch="arm64"
ELSE
RUN echo "GOARCH not detected"; \
exit 1;
END
ENV GOOS="${goos}"
ENV GOARCH="${goarch}"
ENV GOARM="${goarm}"
DO +GO_ARCH_STRING --goos="${goos}" --goarch="${goarch}" --goarm="${goarm}"
# Takes an architecture or GOOS string and sets the BINEXT env var.
BIN_EXT:
FUNCTION
ARG --required arch
LET binext=""
IF [ -z "${arch##*windows*}" ]
SET binext=".exe"
END
ENV BINEXT="${goos}"
# Function to set the version-related environment variables (variables: VERSION, SOURCE, BUILD_TIME and VERSION_SemVer)
# Call example:
# DO +SET_VERSION_INFO
SET_VERSION_INFO:
FUNCTION
ARG gitDir="/tmp/git-info"
# Check if already initialized and skip the rest if true
IF [ -n "$BUILD_TIME" ]
#RUN echo "Version info already initialized"
ELSE
# Make sure git is installed in the image
RUN which git || apk add --no-cache git
# Create a temporary directory for git information only
RUN mkdir -p ${gitDir}
# Copy only the .git directory to the temporary location
COPY --dir .git ${gitDir}/.git
# Check if custom version was provided via command line
IF [ -n "$custom_version" ]
ENV VERSION="${custom_version}"
RUN echo "Using custom version from command line: $VERSION"
ELSE
# Get version from git tags without changing workdir
LET version = "$(git --git-dir=${gitDir}/.git tag --points-at || true)"
IF [ -z "${version}" ]
LET dev_version = "$(git --git-dir=${gitDir}/.git describe --tags --first-parent --abbrev=0 || true)"
IF [ -n "${dev_version}" ]
SET version = "${dev_version}_dev_build"
END
END
IF [ -z "${version}" ]
SET version = "dev_build"
END
ENV VERSION="${version}"
RUN echo "Version: $VERSION"
END
# Create cleaned version without 'v' prefix and without suffix starting with '_'
# Only set VERSION_SemVer if it matches semantic versioning format
LET version_clean = "$(echo "${VERSION}" | sed -E 's/^[vV]//' | sed -E 's/_.*$//')"
IF [ $(echo "${version_clean}" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$') ]
ENV VERSION_SemVer="${version_clean}"
RUN echo "VERSION_SemVer: $VERSION_SemVer"
ELSE
RUN echo "VERSION_SemVer: [Empty - not a valid SemVer in Git Tag] - !!! WARNING !!!"
END
# Get source information without changing workdir
LET source = "$( (git --git-dir=${gitDir}/.git remote -v | cut -f2 | cut -d" " -f1 | head -n 1) || echo "unknown" )"
ENV SOURCE="${source}"
RUN echo "Source: $SOURCE"
# Get build time
LET build_time = "$(date -u "+%Y-%m-%dT%H:%M:%SZ" || echo "unknown")"
ENV BUILD_TIME = "${build_time}"
RUN echo "Build Time: $BUILD_TIME"
END
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# Get Peace of Mind <br> with [Easy Privacy](https://safing.io/)
Portmaster is a free and open-source application firewall that does the heavy lifting for you.
Restore privacy and take back control over all your computer's network activity.
With great defaults your privacy improves without any effort. And if you want to configure and control everything down to the last detail - Portmaster has you covered too. Developed in the EU 🇪🇺, Austria.
__[Download for Free](https://safing.io/download/)__
__[About Us](https://safing.io/about/)__

_seen on:_
[<img src="https://safing.io/assets/img/external/heise_online.svg" height="35">](https://www.heise.de/tests/Datenschutz-Firewall-Portmaster-im-Test-9611687.html)
[](https://www.ghacks.net/2022/11/08/portmaster-1-0-released-open-source-application-firewall/)
[](https://www.youtube.com/watch?v=E8cTRhGtmcM)
[](https://lifehacker.com/the-lesser-known-apps-everyone-should-install-on-a-new-1850223434)
## [Features](https://safing.io/features/)
1. Monitor All Network Activity
2. Full Control: Block Anything
3. Automatically Block Trackers & Malware
4. Set Global & Per‑App Settings
5. Secure DNS (Doh/DoT)
6. Record and Search Network Activity ([$](https://safing.io/pricing/))
7. Per-App Bandwidth Usage ([$](https://safing.io/pricing/))
8. [SPN, our Next-Gen Privacy Network](https://safing.io/spn/) ([$$](https://safing.io/pricing/))
# Technical Introduction
Portmaster is a privacy suite for your Windows and Linux desktop.
### Base Technology
- Portmaster integrates into network stack using nfqueue on Linux and a kernel driver (WFP) on Windows.
- Packets are intercepted at the raw packet level - every packet is seen and can be stopped.
- Ownership of connections is found using eBPF and `/proc` on Linux and a kernel driver and the IP Helper API (`iphlpapi.dll`) on Windows.
- Most settings can be defined per app, which can be matched in different ways.
- Support for special processes with weird or concealed paths/actors:
- Snap, AppImage and Script support on Linux
- Windows Store apps and svchost.exe system services support on Windows
- Everything is 100% local on your device. (except the SPN, naturally)
- Updates are fully signed and downloaded automatically.
- Intelligence data (block lists, geoip) is downloaded and applied automatically.
- The Portmaster Core Service runs as a system service, the UI elements (App, Notifier) run in user context.
- The main UI still uses electron as a wrapper :/ - but this will change in the future. You can also open the UI in the browser
### Feature: Secure DNS
- Portmaster intercepts "astray" DNS queries and reroutes them to itself for seamless integration.
- DNS queries are resolved by the default or configured DoT/DoH resolvers.
- Full support for split horizon and horizon validation to defend against rebinding attacks.
### Feature: Privacy Filter
- Define allowed network scopes: Localhost, LAN, Internet, P2P, Inbound.
- Easy rules based on Internet entities: Domain, IP, Country and more.
- Filter Lists block common malware, ad, tracker domains etc.
### Feature: Network History ($)
- Record connections and their details in a local database and search all of it later
- Auto-delete old history or delete on demand
### Feature: Bandwidth Visibility ($)
- Monitor bandwidth usage per connection and app
### Feature: SPN - Safing Privacy Network ($$)
- A Privacy Network aimed at use cases "between" VPN and Tor.
- Uses onion encryption over multiple hops just like Tor.
- Routes are chosen to cover most distance within the network to increase privacy.
- Exits are chosen near the destination server. This automatically geo-unblocks in many cases.
- Exclude apps and domains/entities from using SPN.
- Change routing algorithm and focus per app.
- Nodes are hosted by Safing (company behind Portmaster) and the community.
- Speeds are pretty decent (>100MBit/s).
- Further Reading: [SPN Whitepaper](https://safing.io/files/whitepaper/Gate17.pdf)
## Documentation
All details and guides in the dedicated [wiki](https://wiki.safing.io/)
- [Getting Started](https://wiki.safing.io/en/Portmaster/App)
- Install
- [on Windows](https://wiki.safing.io/en/Portmaster/Install/Windows)
- [on Linux](https://wiki.safing.io/en/Portmaster/Install/Linux)
- [Contribute](https://wiki.safing.io/en/Contribute)
- [VPN Compatibility](https://wiki.safing.io/en/Portmaster/App/Compatibility#vpn-compatibly)
- [Software Compatibility](https://wiki.safing.io/en/Portmaster/App/Compatibility)
- [Architecture](https://wiki.safing.io/en/Portmaster/Architecture)
- [Settings Handbook](https://docs.safing.io/portmaster/settings)
- [Portmaster Developer API](https://docs.safing.io/portmaster/api)
# Build Portmaster Yourself (WIP)
1. [Install Earthly CLI](https://earthly.dev/get-earthly)
2. [Install Docker Engine](https://docs.docker.com/engine/install/)
3. Run `earthly +release`
4. Find artifacts in `./dist`
================================================
FILE: TESTING.md
================================================
# Testing Portmaster
This page documents ways to test if Portmaster works as intended.
⚠ Work in Progress. Currently we are just collecting helpful things we find.
## Websites for Testing:
- <http://icmpcheck.popcount.org/>: Check
- ICMP path MTU packet delivery
- IP fragmented packet delivery
================================================
FILE: TRADEMARKS
================================================
The names "Safing", "Portmaster", "Gate17" and their logos are trademarks owned by Safing ICS Technologies GmbH (Austria).
Although our code is free, it is very important that we strictly enforce our trademark rights, in order to be able to protect our users against people who use the marks to commit fraud. This means that, while you have considerable freedom to redistribute and modify our software, there are tight restrictions on your ability to use our names and logos in ways which fall in the domain of trademark law, even when built into binaries that we provide.
This file is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Parts of it were taken from https://www.mozilla.org/en-US/foundation/licensing/.
================================================
FILE: assets/data/favicons/browserconfig.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/assets/favicons/ms-icon-70x70.png"/><square150x150logo src="/assets/favicons/ms-icon-150x150.png"/><square310x310logo src="/assets/favicons/ms-icon-310x310.png"/><TileColor>#121213</TileColor></tile></msapplication></browserconfig>
================================================
FILE: assets/data/favicons/head.html
================================================
<link rel="apple-touch-icon" sizes="57x57" href="/assets/favicons/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/favicons/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/favicons/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/favicons/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/favicons/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/favicons/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/favicons/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/favicons/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicons/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/assets/favicons/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
<link rel="manifest" href="/assets/favicons/manifest.json">
<meta name="msapplication-TileColor" content="#121213">
<meta name="msapplication-TileImage" content="/assets/favicons/ms-icon-144x144.png">
<meta name="theme-color" content="#121213">
================================================
FILE: assets/data/favicons/manifest.json
================================================
{
"name": "App",
"icons": [
{
"src": "\/assets\/favicons\/android-icon-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "\/assets\/favicons\/android-icon-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "\/assets\/favicons\/android-icon-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "\/assets\/favicons\/android-icon-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "\/assets\/favicons\/android-icon-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "\/assets\/favicons\/android-icon-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": "4.0"
}
]
}
================================================
FILE: assets/data/fonts/Roboto-300/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-300italic/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-500/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-500italic/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-700/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-700italic/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-italic/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/Roboto-regular/LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: assets/data/fonts/roboto-slimfix.css
================================================
@font-face {
font-family: 'Roboto';
font-weight: 400;
font-style: normal;
src: url('/assets/fonts/Roboto-300/Roboto-300.eot');
src: url('/assets/fonts/Roboto-300/Roboto-300.eot?#iefix') format('embedded-opentype'),
local('Roboto Light'),
local('Roboto-300'),
url('/assets/fonts/Roboto-300/Roboto-300.woff2') format('woff2'),
url('/assets/fonts/Roboto-300/Roboto-300.woff') format('woff'),
url('/assets/fonts/Roboto-300/Roboto-300.ttf') format('truetype'),
url('/assets/fonts/Roboto-300/Roboto-300.svg#Roboto') format('svg');
}
@font-face {
font-family: 'Roboto';
font-weight: 500;
font-style: normal;
src: url('/assets/fonts/Roboto-regular/Roboto-regular.eot');
src: url('/assets/fonts/Roboto-regular/Roboto-regular.eot?#iefix') format('embedded-opentype'),
local('Roboto'),
local('Roboto-regular'),
url('/assets/fonts/Roboto-regular/Roboto-regular.woff2') format('woff2'),
url('/assets/fonts/Roboto-regular/Roboto-regular.woff') format('woff'),
url('/assets/fonts/Roboto-regular/Roboto-regular.ttf') format('truetype'),
url('/assets/fonts/Roboto-regular/Roboto-regular.svg#Roboto') format('svg');
}
@font-face {
font-family: 'Roboto';
font-weight: 700;
font-style: normal;
src: url('/assets/fonts/Roboto-500/Roboto-500.eot');
src: url('/assets/fonts/Roboto-500/Roboto-500.eot?#iefix') format('embedded-opentype'),
local('Roboto Medium'),
local('Roboto-500'),
url('/assets/fonts/Roboto-500/Roboto-500.woff2') format('woff2'),
url('/assets/fonts/Roboto-500/Roboto-500.woff') format('woff'),
url('/assets/fonts/Roboto-500/Roboto-500.ttf') format('truetype'),
url('/assets/fonts/Roboto-500/Roboto-500.svg#Roboto') format('svg');
}
@font-face {
font-family: 'Roboto';
font-weight: 900;
font-style: normal;
src: url('/assets/fonts/Roboto-700/Roboto-700.eot');
src: url('/assets/fonts/Roboto-700/Roboto-700.eot?#iefix') format('embedded-opentype'),
local('Roboto Bold'),
local('Roboto-700'),
url('/assets/fonts/Roboto-700/Roboto-700.woff2') format('woff2'),
url('/assets/fonts/Roboto-700/Roboto-700.woff') format('woff'),
url('/assets/fonts/Roboto-700/Roboto-700.ttf') format('truetype'),
url('/assets/fonts/Roboto-700/Robot
gitextract_qc0_tm9o/
├── .angulardoc.json
├── .earthlyignore
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ ├── report-bug.md
│ │ ├── report-compatibility.md
│ │ └── suggest-feature.md
│ ├── dependabot.yml
│ ├── label-actions.yml
│ └── workflows/
│ ├── angular.yml
│ ├── go.yml
│ ├── issues-first-greet.yml
│ ├── issues-label-actions.yml
│ ├── issues-stale.yml
│ ├── kext.yml
│ ├── release.yml
│ ├── tauri.yml
│ └── windows-dll.yml
├── .gitignore
├── .golangci.yml
├── .travis.yml
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── Earthfile
├── LICENSE
├── README.md
├── TESTING.md
├── TRADEMARKS
├── assets/
│ ├── data/
│ │ ├── favicons/
│ │ │ ├── browserconfig.xml
│ │ │ ├── head.html
│ │ │ └── manifest.json
│ │ ├── fonts/
│ │ │ ├── Roboto-300/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-300italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-500/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-500italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-700/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-700italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-italic/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── Roboto-regular/
│ │ │ │ └── LICENSE.txt
│ │ │ ├── roboto-slimfix.css
│ │ │ └── roboto.css
│ │ ├── icons/
│ │ │ ├── README.md
│ │ │ └── generate_ico.sh
│ │ ├── img/
│ │ │ └── flags/
│ │ │ └── LICENSE.txt
│ │ └── world-50m.json
│ ├── icons.go
│ ├── icons_default.go
│ └── icons_windows.go
├── base/
│ ├── .gitignore
│ ├── README.md
│ ├── api/
│ │ ├── api_bridge.go
│ │ ├── auth_wrapper.go
│ │ ├── authentication.go
│ │ ├── authentication_test.go
│ │ ├── client/
│ │ │ ├── api.go
│ │ │ ├── client.go
│ │ │ ├── const.go
│ │ │ ├── message.go
│ │ │ └── websocket.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── endpoints.go
│ │ ├── endpoints_config.go
│ │ ├── endpoints_debug.go
│ │ ├── endpoints_meta.go
│ │ ├── endpoints_test.go
│ │ ├── enriched-response.go
│ │ ├── init_test.go
│ │ ├── main.go
│ │ ├── module.go
│ │ ├── request.go
│ │ ├── router.go
│ │ └── testclient/
│ │ ├── root/
│ │ │ └── index.html
│ │ └── serve.go
│ ├── apprise/
│ │ └── notify.go
│ ├── config/
│ │ ├── basic_config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── expertise.go
│ │ ├── get-safe.go
│ │ ├── get.go
│ │ ├── get_test.go
│ │ ├── init_test.go
│ │ ├── main.go
│ │ ├── module.go
│ │ ├── option.go
│ │ ├── persistence.go
│ │ ├── persistence_test.go
│ │ ├── perspective.go
│ │ ├── registry.go
│ │ ├── registry_test.go
│ │ ├── release.go
│ │ ├── set.go
│ │ ├── set_test.go
│ │ ├── validate.go
│ │ └── validity.go
│ ├── container/
│ │ ├── container.go
│ │ ├── container_test.go
│ │ ├── doc.go
│ │ └── serialization.go
│ ├── database/
│ │ ├── accessor/
│ │ │ ├── accessor-json-bytes.go
│ │ │ ├── accessor-json-string.go
│ │ │ ├── accessor-struct.go
│ │ │ ├── accessor.go
│ │ │ └── accessor_test.go
│ │ ├── boilerplate_test.go
│ │ ├── controller.go
│ │ ├── controllers.go
│ │ ├── database.go
│ │ ├── database_test.go
│ │ ├── dbmodule/
│ │ │ ├── db.go
│ │ │ └── maintenance.go
│ │ ├── doc.go
│ │ ├── errors.go
│ │ ├── hook.go
│ │ ├── hookbase.go
│ │ ├── interface.go
│ │ ├── interface_cache.go
│ │ ├── interface_cache_test.go
│ │ ├── iterator/
│ │ │ └── iterator.go
│ │ ├── main.go
│ │ ├── maintenance.go
│ │ ├── migration/
│ │ │ ├── error.go
│ │ │ └── migration.go
│ │ ├── query/
│ │ │ ├── README.md
│ │ │ ├── condition-and.go
│ │ │ ├── condition-bool.go
│ │ │ ├── condition-error.go
│ │ │ ├── condition-exists.go
│ │ │ ├── condition-float.go
│ │ │ ├── condition-int.go
│ │ │ ├── condition-not.go
│ │ │ ├── condition-or.go
│ │ │ ├── condition-regex.go
│ │ │ ├── condition-string.go
│ │ │ ├── condition-stringslice.go
│ │ │ ├── condition.go
│ │ │ ├── condition_test.go
│ │ │ ├── operators.go
│ │ │ ├── operators_test.go
│ │ │ ├── parser.go
│ │ │ ├── parser_test.go
│ │ │ ├── query.go
│ │ │ └── query_test.go
│ │ ├── record/
│ │ │ ├── base.go
│ │ │ ├── base_test.go
│ │ │ ├── key.go
│ │ │ ├── meta-bench_test.go
│ │ │ ├── meta-gencode.go
│ │ │ ├── meta-gencode_test.go
│ │ │ ├── meta.colf
│ │ │ ├── meta.gencode
│ │ │ ├── meta.go
│ │ │ ├── record.go
│ │ │ ├── record_test.go
│ │ │ ├── wrapper.go
│ │ │ └── wrapper_test.go
│ │ ├── registry.go
│ │ ├── storage/
│ │ │ ├── badger/
│ │ │ │ ├── badger.go
│ │ │ │ └── badger_test.go
│ │ │ ├── bbolt/
│ │ │ │ ├── bbolt.go
│ │ │ │ └── bbolt_test.go
│ │ │ ├── errors.go
│ │ │ ├── fstree/
│ │ │ │ ├── fstree.go
│ │ │ │ └── fstree_test.go
│ │ │ ├── hashmap/
│ │ │ │ ├── map.go
│ │ │ │ └── map_test.go
│ │ │ ├── injectbase.go
│ │ │ ├── interface.go
│ │ │ ├── sinkhole/
│ │ │ │ └── sinkhole.go
│ │ │ ├── sqlite/
│ │ │ │ ├── bobgen.yaml
│ │ │ │ ├── dberrors/
│ │ │ │ │ ├── bob_errors.bob.go
│ │ │ │ │ ├── bob_main.bob_test.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── dbinfo/
│ │ │ │ │ ├── bob_types.bob.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── factory/
│ │ │ │ │ ├── bobfactory_context.bob.go
│ │ │ │ │ ├── bobfactory_main.bob.go
│ │ │ │ │ ├── bobfactory_main.bob_test.go
│ │ │ │ │ ├── bobfactory_random.bob.go
│ │ │ │ │ ├── bobfactory_random.bob_test.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── migrations/
│ │ │ │ │ ├── 0_settings.sql
│ │ │ │ │ └── 1_initial.sql
│ │ │ │ ├── migrations_config.yml
│ │ │ │ ├── models/
│ │ │ │ │ ├── bob_joins.bob.go
│ │ │ │ │ ├── bob_loaders.bob.go
│ │ │ │ │ ├── bob_types.bob_test.go
│ │ │ │ │ ├── bob_where.bob.go
│ │ │ │ │ └── records.bob.go
│ │ │ │ ├── prepared.go
│ │ │ │ ├── prepared_test.go
│ │ │ │ ├── schema.go
│ │ │ │ ├── sqlite.go
│ │ │ │ └── sqlite_test.go
│ │ │ └── storages.go
│ │ └── subscription.go
│ ├── info/
│ │ └── version.go
│ ├── log/
│ │ ├── formatting.go
│ │ ├── formatting_unix.go
│ │ ├── formatting_windows.go
│ │ ├── input.go
│ │ ├── logging.go
│ │ ├── logging_test.go
│ │ ├── output.go
│ │ ├── slog.go
│ │ ├── trace.go
│ │ ├── trace_test.go
│ │ └── writer.go
│ ├── metrics/
│ │ ├── api.go
│ │ ├── config.go
│ │ ├── metric.go
│ │ ├── metric_counter.go
│ │ ├── metric_counter_fetching.go
│ │ ├── metric_export.go
│ │ ├── metric_gauge.go
│ │ ├── metric_histogram.go
│ │ ├── metrics_host.go
│ │ ├── metrics_info.go
│ │ ├── metrics_logs.go
│ │ ├── metrics_runtime.go
│ │ ├── module.go
│ │ └── persistence.go
│ ├── notifications/
│ │ ├── cleaner.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── module-mirror.go
│ │ ├── module.go
│ │ └── notification.go
│ ├── rng/
│ │ ├── doc.go
│ │ ├── entropy.go
│ │ ├── entropy_test.go
│ │ ├── fullfeed.go
│ │ ├── fullfeed_test.go
│ │ ├── get.go
│ │ ├── get_test.go
│ │ ├── osfeeder.go
│ │ ├── rng.go
│ │ ├── rng_test.go
│ │ └── tickfeeder.go
│ ├── runtime/
│ │ ├── module.go
│ │ ├── provider.go
│ │ ├── registry.go
│ │ ├── registry_test.go
│ │ ├── singe_record_provider.go
│ │ ├── storage.go
│ │ └── trace_provider.go
│ ├── template/
│ │ └── module.go
│ └── utils/
│ ├── atomic.go
│ ├── broadcastflag.go
│ ├── call_limiter.go
│ ├── call_limiter2.go
│ ├── call_limiter_test.go
│ ├── debug/
│ │ ├── debug.go
│ │ ├── debug_android.go
│ │ └── debug_default.go
│ ├── fs.go
│ ├── mimetypes.go
│ ├── onceagain.go
│ ├── onceagain_test.go
│ ├── osdetail/
│ │ ├── colors_windows.go
│ │ ├── command.go
│ │ ├── dnscache_windows.go
│ │ ├── errors.go
│ │ ├── service_windows.go
│ │ ├── shell_windows.go
│ │ ├── svchost_windows.go
│ │ ├── version_windows.go
│ │ └── version_windows_test.go
│ ├── permissions.go
│ ├── permissions_windows.go
│ ├── renameio/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── doc.go
│ │ ├── example_test.go
│ │ ├── symlink_test.go
│ │ ├── tempfile.go
│ │ ├── tempfile_linux_test.go
│ │ ├── writefile.go
│ │ └── writefile_test.go
│ ├── safe.go
│ ├── safe_test.go
│ ├── slices.go
│ ├── slices_test.go
│ ├── stablepool.go
│ ├── stablepool_test.go
│ ├── structure.go
│ ├── structure_test.go
│ ├── uuid.go
│ └── uuid_test.go
├── cmds/
│ ├── cmdbase/
│ │ ├── service.go
│ │ ├── service_linux.go
│ │ ├── service_windows.go
│ │ ├── update.go
│ │ └── version.go
│ ├── integrationtest/
│ │ ├── main.go
│ │ └── netstate.go
│ ├── trafficgen/
│ │ ├── main.go
│ │ └── pack
│ └── winkext-test/
│ ├── main.go
│ ├── main_linux.go
│ └── pack
├── desktop/
│ ├── angular/
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ ├── .vscode/
│ │ │ ├── launch.json
│ │ │ └── tasks.json
│ │ ├── README.md
│ │ ├── angular.json
│ │ ├── browser-extension-dev.config.ts
│ │ ├── browser-extension.config.ts
│ │ ├── docker.sh
│ │ ├── e2e/
│ │ │ ├── protractor.conf.js
│ │ │ ├── src/
│ │ │ │ ├── app.e2e-spec.ts
│ │ │ │ └── app.po.ts
│ │ │ └── tsconfig.json
│ │ ├── karma.conf.js
│ │ ├── package.json
│ │ ├── projects/
│ │ │ ├── portmaster-chrome-extension/
│ │ │ │ ├── karma.conf.js
│ │ │ │ ├── src/
│ │ │ │ │ ├── app/
│ │ │ │ │ │ ├── app-routing.module.ts
│ │ │ │ │ │ ├── app.component.html
│ │ │ │ │ │ ├── app.component.scss
│ │ │ │ │ │ ├── app.component.ts
│ │ │ │ │ │ ├── app.module.ts
│ │ │ │ │ │ ├── domain-list/
│ │ │ │ │ │ │ ├── domain-list.component.html
│ │ │ │ │ │ │ ├── domain-list.component.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── header/
│ │ │ │ │ │ │ ├── header.component.html
│ │ │ │ │ │ │ ├── header.component.scss
│ │ │ │ │ │ │ ├── header.component.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── interceptor.ts
│ │ │ │ │ │ ├── request-interceptor.service.ts
│ │ │ │ │ │ └── welcome/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── intro.component.html
│ │ │ │ │ │ ├── intro.component.ts
│ │ │ │ │ │ └── welcome.module.ts
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ ├── background/
│ │ │ │ │ │ ├── commands.ts
│ │ │ │ │ │ ├── tab-tracker.ts
│ │ │ │ │ │ └── tab-utils.ts
│ │ │ │ │ ├── background.ts
│ │ │ │ │ ├── environments/
│ │ │ │ │ │ ├── environment.prod.ts
│ │ │ │ │ │ └── environment.ts
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── main.ts
│ │ │ │ │ ├── manifest.json
│ │ │ │ │ ├── polyfills.ts
│ │ │ │ │ ├── styles.scss
│ │ │ │ │ └── test.ts
│ │ │ │ ├── tsconfig.app.json
│ │ │ │ └── tsconfig.spec.json
│ │ │ ├── safing/
│ │ │ │ ├── portmaster-api/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── karma.conf.js
│ │ │ │ │ ├── ng-package.json
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── src/
│ │ │ │ │ │ ├── lib/
│ │ │ │ │ │ │ ├── app-profile.service.ts
│ │ │ │ │ │ │ ├── app-profile.types.ts
│ │ │ │ │ │ │ ├── config.service.ts
│ │ │ │ │ │ │ ├── config.types.ts
│ │ │ │ │ │ │ ├── core.types.ts
│ │ │ │ │ │ │ ├── debug-api.service.ts
│ │ │ │ │ │ │ ├── features.ts
│ │ │ │ │ │ │ ├── meta-api.service.ts
│ │ │ │ │ │ │ ├── module.ts
│ │ │ │ │ │ │ ├── netquery.service.ts
│ │ │ │ │ │ │ ├── network.types.ts
│ │ │ │ │ │ │ ├── platform-specific/
│ │ │ │ │ │ │ │ ├── tauri/
│ │ │ │ │ │ │ │ │ ├── tauri-http-interceptor.ts
│ │ │ │ │ │ │ │ │ └── tauri-websocket-subject.ts
│ │ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ │ ├── portapi.service.ts
│ │ │ │ │ │ │ ├── portapi.types.ts
│ │ │ │ │ │ │ ├── spn.service.ts
│ │ │ │ │ │ │ ├── spn.types.ts
│ │ │ │ │ │ │ ├── utils.ts
│ │ │ │ │ │ │ └── websocket.service.ts
│ │ │ │ │ │ ├── public-api.ts
│ │ │ │ │ │ └── test.ts
│ │ │ │ │ ├── tsconfig.lib.json
│ │ │ │ │ ├── tsconfig.lib.prod.json
│ │ │ │ │ └── tsconfig.spec.json
│ │ │ │ └── ui/
│ │ │ │ ├── .eslintrc.json
│ │ │ │ ├── README.md
│ │ │ │ ├── karma.conf.js
│ │ │ │ ├── ng-package.json
│ │ │ │ ├── package.json
│ │ │ │ ├── src/
│ │ │ │ │ ├── lib/
│ │ │ │ │ │ ├── accordion/
│ │ │ │ │ │ │ ├── accordion-group.html
│ │ │ │ │ │ │ ├── accordion-group.ts
│ │ │ │ │ │ │ ├── accordion.html
│ │ │ │ │ │ │ ├── accordion.module.ts
│ │ │ │ │ │ │ ├── accordion.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── animations/
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── dialog/
│ │ │ │ │ │ │ ├── _confirm.dialog.scss
│ │ │ │ │ │ │ ├── _dialog.scss
│ │ │ │ │ │ │ ├── confirm.dialog.html
│ │ │ │ │ │ │ ├── confirm.dialog.ts
│ │ │ │ │ │ │ ├── dialog.animations.ts
│ │ │ │ │ │ │ ├── dialog.container.ts
│ │ │ │ │ │ │ ├── dialog.module.ts
│ │ │ │ │ │ │ ├── dialog.ref.ts
│ │ │ │ │ │ │ ├── dialog.service.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── dropdown/
│ │ │ │ │ │ │ ├── dropdown.html
│ │ │ │ │ │ │ ├── dropdown.module.ts
│ │ │ │ │ │ │ ├── dropdown.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── overlay-stepper/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── overlay-stepper-container.html
│ │ │ │ │ │ │ ├── overlay-stepper-container.ts
│ │ │ │ │ │ │ ├── overlay-stepper.module.ts
│ │ │ │ │ │ │ ├── overlay-stepper.ts
│ │ │ │ │ │ │ ├── refs.ts
│ │ │ │ │ │ │ ├── step-outlet.ts
│ │ │ │ │ │ │ └── step.ts
│ │ │ │ │ │ ├── pagination/
│ │ │ │ │ │ │ ├── _pagination.scss
│ │ │ │ │ │ │ ├── dynamic-items-paginator.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pagination.html
│ │ │ │ │ │ │ ├── pagination.module.ts
│ │ │ │ │ │ │ ├── pagination.ts
│ │ │ │ │ │ │ └── snapshot-paginator.ts
│ │ │ │ │ │ ├── select/
│ │ │ │ │ │ │ ├── _select.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── item.ts
│ │ │ │ │ │ │ ├── select.html
│ │ │ │ │ │ │ ├── select.module.ts
│ │ │ │ │ │ │ └── select.ts
│ │ │ │ │ │ ├── tabs/
│ │ │ │ │ │ │ ├── _tab-group.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── tab-group.html
│ │ │ │ │ │ │ ├── tab-group.ts
│ │ │ │ │ │ │ ├── tab.ts
│ │ │ │ │ │ │ └── tabs.module.ts
│ │ │ │ │ │ ├── tipup/
│ │ │ │ │ │ │ ├── _tipup.scss
│ │ │ │ │ │ │ ├── anchor.ts
│ │ │ │ │ │ │ ├── clone-node.ts
│ │ │ │ │ │ │ ├── css-utils.ts
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── safe.pipe.ts
│ │ │ │ │ │ │ ├── tipup-component.ts
│ │ │ │ │ │ │ ├── tipup.html
│ │ │ │ │ │ │ ├── tipup.module.ts
│ │ │ │ │ │ │ ├── tipup.ts
│ │ │ │ │ │ │ ├── translations.ts
│ │ │ │ │ │ │ └── utils.ts
│ │ │ │ │ │ ├── toggle-switch/
│ │ │ │ │ │ │ ├── _toggle-switch.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── toggle-switch.html
│ │ │ │ │ │ │ ├── toggle-switch.ts
│ │ │ │ │ │ │ └── toggle.module.ts
│ │ │ │ │ │ ├── tooltip/
│ │ │ │ │ │ │ ├── _tooltip-component.scss
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── tooltip-component.html
│ │ │ │ │ │ │ ├── tooltip-component.ts
│ │ │ │ │ │ │ ├── tooltip.module.ts
│ │ │ │ │ │ │ └── tooltip.ts
│ │ │ │ │ │ └── ui.module.ts
│ │ │ │ │ ├── public-api.ts
│ │ │ │ │ └── test.ts
│ │ │ │ ├── theming.scss
│ │ │ │ ├── tsconfig.lib.json
│ │ │ │ ├── tsconfig.lib.prod.json
│ │ │ │ └── tsconfig.spec.json
│ │ │ └── tauri-builtin/
│ │ │ ├── src/
│ │ │ │ ├── app/
│ │ │ │ │ ├── app.component.html
│ │ │ │ │ ├── app.component.ts
│ │ │ │ │ └── app.config.ts
│ │ │ │ ├── index.html
│ │ │ │ ├── main.ts
│ │ │ │ └── styles.scss
│ │ │ └── tsconfig.app.json
│ │ ├── proxy.json
│ │ ├── src/
│ │ │ ├── app/
│ │ │ │ ├── app-routing.module.ts
│ │ │ │ ├── app.component.html
│ │ │ │ ├── app.component.scss
│ │ │ │ ├── app.component.spec.ts
│ │ │ │ ├── app.component.ts
│ │ │ │ ├── app.module.ts
│ │ │ │ ├── integration/
│ │ │ │ │ ├── browser.ts
│ │ │ │ │ ├── electron.ts
│ │ │ │ │ ├── factory.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── integration.ts
│ │ │ │ │ └── taur-app.ts
│ │ │ │ ├── intro/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── intro.module.ts
│ │ │ │ │ ├── step-1-welcome/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-1-welcome.html
│ │ │ │ │ │ └── step-1-welcome.ts
│ │ │ │ │ ├── step-2-trackers/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-2-trackers.html
│ │ │ │ │ │ └── step-2-trackers.ts
│ │ │ │ │ ├── step-3-dns/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-3-dns.html
│ │ │ │ │ │ └── step-3-dns.ts
│ │ │ │ │ ├── step-4-tipups/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── step-4-tipups.html
│ │ │ │ │ │ └── step-4-tipups.ts
│ │ │ │ │ └── step.scss
│ │ │ │ ├── layout/
│ │ │ │ │ ├── navigation/
│ │ │ │ │ │ ├── navigation.html
│ │ │ │ │ │ ├── navigation.scss
│ │ │ │ │ │ └── navigation.ts
│ │ │ │ │ └── side-dash/
│ │ │ │ │ ├── side-dash.html
│ │ │ │ │ ├── side-dash.scss
│ │ │ │ │ └── side-dash.ts
│ │ │ │ ├── package.json
│ │ │ │ ├── pages/
│ │ │ │ │ ├── app-view/
│ │ │ │ │ │ ├── app-insights/
│ │ │ │ │ │ │ ├── app-insights.component.html
│ │ │ │ │ │ │ └── app-insights.component.ts
│ │ │ │ │ │ ├── app-view.html
│ │ │ │ │ │ ├── app-view.scss
│ │ │ │ │ │ ├── app-view.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── merge-profile-dialog/
│ │ │ │ │ │ │ ├── merge-profile-dialog.component.html
│ │ │ │ │ │ │ └── merge-profile-dialog.component.ts
│ │ │ │ │ │ ├── overview.html
│ │ │ │ │ │ ├── overview.scss
│ │ │ │ │ │ ├── overview.ts
│ │ │ │ │ │ ├── qs-history/
│ │ │ │ │ │ │ ├── qs-history.component.html
│ │ │ │ │ │ │ ├── qs-history.component.scss
│ │ │ │ │ │ │ └── qs-history.component.ts
│ │ │ │ │ │ ├── qs-internet/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── qs-internet.html
│ │ │ │ │ │ │ └── qs-internet.ts
│ │ │ │ │ │ ├── qs-select-exit/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── qs-select-exit.html
│ │ │ │ │ │ │ ├── qs-select-exit.scss
│ │ │ │ │ │ │ └── qs-select-exit.ts
│ │ │ │ │ │ └── qs-use-spn/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── qs-use-spn.html
│ │ │ │ │ │ └── qs-use-spn.ts
│ │ │ │ │ ├── dashboard/
│ │ │ │ │ │ ├── dashboard-widget/
│ │ │ │ │ │ │ ├── dashboard-widget.component.html
│ │ │ │ │ │ │ └── dashboard-widget.component.ts
│ │ │ │ │ │ ├── dashboard.component.html
│ │ │ │ │ │ ├── dashboard.component.scss
│ │ │ │ │ │ ├── dashboard.component.ts
│ │ │ │ │ │ └── feature-card/
│ │ │ │ │ │ ├── feature-card.component.html
│ │ │ │ │ │ ├── feature-card.component.scss
│ │ │ │ │ │ └── feature-card.component.ts
│ │ │ │ │ ├── monitor/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── monitor.html
│ │ │ │ │ │ ├── monitor.scss
│ │ │ │ │ │ └── monitor.ts
│ │ │ │ │ ├── page.scss
│ │ │ │ │ ├── settings/
│ │ │ │ │ │ ├── settings.html
│ │ │ │ │ │ ├── settings.scss
│ │ │ │ │ │ └── settings.ts
│ │ │ │ │ ├── spn/
│ │ │ │ │ │ ├── country-details/
│ │ │ │ │ │ │ ├── country-details.html
│ │ │ │ │ │ │ ├── country-details.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── country-overlay/
│ │ │ │ │ │ │ ├── country-overlay.html
│ │ │ │ │ │ │ ├── country-overlay.scss
│ │ │ │ │ │ │ ├── country-overlay.ts
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── map-legend/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── map-legend.html
│ │ │ │ │ │ │ └── map-legend.ts
│ │ │ │ │ │ ├── map-renderer/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── map-renderer.ts
│ │ │ │ │ │ │ └── map-style.scss
│ │ │ │ │ │ ├── map.service.ts
│ │ │ │ │ │ ├── node-icon/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── node-icon.html
│ │ │ │ │ │ │ ├── node-icon.scss
│ │ │ │ │ │ │ └── node-icon.ts
│ │ │ │ │ │ ├── pin-details/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-details.html
│ │ │ │ │ │ │ └── pin-details.ts
│ │ │ │ │ │ ├── pin-list/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-list.html
│ │ │ │ │ │ │ └── pin-list.ts
│ │ │ │ │ │ ├── pin-overlay/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-overlay.html
│ │ │ │ │ │ │ ├── pin-overlay.scss
│ │ │ │ │ │ │ └── pin-overlay.ts
│ │ │ │ │ │ ├── pin-route/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pin-route.html
│ │ │ │ │ │ │ ├── pin-route.scss
│ │ │ │ │ │ │ └── pin-route.ts
│ │ │ │ │ │ ├── spn-feature-carousel/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── spn-feature-carousel.html
│ │ │ │ │ │ │ ├── spn-feature-carousel.scss
│ │ │ │ │ │ │ └── spn-feature-carousel.ts
│ │ │ │ │ │ ├── spn-page.html
│ │ │ │ │ │ ├── spn-page.scss
│ │ │ │ │ │ ├── spn-page.ts
│ │ │ │ │ │ ├── spn.module.ts
│ │ │ │ │ │ └── utils.ts
│ │ │ │ │ └── support/
│ │ │ │ │ ├── form/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── support-form.html
│ │ │ │ │ │ ├── support-form.scss
│ │ │ │ │ │ └── support-form.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── pages.ts
│ │ │ │ │ ├── progress-dialog/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── progress-dialog.html
│ │ │ │ │ │ └── progress-dialog.ts
│ │ │ │ │ ├── support.html
│ │ │ │ │ ├── support.scss
│ │ │ │ │ └── support.ts
│ │ │ │ ├── prompt-entrypoint/
│ │ │ │ │ ├── prompt-entrypoint.ts
│ │ │ │ │ └── prompt.html
│ │ │ │ ├── services/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── notifications.service.spec.ts
│ │ │ │ │ ├── notifications.service.ts
│ │ │ │ │ ├── notifications.types.ts
│ │ │ │ │ ├── package.json
│ │ │ │ │ ├── session-data.service.ts
│ │ │ │ │ ├── status.service.spec.ts
│ │ │ │ │ ├── status.service.ts
│ │ │ │ │ ├── status.types.ts
│ │ │ │ │ ├── supporthub.service.ts
│ │ │ │ │ ├── ui-state.service.ts
│ │ │ │ │ └── virtual-notification.ts
│ │ │ │ └── shared/
│ │ │ │ ├── action-indicator/
│ │ │ │ │ ├── action-indicator.module.ts
│ │ │ │ │ ├── action-indicator.service.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── indicator.html
│ │ │ │ │ ├── indicator.scss
│ │ │ │ │ └── indicator.ts
│ │ │ │ ├── animations.ts
│ │ │ │ ├── app-icon/
│ │ │ │ │ ├── app-icon-resolver.ts
│ │ │ │ │ ├── app-icon.html
│ │ │ │ │ ├── app-icon.module.ts
│ │ │ │ │ ├── app-icon.scss
│ │ │ │ │ ├── app-icon.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── config/
│ │ │ │ │ ├── basic-setting/
│ │ │ │ │ │ ├── basic-setting.html
│ │ │ │ │ │ ├── basic-setting.scss
│ │ │ │ │ │ ├── basic-setting.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── config-settings.html
│ │ │ │ │ ├── config-settings.scss
│ │ │ │ │ ├── config-settings.ts
│ │ │ │ │ ├── config.module.ts
│ │ │ │ │ ├── export-dialog/
│ │ │ │ │ │ ├── export-dialog.component.html
│ │ │ │ │ │ └── export-dialog.component.ts
│ │ │ │ │ ├── filter-lists/
│ │ │ │ │ │ ├── filter-list.html
│ │ │ │ │ │ ├── filter-list.scss
│ │ │ │ │ │ ├── filter-list.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── generic-setting/
│ │ │ │ │ │ ├── generic-setting.html
│ │ │ │ │ │ ├── generic-setting.scss
│ │ │ │ │ │ ├── generic-setting.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── import-dialog/
│ │ │ │ │ │ ├── cursor.ts
│ │ │ │ │ │ ├── import-dialog.component.html
│ │ │ │ │ │ ├── import-dialog.component.ts
│ │ │ │ │ │ └── selection.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── ordererd-list/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── item.html
│ │ │ │ │ │ ├── item.scss
│ │ │ │ │ │ ├── item.ts
│ │ │ │ │ │ ├── ordered-list.html
│ │ │ │ │ │ ├── ordered-list.scss
│ │ │ │ │ │ └── ordered-list.ts
│ │ │ │ │ ├── rule-list/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── list-item.html
│ │ │ │ │ │ ├── list-item.scss
│ │ │ │ │ │ ├── list-item.ts
│ │ │ │ │ │ ├── rule-list.html
│ │ │ │ │ │ ├── rule-list.scss
│ │ │ │ │ │ └── rule-list.ts
│ │ │ │ │ ├── safe.pipe.ts
│ │ │ │ │ └── subsystems.ts
│ │ │ │ ├── count-indicator/
│ │ │ │ │ ├── count-indicator.html
│ │ │ │ │ ├── count-indicator.module.ts
│ │ │ │ │ ├── count-indicator.scss
│ │ │ │ │ ├── count-indicator.ts
│ │ │ │ │ ├── count.pipe.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── country-flag/
│ │ │ │ │ ├── country-flag.ts
│ │ │ │ │ ├── country.module.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── edit-profile-dialog/
│ │ │ │ │ ├── edit-profile-dialog.html
│ │ │ │ │ ├── edit-profile-dialog.scss
│ │ │ │ │ ├── edit-profile-dialog.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── exit-screen/
│ │ │ │ │ ├── exit-screen.html
│ │ │ │ │ ├── exit-screen.scss
│ │ │ │ │ ├── exit-screen.ts
│ │ │ │ │ ├── exit.service.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── expertise/
│ │ │ │ │ ├── expertise-directive.ts
│ │ │ │ │ ├── expertise-switch.html
│ │ │ │ │ ├── expertise-switch.scss
│ │ │ │ │ ├── expertise-switch.ts
│ │ │ │ │ ├── expertise.module.ts
│ │ │ │ │ ├── expertise.service.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── external-link.directive.ts
│ │ │ │ ├── feature-scout/
│ │ │ │ │ ├── feature-scout.html
│ │ │ │ │ ├── feature-scout.scss
│ │ │ │ │ ├── feature-scout.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── focus/
│ │ │ │ │ ├── focus.directive.ts
│ │ │ │ │ ├── focus.module.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── fuzzySearch/
│ │ │ │ │ ├── fuse.service.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── search-pipe.ts
│ │ │ │ ├── loading/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── loading.html
│ │ │ │ │ ├── loading.scss
│ │ │ │ │ └── loading.ts
│ │ │ │ ├── menu/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── menu-group.scss
│ │ │ │ │ ├── menu-item.scss
│ │ │ │ │ ├── menu-trigger.html
│ │ │ │ │ ├── menu-trigger.scss
│ │ │ │ │ ├── menu.html
│ │ │ │ │ ├── menu.module.ts
│ │ │ │ │ └── menu.ts
│ │ │ │ ├── multi-switch/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── multi-switch.html
│ │ │ │ │ ├── multi-switch.module.ts
│ │ │ │ │ ├── multi-switch.scss
│ │ │ │ │ ├── multi-switch.ts
│ │ │ │ │ ├── switch-item.scss
│ │ │ │ │ └── switch-item.ts
│ │ │ │ ├── netquery/
│ │ │ │ │ ├── .eslintrc.json
│ │ │ │ │ ├── add-to-filter/
│ │ │ │ │ │ ├── add-to-filter.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── circular-bar-chart/
│ │ │ │ │ │ └── circular-bar-chart.component.ts
│ │ │ │ │ ├── combined-menu.pipe.ts
│ │ │ │ │ ├── connection-details/
│ │ │ │ │ │ ├── conn-details.html
│ │ │ │ │ │ ├── conn-details.scss
│ │ │ │ │ │ ├── conn-details.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── connection-helper.service.ts
│ │ │ │ │ ├── connection-row/
│ │ │ │ │ │ ├── conn-row.html
│ │ │ │ │ │ ├── conn-row.scss
│ │ │ │ │ │ ├── conn-row.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── line-chart/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── line-chart.ts
│ │ │ │ │ ├── netquery.component.html
│ │ │ │ │ ├── netquery.component.ts
│ │ │ │ │ ├── netquery.module.ts
│ │ │ │ │ ├── pipes/
│ │ │ │ │ │ ├── can-show.pipe.ts
│ │ │ │ │ │ ├── can-use-rules.pipe.ts
│ │ │ │ │ │ ├── country-name.pipe.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── is-blocked.pipe.ts
│ │ │ │ │ │ └── location.pipe.ts
│ │ │ │ │ ├── scope-label/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── scope-label.html
│ │ │ │ │ │ └── scope-label.ts
│ │ │ │ │ ├── search-overlay/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── search-overlay.html
│ │ │ │ │ │ └── search-overlay.ts
│ │ │ │ │ ├── searchbar/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── searchbar.html
│ │ │ │ │ │ └── searchbar.ts
│ │ │ │ │ ├── tag-bar/
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── tag-bar.html
│ │ │ │ │ │ └── tag-bar.ts
│ │ │ │ │ ├── textql/
│ │ │ │ │ │ ├── helper.ts
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ ├── input.ts
│ │ │ │ │ │ ├── lexer.ts
│ │ │ │ │ │ ├── parser.ts
│ │ │ │ │ │ └── token.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ ├── network-scout/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── network-scout.html
│ │ │ │ │ ├── network-scout.scss
│ │ │ │ │ └── network-scout.ts
│ │ │ │ ├── notification/
│ │ │ │ │ ├── notification.html
│ │ │ │ │ ├── notification.scss
│ │ │ │ │ └── notification.ts
│ │ │ │ ├── notification-list/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── notification-list.component.html
│ │ │ │ │ ├── notification-list.component.scss
│ │ │ │ │ └── notification-list.component.ts
│ │ │ │ ├── pipes/
│ │ │ │ │ ├── bytes.pipe.ts
│ │ │ │ │ ├── common-pipes.module.ts
│ │ │ │ │ ├── duration.pipe.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── round.pipe.ts
│ │ │ │ │ ├── time-ago.pipe.ts
│ │ │ │ │ ├── to-profile.pipe.ts
│ │ │ │ │ └── to-seconds.pipe.ts
│ │ │ │ ├── process-details-dialog/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── process-details-dialog.html
│ │ │ │ │ ├── process-details-dialog.scss
│ │ │ │ │ └── process-details-dialog.ts
│ │ │ │ ├── prompt-list/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── prompt-list.component.html
│ │ │ │ │ ├── prompt-list.component.scss
│ │ │ │ │ └── prompt-list.component.ts
│ │ │ │ ├── security-lock/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── security-lock.html
│ │ │ │ │ ├── security-lock.scss
│ │ │ │ │ └── security-lock.ts
│ │ │ │ ├── spn-account-details/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-account-details.html
│ │ │ │ │ ├── spn-account-details.scss
│ │ │ │ │ └── spn-account-details.ts
│ │ │ │ ├── spn-login/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-login.html
│ │ │ │ │ ├── spn-login.scss
│ │ │ │ │ └── spn-login.ts
│ │ │ │ ├── spn-network-status/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-network-status.html
│ │ │ │ │ ├── spn-network-status.scss
│ │ │ │ │ └── spn-network-status.ts
│ │ │ │ ├── spn-status/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── spn-status.html
│ │ │ │ │ └── spn-status.ts
│ │ │ │ ├── text-placeholder/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── placeholder.scss
│ │ │ │ │ └── placeholder.ts
│ │ │ │ └── utils.ts
│ │ │ ├── electron-app.d.ts
│ │ │ ├── environments/
│ │ │ │ ├── environment.prod.ts
│ │ │ │ └── environment.ts
│ │ │ ├── i18n/
│ │ │ │ ├── helptexts.yaml
│ │ │ │ └── helptexts.yaml.d.ts
│ │ │ ├── index.html
│ │ │ ├── main.ts
│ │ │ ├── polyfills.ts
│ │ │ ├── styles.scss
│ │ │ ├── test.ts
│ │ │ ├── theme/
│ │ │ │ ├── _breadcrumbs.scss
│ │ │ │ ├── _button.scss
│ │ │ │ ├── _card.scss
│ │ │ │ ├── _colors.scss
│ │ │ │ ├── _dialog.scss
│ │ │ │ ├── _drag-n-drop.scss
│ │ │ │ ├── _inputs.scss
│ │ │ │ ├── _markdown.scss
│ │ │ │ ├── _pill.scss
│ │ │ │ ├── _scroll.scss
│ │ │ │ ├── _search.scss
│ │ │ │ ├── _table.scss
│ │ │ │ ├── _tailwind.scss
│ │ │ │ ├── _trust-level.scss
│ │ │ │ ├── _typography.scss
│ │ │ │ ├── _verdict.scss
│ │ │ │ └── mixins/
│ │ │ │ └── _pill.scss
│ │ │ └── theme.less
│ │ ├── tailwind.config.js
│ │ ├── tsconfig.app.json
│ │ ├── tsconfig.json
│ │ └── tsconfig.spec.json
│ └── tauri/
│ ├── .cargo/
│ │ └── config.toml
│ ├── .vscode/
│ │ ├── launch.json
│ │ └── tasks.json
│ └── src-tauri/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── Cross.toml
│ ├── README.md
│ ├── build.rs
│ ├── capabilities/
│ │ └── default.json
│ ├── src/
│ │ ├── cli.rs
│ │ ├── commands/
│ │ │ ├── mod.rs
│ │ │ └── tauri_http.rs
│ │ ├── config.rs
│ │ ├── main.rs
│ │ ├── portapi/
│ │ │ ├── client.rs
│ │ │ ├── message.rs
│ │ │ ├── mod.rs
│ │ │ ├── models/
│ │ │ │ ├── config.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── notification.rs
│ │ │ │ ├── spn.rs
│ │ │ │ └── system_status_types.rs
│ │ │ └── types.rs
│ │ ├── portmaster/
│ │ │ ├── commands.rs
│ │ │ ├── mod.rs
│ │ │ ├── notifications.rs
│ │ │ └── websocket.rs
│ │ ├── service/
│ │ │ ├── manager.rs
│ │ │ ├── mod.rs
│ │ │ ├── status.rs
│ │ │ ├── systemd.rs
│ │ │ └── windows_service.rs
│ │ ├── traymenu.rs
│ │ ├── window.rs
│ │ └── xdg/
│ │ └── mod.rs
│ ├── tauri.conf.json5
│ └── templates/
│ ├── NSIS_Simple_Service_Plugin_Unicode_1.30/
│ │ ├── License.txt
│ │ ├── Readme.txt
│ │ └── Source/
│ │ ├── LSASecurityControl.pas
│ │ ├── NSIS Plugins.groupproj
│ │ ├── NSIS.pas
│ │ ├── ServiceControl.pas
│ │ ├── SimpleSC.dpr
│ │ ├── SimpleSC.dproj
│ │ └── SimpleSC.res
│ ├── nsis/
│ │ └── install_hooks.nsh
│ └── wix/
│ ├── CheckServiceStatus.vbs
│ ├── Migration.vbs
│ ├── files.wxs
│ ├── main.wxs
│ ├── main_original.wxs
│ ├── migration.wxs
│ └── old_service_check.wxs
├── go.mod
├── go.sum
├── packaging/
│ ├── README.md
│ ├── linux/
│ │ ├── dev_helpers/
│ │ │ └── build_tauri.sh
│ │ ├── portmaster-autostart.desktop
│ │ ├── portmaster.desktop
│ │ ├── portmaster.service
│ │ ├── postinst
│ │ ├── postrm
│ │ └── readme.md
│ └── windows/
│ ├── .gitkeep
│ ├── dev_helpers/
│ │ ├── build_angular.ps1
│ │ └── build_tauri.ps1
│ ├── generate_windows_installers.ps1
│ └── sign_binaries_in_dist.ps1
├── runtime/
│ └── .gitkeep
├── service/
│ ├── broadcasts/
│ │ ├── api.go
│ │ ├── data.go
│ │ ├── install_info.go
│ │ ├── module.go
│ │ ├── notify.go
│ │ └── state.go
│ ├── compat/
│ │ ├── api.go
│ │ ├── callbacks.go
│ │ ├── debug_default.go
│ │ ├── debug_linux.go
│ │ ├── debug_windows.go
│ │ ├── iptables.go
│ │ ├── iptables_test.go
│ │ ├── module.go
│ │ ├── notify.go
│ │ ├── selfcheck.go
│ │ ├── wfpstate.go
│ │ └── wfpstate_test.go
│ ├── config.go
│ ├── configure/
│ │ └── updates.go
│ ├── control/
│ │ ├── api.go
│ │ ├── module.go
│ │ └── pause.go
│ ├── core/
│ │ ├── api.go
│ │ ├── base/
│ │ │ ├── databases.go
│ │ │ ├── logs.go
│ │ │ ├── module.go
│ │ │ └── profiling.go
│ │ ├── config.go
│ │ ├── core.go
│ │ ├── events.go
│ │ ├── os_default.go
│ │ ├── os_windows.go
│ │ ├── update_config.go
│ │ └── update_versions.go
│ ├── debug.go
│ ├── debug_test.go
│ ├── detection/
│ │ └── dga/
│ │ ├── lms.go
│ │ └── lms_test.go
│ ├── firewall/
│ │ ├── api.go
│ │ ├── bypassing.go
│ │ ├── config.go
│ │ ├── dns.go
│ │ ├── inspection/
│ │ │ └── inspection.go
│ │ ├── interception/
│ │ │ ├── dnsmonitor/
│ │ │ │ ├── etwlink_windows.go
│ │ │ │ ├── eventlistener.go
│ │ │ │ ├── eventlistener_linux.go
│ │ │ │ ├── eventlistener_windows.go
│ │ │ │ ├── module.go
│ │ │ │ └── varlinktypes.go
│ │ │ ├── ebpf/
│ │ │ │ ├── bandwidth/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── interface.go
│ │ │ │ ├── connection_listener/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── worker.go
│ │ │ │ ├── exec/
│ │ │ │ │ ├── bpf_bpfeb.go
│ │ │ │ │ ├── bpf_bpfeb.o
│ │ │ │ │ ├── bpf_bpfel.go
│ │ │ │ │ ├── bpf_bpfel.o
│ │ │ │ │ └── exec.go
│ │ │ │ └── programs/
│ │ │ │ ├── bandwidth.c
│ │ │ │ ├── bpf/
│ │ │ │ │ ├── bpf_core_read.h
│ │ │ │ │ ├── bpf_helper_defs.h
│ │ │ │ │ ├── bpf_helpers.h
│ │ │ │ │ └── bpf_tracing.h
│ │ │ │ ├── exec.c
│ │ │ │ ├── monitor.c
│ │ │ │ ├── update.sh
│ │ │ │ └── vmlinux-x86.h
│ │ │ ├── interception_default.go
│ │ │ ├── interception_linux.go
│ │ │ ├── interception_windows.go
│ │ │ ├── introspection.go
│ │ │ ├── module.go
│ │ │ ├── nfq/
│ │ │ │ ├── conntrack.go
│ │ │ │ ├── nfq.go
│ │ │ │ └── packet.go
│ │ │ ├── nfqueue_linux.go
│ │ │ ├── packet_tracer.go
│ │ │ ├── windowskext/
│ │ │ │ ├── bandwidth_stats.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── handler.go
│ │ │ │ ├── kext.go
│ │ │ │ ├── packet.go
│ │ │ │ ├── service.go
│ │ │ │ └── syscall.go
│ │ │ └── windowskext2/
│ │ │ ├── doc.go
│ │ │ ├── handler.go
│ │ │ ├── kext.go
│ │ │ ├── packet.go
│ │ │ └── service.go
│ │ ├── master.go
│ │ ├── module.go
│ │ ├── packet_handler.go
│ │ ├── preauth.go
│ │ ├── prompt.go
│ │ └── tunnel.go
│ ├── instance.go
│ ├── integration/
│ │ ├── etw_windows.go
│ │ ├── integration.go
│ │ ├── integration_windows.go
│ │ └── module.go
│ ├── intel/
│ │ ├── block_reason.go
│ │ ├── customlists/
│ │ │ ├── config.go
│ │ │ ├── lists.go
│ │ │ └── module.go
│ │ ├── entity.go
│ │ ├── entity_test.go
│ │ ├── filterlists/
│ │ │ ├── bloom.go
│ │ │ ├── cache_version.go
│ │ │ ├── database.go
│ │ │ ├── decoder.go
│ │ │ ├── index.go
│ │ │ ├── keys.go
│ │ │ ├── lookup.go
│ │ │ ├── module.go
│ │ │ ├── module_test.go
│ │ │ ├── record.go
│ │ │ └── updater.go
│ │ ├── geoip/
│ │ │ ├── country_info.go
│ │ │ ├── country_info_test.go
│ │ │ ├── database.go
│ │ │ ├── init_test.go
│ │ │ ├── location.go
│ │ │ ├── location_test.go
│ │ │ ├── lookup.go
│ │ │ ├── lookup_test.go
│ │ │ ├── module.go
│ │ │ ├── regions.go
│ │ │ └── regions_test.go
│ │ └── resolver.go
│ ├── interop/
│ │ ├── api.go
│ │ ├── ivpn/
│ │ │ ├── ivpn.go
│ │ │ └── notification.go
│ │ ├── module.go
│ │ └── verdict_handler.go
│ ├── mgr/
│ │ ├── doc.go
│ │ ├── events.go
│ │ ├── group.go
│ │ ├── group_ext.go
│ │ ├── group_module.go
│ │ ├── manager.go
│ │ ├── sleepyticker.go
│ │ ├── sleepyticker_test.go
│ │ ├── states.go
│ │ ├── worker.go
│ │ ├── worker_info.go
│ │ ├── worker_test.go
│ │ ├── workermgr.go
│ │ └── workermgr_test.go
│ ├── nameserver/
│ │ ├── config.go
│ │ ├── conflict.go
│ │ ├── failing.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── nameserver.go
│ │ ├── nsutil/
│ │ │ └── nsutil.go
│ │ └── response.go
│ ├── netenv/
│ │ ├── addresses_test.go
│ │ ├── adresses.go
│ │ ├── api.go
│ │ ├── dbus_linux.go
│ │ ├── dbus_linux_test.go
│ │ ├── dialing.go
│ │ ├── environment.go
│ │ ├── environment_default.go
│ │ ├── environment_linux.go
│ │ ├── environment_linux_test.go
│ │ ├── environment_test.go
│ │ ├── environment_windows.go
│ │ ├── environment_windows_test.go
│ │ ├── icmp_listener.go
│ │ ├── init_test.go
│ │ ├── location.go
│ │ ├── location_default.go
│ │ ├── location_test.go
│ │ ├── location_windows.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── network-change.go
│ │ ├── notes.md
│ │ ├── online-status.go
│ │ ├── online-status_test.go
│ │ ├── os_android.go
│ │ └── os_default.go
│ ├── netquery/
│ │ ├── active_chart_handler.go
│ │ ├── bandwidth_chart_handler.go
│ │ ├── database.go
│ │ ├── manager.go
│ │ ├── module_api.go
│ │ ├── orm/
│ │ │ ├── decoder.go
│ │ │ ├── decoder_test.go
│ │ │ ├── encoder.go
│ │ │ ├── encoder_test.go
│ │ │ ├── query_runner.go
│ │ │ ├── schema_builder.go
│ │ │ └── schema_builder_test.go
│ │ ├── query.go
│ │ ├── query_handler.go
│ │ ├── query_request.go
│ │ ├── query_test.go
│ │ └── runtime_query_runner.go
│ ├── network/
│ │ ├── api.go
│ │ ├── api_test.go
│ │ ├── clean.go
│ │ ├── connection.go
│ │ ├── connection_android.go
│ │ ├── connection_handler.go
│ │ ├── connection_store.go
│ │ ├── database.go
│ │ ├── dns.go
│ │ ├── iphelper/
│ │ │ ├── get.go
│ │ │ ├── iphelper.go
│ │ │ ├── tables.go
│ │ │ └── tables_test.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── multicast.go
│ │ ├── netutils/
│ │ │ ├── address.go
│ │ │ ├── dns.go
│ │ │ ├── dns_test.go
│ │ │ ├── ip.go
│ │ │ ├── ip_test.go
│ │ │ └── tcpassembly.go
│ │ ├── packet/
│ │ │ ├── bandwidth.go
│ │ │ ├── const.go
│ │ │ ├── info_only.go
│ │ │ ├── packet.go
│ │ │ ├── packetinfo.go
│ │ │ └── parse.go
│ │ ├── ports.go
│ │ ├── proc/
│ │ │ ├── findpid.go
│ │ │ ├── pids_by_user.go
│ │ │ ├── tables.go
│ │ │ └── tables_test.go
│ │ ├── reference/
│ │ │ ├── ports.go
│ │ │ └── protocols.go
│ │ ├── socket/
│ │ │ └── socket.go
│ │ ├── state/
│ │ │ ├── exists.go
│ │ │ ├── info.go
│ │ │ ├── lookup.go
│ │ │ ├── system_default.go
│ │ │ ├── system_linux.go
│ │ │ ├── system_windows.go
│ │ │ ├── tcp.go
│ │ │ └── udp.go
│ │ └── status.go
│ ├── process/
│ │ ├── api.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── doc.go
│ │ ├── executable.go
│ │ ├── find.go
│ │ ├── module.go
│ │ ├── process.go
│ │ ├── process_default.go
│ │ ├── process_linux.go
│ │ ├── process_windows.go
│ │ ├── profile.go
│ │ ├── special.go
│ │ ├── tags/
│ │ │ ├── appimage_unix.go
│ │ │ ├── flatpak_unix.go
│ │ │ ├── interpreter_unix.go
│ │ │ ├── net.go
│ │ │ ├── snap_unix.go
│ │ │ ├── svchost_windows.go
│ │ │ └── winstore_windows.go
│ │ └── tags.go
│ ├── profile/
│ │ ├── active.go
│ │ ├── api.go
│ │ ├── binmeta/
│ │ │ ├── convert.go
│ │ │ ├── find_default.go
│ │ │ ├── find_linux.go
│ │ │ ├── find_linux_test.go
│ │ │ ├── find_windows.go
│ │ │ ├── find_windows_test.go
│ │ │ ├── icon.go
│ │ │ ├── icons.go
│ │ │ ├── ignore.go
│ │ │ ├── locations_linux.go
│ │ │ ├── name.go
│ │ │ └── name_test.go
│ │ ├── config-update.go
│ │ ├── config.go
│ │ ├── database.go
│ │ ├── endpoints/
│ │ │ ├── annotations.go
│ │ │ ├── endpoint-any.go
│ │ │ ├── endpoint-asn.go
│ │ │ ├── endpoint-continent.go
│ │ │ ├── endpoint-country.go
│ │ │ ├── endpoint-domain.go
│ │ │ ├── endpoint-ip.go
│ │ │ ├── endpoint-iprange.go
│ │ │ ├── endpoint-lists.go
│ │ │ ├── endpoint-scopes.go
│ │ │ ├── endpoint.go
│ │ │ ├── endpoint_test.go
│ │ │ ├── endpoints.go
│ │ │ ├── endpoints_test.go
│ │ │ └── reason.go
│ │ ├── fingerprint.go
│ │ ├── fingerprint_test.go
│ │ ├── framework.go
│ │ ├── framework_test.go
│ │ ├── get.go
│ │ ├── merge.go
│ │ ├── meta.go
│ │ ├── migrations.go
│ │ ├── module.go
│ │ ├── profile-layered-provider.go
│ │ ├── profile-layered.go
│ │ ├── profile.go
│ │ └── special.go
│ ├── resolver/
│ │ ├── api.go
│ │ ├── block-detection.go
│ │ ├── compat.go
│ │ ├── config.go
│ │ ├── doc.go
│ │ ├── failing.go
│ │ ├── ipinfo.go
│ │ ├── ipinfo_test.go
│ │ ├── main.go
│ │ ├── main_test.go
│ │ ├── metrics.go
│ │ ├── namerecord.go
│ │ ├── namerecord_test.go
│ │ ├── resolve.go
│ │ ├── resolver-env.go
│ │ ├── resolver-https.go
│ │ ├── resolver-mdns.go
│ │ ├── resolver-plain.go
│ │ ├── resolver-tcp.go
│ │ ├── resolver.go
│ │ ├── resolver_test.go
│ │ ├── resolvers.go
│ │ ├── resolvers_test.go
│ │ ├── reverse.go
│ │ ├── reverse_test.go
│ │ ├── rr_context.go
│ │ ├── rrcache.go
│ │ ├── rrcache_test.go
│ │ ├── scopes.go
│ │ └── test/
│ │ └── resolving.bash
│ ├── status/
│ │ ├── module.go
│ │ ├── notifications.go
│ │ ├── security_level.go
│ │ └── status.go
│ ├── sync/
│ │ ├── module.go
│ │ ├── profile.go
│ │ ├── setting_single.go
│ │ ├── settings.go
│ │ └── util.go
│ ├── ui/
│ │ ├── api.go
│ │ ├── module.go
│ │ └── serve.go
│ └── updates/
│ ├── downloader.go
│ ├── index.go
│ ├── index_scan.go
│ ├── module.go
│ ├── updates_test.go
│ └── upgrade.go
├── spn/
│ ├── TESTING.md
│ ├── TRADEMARKS
│ ├── access/
│ │ ├── account/
│ │ │ ├── auth.go
│ │ │ ├── client.go
│ │ │ ├── types.go
│ │ │ └── view.go
│ │ ├── api.go
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── database.go
│ │ ├── features.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── notify.go
│ │ ├── op_auth.go
│ │ ├── storage.go
│ │ ├── token/
│ │ │ ├── errors.go
│ │ │ ├── module_test.go
│ │ │ ├── pblind.go
│ │ │ ├── pblind_gen_test.go
│ │ │ ├── pblind_test.go
│ │ │ ├── registry.go
│ │ │ ├── request.go
│ │ │ ├── request_test.go
│ │ │ ├── scramble.go
│ │ │ ├── scramble_gen_test.go
│ │ │ ├── scramble_test.go
│ │ │ ├── token.go
│ │ │ └── token_test.go
│ │ └── zones.go
│ ├── cabin/
│ │ ├── config-public.go
│ │ ├── database.go
│ │ ├── identity.go
│ │ ├── identity_test.go
│ │ ├── keys.go
│ │ ├── keys_test.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── verification.go
│ │ └── verification_test.go
│ ├── captain/
│ │ ├── api.go
│ │ ├── bootstrap.go
│ │ ├── client.go
│ │ ├── config.go
│ │ ├── establish.go
│ │ ├── exceptions.go
│ │ ├── gossip.go
│ │ ├── hooks.go
│ │ ├── intel.go
│ │ ├── module.go
│ │ ├── navigation.go
│ │ ├── op_gossip.go
│ │ ├── op_gossip_query.go
│ │ ├── op_publish.go
│ │ ├── piers.go
│ │ ├── public.go
│ │ └── status.go
│ ├── conf/
│ │ ├── map.go
│ │ ├── mode.go
│ │ ├── networks.go
│ │ └── version.go
│ ├── crew/
│ │ ├── connect.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── op_connect.go
│ │ ├── op_connect_test.go
│ │ ├── op_ping.go
│ │ ├── op_ping_test.go
│ │ ├── policy.go
│ │ └── sticky.go
│ ├── debug.go
│ ├── docks/
│ │ ├── bandwidth_test.go
│ │ ├── controller.go
│ │ ├── crane.go
│ │ ├── crane_establish.go
│ │ ├── crane_init.go
│ │ ├── crane_netstate.go
│ │ ├── crane_terminal.go
│ │ ├── crane_test.go
│ │ ├── crane_verify.go
│ │ ├── cranehooks.go
│ │ ├── hub_import.go
│ │ ├── measurements.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── op_capacity.go
│ │ ├── op_capacity_test.go
│ │ ├── op_expand.go
│ │ ├── op_latency.go
│ │ ├── op_latency_test.go
│ │ ├── op_sync_state.go
│ │ ├── op_whoami.go
│ │ ├── op_whoami_test.go
│ │ ├── terminal_expansion.go
│ │ └── terminal_expansion_test.go
│ ├── hub/
│ │ ├── database.go
│ │ ├── errors.go
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── hub.go
│ │ ├── hub_test.go
│ │ ├── intel.go
│ │ ├── intel_override.go
│ │ ├── measurements.go
│ │ ├── status.go
│ │ ├── transport.go
│ │ ├── transport_test.go
│ │ ├── truststores.go
│ │ ├── update.go
│ │ └── update_test.go
│ ├── instance.go
│ ├── navigator/
│ │ ├── api.go
│ │ ├── api_route.go
│ │ ├── costs.go
│ │ ├── database.go
│ │ ├── findnearest.go
│ │ ├── findnearest_test.go
│ │ ├── findroutes.go
│ │ ├── findroutes_test.go
│ │ ├── intel.go
│ │ ├── map.go
│ │ ├── map_stats.go
│ │ ├── map_test.go
│ │ ├── measurements.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── optimize.go
│ │ ├── optimize_region.go
│ │ ├── optimize_test.go
│ │ ├── options.go
│ │ ├── pin.go
│ │ ├── pin_export.go
│ │ ├── region.go
│ │ ├── route.go
│ │ ├── routing-profiles.go
│ │ ├── sort.go
│ │ ├── sort_test.go
│ │ ├── state.go
│ │ ├── state_test.go
│ │ └── update.go
│ ├── patrol/
│ │ ├── domains.go
│ │ ├── domains_test.go
│ │ ├── http.go
│ │ └── module.go
│ ├── ships/
│ │ ├── connection_test.go
│ │ ├── http.go
│ │ ├── http_info.go
│ │ ├── http_info_page.html.tmpl
│ │ ├── http_info_test.go
│ │ ├── http_shared.go
│ │ ├── http_shared_test.go
│ │ ├── kcp.go
│ │ ├── launch.go
│ │ ├── masking.go
│ │ ├── module.go
│ │ ├── mtu.go
│ │ ├── pier.go
│ │ ├── registry.go
│ │ ├── ship.go
│ │ ├── tcp.go
│ │ ├── testship.go
│ │ ├── testship_test.go
│ │ └── virtual_network.go
│ ├── sluice/
│ │ ├── module.go
│ │ ├── packet_listener.go
│ │ ├── request.go
│ │ ├── sluice.go
│ │ ├── sluices.go
│ │ └── udp_listener.go
│ ├── spn.go
│ ├── terminal/
│ │ ├── control_flow.go
│ │ ├── defaults.go
│ │ ├── errors.go
│ │ ├── fmt.go
│ │ ├── init.go
│ │ ├── metrics.go
│ │ ├── module.go
│ │ ├── module_test.go
│ │ ├── msg.go
│ │ ├── msgtypes.go
│ │ ├── operation.go
│ │ ├── operation_base.go
│ │ ├── operation_counter.go
│ │ ├── permission.go
│ │ ├── rate_limit.go
│ │ ├── session.go
│ │ ├── session_test.go
│ │ ├── terminal.go
│ │ ├── terminal_test.go
│ │ ├── testing.go
│ │ └── upstream.go
│ ├── test
│ ├── testing/
│ │ ├── README.md
│ │ └── simple/
│ │ ├── README.md
│ │ ├── clientsim.sh
│ │ ├── config-template.json
│ │ ├── docker-compose.yml
│ │ ├── entrypoint.sh
│ │ ├── inject-intel.sh
│ │ ├── intel-client.yaml
│ │ ├── intel-testnet.json
│ │ ├── join.sh
│ │ ├── reset-databases.sh
│ │ ├── run.sh
│ │ └── stop.sh
│ ├── tools/
│ │ ├── Dockerfile
│ │ ├── container-init.sh
│ │ ├── install.sh
│ │ ├── install.v2.sh
│ │ ├── start-checksum.txt
│ │ └── sysctl.conf
│ └── unit/
│ ├── doc.go
│ ├── scheduler.go
│ ├── scheduler_stats.go
│ ├── scheduler_test.go
│ ├── unit.go
│ ├── unit_debug.go
│ └── unit_test.go
├── windows_core_dll/
│ ├── build.ps1
│ ├── dllmain.cpp
│ ├── framework.h
│ ├── pch.cpp
│ ├── pch.h
│ ├── windows_core_dll.sln
│ ├── windows_core_dll.vcxproj
│ ├── windows_core_dll.vcxproj.filters
│ └── windows_core_dll.vcxproj.user
└── windows_kext/
├── .gitignore
├── PacketFlow.md
├── PortmasterKext64.inf
├── README.md
├── c_helper/
│ ├── ARM64/
│ │ └── c_helper.lib
│ ├── c_helper.filters
│ ├── c_helper.sln
│ ├── c_helper.vcxproj
│ ├── helper.c
│ └── x64/
│ └── c_helper.lib
├── driver/
│ ├── .cargo/
│ │ └── config.toml
│ ├── Cargo.toml
│ ├── Makefile.toml
│ ├── README.md
│ ├── rust-toolchain
│ └── src/
│ ├── ale_callouts.rs
│ ├── array_holder.rs
│ ├── bandwidth.rs
│ ├── callouts.rs
│ ├── common.rs
│ ├── connection.rs
│ ├── connection_cache.rs
│ ├── connection_map.rs
│ ├── device.rs
│ ├── entry.rs
│ ├── id_cache.rs
│ ├── lib.rs
│ ├── logger.rs
│ ├── packet_callouts.rs
│ ├── packet_util.rs
│ └── stream_callouts.rs
├── kextinterface/
│ ├── command.go
│ ├── info.go
│ ├── ioctl.go
│ ├── kext.go
│ ├── kext_file.go
│ ├── kext_file_test.go
│ ├── protocol_test.go
│ └── version.txt
├── link-dev.ps1
├── protocol/
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ ├── command.rs
│ ├── info.rs
│ └── lib.rs
├── test/
│ ├── BUILD_DEBUG.md
│ ├── README.md
│ └── build_test.ps1
├── test_protocol.sh
└── wdk/
├── .cargo/
│ └── config.toml
├── Cargo.toml
├── README.md
├── build.rs
├── rust-analyzer.cargo.target
├── rust-toolchain
└── src/
├── allocator.rs
├── attributes.rs
├── consts.rs
├── debug.rs
├── driver.rs
├── error.rs
├── fast_mutex.rs
├── ffi.rs
├── filter_engine/
│ ├── callout.rs
│ ├── callout_data.rs
│ ├── classify.rs
│ ├── connect_request.rs
│ ├── ffi.rs
│ ├── layer.rs
│ ├── metadata.rs
│ ├── mod.rs
│ ├── net_buffer.rs
│ ├── packet.rs
│ ├── stream_data.rs
│ └── transaction.rs
├── interface.rs
├── ioqueue.rs
├── irp_helpers.rs
├── lib.rs
├── rw_spin_lock.rs
├── spin_lock.rs
└── utils.rs
Showing preview only (1,651K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (22836 symbols across 1072 files)
FILE: assets/icons_default.go
constant GreenID (line 19) | GreenID = 0
constant YellowID (line 20) | YellowID = 1
constant RedID (line 21) | RedID = 2
constant BlueID (line 22) | BlueID = 3
function init (line 43) | func init() {
function setColoredIcons (line 47) | func setColoredIcons() {
function ScaleColoredIconsTo (line 59) | func ScaleColoredIconsTo(pixelSize int) {
function quickScalePNG (line 70) | func quickScalePNG(imgData []byte, pixelSize int) []byte {
function scalePNGTo (line 79) | func scalePNGTo(imgData []byte, pixelSize int) ([]byte, error) {
FILE: assets/icons_windows.go
constant GreenID (line 9) | GreenID = 0
constant YellowID (line 10) | YellowID = 1
constant RedID (line 11) | RedID = 2
constant BlueID (line 12) | BlueID = 3
function ScaleColoredIconsTo (line 41) | func ScaleColoredIconsTo(pixelSize int) {}
FILE: base/api/api_bridge.go
constant endpointBridgeRemoteAddress (line 19) | endpointBridgeRemoteAddress = "websocket-bridge"
constant apiDatabaseName (line 20) | apiDatabaseName = "api"
function registerEndpointBridgeDB (line 23) | func registerEndpointBridgeDB() error {
type endpointBridgeStorage (line 36) | type endpointBridgeStorage struct
method Get (line 62) | func (ebs *endpointBridgeStorage) Get(key string) (record.Record, erro...
method GetMeta (line 74) | func (ebs *endpointBridgeStorage) GetMeta(key string) (*record.Meta, e...
method Put (line 82) | func (ebs *endpointBridgeStorage) Put(r record.Record) (record.Record,...
method ReadOnly (line 110) | func (ebs *endpointBridgeStorage) ReadOnly() bool {
type EndpointBridgeRequest (line 41) | type EndpointBridgeRequest struct
type EndpointBridgeResponse (line 53) | type EndpointBridgeResponse struct
function callAPI (line 114) | func callAPI(ebr *EndpointBridgeRequest) (record.Record, error) {
FILE: base/api/auth_wrapper.go
function WrapInAuthHandler (line 7) | func WrapInAuthHandler(fn http.HandlerFunc, read, write Permission) http...
type wrappedAuthenticatedHandler (line 15) | type wrappedAuthenticatedHandler struct
method ReadPermission (line 23) | func (wah *wrappedAuthenticatedHandler) ReadPermission(r *http.Request...
method WritePermission (line 28) | func (wah *wrappedAuthenticatedHandler) WritePermission(r *http.Reques...
FILE: base/api/authentication.go
constant sessionCookieName (line 22) | sessionCookieName = "Portmaster-API-Token"
constant sessionCookieTTL (line 23) | sessionCookieTTL = 5 * time.Minute
type Permission (line 44) | type Permission
method String (line 561) | func (p Permission) String() string {
method Role (line 583) | func (p Permission) Role() string {
constant NotFound (line 48) | NotFound Permission = -2
constant Dynamic (line 52) | Dynamic Permission = -1
constant NotSupported (line 55) | NotSupported Permission = 0
constant PermitAnyone (line 59) | PermitAnyone Permission = 1
constant PermitUser (line 64) | PermitUser Permission = 2
constant PermitAdmin (line 69) | PermitAdmin Permission = 3
constant PermitSelf (line 73) | PermitSelf Permission = 4
type AuthenticatorFunc (line 79) | type AuthenticatorFunc
type AuthToken (line 85) | type AuthToken struct
type session (line 91) | type session struct
method Expired (line 99) | func (sess *session) Expired() bool {
method Refresh (line 107) | func (sess *session) Refresh(ttl time.Duration) {
type AuthenticatedHandler (line 117) | type AuthenticatedHandler interface
function SetAuthenticator (line 123) | func SetAuthenticator(fn AuthenticatorFunc) error {
function authenticateRequest (line 136) | func authenticateRequest(w http.ResponseWriter, r *http.Request, targetH...
function checkAuth (line 244) | func checkAuth(w http.ResponseWriter, r *http.Request, authRequired bool...
function checkAPIKey (line 311) | func checkAPIKey(r *http.Request) *AuthToken {
function updateAPIKeys (line 353) | func updateAPIKeys() {
function checkSessionCookie (line 447) | func checkSessionCookie(r *http.Request) *AuthToken {
function createSession (line 475) | func createSession(w http.ResponseWriter, r *http.Request, token *AuthTo...
function cleanSessions (line 507) | func cleanSessions(_ *mgr.WorkerCtx) error {
function deleteSession (line 520) | func deleteSession(sessionKey string) {
function getEffectiveMethod (line 527) | func getEffectiveMethod(r *http.Request) (eMethod string, readMethod boo...
function parseAPIPermission (line 548) | func parseAPIPermission(s string) (Permission, error) {
FILE: base/api/authentication_test.go
function testAuthenticator (line 14) | func testAuthenticator(r *http.Request, s *http.Server) (*AuthToken, err...
type testAuthHandler (line 25) | type testAuthHandler struct
method ReadPermission (line 30) | func (ah *testAuthHandler) ReadPermission(r *http.Request) Permission {
method WritePermission (line 34) | func (ah *testAuthHandler) WritePermission(r *http.Request) Permission {
method ServeHTTP (line 38) | func (ah *testAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Re...
function makeAuthTestPath (line 51) | func makeAuthTestPath(reading bool, p Permission) string {
function TestPermissions (line 58) | func TestPermissions(t *testing.T) {
function TestPermissionDefinitions (line 180) | func TestPermissionDefinitions(t *testing.T) {
FILE: base/api/client/api.go
method Get (line 4) | func (c *Client) Get(key string, handleFunc func(*Message)) *Operation {
method Query (line 11) | func (c *Client) Query(query string, handleFunc func(*Message)) *Operati...
method Sub (line 18) | func (c *Client) Sub(query string, handleFunc func(*Message)) *Operation {
method Qsub (line 25) | func (c *Client) Qsub(query string, handleFunc func(*Message)) *Operation {
method Create (line 32) | func (c *Client) Create(key string, value interface{}, handleFunc func(*...
method Update (line 39) | func (c *Client) Update(key string, value interface{}, handleFunc func(*...
method Insert (line 46) | func (c *Client) Insert(key string, value interface{}, handleFunc func(*...
method Delete (line 53) | func (c *Client) Delete(key string, handleFunc func(*Message)) *Operation {
FILE: base/api/client/client.go
constant backOffTimer (line 14) | backOffTimer = 1 * time.Second
constant offlineSignal (line 16) | offlineSignal uint8 = 0
constant onlineSignal (line 17) | onlineSignal uint8 = 1
type Client (line 21) | type Client struct
method Connect (line 59) | func (c *Client) Connect() error {
method StayConnected (line 71) | func (c *Client) StayConnected() {
method Shutdown (line 87) | func (c *Client) Shutdown() {
method signalOnline (line 95) | func (c *Client) signalOnline() {
method signalOffline (line 115) | func (c *Client) signalOffline() {
method Online (line 136) | func (c *Client) Online() <-chan struct{} {
method Offline (line 143) | func (c *Client) Offline() <-chan struct{} {
method handler (line 149) | func (c *Client) handler() {
method NewOperation (line 226) | func (c *Client) NewOperation(handleFunc func(*Message)) *Operation {
function NewClient (line 42) | func NewClient(server string) *Client {
type Operation (line 178) | type Operation struct
method handle (line 187) | func (op *Operation) handle(m *Message) {
method Cancel (line 200) | func (op *Operation) Cancel() {
method Send (line 208) | func (op *Operation) Send(command, text string, data interface{}) {
method EnableResuscitation (line 221) | func (op *Operation) EnableResuscitation() {
FILE: base/api/client/const.go
constant msgRequestGet (line 5) | msgRequestGet = "get"
constant msgRequestQuery (line 6) | msgRequestQuery = "query"
constant msgRequestSub (line 7) | msgRequestSub = "sub"
constant msgRequestQsub (line 8) | msgRequestQsub = "qsub"
constant msgRequestCreate (line 9) | msgRequestCreate = "create"
constant msgRequestUpdate (line 10) | msgRequestUpdate = "update"
constant msgRequestInsert (line 11) | msgRequestInsert = "insert"
constant msgRequestDelete (line 12) | msgRequestDelete = "delete"
constant MsgOk (line 14) | MsgOk = "ok"
constant MsgError (line 15) | MsgError = "error"
constant MsgDone (line 16) | MsgDone = "done"
constant MsgSuccess (line 17) | MsgSuccess = "success"
constant MsgUpdate (line 18) | MsgUpdate = "upd"
constant MsgNew (line 19) | MsgNew = "new"
constant MsgDelete (line 20) | MsgDelete = "del"
constant MsgWarning (line 21) | MsgWarning = "warning"
constant MsgOffline (line 23) | MsgOffline = "offline"
constant apiSeperator (line 25) | apiSeperator = "|"
FILE: base/api/client/message.go
type Message (line 17) | type Message struct
method Pack (line 74) | func (m *Message) Pack() ([]byte, error) {
function ParseMessage (line 27) | func ParseMessage(data []byte) (*Message, error) {
FILE: base/api/client/websocket.go
type wsState (line 13) | type wsState struct
method Error (line 114) | func (state *wsState) Error(message string) {
method wsConnect (line 20) | func (c *Client) wsConnect() error {
method wsReader (line 50) | func (c *Client) wsReader(state *wsState) {
method wsWriter (line 77) | func (c *Client) wsWriter(state *wsState) {
FILE: base/api/config.go
constant CfgDefaultListenAddressKey (line 11) | CfgDefaultListenAddressKey = "core/listenAddress"
constant CfgAPIKeys (line 12) | CfgAPIKeys = "core/apiKeys"
function init (line 25) | func init() {
function getDefaultListenAddress (line 34) | func getDefaultListenAddress() string {
function registerConfig (line 43) | func registerConfig() error {
function SetDefaultAPIListenAddress (line 89) | func SetDefaultAPIListenAddress(address string) {
FILE: base/api/database.go
constant dbMsgTypeOk (line 27) | dbMsgTypeOk = "ok"
constant dbMsgTypeError (line 28) | dbMsgTypeError = "error"
constant dbMsgTypeDone (line 29) | dbMsgTypeDone = "done"
constant dbMsgTypeSuccess (line 30) | dbMsgTypeSuccess = "success"
constant dbMsgTypeUpd (line 31) | dbMsgTypeUpd = "upd"
constant dbMsgTypeNew (line 32) | dbMsgTypeNew = "new"
constant dbMsgTypeDel (line 33) | dbMsgTypeDel = "del"
constant dbMsgTypeWarning (line 34) | dbMsgTypeWarning = "warning"
constant dbAPISeperator (line 36) | dbAPISeperator = "|"
constant emptyString (line 37) | emptyString = ""
function init (line 45) | func init() {
type DatabaseAPI (line 56) | type DatabaseAPI struct
method Handle (line 201) | func (api *DatabaseAPI) Handle(msg []byte) {
method send (line 296) | func (api *DatabaseAPI) send(opID []byte, msgType string, msgOrKey str...
method handleGet (line 314) | func (api *DatabaseAPI) handleGet(opID []byte, key string) {
method handleQuery (line 332) | func (api *DatabaseAPI) handleQuery(opID []byte, queryText string) {
method processQuery (line 352) | func (api *DatabaseAPI) processQuery(opID []byte, q *query.Query) (ok ...
method handleSub (line 402) | func (api *DatabaseAPI) handleSub(opID []byte, queryText string) {
method registerSub (line 424) | func (api *DatabaseAPI) registerSub(opID []byte, q *query.Query) (sub ...
method processSub (line 435) | func (api *DatabaseAPI) processSub(opID []byte, sub *database.Subscrip...
method handleQsub (line 485) | func (api *DatabaseAPI) handleQsub(opID []byte, queryText string) {
method handleCancel (line 515) | func (api *DatabaseAPI) handleCancel(opID []byte) {
method cancelQuery (line 520) | func (api *DatabaseAPI) cancelQuery(opID []byte) {
method cancelSub (line 537) | func (api *DatabaseAPI) cancelSub(opID []byte) {
method handlePut (line 557) | func (api *DatabaseAPI) handlePut(opID []byte, key string, data []byte...
method handleInsert (line 597) | func (api *DatabaseAPI) handleInsert(opID []byte, key string, data []b...
method handleDelete (line 649) | func (api *DatabaseAPI) handleDelete(opID []byte, key string) {
type DatabaseWebsocketAPI (line 71) | type DatabaseWebsocketAPI struct
method handler (line 131) | func (api *DatabaseWebsocketAPI) handler(_ *mgr.WorkerCtx) error {
method writer (line 146) | func (api *DatabaseWebsocketAPI) writer(ctx *mgr.WorkerCtx) error {
method shutdown (line 175) | func (api *DatabaseWebsocketAPI) shutdown(err error) error {
function allowAnyOrigin (line 78) | func allowAnyOrigin(r *http.Request) bool {
function CreateDatabaseAPI (line 83) | func CreateDatabaseAPI(sendFunction func(data []byte)) DatabaseAPI {
function startDatabaseWebsocketAPI (line 94) | func startDatabaseWebsocketAPI(w http.ResponseWriter, r *http.Request) {
function MarshalRecord (line 664) | func MarshalRecord(r record.Record, withDSDIdentifier bool) ([]byte, err...
FILE: base/api/endpoints.go
type Endpoint (line 24) | type Endpoint struct
method check (line 235) | func (e *Endpoint) check() error {
method ServeHTTP (line 370) | func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
type Parameter (line 82) | type Parameter struct
type HTTPStatusProvider (line 91) | type HTTPStatusProvider interface
type HTTPStatusError (line 96) | type HTTPStatusError struct
method Error (line 102) | func (e *HTTPStatusError) Error() string {
method Unwrap (line 107) | func (e *HTTPStatusError) Unwrap() error {
method HTTPStatus (line 112) | func (e *HTTPStatusError) HTTPStatus() int {
function ErrorWithStatus (line 117) | func ErrorWithStatus(err error, code int) error {
type ActionFunc (line 126) | type ActionFunc
type DataFunc (line 129) | type DataFunc
type StructFunc (line 132) | type StructFunc
type RecordFunc (line 136) | type RecordFunc
constant MimeTypeJSON (line 141) | MimeTypeJSON string = "application/json"
constant MimeTypeText (line 142) | MimeTypeText string = "text/plain"
constant apiV1Path (line 144) | apiV1Path = "/api/v1/"
function init (line 147) | func init() {
function getAPIContext (line 164) | func getAPIContext(r *http.Request) (apiEndpoint *Endpoint, apiRequest *...
function RegisterEndpoint (line 205) | func RegisterEndpoint(e Endpoint) error {
function GetEndpointByPath (line 224) | func GetEndpointByPath(path string) (*Endpoint, error) {
function ExportEndpoints (line 316) | func ExportEndpoints() []*Endpoint {
type sortByPath (line 330) | type sortByPath
method Len (line 332) | func (eps sortByPath) Len() int { return len(eps) }
method Less (line 333) | func (eps sortByPath) Less(i, j int) bool { return eps[i].Path < eps[j...
method Swap (line 334) | func (eps sortByPath) Swap(i, j int) { eps[i], eps[j] = eps[j], e...
type endpointHandler (line 336) | type endpointHandler struct
method ReadPermission (line 341) | func (eh *endpointHandler) ReadPermission(r *http.Request) Permission {
method WritePermission (line 350) | func (eh *endpointHandler) WritePermission(r *http.Request) Permission {
method ServeHTTP (line 359) | func (eh *endpointHandler) ServeHTTP(w http.ResponseWriter, r *http.Re...
function readBody (line 507) | func readBody(w http.ResponseWriter, r *http.Request) (inputData []byte,...
FILE: base/api/endpoints_config.go
function registerConfigEndpoints (line 7) | func registerConfigEndpoints() error {
function listConfig (line 22) | func listConfig(ar *Request) (i interface{}, err error) {
FILE: base/api/endpoints_debug.go
function registerDebugEndpoints (line 19) | func registerDebugEndpoints() error {
function ping (line 132) | func ping(ar *Request) (msg string, err error) {
function ready (line 137) | func ready(ar *Request) (msg string, err error) {
function getStack (line 145) | func getStack(_ *Request) (data []byte, err error) {
function printStack (line 155) | func printStack(_ *Request) (msg string, err error) {
function handleCPUProfile (line 170) | func handleCPUProfile(ar *Request) (data []byte, err error) {
function handleHeapProfile (line 207) | func handleHeapProfile(ar *Request) (data []byte, err error) {
function handleAllocsProfile (line 222) | func handleAllocsProfile(ar *Request) (data []byte, err error) {
function debugInfo (line 237) | func debugInfo(ar *Request) (data []byte, err error) {
FILE: base/api/endpoints_meta.go
function registerMetaEndpoints (line 9) | func registerMetaEndpoints() error {
function listEndpoints (line 64) | func listEndpoints(ar *Request) (data []byte, err error) {
function permissions (line 69) | func permissions(ar *Request) (i interface{}, err error) {
function authBearer (line 87) | func authBearer(w http.ResponseWriter, r *http.Request) {
function authBasic (line 103) | func authBasic(w http.ResponseWriter, r *http.Request) {
function authReset (line 119) | func authReset(w http.ResponseWriter, r *http.Request) {
FILE: base/api/endpoints_test.go
constant successMsg (line 14) | successMsg = "endpoint api success"
constant failedMsg (line 15) | failedMsg = "endpoint api failed"
type actionTestRecord (line 18) | type actionTestRecord struct
function TestEndpoints (line 24) | func TestEndpoints(t *testing.T) {
function TestActionRegistration (line 118) | func TestActionRegistration(t *testing.T) {
FILE: base/api/enriched-response.go
type LoggingResponseWriter (line 13) | type LoggingResponseWriter struct
method Header (line 28) | func (lrw *LoggingResponseWriter) Header() http.Header {
method Write (line 33) | func (lrw *LoggingResponseWriter) Write(b []byte) (int, error) {
method WriteHeader (line 38) | func (lrw *LoggingResponseWriter) WriteHeader(code int) {
method Hijack (line 44) | func (lrw *LoggingResponseWriter) Hijack() (net.Conn, *bufio.ReadWrite...
function NewLoggingResponseWriter (line 20) | func NewLoggingResponseWriter(w http.ResponseWriter, r *http.Request) *L...
function RequestLogger (line 58) | func RequestLogger(next http.Handler) http.Handler {
FILE: base/api/init_test.go
type testInstance (line 9) | type testInstance struct
method Config (line 15) | func (stub *testInstance) Config() *config.Config {
method SetCmdLineOperation (line 19) | func (stub *testInstance) SetCmdLineOperation(f func() error) {}
method Ready (line 21) | func (stub *testInstance) Ready() bool {
function TestMain (line 25) | func TestMain(m *testing.M) {
FILE: base/api/main.go
function init (line 21) | func init() {
function prep (line 25) | func prep() error {
function start (line 52) | func start() error {
function stop (line 70) | func stop() error {
function exportEndpointsCmd (line 74) | func exportEndpointsCmd() error {
FILE: base/api/module.go
type API (line 12) | type API struct
method Manager (line 19) | func (api *API) Manager() *mgr.Manager {
method Start (line 24) | func (api *API) Start() error {
method Stop (line 34) | func (api *API) Stop() error {
function New (line 45) | func New(instance instance) (*API, error) {
type instance (line 61) | type instance interface
FILE: base/api/request.go
type Request (line 13) | type Request struct
type apiRequestContextKey (line 37) | type apiRequestContextKey struct
function GetAPIRequest (line 43) | func GetAPIRequest(r *http.Request) *Request {
function TextResponse (line 52) | func TextResponse(w http.ResponseWriter, r *http.Request, text string) {
FILE: base/api/router.go
function RegisterHandler (line 42) | func RegisterHandler(path string, handler http.Handler) *mux.Route {
function RegisterHandleFunc (line 49) | func RegisterHandleFunc(path string, handleFunc func(http.ResponseWriter...
function startServer (line 55) | func startServer() {
function stopServer (line 72) | func stopServer() error {
function serverManager (line 86) | func serverManager(ctx *mgr.WorkerCtx) error {
type mainHandler (line 108) | type mainHandler struct
method ServeHTTP (line 112) | func (mh *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques...
method handle (line 118) | func (mh *mainHandler) handle(w http.ResponseWriter, r *http.Request) ...
function cleanRequestPath (line 310) | func cleanRequestPath(requestPath string) string {
FILE: base/api/testclient/serve.go
function init (line 9) | func init() {
FILE: base/apprise/notify.go
type Notifier (line 17) | type Notifier struct
method Send (line 87) | func (n *Notifier) Send(ctx context.Context, m *Message) error {
method applyDefaults (line 137) | func (n *Notifier) applyDefaults(m *Message) {
method SetClient (line 150) | func (n *Notifier) SetClient(client *http.Client) {
method getClient (line 157) | func (n *Notifier) getClient() *http.Client {
type Message (line 39) | type Message struct
type MsgType (line 62) | type MsgType
constant TypeInfo (line 66) | TypeInfo MsgType = "info"
constant TypeSuccess (line 67) | TypeSuccess MsgType = "success"
constant TypeWarning (line 68) | TypeWarning MsgType = "warning"
constant TypeFailure (line 69) | TypeFailure MsgType = "failure"
type MsgFormat (line 73) | type MsgFormat
constant FormatText (line 77) | FormatText MsgFormat = "text"
constant FormatMarkdown (line 78) | FormatMarkdown MsgFormat = "markdown"
constant FormatHTML (line 79) | FormatHTML MsgFormat = "html"
type errorResponse (line 82) | type errorResponse struct
FILE: base/config/basic_config.go
function init (line 20) | func init() {
function registerBasicOptions (line 24) | func registerBasicOptions() error {
function loadLogLevel (line 98) | func loadLogLevel() error {
function setLogLevel (line 102) | func setLogLevel(_ *mgr.WorkerCtx, _ struct{}) (cancel bool, err error) {
FILE: base/config/database.go
type StorageInterface (line 19) | type StorageInterface struct
method Get (line 24) | func (s *StorageInterface) Get(key string) (record.Record, error) {
method Put (line 34) | func (s *StorageInterface) Put(r record.Record) (record.Record, error) {
method Delete (line 82) | func (s *StorageInterface) Delete(key string) error {
method Query (line 87) | func (s *StorageInterface) Query(q *query.Query, local, internal bool)...
method processQuery (line 104) | func (s *StorageInterface) processQuery(it *iterator.Iterator, opts []...
method ReadOnly (line 120) | func (s *StorageInterface) ReadOnly() bool {
function registerAsDatabase (line 124) | func registerAsDatabase() error {
function handleOptionUpdate (line 146) | func handleOptionUpdate(option *Option, push bool) {
function pushUpdate (line 162) | func pushUpdate(option *Option) {
FILE: base/config/expertise.go
type ExpertiseLevel (line 13) | type ExpertiseLevel
constant ExpertiseLevelUser (line 17) | ExpertiseLevelUser ExpertiseLevel = 0
constant ExpertiseLevelExpert (line 18) | ExpertiseLevelExpert ExpertiseLevel = 1
constant ExpertiseLevelDeveloper (line 19) | ExpertiseLevelDeveloper ExpertiseLevel = 2
constant ExpertiseLevelNameUser (line 21) | ExpertiseLevelNameUser = "user"
constant ExpertiseLevelNameExpert (line 22) | ExpertiseLevelNameExpert = "expert"
constant ExpertiseLevelNameDeveloper (line 23) | ExpertiseLevelNameDeveloper = "developer"
constant expertiseLevelKey (line 25) | expertiseLevelKey = "core/expertiseLevel"
function init (line 34) | func init() {
function registerExpertiseLevelOption (line 38) | func registerExpertiseLevelOption() {
function updateExpertiseLevel (line 79) | func updateExpertiseLevel() {
function GetExpertiseLevel (line 102) | func GetExpertiseLevel() uint8 {
FILE: base/config/get-safe.go
type safe (line 5) | type safe struct
method GetAsString (line 11) | func (cs *safe) GetAsString(name string, fallback string) StringOption {
method GetAsStringArray (line 37) | func (cs *safe) GetAsStringArray(name string, fallback []string) Strin...
method GetAsInt (line 63) | func (cs *safe) GetAsInt(name string, fallback int64) IntOption {
method GetAsBool (line 89) | func (cs *safe) GetAsBool(name string, fallback bool) BoolOption {
FILE: base/config/get.go
type StringOption (line 9) | type StringOption
type StringArrayOption (line 11) | type StringArrayOption
type IntOption (line 13) | type IntOption
type BoolOption (line 15) | type BoolOption
function getValueCache (line 18) | func getValueCache(name string, option *Option, requestedType OptionType...
function GetAsString (line 52) | func GetAsString(name string, fallback string) StringOption {
function GetAsStringArray (line 75) | func GetAsStringArray(name string, fallback []string) StringArrayOption {
function GetAsInt (line 98) | func GetAsInt(name string, fallback int64) IntOption {
function GetAsBool (line 121) | func GetAsBool(name string, fallback bool) BoolOption {
FILE: base/config/get_test.go
function parseAndReplaceConfig (line 11) | func parseAndReplaceConfig(jsonData string) error {
function parseAndReplaceDefaultConfig (line 24) | func parseAndReplaceDefaultConfig(jsonData string) error {
function quickRegister (line 37) | func quickRegister(t *testing.T, key string, optType OptionType, default...
function TestGet (line 54) | func TestGet(t *testing.T) { //nolint:paralleltest
function TestReleaseLevel (line 195) | func TestReleaseLevel(t *testing.T) { //nolint:paralleltest
function BenchmarkGetAsStringCached (line 293) | func BenchmarkGetAsStringCached(b *testing.B) {
function BenchmarkGetAsStringRefetch (line 315) | func BenchmarkGetAsStringRefetch(b *testing.B) {
function BenchmarkGetAsIntCached (line 333) | func BenchmarkGetAsIntCached(b *testing.B) {
function BenchmarkGetAsIntRefetch (line 352) | func BenchmarkGetAsIntRefetch(b *testing.B) {
FILE: base/config/init_test.go
type testInstance (line 9) | type testInstance struct
method DataDir (line 15) | func (stub testInstance) DataDir() string {
method SetCmdLineOperation (line 19) | func (stub testInstance) SetCmdLineOperation(f func() error) {}
function newTestInstance (line 21) | func newTestInstance(testName string) (*testInstance, error) {
function TestMain (line 32) | func TestMain(m *testing.M) {
function TestConfigPersistence (line 47) | func TestConfigPersistence(t *testing.T) { //nolint:paralleltest
FILE: base/config/main.go
constant ChangeEvent (line 19) | ChangeEvent = "config change"
function init (line 23) | func init() {
function prep (line 27) | func prep() error {
function start (line 39) | func start() error {
function exportConfigCmd (line 63) | func exportConfigCmd() error {
function AddToDebugInfo (line 82) | func AddToDebugInfo(di *debug.Info) {
function GetActiveConfigValues (line 111) | func GetActiveConfigValues() map[string]interface{} {
FILE: base/config/module.go
type Config (line 11) | type Config struct
method Manager (line 20) | func (u *Config) Manager() *mgr.Manager {
method Start (line 25) | func (u *Config) Start() error {
method Stop (line 30) | func (u *Config) Stop() error {
function New (line 40) | func New(instance instance) (*Config, error) {
type instance (line 58) | type instance interface
FILE: base/config/option.go
type OptionType (line 18) | type OptionType
constant optTypeAny (line 22) | optTypeAny OptionType = 0
constant OptTypeString (line 23) | OptTypeString OptionType = 1
constant OptTypeStringArray (line 24) | OptTypeStringArray OptionType = 2
constant OptTypeInt (line 25) | OptTypeInt OptionType = 3
constant OptTypeBool (line 26) | OptTypeBool OptionType = 4
function getTypeName (line 29) | func getTypeName(t OptionType) string {
type PossibleValue (line 48) | type PossibleValue struct
type Annotations (line 67) | type Annotations
type MigrationFunc (line 70) | type MigrationFunc
constant DisplayHintAnnotation (line 79) | DisplayHintAnnotation = "safing/portbase:ui:display-hint"
constant DisplayOrderAnnotation (line 84) | DisplayOrderAnnotation = "safing/portbase:ui:order"
constant UnitAnnotation (line 86) | UnitAnnotation = "safing/portbase:ui:unit"
constant CategoryAnnotation (line 92) | CategoryAnnotation = "safing/portbase:ui:category"
constant SubsystemAnnotation (line 95) | SubsystemAnnotation = "safing/portbase:module:subsystem"
constant StackableAnnotation (line 101) | StackableAnnotation = "safing/portbase:options:stackable"
constant RestartPendingAnnotation (line 105) | RestartPendingAnnotation = "safing/portbase:options:restart-pending"
constant QuickSettingsAnnotation (line 110) | QuickSettingsAnnotation = "safing/portbase:ui:quick-setting"
constant RequiresAnnotation (line 114) | RequiresAnnotation = "safing/portbase:config:requires"
constant RequiresFeatureIDAnnotation (line 118) | RequiresFeatureIDAnnotation = "safing/portmaster:ui:config:requires-feat...
constant SettablePerAppAnnotation (line 121) | SettablePerAppAnnotation = "safing/portmaster:settable-per-app"
constant RequiresUIReloadAnnotation (line 127) | RequiresUIReloadAnnotation = "safing/portmaster:ui:requires-reload"
type QuickSettingsAction (line 131) | type QuickSettingsAction
constant QuickReplace (line 136) | QuickReplace = QuickSettingsAction("replace")
constant QuickMergeTop (line 140) | QuickMergeTop = QuickSettingsAction("merge-top")
constant QuickMergeBottom (line 144) | QuickMergeBottom = QuickSettingsAction("merge-bottom")
type QuickSetting (line 149) | type QuickSetting struct
type ValueRequirement (line 162) | type ValueRequirement struct
constant DisplayHintOneOf (line 177) | DisplayHintOneOf = "one-of"
constant DisplayHintOrdered (line 182) | DisplayHintOrdered = "ordered"
constant DisplayHintFilePicker (line 185) | DisplayHintFilePicker = "file-picker"
type Option (line 189) | type Option struct
method AddAnnotation (line 276) | func (option *Option) AddAnnotation(key string, value interface{}) {
method SetAnnotation (line 292) | func (option *Option) SetAnnotation(key string, value interface{}) {
method setAnnotation (line 301) | func (option *Option) setAnnotation(key string, value interface{}) {
method GetAnnotation (line 309) | func (option *Option) GetAnnotation(key string) (interface{}, bool) {
method AnnotationEquals (line 322) | func (option *Option) AnnotationEquals(key string, value any) bool {
method copyOrNil (line 337) | func (option *Option) copyOrNil() *Option {
method IsSetByUser (line 346) | func (option *Option) IsSetByUser() bool {
method UserValue (line 355) | func (option *Option) UserValue() any {
method ValidateValue (line 366) | func (option *Option) ValidateValue(value any) error {
method Export (line 378) | func (option *Option) Export() (record.Record, error) {
method export (line 385) | func (option *Option) export() (record.Record, error) {
type sortByKey (line 414) | type sortByKey
method Len (line 416) | func (opts sortByKey) Len() int { return len(opts) }
method Less (line 417) | func (opts sortByKey) Less(i, j int) bool { return opts[i].Key < opts[...
method Swap (line 418) | func (opts sortByKey) Swap(i, j int) { opts[i], opts[j] = opts[j]...
FILE: base/config/persistence.go
function GetLoadedConfigValidationErrors (line 23) | func GetLoadedConfigValidationErrors() []*ValidationError {
function loadConfig (line 30) | func loadConfig(requireValidConfig bool) error {
function SaveConfig (line 64) | func SaveConfig() error {
function JSONToMap (line 100) | func JSONToMap(jsonData []byte) (map[string]interface{}, error) {
function Flatten (line 111) | func Flatten(config map[string]interface{}) (flattenedConfig map[string]...
function flattenMap (line 117) | func flattenMap(rootMap, subMap map[string]interface{}, subKey string) {
function MapToJSON (line 135) | func MapToJSON(config map[string]interface{}) ([]byte, error) {
function Expand (line 140) | func Expand(flattenedConfig map[string]interface{}) (config map[string]i...
function PutValueIntoHierarchicalConfig (line 149) | func PutValueIntoHierarchicalConfig(config map[string]interface{}, key s...
function CleanFlattenedConfig (line 186) | func CleanFlattenedConfig(flattenedConfig map[string]interface{}) {
function CleanHierarchicalConfig (line 199) | func CleanHierarchicalConfig(config map[string]interface{}) {
function cleanSubMap (line 206) | func cleanSubMap(subMap map[string]interface{}, subKey string) (empty bo...
FILE: base/config/persistence_test.go
function TestJSONMapConversion (line 38) | func TestJSONMapConversion(t *testing.T) {
function TestConfigCleaning (line 70) | func TestConfigCleaning(t *testing.T) {
FILE: base/config/perspective.go
type Perspective (line 10) | type Perspective struct
method getPerspectiveValueCache (line 68) | func (p *Perspective) getPerspectiveValueCache(name string, requestedT...
method Has (line 94) | func (p *Perspective) Has(name string) bool {
method GetAsString (line 100) | func (p *Perspective) GetAsString(name string) (value string, ok bool) {
method GetAsStringArray (line 109) | func (p *Perspective) GetAsStringArray(name string) (value []string, o...
method GetAsInt (line 118) | func (p *Perspective) GetAsInt(name string) (value int64, ok bool) {
method GetAsBool (line 127) | func (p *Perspective) GetAsBool(name string) (value bool, ok bool) {
type perspectiveOption (line 14) | type perspectiveOption struct
function NewPerspective (line 20) | func NewPerspective(config map[string]interface{}) (*Perspective, error) {
FILE: base/config/registry.go
function ForEachOption (line 21) | func ForEachOption(fn func(opt *Option) error) error {
function ExportOptions (line 36) | func ExportOptions() []*Option {
function GetOption (line 53) | func GetOption(name string) (*Option, error) {
function Register (line 66) | func Register(option *Option) error {
FILE: base/config/registry_test.go
function TestRegistry (line 7) | func TestRegistry(t *testing.T) { //nolint:paralleltest
FILE: base/config/release.go
type ReleaseLevel (line 11) | type ReleaseLevel
constant ReleaseLevelStable (line 15) | ReleaseLevelStable ReleaseLevel = 0
constant ReleaseLevelBeta (line 16) | ReleaseLevelBeta ReleaseLevel = 1
constant ReleaseLevelExperimental (line 17) | ReleaseLevelExperimental ReleaseLevel = 2
constant ReleaseLevelNameStable (line 19) | ReleaseLevelNameStable = "stable"
constant ReleaseLevelNameBeta (line 20) | ReleaseLevelNameBeta = "beta"
constant ReleaseLevelNameExperimental (line 21) | ReleaseLevelNameExperimental = "experimental"
constant releaseLevelKey (line 23) | releaseLevelKey = "core/releaseLevel"
function init (line 32) | func init() {
function registerReleaseLevelOption (line 36) | func registerReleaseLevelOption() {
function updateReleaseLevel (line 77) | func updateReleaseLevel() {
function getReleaseLevel (line 99) | func getReleaseLevel() ReleaseLevel {
FILE: base/config/set.go
function getValidityFlag (line 22) | func getValidityFlag() *abool.AtomicBool {
function signalChanges (line 30) | func signalChanges() {
function ValidateConfig (line 42) | func ValidateConfig(newValues map[string]interface{}) (validationErrors ...
function ReplaceConfig (line 76) | func ReplaceConfig(newValues map[string]interface{}) (validationErrors [...
function ReplaceDefaultConfig (line 114) | func ReplaceDefaultConfig(newValues map[string]interface{}) (validationE...
function SetConfigOption (line 152) | func SetConfigOption(key string, value any) error {
function setConfigOption (line 156) | func setConfigOption(key string, value any, push bool) (err error) {
function SetDefaultConfigOption (line 194) | func SetDefaultConfigOption(key string, value interface{}) error {
function setDefaultConfigOption (line 198) | func setDefaultConfigOption(key string, value interface{}, push bool) (e...
FILE: base/config/set_test.go
function TestLayersGetters (line 6) | func TestLayersGetters(t *testing.T) { //nolint:paralleltest
function TestLayersSetters (line 82) | func TestLayersSetters(t *testing.T) { //nolint:paralleltest
FILE: base/config/validate.go
type valueCache (line 12) | type valueCache struct
method getData (line 19) | func (vc *valueCache) getData(opt *Option) interface{} {
function isAllowedPossibleValue (line 43) | func isAllowedPossibleValue(opt *Option, value interface{}) error {
function migrateValue (line 70) | func migrateValue(option *Option, value any) any {
function validateValue (line 83) | func validateValue(option *Option, value interface{}) (*valueCache, *Val...
type ValidationError (line 219) | type ValidationError struct
method Error (line 225) | func (ve *ValidationError) Error() string {
method Unwrap (line 230) | func (ve *ValidationError) Unwrap() error {
function invalid (line 234) | func invalid(option *Option, format string, a ...interface{}) *Validatio...
FILE: base/config/validity.go
type ValidityFlag (line 8) | type ValidityFlag struct
method IsValid (line 22) | func (vf *ValidityFlag) IsValid() bool {
method Refresh (line 27) | func (vf *ValidityFlag) Refresh() {
function NewValidityFlag (line 14) | func NewValidityFlag() *ValidityFlag {
FILE: base/container/container.go
type Container (line 11) | type Container struct
method Prepend (line 34) | func (c *Container) Prepend(data []byte) {
method Append (line 43) | func (c *Container) Append(data []byte) {
method PrependNumber (line 48) | func (c *Container) PrependNumber(n uint64) {
method AppendNumber (line 53) | func (c *Container) AppendNumber(n uint64) {
method PrependInt (line 58) | func (c *Container) PrependInt(n int) {
method AppendInt (line 63) | func (c *Container) AppendInt(n int) {
method AppendAsBlock (line 68) | func (c *Container) AppendAsBlock(data []byte) {
method PrependAsBlock (line 74) | func (c *Container) PrependAsBlock(data []byte) {
method AppendContainer (line 80) | func (c *Container) AppendContainer(data *Container) {
method AppendContainerAsBlock (line 85) | func (c *Container) AppendContainerAsBlock(data *Container) {
method HoldsData (line 91) | func (c *Container) HoldsData() bool {
method Length (line 101) | func (c *Container) Length() (length int) {
method Replace (line 109) | func (c *Container) Replace(data []byte) {
method CompileData (line 114) | func (c *Container) CompileData() []byte {
method Get (line 129) | func (c *Container) Get(n int) ([]byte, error) {
method GetAll (line 139) | func (c *Container) GetAll() []byte {
method GetAsContainer (line 147) | func (c *Container) GetAsContainer(n int) (*Container, error) {
method GetMax (line 157) | func (c *Container) GetMax(n int) []byte {
method WriteToSlice (line 164) | func (c *Container) WriteToSlice(slice []byte) (n int, containerEmptie...
method WriteAllTo (line 185) | func (c *Container) WriteAllTo(writer io.Writer) error {
method clean (line 199) | func (c *Container) clean() {
method renewCompartments (line 205) | func (c *Container) renewCompartments() {
method carbonCopy (line 213) | func (c *Container) carbonCopy() *Container {
method checkOffset (line 223) | func (c *Container) checkOffset() {
method PrependLength (line 232) | func (c *Container) PrependLength() {
method Peek (line 237) | func (c *Container) Peek(n int) []byte {
method PeekContainer (line 265) | func (c *Container) PeekContainer(n int) (newC *Container) {
method skip (line 289) | func (c *Container) skip(n int) {
method GetNextBlock (line 309) | func (c *Container) GetNextBlock() ([]byte, error) {
method GetNextBlockAsContainer (line 318) | func (c *Container) GetNextBlockAsContainer() (*Container, error) {
method GetNextN8 (line 327) | func (c *Container) GetNextN8() (uint8, error) {
method GetNextN16 (line 338) | func (c *Container) GetNextN16() (uint16, error) {
method GetNextN32 (line 349) | func (c *Container) GetNextN32() (uint32, error) {
method GetNextN64 (line 360) | func (c *Container) GetNextN64() (uint64, error) {
function NewContainer (line 20) | func NewContainer(data ...[]byte) *Container {
function New (line 27) | func New(data ...[]byte) *Container {
FILE: base/container/container_test.go
function TestContainerDataHandling (line 25) | func TestContainerDataHandling(t *testing.T) {
function compareMany (line 77) | func compareMany(t *testing.T, reference []byte, other ...[]byte) {
function TestDataFetching (line 87) | func TestDataFetching(t *testing.T) {
function TestBlocks (line 107) | func TestBlocks(t *testing.T) {
function TestContainerBlockHandling (line 149) | func TestContainerBlockHandling(t *testing.T) {
function TestContainerMisc (line 194) | func TestContainerMisc(t *testing.T) {
function TestDeprecated (line 204) | func TestDeprecated(t *testing.T) {
FILE: base/container/serialization.go
method MarshalJSON (line 8) | func (c *Container) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 13) | func (c *Container) UnmarshalJSON(data []byte) error {
FILE: base/database/accessor/accessor-json-bytes.go
type JSONBytesAccessor (line 9) | type JSONBytesAccessor struct
method Set (line 21) | func (ja *JSONBytesAccessor) Set(key string, value interface{}) error {
method Get (line 39) | func (ja *JSONBytesAccessor) Get(key string) (value interface{}, ok bo...
method GetString (line 48) | func (ja *JSONBytesAccessor) GetString(key string) (value string, ok b...
method GetStringArray (line 57) | func (ja *JSONBytesAccessor) GetStringArray(key string) (value []strin...
method GetInt (line 75) | func (ja *JSONBytesAccessor) GetInt(key string) (value int64, ok bool) {
method GetFloat (line 84) | func (ja *JSONBytesAccessor) GetFloat(key string) (value float64, ok b...
method GetBool (line 93) | func (ja *JSONBytesAccessor) GetBool(key string) (value bool, ok bool) {
method Exists (line 108) | func (ja *JSONBytesAccessor) Exists(key string) bool {
method Type (line 114) | func (ja *JSONBytesAccessor) Type() string {
function NewJSONBytesAccessor (line 14) | func NewJSONBytesAccessor(json *[]byte) *JSONBytesAccessor {
FILE: base/database/accessor/accessor-json-string.go
type JSONAccessor (line 11) | type JSONAccessor struct
method Set (line 23) | func (ja *JSONAccessor) Set(key string, value interface{}) error {
method Get (line 63) | func (ja *JSONAccessor) Get(key string) (value interface{}, ok bool) {
method GetString (line 72) | func (ja *JSONAccessor) GetString(key string) (value string, ok bool) {
method GetStringArray (line 81) | func (ja *JSONAccessor) GetStringArray(key string) (value []string, ok...
method GetInt (line 99) | func (ja *JSONAccessor) GetInt(key string) (value int64, ok bool) {
method GetFloat (line 108) | func (ja *JSONAccessor) GetFloat(key string) (value float64, ok bool) {
method GetBool (line 117) | func (ja *JSONAccessor) GetBool(key string) (value bool, ok bool) {
method Exists (line 132) | func (ja *JSONAccessor) Exists(key string) bool {
method Type (line 138) | func (ja *JSONAccessor) Type() string {
function NewJSONAccessor (line 16) | func NewJSONAccessor(json *string) *JSONAccessor {
function checkJSONValueType (line 40) | func checkJSONValueType(jsonValue gjson.Result, key string, value interf...
FILE: base/database/accessor/accessor-struct.go
type StructAccessor (line 10) | type StructAccessor struct
method Set (line 22) | func (sa *StructAccessor) Set(key string, value interface{}) error {
method Get (line 90) | func (sa *StructAccessor) Get(key string) (value interface{}, ok bool) {
method GetString (line 99) | func (sa *StructAccessor) GetString(key string) (value string, ok bool) {
method GetStringArray (line 108) | func (sa *StructAccessor) GetStringArray(key string) (value []string, ...
method GetInt (line 122) | func (sa *StructAccessor) GetInt(key string) (value int64, ok bool) {
method GetFloat (line 138) | func (sa *StructAccessor) GetFloat(key string) (value float64, ok bool) {
method GetBool (line 152) | func (sa *StructAccessor) GetBool(key string) (value bool, ok bool) {
method Exists (line 161) | func (sa *StructAccessor) Exists(key string) bool {
method Type (line 167) | func (sa *StructAccessor) Type() string {
function NewStructAccessor (line 15) | func NewStructAccessor(object interface{}) *StructAccessor {
FILE: base/database/accessor/accessor.go
constant emptyString (line 4) | emptyString = ""
type Accessor (line 8) | type Accessor interface
FILE: base/database/accessor/accessor_test.go
type TestStruct (line 11) | type TestStruct struct
function testGetString (line 51) | func testGetString(t *testing.T, acc Accessor, key string, shouldSucceed...
function testGetStringArray (line 66) | func testGetStringArray(t *testing.T, acc Accessor, key string, shouldSu...
function testGetInt (line 81) | func testGetInt(t *testing.T, acc Accessor, key string, shouldSucceed bo...
function testGetFloat (line 96) | func testGetFloat(t *testing.T, acc Accessor, key string, shouldSucceed ...
function testGetBool (line 111) | func testGetBool(t *testing.T, acc Accessor, key string, shouldSucceed b...
function testExists (line 126) | func testExists(t *testing.T, acc Accessor, key string, shouldSucceed bo...
function testSet (line 138) | func testSet(t *testing.T, acc Accessor, key string, shouldSucceed bool,...
function TestAccessor (line 150) | func TestAccessor(t *testing.T) {
FILE: base/database/boilerplate_test.go
type Example (line 10) | type Example struct
method Save (line 49) | func (e *Example) Save() error {
method SaveAs (line 53) | func (e *Example) SaveAs(key string) error {
function GetExample (line 24) | func GetExample(key string) (*Example, error) {
function NewExample (line 58) | func NewExample(key, name string, score int) *Example {
FILE: base/database/controller.go
type Controller (line 16) | type Controller struct
method ReadOnly (line 38) | func (c *Controller) ReadOnly() bool {
method Injected (line 43) | func (c *Controller) Injected() bool {
method Get (line 48) | func (c *Controller) Get(key string) (record.Record, error) {
method GetMeta (line 82) | func (c *Controller) GetMeta(key string) (*record.Meta, error) {
method Put (line 121) | func (c *Controller) Put(r record.Record) (err error) {
method PutMany (line 158) | func (c *Controller) PutMany() (chan<- record.Record, <-chan error) {
method Query (line 181) | func (c *Controller) Query(q *query.Query, local, internal bool) (*ite...
method PushUpdate (line 197) | func (c *Controller) PushUpdate(r record.Record) {
method addSubscription (line 207) | func (c *Controller) addSubscription(sub *Subscription) {
method Maintain (line 219) | func (c *Controller) Maintain(ctx context.Context) error {
method MaintainThorough (line 232) | func (c *Controller) MaintainThorough(ctx context.Context) error {
method MaintainRecordStates (line 245) | func (c *Controller) MaintainRecordStates(ctx context.Context, purgeDe...
method Purge (line 255) | func (c *Controller) Purge(ctx context.Context, q *query.Query, local,...
method PurgeOlderThan (line 269) | func (c *Controller) PurgeOlderThan(ctx context.Context, prefix string...
method Shutdown (line 282) | func (c *Controller) Shutdown() error {
method notifySubscribers (line 290) | func (c *Controller) notifySubscribers(r record.Record) {
method runPreGetHooks (line 304) | func (c *Controller) runPreGetHooks(key string) error {
method runPostGetHooks (line 325) | func (c *Controller) runPostGetHooks(r record.Record) (record.Record, ...
method runPrePutHooks (line 348) | func (c *Controller) runPrePutHooks(r record.Record) (record.Record, e...
function newController (line 29) | func newController(database *Database, storageInt storage.Interface, sha...
FILE: base/database/controllers.go
constant StorageTypeInjected (line 12) | StorageTypeInjected = "injected"
function getController (line 19) | func getController(name string) (*Controller, error) {
function InjectDatabase (line 68) | func InjectDatabase(name string, storageInt storage.Interface) (*Control...
method Withdraw (line 99) | func (c *Controller) Withdraw() {
FILE: base/database/database.go
type Database (line 8) | type Database struct
method Loaded (line 19) | func (db *Database) Loaded() {
method Updated (line 24) | func (db *Database) Updated() {
FILE: base/database/database_test.go
function TestMain (line 24) | func TestMain(m *testing.M) {
function makeKey (line 44) | func makeKey(dbName, key string) string {
function testDatabase (line 48) | func testDatabase(t *testing.T, storageType string, shadowDelete bool) {...
function TestDatabaseSystem (line 250) | func TestDatabaseSystem(t *testing.T) { //nolint:tparallel
function countRecords (line 296) | func countRecords(t *testing.T, db *Interface, query *q.Query) int {
FILE: base/database/dbmodule/db.go
type DBModule (line 12) | type DBModule struct
method Manager (line 17) | func (dbm *DBModule) Manager() *mgr.Manager {
method Start (line 21) | func (dbm *DBModule) Start() error {
method Stop (line 25) | func (dbm *DBModule) Stop() error {
function SetDatabaseLocation (line 32) | func SetDatabaseLocation(dir string) {
function prep (line 38) | func prep() error {
function start (line 47) | func start() error {
function stop (line 52) | func stop() error {
function New (line 61) | func New(instance instance) (*DBModule, error) {
type instance (line 83) | type instance interface
FILE: base/database/dbmodule/maintenance.go
function startMaintenanceTasks (line 11) | func startMaintenanceTasks() {
function maintainBasic (line 17) | func maintainBasic(ctx *mgr.WorkerCtx) error {
function maintainThorough (line 22) | func maintainThorough(ctx *mgr.WorkerCtx) error {
function maintainRecords (line 27) | func maintainRecords(ctx *mgr.WorkerCtx) error {
FILE: base/database/hook.go
type Hook (line 11) | type Hook interface
type RegisteredHook (line 42) | type RegisteredHook struct
method Cancel (line 75) | func (h *RegisteredHook) Cancel() error {
function RegisterHook (line 49) | func RegisterHook(q *query.Query, hook Hook) (*RegisteredHook, error) {
FILE: base/database/hookbase.go
type HookBase (line 8) | type HookBase struct
method UsesPreGet (line 11) | func (b *HookBase) UsesPreGet() bool {
method UsesPostGet (line 16) | func (b *HookBase) UsesPostGet() bool {
method UsesPrePut (line 21) | func (b *HookBase) UsesPrePut() bool {
method PreGet (line 26) | func (b *HookBase) PreGet(dbKey string) error {
method PostGet (line 31) | func (b *HookBase) PostGet(r record.Record) (record.Record, error) {
method PrePut (line 36) | func (b *HookBase) PrePut(r record.Record) (record.Record, error) {
FILE: base/database/interface.go
constant getDBFromKey (line 20) | getDBFromKey = ""
type Interface (line 24) | type Interface struct
method Exists (line 139) | func (i *Interface) Exists(key string) (bool, error) {
method Get (line 155) | func (i *Interface) Get(key string) (record.Record, error) {
method getRecord (line 160) | func (i *Interface) getRecord(dbName string, dbKey string, mustBeWrite...
method getMeta (line 204) | func (i *Interface) getMeta(dbName string, dbKey string, mustBeWriteab...
method InsertValue (line 239) | func (i *Interface) InsertValue(key string, attribute string, value in...
method Put (line 269) | func (i *Interface) Put(r record.Record) (err error) {
method PutNew (line 307) | func (i *Interface) PutNew(r record.Record) (err error) {
method PutMany (line 354) | func (i *Interface) PutMany(dbName string) (put func(record.Record) er...
method SetAbsoluteExpiry (line 447) | func (i *Interface) SetAbsoluteExpiry(key string, time int64) error {
method SetRelativateExpiry (line 462) | func (i *Interface) SetRelativateExpiry(key string, duration int64) er...
method MakeSecret (line 477) | func (i *Interface) MakeSecret(key string) error {
method MakeCrownJewel (line 492) | func (i *Interface) MakeCrownJewel(key string) error {
method Delete (line 507) | func (i *Interface) Delete(key string) error {
method Query (line 526) | func (i *Interface) Query(q *query.Query) (*iterator.Iterator, error) {
method Purge (line 546) | func (i *Interface) Purge(ctx context.Context, q *query.Query) (int, e...
method PurgeOlderThan (line 567) | func (i *Interface) PurgeOlderThan(ctx context.Context, prefix string,...
method Subscribe (line 587) | func (i *Interface) Subscribe(q *query.Query) (*Subscription, error) {
type Options (line 34) | type Options struct
method Apply (line 80) | func (o *Options) Apply(r record.Record) {
method HasAllPermissions (line 97) | func (o *Options) HasAllPermissions() bool {
method hasAccessPermission (line 103) | func (o *Options) hasAccessPermission(r record.Record) bool {
function NewInterface (line 118) | func NewInterface(opts *Options) *Interface {
FILE: base/database/interface_cache.go
method DelayedCacheWriter (line 13) | func (i *Interface) DelayedCacheWriter(wc *mgr.WorkerCtx) error {
method ClearCache (line 64) | func (i *Interface) ClearCache() {
method FlushCache (line 75) | func (i *Interface) FlushCache() {
method flushWriteCache (line 84) | func (i *Interface) flushWriteCache(percentThreshold int) {
method cacheEvictHandler (line 120) | func (i *Interface) cacheEvictHandler(keyData, _ interface{}) {
method checkCache (line 165) | func (i *Interface) checkCache(key string) record.Record {
method updateCache (line 187) | func (i *Interface) updateCache(r record.Record, write bool, remove bool...
FILE: base/database/interface_cache_test.go
function benchmarkCacheWriting (line 12) | func benchmarkCacheWriting(b *testing.B, storageType string, cacheSize i...
function benchmarkCacheReadWrite (line 74) | func benchmarkCacheReadWrite(b *testing.B, storageType string, cacheSize...
function BenchmarkCache (line 143) | func BenchmarkCache(b *testing.B) {
FILE: base/database/iterator/iterator.go
type Iterator (line 12) | type Iterator struct
method Finish (line 31) | func (it *Iterator) Finish(err error) {
method Cancel (line 43) | func (it *Iterator) Cancel() {
method Err (line 50) | func (it *Iterator) Err() error {
function New (line 22) | func New() *Iterator {
FILE: base/database/main.go
function Initialize (line 22) | func Initialize(databasesRootDir string) error {
function Shutdown (line 38) | func Shutdown() (err error) {
function getLocation (line 58) | func getLocation(name, storageType string) (string, error) {
FILE: base/database/maintenance.go
function Maintain (line 9) | func Maintain(ctx context.Context) (err error) {
function MaintainThorough (line 23) | func MaintainThorough(ctx context.Context) (err error) {
function MaintainRecordStates (line 37) | func MaintainRecordStates(ctx context.Context) (err error) {
function duplicateControllers (line 54) | func duplicateControllers() (all []*Controller) {
FILE: base/database/migration/error.go
type DiagnosticStep (line 6) | type DiagnosticStep struct
type Diagnostics (line 12) | type Diagnostics struct
method Error (line 38) | func (err *Diagnostics) Error() string {
method Unwrap (line 53) | func (err *Diagnostics) Unwrap() error {
FILE: base/database/migration/migration.go
type MigrateFunc (line 25) | type MigrateFunc
type Migration (line 30) | type Migration struct
type Registry (line 42) | type Registry struct
method Add (line 59) | func (reg *Registry) Add(migrations ...Migration) error {
method Migrate (line 74) | func (reg *Registry) Migrate(ctx context.Context) (err error) {
method getLatestSuccessfulMigration (line 138) | func (reg *Registry) getLatestSuccessfulMigration(db *database.Interfa...
method saveLastSuccessfulMigration (line 169) | func (reg *Registry) saveLastSuccessfulMigration(db *database.Interfac...
method getExecutionPlan (line 179) | func (reg *Registry) getExecutionPlan(startOfMigration *version.Versio...
function New (line 52) | func New(key string) *Registry {
FILE: base/database/query/condition-and.go
function And (line 11) | func And(conditions ...Condition) Condition {
type andCond (line 17) | type andCond struct
method complies (line 21) | func (c *andCond) complies(acc accessor.Accessor) bool {
method check (line 30) | func (c *andCond) check() (err error) {
method string (line 40) | func (c *andCond) string() string {
FILE: base/database/query/condition-bool.go
type boolCondition (line 11) | type boolCondition struct
method complies (line 46) | func (c *boolCondition) complies(acc accessor.Accessor) bool {
method check (line 60) | func (c *boolCondition) check() error {
method string (line 67) | func (c *boolCondition) string() string {
function newBoolCondition (line 17) | func newBoolCondition(key string, operator uint8, value interface{}) *bo...
FILE: base/database/query/condition-error.go
type errorCondition (line 7) | type errorCondition struct
method complies (line 17) | func (c *errorCondition) complies(acc accessor.Accessor) bool {
method check (line 21) | func (c *errorCondition) check() error {
method string (line 25) | func (c *errorCondition) string() string {
function newErrorCondition (line 11) | func newErrorCondition(err error) *errorCondition {
FILE: base/database/query/condition-exists.go
type existsCondition (line 10) | type existsCondition struct
method complies (line 22) | func (c *existsCondition) complies(acc accessor.Accessor) bool {
method check (line 26) | func (c *existsCondition) check() error {
method string (line 33) | func (c *existsCondition) string() string {
function newExistsCondition (line 15) | func newExistsCondition(key string, operator uint8) *existsCondition {
FILE: base/database/query/condition-float.go
type floatCondition (line 11) | type floatCondition struct
method complies (line 66) | func (c *floatCondition) complies(acc accessor.Accessor) bool {
method check (line 88) | func (c *floatCondition) check() error {
method string (line 95) | func (c *floatCondition) string() string {
function newFloatCondition (line 17) | func newFloatCondition(key string, operator uint8, value interface{}) *f...
FILE: base/database/query/condition-int.go
type intCondition (line 11) | type intCondition struct
method complies (line 62) | func (c *intCondition) complies(acc accessor.Accessor) bool {
method check (line 84) | func (c *intCondition) check() error {
method string (line 91) | func (c *intCondition) string() string {
function newIntCondition (line 17) | func newIntCondition(key string, operator uint8, value interface{}) *int...
FILE: base/database/query/condition-not.go
function Not (line 11) | func Not(c Condition) Condition {
type notCond (line 17) | type notCond struct
method complies (line 21) | func (c *notCond) complies(acc accessor.Accessor) bool {
method check (line 25) | func (c *notCond) check() error {
method string (line 29) | func (c *notCond) string() string {
FILE: base/database/query/condition-or.go
function Or (line 11) | func Or(conditions ...Condition) Condition {
type orCond (line 17) | type orCond struct
method complies (line 21) | func (c *orCond) complies(acc accessor.Accessor) bool {
method check (line 30) | func (c *orCond) check() (err error) {
method string (line 40) | func (c *orCond) string() string {
FILE: base/database/query/condition-regex.go
type regexCondition (line 11) | type regexCondition struct
method complies (line 40) | func (c *regexCondition) complies(acc accessor.Accessor) bool {
method check (line 54) | func (c *regexCondition) check() error {
method string (line 61) | func (c *regexCondition) string() string {
function newRegexCondition (line 17) | func newRegexCondition(key string, operator uint8, value interface{}) *r...
FILE: base/database/query/condition-string.go
type stringCondition (line 11) | type stringCondition struct
method complies (line 33) | func (c *stringCondition) complies(acc accessor.Accessor) bool {
method check (line 53) | func (c *stringCondition) check() error {
method string (line 60) | func (c *stringCondition) string() string {
function newStringCondition (line 17) | func newStringCondition(key string, operator uint8, value interface{}) *...
FILE: base/database/query/condition-stringslice.go
type stringSliceCondition (line 11) | type stringSliceCondition struct
method complies (line 46) | func (c *stringSliceCondition) complies(acc accessor.Accessor) bool {
method check (line 60) | func (c *stringSliceCondition) check() error {
method string (line 67) | func (c *stringSliceCondition) string() string {
function newStringSliceCondition (line 17) | func newStringSliceCondition(key string, operator uint8, value interface...
FILE: base/database/query/condition.go
type Condition (line 10) | type Condition interface
constant Equals (line 18) | Equals uint8 = iota
constant GreaterThan (line 19) | GreaterThan
constant GreaterThanOrEqual (line 20) | GreaterThanOrEqual
constant LessThan (line 21) | LessThan
constant LessThanOrEqual (line 22) | LessThanOrEqual
constant FloatEquals (line 23) | FloatEquals
constant FloatGreaterThan (line 24) | FloatGreaterThan
constant FloatGreaterThanOrEqual (line 25) | FloatGreaterThanOrEqual
constant FloatLessThan (line 26) | FloatLessThan
constant FloatLessThanOrEqual (line 27) | FloatLessThanOrEqual
constant SameAs (line 28) | SameAs
constant Contains (line 29) | Contains
constant StartsWith (line 30) | StartsWith
constant EndsWith (line 31) | EndsWith
constant In (line 32) | In
constant Matches (line 33) | Matches
constant Is (line 34) | Is
constant Exists (line 35) | Exists
constant errorPresent (line 37) | errorPresent uint8 = 255
function Where (line 41) | func Where(key string, operator uint8, value interface{}) Condition {
FILE: base/database/query/condition_test.go
function testSuccess (line 5) | func testSuccess(t *testing.T, c Condition) {
function TestInterfaces (line 14) | func TestInterfaces(t *testing.T) {
function testCondError (line 47) | func testCondError(t *testing.T, c Condition) {
function TestConditionErrors (line 56) | func TestConditionErrors(t *testing.T) {
function TestWhere (line 78) | func TestWhere(t *testing.T) {
FILE: base/database/query/operators.go
function init (line 34) | func init() {
function getOpName (line 47) | func getOpName(operator uint8) string {
FILE: base/database/query/operators_test.go
function TestGetOpName (line 5) | func TestGetOpName(t *testing.T) {
FILE: base/database/query/parser.go
type snippet (line 11) | type snippet struct
function ParseQuery (line 19) | func ParseQuery(query string) (*Query, error) {
function extractSnippets (line 124) | func extractSnippets(text string) (snippets []*snippet, err error) {
function parseAndOr (line 199) | func parseAndOr(getSnippet func() (*snippet, error), remainingSnippets f...
function parseCondition (line 293) | func parseCondition(firstSnippet *snippet, getSnippet func() (*snippet, ...
function prepToken (line 338) | func prepToken(text string) string {
function escapeString (line 343) | func escapeString(token string) string {
FILE: base/database/query/parser_test.go
function TestExtractSnippets (line 10) | func TestExtractSnippets(t *testing.T) {
function testParsing (line 62) | func testParsing(t *testing.T, queryText string, expectedResult *Query) {
function TestParseQuery (line 90) | func TestParseQuery(t *testing.T) {
function testParseError (line 139) | func testParseError(t *testing.T, queryText string, expectedErrorString ...
function TestParseErrors (line 152) | func TestParseErrors(t *testing.T) {
FILE: base/database/query/query.go
type Query (line 22) | type Query struct
method Where (line 42) | func (q *Query) Where(condition Condition) *Query {
method Limit (line 48) | func (q *Query) Limit(limit int) *Query {
method Offset (line 54) | func (q *Query) Offset(offset int) *Query {
method OrderBy (line 60) | func (q *Query) OrderBy(key string) *Query {
method Check (line 66) | func (q *Query) Check() (*Query, error) {
method MustBeValid (line 84) | func (q *Query) MustBeValid() *Query {
method IsChecked (line 93) | func (q *Query) IsChecked() bool {
method MatchesKey (line 98) | func (q *Query) MatchesKey(dbKey string) bool {
method HasWhereCondition (line 103) | func (q *Query) HasWhereCondition() bool {
method MatchesRecord (line 108) | func (q *Query) MatchesRecord(r record.Record) bool {
method MatchesAccessor (line 121) | func (q *Query) MatchesAccessor(acc accessor.Accessor) bool {
method Matches (line 129) | func (q *Query) Matches(r record.Record) bool {
method Print (line 137) | func (q *Query) Print() string {
method DatabaseName (line 168) | func (q *Query) DatabaseName() string {
method DatabaseKeyPrefix (line 173) | func (q *Query) DatabaseKeyPrefix() string {
function New (line 33) | func New(prefix string) *Query {
FILE: base/database/query/query_test.go
function testQuery (line 49) | func testQuery(t *testing.T, r record.Record, shouldMatch bool, conditio...
function TestQuery (line 64) | func TestQuery(t *testing.T) {
FILE: base/database/record/base.go
type Base (line 29) | type Base struct
method SetKey (line 39) | func (b *Base) SetKey(key string) {
method ResetKey (line 49) | func (b *Base) ResetKey() {
method Key (line 57) | func (b *Base) Key() string {
method KeyIsSet (line 64) | func (b *Base) KeyIsSet() bool {
method DatabaseName (line 71) | func (b *Base) DatabaseName() string {
method DatabaseKey (line 78) | func (b *Base) DatabaseKey() string {
method Meta (line 83) | func (b *Base) Meta() *Meta {
method CreateMeta (line 88) | func (b *Base) CreateMeta() {
method UpdateMeta (line 93) | func (b *Base) UpdateMeta() {
method SetMeta (line 101) | func (b *Base) SetMeta(meta *Meta) {
method Marshal (line 106) | func (b *Base) Marshal(self Record, format uint8) ([]byte, error) {
method MarshalDataOnly (line 123) | func (b *Base) MarshalDataOnly(self Record, format uint8) ([]byte, err...
method MarshalRecord (line 136) | func (b *Base) MarshalRecord(self Record) ([]byte, error) {
method IsWrapped (line 162) | func (b *Base) IsWrapped() bool {
method GetAccessor (line 167) | func (b *Base) GetAccessor(self Record) accessor.Accessor {
FILE: base/database/record/base_test.go
function TestBaseRecord (line 5) | func TestBaseRecord(t *testing.T) {
FILE: base/database/record/key.go
function ParseKey (line 8) | func ParseKey(key string) (dbName, dbKey string) {
FILE: base/database/record/meta-bench_test.go
function BenchmarkAllocateBytes (line 38) | func BenchmarkAllocateBytes(b *testing.B) {
function BenchmarkAllocateStruct1 (line 44) | func BenchmarkAllocateStruct1(b *testing.B) {
function BenchmarkAllocateStruct2 (line 51) | func BenchmarkAllocateStruct2(b *testing.B) {
function BenchmarkMetaSerializeContainer (line 57) | func BenchmarkMetaSerializeContainer(b *testing.B) {
function BenchmarkMetaUnserializeContainer (line 78) | func BenchmarkMetaUnserializeContainer(b *testing.B) {
function BenchmarkMetaSerializeVarInt (line 153) | func BenchmarkMetaSerializeVarInt(b *testing.B) {
function BenchmarkMetaUnserializeVarInt (line 192) | func BenchmarkMetaUnserializeVarInt(b *testing.B) {
function BenchmarkMetaSerializeWithCodegen (line 286) | func BenchmarkMetaSerializeWithCodegen(b *testing.B) {
function BenchmarkMetaUnserializeWithCodegen (line 296) | func BenchmarkMetaUnserializeWithCodegen(b *testing.B) {
function BenchmarkMetaSerializeWithDSDJSON (line 318) | func BenchmarkMetaSerializeWithDSDJSON(b *testing.B) {
function BenchmarkMetaUnserializeWithDSDJSON (line 328) | func BenchmarkMetaUnserializeWithDSDJSON(b *testing.B) {
FILE: base/database/record/meta-gencode.go
method GenCodeSize (line 8) | func (m *Meta) GenCodeSize() (s int) {
method GenCodeMarshal (line 14) | func (m *Meta) GenCodeMarshal(buf []byte) ([]byte, error) {
method GenCodeUnmarshal (line 119) | func (m *Meta) GenCodeUnmarshal(buf []byte) (uint64, error) {
FILE: base/database/record/meta-gencode_test.go
function TestGenCode (line 18) | func TestGenCode(t *testing.T) {
FILE: base/database/record/meta.go
type Meta (line 6) | type Meta struct
method SetAbsoluteExpiry (line 16) | func (m *Meta) SetAbsoluteExpiry(seconds int64) {
method SetRelativateExpiry (line 22) | func (m *Meta) SetRelativateExpiry(seconds int64) {
method GetAbsoluteExpiry (line 29) | func (m *Meta) GetAbsoluteExpiry() int64 {
method GetRelativeExpiry (line 35) | func (m *Meta) GetRelativeExpiry() int64 {
method MakeCrownJewel (line 48) | func (m *Meta) MakeCrownJewel() {
method IsCrownJewel (line 53) | func (m *Meta) IsCrownJewel() bool {
method MakeSecret (line 58) | func (m *Meta) MakeSecret() {
method IsSecret (line 63) | func (m *Meta) IsSecret() bool {
method Update (line 68) | func (m *Meta) Update() {
method Reset (line 80) | func (m *Meta) Reset() {
method Delete (line 88) | func (m *Meta) Delete() {
method IsDeleted (line 93) | func (m *Meta) IsDeleted() bool {
method CheckValidity (line 98) | func (m *Meta) CheckValidity() (valid bool) {
method CheckPermission (line 114) | func (m *Meta) CheckPermission(local, internal bool) (permitted bool) {
method Duplicate (line 130) | func (m *Meta) Duplicate() *Meta {
FILE: base/database/record/record.go
type Record (line 8) | type Record interface
FILE: base/database/record/record_test.go
type TestRecord (line 7) | type TestRecord struct
FILE: base/database/record/wrapper.go
type Wrapper (line 15) | type Wrapper struct
method Marshal (line 97) | func (w *Wrapper) Marshal(r Record, format uint8) ([]byte, error) {
method MarshalDataOnly (line 118) | func (w *Wrapper) MarshalDataOnly(self Record, format uint8) ([]byte, ...
method MarshalRecord (line 135) | func (w *Wrapper) MarshalRecord(r Record) ([]byte, error) {
method IsWrapped (line 163) | func (w *Wrapper) IsWrapped() bool {
method GetAccessor (line 186) | func (w *Wrapper) GetAccessor(self Record) accessor.Accessor {
function NewRawWrapper (line 24) | func NewRawWrapper(database, key string, data []byte) (*Wrapper, error) {
function NewWrapper (line 67) | func NewWrapper(key string, meta *Meta, format uint8, data []byte) (*Wra...
function NewWrapperFromDatabase (line 83) | func NewWrapperFromDatabase(dbName, dbKey string, meta *Meta, format uin...
function Unwrap (line 168) | func Unwrap(wrapped, r Record) error {
FILE: base/database/record/wrapper_test.go
function TestWrapper (line 10) | func TestWrapper(t *testing.T) {
FILE: base/database/registry.go
function Register (line 22) | func Register(db *Database) (*Database, error) {
function getDatabase (line 56) | func getDatabase(name string) (*Database, error) {
FILE: base/database/storage/badger/badger.go
type Badger (line 19) | type Badger struct
method Get (line 50) | func (b *Badger) Get(key string) (record.Record, error) {
method GetMeta (line 86) | func (b *Badger) GetMeta(key string) (*record.Meta, error) {
method Put (line 98) | func (b *Badger) Put(r record.Record) (record.Record, error) {
method Delete (line 114) | func (b *Badger) Delete(key string) error {
method Query (line 125) | func (b *Badger) Query(q *query.Query, local, internal bool) (*iterato...
method queryExecutor (line 138) | func (b *Badger) queryExecutor(queryIter *iterator.Iterator, q *query....
method ReadOnly (line 199) | func (b *Badger) ReadOnly() bool {
method Injected (line 204) | func (b *Badger) Injected() bool {
method Maintain (line 209) | func (b *Badger) Maintain(_ context.Context) error {
method MaintainThorough (line 215) | func (b *Badger) MaintainThorough(_ context.Context) (err error) {
method MaintainRecordStates (line 223) | func (b *Badger) MaintainRecordStates(ctx context.Context, purgeDelete...
method Shutdown (line 229) | func (b *Badger) Shutdown() error {
function init (line 24) | func init() {
function NewBadger (line 29) | func NewBadger(name, location string) (storage.Interface, error) {
FILE: base/database/storage/badger/badger_test.go
type TestRecord (line 21) | type TestRecord struct
function TestBadger (line 40) | func TestBadger(t *testing.T) {
FILE: base/database/storage/bbolt/bbolt.go
type BBolt (line 22) | type BBolt struct
method Get (line 68) | func (b *BBolt) Get(key string) (record.Record, error) {
method GetMeta (line 97) | func (b *BBolt) GetMeta(key string) (*record.Meta, error) {
method Put (line 109) | func (b *BBolt) Put(r record.Record) (record.Record, error) {
method PutMany (line 129) | func (b *BBolt) PutMany(shadowDelete bool) (chan<- record.Record, <-ch...
method batchPutOrDelete (line 150) | func (b *BBolt) batchPutOrDelete(bucket *bbolt.Bucket, shadowDelete bo...
method Delete (line 170) | func (b *BBolt) Delete(key string) error {
method Query (line 185) | func (b *BBolt) Query(q *query.Query, local, internal bool) (*iterator...
method queryExecutor (line 197) | func (b *BBolt) queryExecutor(queryIter *iterator.Iterator, q *query.Q...
method ReadOnly (line 260) | func (b *BBolt) ReadOnly() bool {
method Injected (line 265) | func (b *BBolt) Injected() bool {
method MaintainRecordStates (line 270) | func (b *BBolt) MaintainRecordStates(ctx context.Context, purgeDeleted...
method Purge (line 333) | func (b *BBolt) Purge(ctx context.Context, q *query.Query, local, inte...
method Shutdown (line 425) | func (b *BBolt) Shutdown() error {
function init (line 27) | func init() {
function NewBBolt (line 32) | func NewBBolt(name, location string) (storage.Interface, error) {
FILE: base/database/storage/bbolt/bbolt_test.go
type TestRecord (line 23) | type TestRecord struct
function TestBBolt (line 42) | func TestBBolt(t *testing.T) {
FILE: base/database/storage/fstree/fstree.go
constant defaultFileMode (line 26) | defaultFileMode = os.FileMode(0o0644)
constant defaultDirMode (line 27) | defaultDirMode = os.FileMode(0o0755)
constant onWindows (line 28) | onWindows = runtime.GOOS == "windows"
type FSTree (line 32) | type FSTree struct
method buildFilePath (line 70) | func (fst *FSTree) buildFilePath(key string, checkKeyLength bool) (str...
method Get (line 85) | func (fst *FSTree) Get(key string) (record.Record, error) {
method GetMeta (line 107) | func (fst *FSTree) GetMeta(key string) (*record.Meta, error) {
method Put (line 119) | func (fst *FSTree) Put(r record.Record) (record.Record, error) {
method Delete (line 147) | func (fst *FSTree) Delete(key string) error {
method Query (line 163) | func (fst *FSTree) Query(q *query.Query, local, internal bool) (*itera...
method queryExecutor (line 192) | func (fst *FSTree) queryExecutor(walkRoot string, queryIter *iterator....
method ReadOnly (line 258) | func (fst *FSTree) ReadOnly() bool {
method Injected (line 263) | func (fst *FSTree) Injected() bool {
method MaintainRecordStates (line 268) | func (fst *FSTree) MaintainRecordStates(ctx context.Context, purgeDele...
method Shutdown (line 274) | func (fst *FSTree) Shutdown() error {
function init (line 37) | func init() {
function NewFSTree (line 42) | func NewFSTree(name, location string) (storage.Interface, error) {
function writeFile (line 283) | func writeFile(filename string, data []byte, perm os.FileMode) error {
FILE: base/database/storage/hashmap/map.go
type HashMap (line 17) | type HashMap struct
method Get (line 36) | func (hm *HashMap) Get(key string) (record.Record, error) {
method GetMeta (line 48) | func (hm *HashMap) GetMeta(key string) (*record.Meta, error) {
method Put (line 60) | func (hm *HashMap) Put(r record.Record) (record.Record, error) {
method PutMany (line 69) | func (hm *HashMap) PutMany(shadowDelete bool) (chan<- record.Record, <...
method batchPutOrDelete (line 89) | func (hm *HashMap) batchPutOrDelete(shadowDelete bool, r record.Record) {
method Delete (line 104) | func (hm *HashMap) Delete(key string) error {
method Query (line 113) | func (hm *HashMap) Query(q *query.Query, local, internal bool) (*itera...
method queryExecutor (line 125) | func (hm *HashMap) queryExecutor(queryIter *iterator.Iterator, q *quer...
method ReadOnly (line 165) | func (hm *HashMap) ReadOnly() bool {
method Injected (line 170) | func (hm *HashMap) Injected() bool {
method MaintainRecordStates (line 175) | func (hm *HashMap) MaintainRecordStates(ctx context.Context, purgeDele...
method Shutdown (line 214) | func (hm *HashMap) Shutdown() error {
function init (line 23) | func init() {
function NewHashMap (line 28) | func NewHashMap(name, location string) (storage.Interface, error) {
FILE: base/database/storage/hashmap/map_test.go
type TestRecord (line 19) | type TestRecord struct
function TestHashMap (line 38) | func TestHashMap(t *testing.T) {
FILE: base/database/storage/injectbase.go
type InjectBase (line 17) | type InjectBase struct
method Get (line 23) | func (i *InjectBase) Get(key string) (record.Record, error) {
method Put (line 28) | func (i *InjectBase) Put(m record.Record) (record.Record, error) {
method Delete (line 33) | func (i *InjectBase) Delete(key string) error {
method Query (line 38) | func (i *InjectBase) Query(q *query.Query, local, internal bool) (*ite...
method ReadOnly (line 43) | func (i *InjectBase) ReadOnly() bool {
method Injected (line 48) | func (i *InjectBase) Injected() bool {
method MaintainRecordStates (line 53) | func (i *InjectBase) MaintainRecordStates(ctx context.Context, purgeDe...
method Shutdown (line 58) | func (i *InjectBase) Shutdown() error {
FILE: base/database/storage/interface.go
type Interface (line 13) | type Interface interface
type MetaHandler (line 30) | type MetaHandler interface
type Maintainer (line 35) | type Maintainer interface
type Batcher (line 41) | type Batcher interface
type Purger (line 46) | type Purger interface
type PurgeOlderThan (line 51) | type PurgeOlderThan interface
FILE: base/database/storage/sinkhole/sinkhole.go
type Sinkhole (line 15) | type Sinkhole struct
method Exists (line 38) | func (s *Sinkhole) Exists(key string) (bool, error) {
method Get (line 43) | func (s *Sinkhole) Get(key string) (record.Record, error) {
method GetMeta (line 48) | func (s *Sinkhole) GetMeta(key string) (*record.Meta, error) {
method Put (line 53) | func (s *Sinkhole) Put(r record.Record) (record.Record, error) {
method PutMany (line 58) | func (s *Sinkhole) PutMany(shadowDelete bool) (chan<- record.Record, <...
method Delete (line 74) | func (s *Sinkhole) Delete(key string) error {
method Query (line 79) | func (s *Sinkhole) Query(q *query.Query, local, internal bool) (*itera...
method ReadOnly (line 84) | func (s *Sinkhole) ReadOnly() bool {
method Injected (line 89) | func (s *Sinkhole) Injected() bool {
method Maintain (line 94) | func (s *Sinkhole) Maintain(ctx context.Context) error {
method MaintainThorough (line 99) | func (s *Sinkhole) MaintainThorough(ctx context.Context) error {
method MaintainRecordStates (line 104) | func (s *Sinkhole) MaintainRecordStates(ctx context.Context, purgeDele...
method Shutdown (line 109) | func (s *Sinkhole) Shutdown() error {
function init (line 26) | func init() {
function NewSinkhole (line 31) | func NewSinkhole(name, location string) (storage.Interface, error) {
FILE: base/database/storage/sqlite/dberrors/bob_errors.bob.go
type UniqueConstraintError (line 17) | type UniqueConstraintError struct
method Error (line 28) | func (e *UniqueConstraintError) Error() string {
method Is (line 32) | func (e *UniqueConstraintError) Is(target error) bool {
FILE: base/database/storage/sqlite/dberrors/records.bob.go
type recordErrors (line 15) | type recordErrors struct
FILE: base/database/storage/sqlite/dbinfo/bob_types.bob.go
type Table (line 8) | type Table struct
type columns (line 20) | type columns interface
type column (line 24) | type column struct
type indexes (line 34) | type indexes interface
type index (line 38) | type index struct
type indexColumn (line 47) | type indexColumn struct
type constraint (line 53) | type constraint struct
type foreignKeys (line 59) | type foreignKeys interface
type foreignKey (line 63) | type foreignKey struct
type uniques (line 69) | type uniques interface
type checks (line 73) | type checks interface
type check (line 77) | type check struct
FILE: base/database/storage/sqlite/dbinfo/records.bob.go
type recordColumns (line 125) | type recordColumns struct
method AsSlice (line 137) | func (c recordColumns) AsSlice() []column {
type recordIndexes (line 143) | type recordIndexes struct
method AsSlice (line 147) | func (i recordIndexes) AsSlice() []index {
type recordForeignKeys (line 153) | type recordForeignKeys struct
method AsSlice (line 155) | func (f recordForeignKeys) AsSlice() []foreignKey {
type recordUniques (line 159) | type recordUniques struct
method AsSlice (line 161) | func (u recordUniques) AsSlice() []constraint {
type recordChecks (line 165) | type recordChecks struct
method AsSlice (line 167) | func (c recordChecks) AsSlice() []check {
FILE: base/database/storage/sqlite/factory/bobfactory_context.bob.go
type contextKey (line 8) | type contextKey
type contextual (line 14) | type contextual struct
function newContextual (line 18) | func newContextual[V any](key string) contextual[V] {
method WithValue (line 22) | func (k contextual[V]) WithValue(ctx context.Context, val V) context.Con...
method Value (line 26) | func (k contextual[V]) Value(ctx context.Context) (V, bool) {
FILE: base/database/storage/sqlite/factory/bobfactory_main.bob.go
type Factory (line 13) | type Factory struct
method NewRecord (line 21) | func (f *Factory) NewRecord(mods ...RecordMod) *RecordTemplate {
method NewRecordWithContext (line 25) | func (f *Factory) NewRecordWithContext(ctx context.Context, mods ...Re...
method FromExistingRecord (line 37) | func (f *Factory) FromExistingRecord(m *models.Record) *RecordTemplate {
method ClearBaseRecordMods (line 53) | func (f *Factory) ClearBaseRecordMods() {
method AddBaseRecordMod (line 57) | func (f *Factory) AddBaseRecordMod(mods ...RecordMod) {
function New (line 17) | func New() *Factory {
FILE: base/database/storage/sqlite/factory/bobfactory_main.bob_test.go
function TestCreateRecord (line 11) | func TestCreateRecord(t *testing.T) {
FILE: base/database/storage/sqlite/factory/bobfactory_random.bob.go
function random___byte (line 15) | func random___byte(f *faker.Faker, limits ...string) []byte {
function random_bool (line 23) | func random_bool(f *faker.Faker, limits ...string) bool {
function random_int64 (line 31) | func random_int64(f *faker.Faker, limits ...string) int64 {
function random_string (line 39) | func random_string(f *faker.Faker, limits ...string) string {
FILE: base/database/storage/sqlite/factory/bobfactory_random.bob_test.go
function TestRandom___byte (line 16) | func TestRandom___byte(t *testing.T) {
function TestRandom_int64 (line 27) | func TestRandom_int64(t *testing.T) {
function TestRandom_string (line 38) | func TestRandom_string(t *testing.T) {
FILE: base/database/storage/sqlite/factory/records.bob.go
type RecordMod (line 18) | type RecordMod interface
type RecordModFunc (line 22) | type RecordModFunc
method Apply (line 24) | func (f RecordModFunc) Apply(ctx context.Context, n *RecordTemplate) {
type RecordModSlice (line 28) | type RecordModSlice
method Apply (line 30) | func (mods RecordModSlice) Apply(ctx context.Context, n *RecordTemplat...
type RecordTemplate (line 38) | type RecordTemplate struct
method Apply (line 55) | func (o *RecordTemplate) Apply(ctx context.Context, mods ...RecordMod) {
method setModelRels (line 63) | func (t RecordTemplate) setModelRels(o *models.Record) {}
method BuildSetter (line 67) | func (o RecordTemplate) BuildSetter() *models.RecordSetter {
method BuildManySetter (line 112) | func (o RecordTemplate) BuildManySetter(number int) []*models.RecordSe...
method Build (line 125) | func (o RecordTemplate) Build() *models.Record {
method BuildMany (line 164) | func (o RecordTemplate) BuildMany(number int) models.RecordSlice {
method insertOptRels (line 192) | func (o *RecordTemplate) insertOptRels(ctx context.Context, exec bob.E...
method Create (line 200) | func (o *RecordTemplate) Create(ctx context.Context, exec bob.Executor...
method MustCreate (line 219) | func (o *RecordTemplate) MustCreate(ctx context.Context, exec bob.Exec...
method CreateOrFail (line 230) | func (o *RecordTemplate) CreateOrFail(ctx context.Context, tb testing....
method CreateMany (line 242) | func (o RecordTemplate) CreateMany(ctx context.Context, exec bob.Execu...
method MustCreateMany (line 259) | func (o RecordTemplate) MustCreateMany(ctx context.Context, exec bob.E...
method CreateManyOrFail (line 270) | func (o RecordTemplate) CreateManyOrFail(ctx context.Context, tb testi...
function ensureCreatableRecord (line 174) | func ensureCreatableRecord(m *models.RecordSetter) {
type recordMods (line 283) | type recordMods struct
method RandomizeAllColumns (line 285) | func (m recordMods) RandomizeAllColumns(f *faker.Faker) RecordMod {
method Key (line 300) | func (m recordMods) Key(val string) RecordMod {
method KeyFunc (line 307) | func (m recordMods) KeyFunc(f func() string) RecordMod {
method UnsetKey (line 314) | func (m recordMods) UnsetKey() RecordMod {
method RandomKey (line 322) | func (m recordMods) RandomKey(f *faker.Faker) RecordMod {
method Format (line 331) | func (m recordMods) Format(val null.Val[int64]) RecordMod {
method FormatFunc (line 338) | func (m recordMods) FormatFunc(f func() null.Val[int64]) RecordMod {
method UnsetFormat (line 345) | func (m recordMods) UnsetFormat() RecordMod {
method RandomFormat (line 354) | func (m recordMods) RandomFormat(f *faker.Faker) RecordMod {
method RandomFormatNotNull (line 370) | func (m recordMods) RandomFormatNotNull(f *faker.Faker) RecordMod {
method Value (line 384) | func (m recordMods) Value(val null.Val[[]byte]) RecordMod {
method ValueFunc (line 391) | func (m recordMods) ValueFunc(f func() null.Val[[]byte]) RecordMod {
method UnsetValue (line 398) | func (m recordMods) UnsetValue() RecordMod {
method RandomValue (line 407) | func (m recordMods) RandomValue(f *faker.Faker) RecordMod {
method RandomValueNotNull (line 423) | func (m recordMods) RandomValueNotNull(f *faker.Faker) RecordMod {
method Created (line 437) | func (m recordMods) Created(val int64) RecordMod {
method CreatedFunc (line 444) | func (m recordMods) CreatedFunc(f func() int64) RecordMod {
method UnsetCreated (line 451) | func (m recordMods) UnsetCreated() RecordMod {
method RandomCreated (line 459) | func (m recordMods) RandomCreated(f *faker.Faker) RecordMod {
method Modified (line 468) | func (m recordMods) Modified(val int64) RecordMod {
method ModifiedFunc (line 475) | func (m recordMods) ModifiedFunc(f func() int64) RecordMod {
method UnsetModified (line 482) | func (m recordMods) UnsetModified() RecordMod {
method RandomModified (line 490) | func (m recordMods) RandomModified(f *faker.Faker) RecordMod {
method Expires (line 499) | func (m recordMods) Expires(val int64) RecordMod {
method ExpiresFunc (line 506) | func (m recordMods) ExpiresFunc(f func() int64) RecordMod {
method UnsetExpires (line 513) | func (m recordMods) UnsetExpires() RecordMod {
method RandomExpires (line 521) | func (m recordMods) RandomExpires(f *faker.Faker) RecordMod {
method Deleted (line 530) | func (m recordMods) Deleted(val int64) RecordMod {
method DeletedFunc (line 537) | func (m recordMods) DeletedFunc(f func() int64) RecordMod {
method UnsetDeleted (line 544) | func (m recordMods) UnsetDeleted() RecordMod {
method RandomDeleted (line 552) | func (m recordMods) RandomDeleted(f *faker.Faker) RecordMod {
method Secret (line 561) | func (m recordMods) Secret(val bool) RecordMod {
method SecretFunc (line 568) | func (m recordMods) SecretFunc(f func() bool) RecordMod {
method UnsetSecret (line 575) | func (m recordMods) UnsetSecret() RecordMod {
method RandomSecret (line 583) | func (m recordMods) RandomSecret(f *faker.Faker) RecordMod {
method Crownjewel (line 592) | func (m recordMods) Crownjewel(val bool) RecordMod {
method CrownjewelFunc (line 599) | func (m recordMods) CrownjewelFunc(f func() bool) RecordMod {
method UnsetCrownjewel (line 606) | func (m recordMods) UnsetCrownjewel() RecordMod {
method RandomCrownjewel (line 614) | func (m recordMods) RandomCrownjewel(f *faker.Faker) RecordMod {
method WithParentsCascading (line 622) | func (m recordMods) WithParentsCascading() RecordMod {
FILE: base/database/storage/sqlite/migrations/1_initial.sql
type records (line 3) | CREATE TABLE records (
FILE: base/database/storage/sqlite/models/bob_joins.bob.go
type joinSet (line 19) | type joinSet struct
method AliasedAs (line 25) | func (j joinSet[Q]) AliasedAs(alias string) joinSet[Q] {
type joins (line 33) | type joins struct
function buildJoinSet (line 35) | func buildJoinSet[Q interface{ aliasedAs(string) Q }, C any, F func(C, s...
function getJoins (line 43) | func getJoins[Q dialect.Joinable]() joins[Q] {
type modAs (line 47) | type modAs struct
method Apply (line 52) | func (m modAs[Q, C]) Apply(q Q) {
method AliasedAs (line 56) | func (m modAs[Q, C]) AliasedAs(alias string) bob.Mod[Q] {
function randInt (line 61) | func randInt() int64 {
FILE: base/database/storage/sqlite/models/bob_loaders.bob.go
type preloaders (line 19) | type preloaders struct
function getPreloaders (line 21) | func getPreloaders() preloaders {
type thenLoaders (line 31) | type thenLoaders struct
function getThenLoaders (line 33) | func getThenLoaders[Q orm.Loadable]() thenLoaders[Q] {
function thenLoadBuilder (line 37) | func thenLoadBuilder[Q orm.Loadable, T any](name string, f func(context....
FILE: base/database/storage/sqlite/models/bob_where.bob.go
function Where (line 19) | func Where[Q sqlite.Filterable]() struct {
FILE: base/database/storage/sqlite/models/records.bob.go
type Record (line 23) | type Record struct
method AfterQueryHook (line 317) | func (o *Record) AfterQueryHook(ctx context.Context, exec bob.Executor...
method primaryKeyVals (line 335) | func (o *Record) primaryKeyVals() bob.Expression {
method pkEQ (line 339) | func (o *Record) pkEQ() dialect.Expression {
method Update (line 346) | func (o *Record) Update(ctx context.Context, exec bob.Executor, s *Rec...
method Delete (line 358) | func (o *Record) Delete(ctx context.Context, exec bob.Executor) error {
method Reload (line 364) | func (o *Record) Reload(ctx context.Context, exec bob.Executor) error {
type RecordSlice (line 37) | type RecordSlice
method AfterQueryHook (line 378) | func (o RecordSlice) AfterQueryHook(ctx context.Context, exec bob.Exec...
method pkIN (line 395) | func (o RecordSlice) pkIN() dialect.Expression {
method copyMatchingRows (line 412) | func (o RecordSlice) copyMatchingRows(from ...*Record) {
method UpdateMod (line 426) | func (o RecordSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
method DeleteMod (line 455) | func (o RecordSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] {
method UpdateAll (line 483) | func (o RecordSlice) UpdateAll(ctx context.Context, exec bob.Executor,...
method DeleteAll (line 492) | func (o RecordSlice) DeleteAll(ctx context.Context, exec bob.Executor)...
method ReloadAll (line 501) | func (o RecordSlice) ReloadAll(ctx context.Context, exec bob.Executor)...
function buildRecordColumns (line 45) | func buildRecordColumns(alias string) recordColumns {
type recordColumns (line 63) | type recordColumns struct
method Alias (line 77) | func (c recordColumns) Alias() string {
method AliasedAs (line 81) | func (recordColumns) AliasedAs(alias string) recordColumns {
type RecordSetter (line 88) | type RecordSetter struct
method SetColumns (line 100) | func (s RecordSetter) SetColumns() []string {
method Overwrite (line 132) | func (s RecordSetter) Overwrite(t *Record) {
method Apply (line 162) | func (s *RecordSetter) Apply(q *dialect.InsertQuery) {
method UpdateMod (line 221) | func (s RecordSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
method Expressions (line 225) | func (s RecordSetter) Expressions(prefix ...string) []bob.Expression {
function FindRecord (line 296) | func FindRecord(ctx context.Context, exec bob.Executor, KeyPK string, co...
function RecordExists (line 310) | func RecordExists(ctx context.Context, exec bob.Executor, KeyPK string) ...
type recordWhere (line 516) | type recordWhere struct
method AliasedAs (line 528) | func (recordWhere[Q]) AliasedAs(alias string) recordWhere[Q] {
function buildRecordWhere (line 532) | func buildRecordWhere[Q sqlite.Filterable](cols recordColumns) recordWhe...
FILE: base/database/storage/sqlite/prepared.go
method putManyWithPreparedStmts (line 21) | func (db *SQLite) putManyWithPreparedStmts(shadowDelete bool) (chan<- re...
function writeWithPreparedStatement (line 84) | func writeWithPreparedStatement(ctx context.Context, pStmt *bob.StdPrepa...
FILE: base/database/storage/sqlite/prepared_test.go
function BenchmarkPutMany (line 8) | func BenchmarkPutMany(b *testing.B) {
function BenchmarkPutManyPreparedStmt (line 20) | func BenchmarkPutManyPreparedStmt(b *testing.B) {
function benchPutMany (line 32) | func benchPutMany(b *testing.B) { //nolint:thelper
FILE: base/database/storage/sqlite/schema.go
function getMigrations (line 30) | func getMigrations() migrate.EmbedFileSystemMigrationSource {
function getMeta (line 37) | func getMeta(r *models.Record) *record.Meta {
FILE: base/database/storage/sqlite/sqlite.go
type SQLite (line 38) | type SQLite struct
method Get (line 119) | func (db *SQLite) Get(key string) (record.Record, error) {
method GetMeta (line 140) | func (db *SQLite) GetMeta(key string) (*record.Meta, error) {
method Put (line 150) | func (db *SQLite) Put(r record.Record) (record.Record, error) {
method putRecord (line 154) | func (db *SQLite) putRecord(r record.Record, tx *bob.Tx) (record.Recor...
method PutMany (line 228) | func (db *SQLite) PutMany(shadowDelete bool) (chan<- record.Record, <-...
method Delete (line 279) | func (db *SQLite) Delete(key string) error {
method Query (line 288) | func (db *SQLite) Query(q *query.Query, local, internal bool) (*iterat...
method queryExecutor (line 303) | func (db *SQLite) queryExecutor(queryIter *iterator.Iterator, q *query...
method Purge (line 391) | func (db *SQLite) Purge(ctx context.Context, q *query.Query, local, in...
method PurgeOlderThan (line 440) | func (db *SQLite) PurgeOlderThan(ctx context.Context, prefix string, p...
method ReadOnly (line 493) | func (db *SQLite) ReadOnly() bool {
method Injected (line 498) | func (db *SQLite) Injected() bool {
method MaintainRecordStates (line 503) | func (db *SQLite) MaintainRecordStates(ctx context.Context, purgeDelet...
method Maintain (line 558) | func (db *SQLite) Maintain(ctx context.Context) error {
method MaintainThorough (line 568) | func (db *SQLite) MaintainThorough(ctx context.Context) error {
method Shutdown (line 578) | func (db *SQLite) Shutdown() error {
function init (line 49) | func init() {
function NewSQLite (line 56) | func NewSQLite(name, location string) (*SQLite, error) {
function openSQLite (line 61) | func openSQLite(name, location string, printStmts bool) (*SQLite, error) {
type statementLogger (line 585) | type statementLogger struct
method Log (line 587) | func (sl statementLogger) Log(ctx context.Context, level sqldblogger.L...
FILE: base/database/storage/sqlite/sqlite_test.go
type TestRecord (line 22) | type TestRecord struct
function TestSQLite (line 41) | func TestSQLite(t *testing.T) {
FILE: base/database/storage/storages.go
type Factory (line 10) | type Factory
function Register (line 18) | func Register(name string, factory Factory) error {
function CreateDatabase (line 32) | func CreateDatabase(name, storageType, location string) (Interface, erro...
function StartDatabase (line 37) | func StartDatabase(name, storageType, location string) (Interface, error) {
FILE: base/database/subscription.go
type Subscription (line 9) | type Subscription struct
method Cancel (line 18) | func (s *Subscription) Cancel() error {
FILE: base/info/version.go
function init (line 26) | func init() {
type Info (line 53) | type Info struct
function Set (line 71) | func Set(setName string, setVersion string, setLicenseName string) {
function GetInfo (line 82) | func GetInfo() *Info {
function Version (line 116) | func Version() string {
function VersionNumber (line 121) | func VersionNumber() string {
function FullVersion (line 126) | func FullVersion() string {
function CondensedVersion (line 156) | func CondensedVersion() string {
function CheckVersion (line 178) | func CheckVersion() error {
FILE: base/log/formatting.go
constant maxCount (line 11) | maxCount uint16 = 999
constant timeFormat (line 12) | timeFormat string = "2006-01-02 15:04:05.000"
method String (line 15) | func (s Severity) String() string {
function formatLine (line 34) | func formatLine(line *logLine, duplicates uint64, useColor bool) string {
function formatDuplicates (line 153) | func formatDuplicates(duplicates uint64) string {
FILE: base/log/formatting_unix.go
constant rightArrow (line 6) | rightArrow = "▶"
constant leftArrow (line 7) | leftArrow = "◀"
constant colorDim (line 11) | colorDim = "\033[2m"
constant colorEndDim (line 12) | colorEndDim = "\033[22m"
constant colorRed (line 13) | colorRed = "\033[91m"
constant colorYellow (line 14) | colorYellow = "\033[93m"
constant colorBlue (line 15) | colorBlue = "\033[34m"
constant colorMagenta (line 16) | colorMagenta = "\033[35m"
constant colorCyan (line 17) | colorCyan = "\033[36m"
constant colorGreen (line 18) | colorGreen = "\033[92m"
method color (line 26) | func (s Severity) color() string {
function endColor (line 45) | func endColor() string {
function blueColor (line 49) | func blueColor() string {
function dimColor (line 53) | func dimColor() string {
function endDimColor (line 57) | func endDimColor() string {
FILE: base/log/formatting_windows.go
constant rightArrow (line 8) | rightArrow = ">"
constant leftArrow (line 9) | leftArrow = "<"
constant colorDim (line 13) | colorDim = "\033[2m"
constant colorEndDim (line 14) | colorEndDim = "\033[22m"
constant colorRed (line 15) | colorRed = "\033[91m"
constant colorYellow (line 16) | colorYellow = "\033[93m"
constant colorBlue (line 17) | colorBlue = "\033[34m"
constant colorMagenta (line 18) | colorMagenta = "\033[35m"
constant colorCyan (line 19) | colorCyan = "\033[36m"
constant colorGreen (line 20) | colorGreen = "\033[92m"
function init (line 31) | func init() {
method color (line 35) | func (s Severity) color() string {
function endColor (line 55) | func endColor() string {
function blueColor (line 62) | func blueColor() string {
function dimColor (line 69) | func dimColor() string {
function endDimColor (line 76) | func endDimColor() string {
FILE: base/log/input.go
function log (line 16) | func log(level Severity, msg string, tracer *ContextTracer) {
function fastcheck (line 82) | func fastcheck(level Severity) bool {
function Trace (line 87) | func Trace(msg string) {
function Tracef (line 94) | func Tracef(format string, things ...interface{}) {
function Debug (line 101) | func Debug(msg string) {
function Debugf (line 108) | func Debugf(format string, things ...interface{}) {
function Info (line 115) | func Info(msg string) {
function Infof (line 122) | func Infof(format string, things ...interface{}) {
function Warning (line 129) | func Warning(msg string) {
function Warningf (line 137) | func Warningf(format string, things ...interface{}) {
function Error (line 145) | func Error(msg string) {
function Errorf (line 153) | func Errorf(format string, things ...interface{}) {
function Critical (line 161) | func Critical(msg string) {
function Criticalf (line 169) | func Criticalf(format string, things ...interface{}) {
function TotalWarningLogLines (line 178) | func TotalWarningLogLines() uint64 {
function TotalErrorLogLines (line 184) | func TotalErrorLogLines() uint64 {
function TotalCriticalLogLines (line 190) | func TotalCriticalLogLines() uint64 {
FILE: base/log/logging.go
type Severity (line 35) | type Severity
method toSLogLevel (line 37) | func (s Severity) toSLogLevel() slog.Level {
method Name (line 155) | func (s Severity) Name() string {
type Message (line 59) | type Message interface
type logLine (line 67) | type logLine struct
method Text (line 76) | func (ll *logLine) Text() string {
method Severity (line 80) | func (ll *logLine) Severity() Severity {
method Time (line 84) | func (ll *logLine) Time() time.Time {
method File (line 88) | func (ll *logLine) File() string {
method LineNumber (line 92) | func (ll *logLine) LineNumber() int {
method Equal (line 96) | func (ll *logLine) Equal(ol *logLine) bool {
constant TraceLevel (line 114) | TraceLevel Severity = 1
constant DebugLevel (line 115) | DebugLevel Severity = 2
constant InfoLevel (line 116) | InfoLevel Severity = 3
constant WarningLevel (line 117) | WarningLevel Severity = 4
constant ErrorLevel (line 118) | ErrorLevel Severity = 5
constant CriticalLevel (line 119) | CriticalLevel Severity = 6
function GetLogLevel (line 142) | func GetLogLevel() Severity {
function SetLogLevel (line 147) | func SetLogLevel(level Severity) {
function ParseLevel (line 175) | func ParseLevel(level string) Severity {
function Start (line 194) | func Start(level string, logToStdout bool, logDir string) error {
function Shutdown (line 245) | func Shutdown() {
FILE: base/log/logging_test.go
function init (line 9) | func init() {
function TestLogging (line 16) | func TestLogging(t *testing.T) {
FILE: base/log/output.go
type Adapter (line 13) | type Adapter interface
function EnableScheduling (line 24) | func EnableScheduling() {
function TriggerWriter (line 31) | func TriggerWriter() {
function TriggerWriterChannel (line 41) | func TriggerWriterChannel() chan struct{} {
function startWriter (line 45) | func startWriter() {
function writeVersion (line 71) | func writeVersion() {
function writerManager (line 86) | func writerManager() {
function writer (line 99) | func writer() error {
function finalizeWriting (line 200) | func finalizeWriting() {
function addUnexpectedLogs (line 238) | func addUnexpectedLogs(line *logLine) {
function addUnexpectedLogLine (line 257) | func addUnexpectedLogLine(line *logLine) {
function GetLastUnexpectedLogs (line 269) | func GetLastUnexpectedLogs() []string {
FILE: base/log/slog.go
function setupSLog (line 14) | func setupSLog(level Severity) {
function windowsColoring (line 55) | func windowsColoring(lw *LogWriter) io.Writer {
FILE: base/log/trace.go
type ContextTracerKey (line 13) | type ContextTracerKey struct
type ContextTracer (line 16) | type ContextTracer struct
method Submit (line 54) | func (tracer *ContextTracer) Submit() {
method log (line 108) | func (tracer *ContextTracer) log(level Severity, msg string) {
method Trace (line 134) | func (tracer *ContextTracer) Trace(msg string) {
method Tracef (line 144) | func (tracer *ContextTracer) Tracef(format string, things ...interface...
method Debug (line 154) | func (tracer *ContextTracer) Debug(msg string) {
method Debugf (line 164) | func (tracer *ContextTracer) Debugf(format string, things ...interface...
method Info (line 174) | func (tracer *ContextTracer) Info(msg string) {
method Infof (line 184) | func (tracer *ContextTracer) Infof(format string, things ...interface{...
method Warning (line 194) | func (tracer *ContextTracer) Warning(msg string) {
method Warningf (line 204) | func (tracer *ContextTracer) Warningf(format string, things ...interfa...
method Error (line 214) | func (tracer *ContextTracer) Error(msg string) {
method Errorf (line 224) | func (tracer *ContextTracer) Errorf(format string, things ...interface...
method Critical (line 234) | func (tracer *ContextTracer) Critical(msg string) {
method Criticalf (line 244) | func (tracer *ContextTracer) Criticalf(format string, things ...interf...
function AddTracer (line 24) | func AddTracer(ctx context.Context) (context.Context, *ContextTracer) {
function Tracer (line 43) | func Tracer(ctx context.Context) *ContextTracer {
FILE: base/log/trace_test.go
function TestContextTracer (line 9) | func TestContextTracer(t *testing.T) {
FILE: base/log/writer.go
type LogWriter (line 14) | type LogWriter struct
method Write (line 47) | func (l *LogWriter) Write(buf []byte) (int, error) {
method WriteMessage (line 62) | func (l *LogWriter) WriteMessage(msg Message, duplicates uint64) {
method IsStdout (line 77) | func (l *LogWriter) IsStdout() bool {
method Close (line 82) | func (l *LogWriter) Close() {
function NewStdoutWriter (line 21) | func NewStdoutWriter() *LogWriter {
function NewFileWriter (line 29) | func NewFileWriter(dir string) (*LogWriter, error) {
function CleanOldLogs (line 89) | func CleanOldLogs(dir string, threshold time.Duration) error {
FILE: base/metrics/api.go
function registerAPI (line 17) | func registerAPI() error {
type metricsAPI (line 55) | type metricsAPI struct
method ReadPermission (line 57) | func (m *metricsAPI) ReadPermission(*http.Request) api.Permission { re...
method WritePermission (line 59) | func (m *metricsAPI) WritePermission(*http.Request) api.Permission { r...
method ServeHTTP (line 61) | func (m *metricsAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
function WriteMetrics (line 87) | func WriteMetrics(w io.Writer, permission api.Permission, expertiseLevel...
function writeMetricsTo (line 100) | func writeMetricsTo(ctx context.Context, url string) error {
function metricsWriter (line 141) | func metricsWriter(ctx *mgr.WorkerCtx) error {
FILE: base/metrics/config.go
function init (line 31) | func init() {
function prepConfig (line 45) | func prepConfig() error {
FILE: base/metrics/metric.go
constant prometheusBaseFormt (line 19) | prometheusBaseFormt = "[a-zA-Z_][a-zA-Z0-9_]*"
constant PrometheusFormatRequirement (line 20) | PrometheusFormatRequirement = "^" + prometheusBaseFormt + "$"
type Metric (line 26) | type Metric interface
type metricBase (line 33) | type metricBase struct
method ID (line 102) | func (m *metricBase) ID() string {
method LabeledID (line 107) | func (m *metricBase) LabeledID() string {
method Opts (line 112) | func (m *metricBase) Opts() *Options {
method WritePrometheus (line 117) | func (m *metricBase) WritePrometheus(w io.Writer) {
method buildLabeledID (line 121) | func (m *metricBase) buildLabeledID() string {
type Options (line 42) | type Options struct
function newMetricBase (line 68) | func newMetricBase(id string, labels map[string]string, opts Options) (*...
FILE: base/metrics/metric_counter.go
type Counter (line 8) | type Counter struct
method CurrentValue (line 47) | func (c *Counter) CurrentValue() uint64 {
function NewCounter (line 14) | func NewCounter(id string, labels map[string]string, opts *Options) (*Co...
FILE: base/metrics/metric_counter_fetching.go
type FetchingCounter (line 11) | type FetchingCounter struct
method CurrentValue (line 54) | func (fc *FetchingCounter) CurrentValue() uint64 {
method WritePrometheus (line 59) | func (fc *FetchingCounter) WritePrometheus(w io.Writer) {
function NewFetchingCounter (line 18) | func NewFetchingCounter(id string, labels map[string]string, fn func() u...
FILE: base/metrics/metric_export.go
type UIntMetric (line 8) | type UIntMetric interface
type FloatMetric (line 13) | type FloatMetric interface
type MetricExport (line 18) | type MetricExport struct
function ExportMetrics (line 24) | func ExportMetrics(requestPermission api.Permission) []*MetricExport {
function ExportValues (line 46) | func ExportValues(requestPermission api.Permission, internalOnly bool) m...
function getCurrentValue (line 81) | func getCurrentValue(metric Metric) any {
FILE: base/metrics/metric_gauge.go
type Gauge (line 8) | type Gauge struct
method CurrentValue (line 44) | func (g *Gauge) CurrentValue() float64 {
function NewGauge (line 14) | func NewGauge(id string, labels map[string]string, fn func() float64, op...
FILE: base/metrics/metric_histogram.go
type Histogram (line 8) | type Histogram struct
function NewHistogram (line 14) | func NewHistogram(id string, labels map[string]string, opts *Options) (*...
FILE: base/metrics/metrics_host.go
constant hostStatTTL (line 16) | hostStatTTL = 1 * time.Second
function registerHostMetrics (line 18) | func registerHostMetrics() (err error) {
function getUint64HostStat (line 72) | func getUint64HostStat(getStat func() (uint64, bool)) func() float64 {
function getFloat64HostStat (line 79) | func getFloat64HostStat(getStat func() (float64, bool)) func() float64 {
function getLoadAvg (line 92) | func getLoadAvg() *load.AvgStat {
function LoadAvg1 (line 114) | func LoadAvg1() (loadAvg float64, ok bool) {
function LoadAvg5 (line 122) | func LoadAvg5() (loadAvg float64, ok bool) {
function LoadAvg15 (line 130) | func LoadAvg15() (loadAvg float64, ok bool) {
function getMemStat (line 143) | func getMemStat() *mem.VirtualMemoryStat {
function MemTotal (line 165) | func MemTotal() (total uint64, ok bool) {
function MemUsed (line 173) | func MemUsed() (used uint64, ok bool) {
function MemAvailable (line 181) | func MemAvailable() (available uint64, ok bool) {
function MemUsedPercent (line 189) | func MemUsedPercent() (usedPercent float64, ok bool) {
function getDiskStat (line 202) | func getDiskStat() *disk.UsageStat {
function DiskTotal (line 224) | func DiskTotal() (total uint64, ok bool) {
function DiskUsed (line 232) | func DiskUsed() (used uint64, ok bool) {
function DiskFree (line 240) | func DiskFree() (free uint64, ok bool) {
function DiskUsedPercent (line 248) | func DiskUsedPercent() (usedPercent float64, ok bool) {
FILE: base/metrics/metrics_info.go
function registerInfoMetric (line 13) | func registerInfoMetric() error {
function checkUnknown (line 40) | func checkUnknown(s string) string {
FILE: base/metrics/metrics_logs.go
function registerLogMetrics (line 8) | func registerLogMetrics() (err error) {
FILE: base/metrics/metrics_runtime.go
function registerRuntimeMetric (line 17) | func registerRuntimeMetric() error {
type runtimeMetrics (line 32) | type runtimeMetrics struct
method WritePrometheus (line 36) | func (r *runtimeMetrics) WritePrometheus(w io.Writer) {
FILE: base/metrics/module.go
type Metrics (line 13) | type Metrics struct
method Manager (line 20) | func (met *Metrics) Manager() *mgr.Manager {
method Start (line 24) | func (met *Metrics) Start() error {
method Stop (line 28) | func (met *Metrics) Stop() error {
method SetSleep (line 32) | func (met *Metrics) SetSleep(enabled bool) {
function start (line 65) | func start() error {
function stop (line 103) | func stop() error {
function register (line 120) | func register(m Metric) error {
function SetNamespace (line 154) | func SetNamespace(namespace string) error {
function AddGlobalLabel (line 174) | func AddGlobalLabel(name, value string) error {
type byLabeledID (line 191) | type byLabeledID
method Len (line 193) | func (r byLabeledID) Len() int { return len(r) }
method Less (line 194) | func (r byLabeledID) Less(i, j int) bool { return r[i].LabeledID() < r...
method Swap (line 195) | func (r byLabeledID) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
function New (line 197) | func New(instance instance) (*Metrics, error) {
type instance (line 216) | type instance interface
FILE: base/metrics/persistence.go
type metricsStorage (line 32) | type metricsStorage struct
function EnableMetricPersistence (line 47) | func EnableMetricPersistence(key string) error {
method loadState (line 83) | func (c *Counter) loadState() {
function storePersistentMetrics (line 92) | func storePersistentMetrics() {
function getMetricsStorage (line 130) | func getMetricsStorage(key string) (*metricsStorage, error) {
FILE: base/notifications/cleaner.go
function cleaner (line 9) | func cleaner(ctx *mgr.WorkerCtx) error { //nolint:unparam // Conforms to...
function deleteExpiredNotifs (line 23) | func deleteExpiredNotifs() {
method isExpired (line 35) | func (n *Notification) isExpired() bool {
function getNotsCopy (line 42) | func getNotsCopy() []*Notification {
FILE: base/notifications/config.go
function registerConfig (line 13) | func registerConfig() error {
FILE: base/notifications/database.go
type StorageInterface (line 32) | type StorageInterface struct
method Get (line 56) | func (s *StorageInterface) Get(key string) (record.Record, error) {
method Query (line 81) | func (s *StorageInterface) Query(q *query.Query, local, internal bool)...
method processQuery (line 89) | func (s *StorageInterface) processQuery(q *query.Query, it *iterator.I...
method Put (line 125) | func (s *StorageInterface) Put(r record.Record) (record.Record, error) {
method Delete (line 198) | func (s *StorageInterface) Delete(key string) error {
method ReadOnly (line 216) | func (s *StorageInterface) ReadOnly() bool {
function registerAsDatabase (line 36) | func registerAsDatabase() error {
function getNotification (line 72) | func getNotification(eventID string) (n *Notification, ok bool) {
function inQuery (line 108) | func inQuery(n *Notification, q *query.Query) bool {
function applyUpdate (line 143) | func applyUpdate(n *Notification, key string) (*Notification, error) {
function EnsureNotification (line 221) | func EnsureNotification(r record.Record) (*Notification, error) {
FILE: base/notifications/module-mirror.go
method SyncWithState (line 10) | func (n *Notification) SyncWithState(state *mgr.StateMgr) {
function notifTypeToStateType (line 45) | func notifTypeToStateType(notifType Type) mgr.StateType {
FILE: base/notifications/module.go
type Notifications (line 12) | type Notifications struct
method Manager (line 19) | func (n *Notifications) Manager() *mgr.Manager {
method States (line 23) | func (n *Notifications) States() *mgr.StateMgr {
method Start (line 27) | func (n *Notifications) Start() error {
method Stop (line 31) | func (n *Notifications) Stop() error {
method NotifyInfo (line 40) | func (n *Notifications) NotifyInfo(id, title, msg string, actions ...A...
method NotifyWarn (line 49) | func (n *Notifications) NotifyWarn(id, title, msg string, actions ...A...
method NotifyError (line 58) | func (n *Notifications) NotifyError(id, title, msg string, actions ......
method NotifyPrompt (line 67) | func (n *Notifications) NotifyPrompt(id, title, msg string, actions .....
method Notify (line 72) | func (n *Notifications) Notify(notification *Notification) *Notificati...
function prep (line 76) | func prep() error {
function start (line 80) | func start() error {
function showConfigLoadingErrors (line 92) | func showConfigLoadingErrors() {
function New (line 133) | func New(instance instance) (*Notifications, error) {
type instance (line 152) | type instance interface
FILE: base/notifications/notification.go
type Type (line 16) | type Type
constant Info (line 20) | Info Type = 0
constant Warning (line 21) | Warning Type = 1
constant Prompt (line 22) | Prompt Type = 2
constant Error (line 23) | Error Type = 3
type State (line 27) | type State
type NotificationActionFn (line 31) | type NotificationActionFn
constant Active (line 39) | Active State = "active"
constant Responded (line 43) | Responded State = "responded"
constant Executed (line 46) | Executed State = "executed"
type Notification (line 50) | type Notification struct
method Save (line 287) | func (n *Notification) Save() {
method save (line 293) | func (n *Notification) save(pushUpdate bool) {
method SetActionFunction (line 361) | func (n *Notification) SetActionFunction(fn NotificationActionFn) *Not...
method Response (line 369) | func (n *Notification) Response() <-chan string {
method Update (line 381) | func (n *Notification) Update(expires int64) {
method Delete (line 409) | func (n *Notification) Delete() {
method delete (line 426) | func (n *Notification) delete(pushUpdate bool) {
method Expired (line 471) | func (n *Notification) Expired() <-chan struct{} {
method selectAndExecuteAction (line 483) | func (n *Notification) selectAndExecuteAction(id string) {
method Lock (line 530) | func (n *Notification) Lock() {
method Unlock (line 540) | func (n *Notification) Unlock() {
type Action (line 113) | type Action struct
type ActionVisibility (line 131) | type ActionVisibility
constant ActionVisibilityDefault (line 135) | ActionVisibilityDefault ActionVisibility = ""
constant ActionVisibilityDetailed (line 138) | ActionVisibilityDetailed ActionVisibility = "detailed"
constant ActionVisibilityInAppOnly (line 140) | ActionVisibilityInAppOnly ActionVisibility = "in-app-only"
type ActionType (line 144) | type ActionType
constant ActionTypeNone (line 148) | ActionTypeNone = ""
constant ActionTypeOpenURL (line 149) | ActionTypeOpenURL = "open-url"
constant ActionTypeOpenPage (line 150) | ActionTypeOpenPage = "open-page"
constant ActionTypeOpenSetting (line 151) | ActionTypeOpenSetting = "open-setting"
constant ActionTypeOpenProfile (line 152) | ActionTypeOpenProfile = "open-profile"
constant ActionTypeInjectEvent (line 153) | ActionTypeInjectEvent = "inject-event"
constant ActionTypeWebhook (line 154) | ActionTypeWebhook = "call-webhook"
type ActionTypeOpenSettingPayload (line 158) | type ActionTypeOpenSettingPayload struct
type ActionTypeWebhookPayload (line 167) | type ActionTypeWebhookPayload struct
function Get (line 184) | func Get(id string) *Notification {
function Delete (line 195) | func Delete(id string) {
function NotifyInfo (line 215) | func NotifyInfo(id, title, msg string, actions ...Action) *Notification {
function NotifyWarn (line 224) | func NotifyWarn(id, title, msg string, actions ...Action) *Notification {
function NotifyError (line 233) | func NotifyError(id, title, msg string, actions ...Action) *Notification {
function NotifyPrompt (line 242) | func NotifyPrompt(id, title, msg string, actions ...Action) *Notification {
function notify (line 246) | func notify(nType Type, id, title, msg string, showOnSystem bool, action...
function Notify (line 277) | func Notify(n *Notification) *Notification {
FILE: base/rng/entropy.go
constant minFeedEntropy (line 13) | minFeedEntropy = 256
type Feeder (line 19) | type Feeder struct
method NeedsEntropy (line 43) | func (f *Feeder) NeedsEntropy() bool {
method SupplyEntropy (line 48) | func (f *Feeder) SupplyEntropy(data []byte, entropy int) {
method SupplyEntropyIfNeeded (line 56) | func (f *Feeder) SupplyEntropyIfNeeded(data []byte, entropy int) {
method SupplyEntropyAsInt (line 71) | func (f *Feeder) SupplyEntropyAsInt(n int64, entropy int) {
method SupplyEntropyAsIntIfNeeded (line 78) | func (f *Feeder) SupplyEntropyAsIntIfNeeded(n int64, entropy int) {
method CloseFeeder (line 87) | func (f *Feeder) CloseFeeder() {
method run (line 91) | func (f *Feeder) run(ctx *mgr.WorkerCtx) error {
type entropyData (line 26) | type entropyData struct
function NewFeeder (line 32) | func NewFeeder() *Feeder {
FILE: base/rng/entropy_test.go
function TestFeeder (line 8) | func TestFeeder(t *testing.T) {
FILE: base/rng/fullfeed.go
function getFullFeedDuration (line 9) | func getFullFeedDuration() time.Duration {
function fullFeeder (line 21) | func fullFeeder(ctx *mgr.WorkerCtx) error {
FILE: base/rng/fullfeed_test.go
function TestFullFeeder (line 7) | func TestFullFeeder(t *testing.T) {
FILE: base/rng/get.go
constant reseedAfterSeconds (line 12) | reseedAfterSeconds = 600
constant reseedAfterBytes (line 13) | reseedAfterBytes = 1048576
type reader (line 25) | type reader struct
method Read (line 62) | func (r reader) Read(b []byte) (n int, err error) {
function init (line 27) | func init() {
function checkEntropy (line 31) | func checkEntropy() (err error) {
function Read (line 50) | func Read(b []byte) (n int, err error) {
function Bytes (line 67) | func Bytes(n int) ([]byte, error) {
function Number (line 79) | func Number(max uint64) (uint64, error) {
FILE: base/rng/get_test.go
function TestNumberRandomness (line 7) | func TestNumberRandomness(t *testing.T) {
FILE: base/rng/osfeeder.go
function osFeeder (line 10) | func osFeeder(ctx *mgr.WorkerCtx) error {
FILE: base/rng/rng.go
type Rng (line 19) | type Rng struct
method Manager (line 46) | func (r *Rng) Manager() *mgr.Manager {
method Start (line 51) | func (r *Rng) Start() error {
method Stop (line 91) | func (r *Rng) Stop() error {
function newCipher (line 34) | func newCipher(key []byte) (cipher.Block, error) {
function New (line 101) | func New(instance instance) (*Rng, error) {
type instance (line 114) | type instance interface
FILE: base/rng/rng_test.go
function init (line 7) | func init() {
function TestRNG (line 20) | func TestRNG(t *testing.T) {
FILE: base/rng/tickfeeder.go
function getTickFeederTickDuration (line 10) | func getTickFeederTickDuration() time.Duration {
function tickFeeder (line 35) | func tickFeeder(ctx *mgr.WorkerCtx) error {
FILE: base/runtime/module.go
type Runtime (line 15) | type Runtime struct
method Manager (line 20) | func (r *Runtime) Manager() *mgr.Manager {
method Start (line 24) | func (r *Runtime) Start() error {
method Stop (line 42) | func (r *Runtime) Stop() error {
function Register (line 48) | func Register(key string, provider ValueProvider) (PushFunc, error) {
function New (line 57) | func New(instance instance) (*Runtime, error) {
type instance (line 71) | type instance interface
FILE: base/runtime/provider.go
type PushFunc (line 24) | type PushFunc
type ValueProvider (line 28) | type ValueProvider interface
type SimpleValueSetterFunc (line 43) | type SimpleValueSetterFunc
method Set (line 51) | func (fn SimpleValueSetterFunc) Set(r record.Record) (record.Record, e...
method Get (line 56) | func (SimpleValueSetterFunc) Get(_ string) ([]record.Record, error) {
type SimpleValueGetterFunc (line 47) | type SimpleValueGetterFunc
method Set (line 61) | func (SimpleValueGetterFunc) Set(r record.Record) (record.Record, erro...
method Get (line 66) | func (fn SimpleValueGetterFunc) Get(keyOrPrefix string) ([]record.Reco...
FILE: base/runtime/registry.go
type Registry (line 41) | type Registry struct
method DatabaseName (line 69) | func (r *Registry) DatabaseName() string {
method InjectAsDatabase (line 78) | func (r *Registry) InjectAsDatabase(name string) error {
method Register (line 101) | func (r *Registry) Register(keyOrPrefix string, p ValueProvider) (Push...
method Get (line 148) | func (r *Registry) Get(key string) (record.Record, error) {
method Put (line 179) | func (r *Registry) Put(m record.Record) (record.Record, error) {
method Query (line 197) | func (r *Registry) Query(q *query.Query, local, internal bool) (*itera...
method getMatchingProvider (line 268) | func (r *Registry) getMatchingProvider(key string) *keyedValueProvider {
method collectProviderByPrefix (line 284) | func (r *Registry) collectProviderByPrefix(prefix string) []*keyedValu...
method GetRegistrationKeys (line 305) | func (r *Registry) GetRegistrationKeys() []string {
method asStorage (line 320) | func (r *Registry) asStorage() storage.Interface {
type keyedValueProvider (line 50) | type keyedValueProvider struct
function NewRegistry (line 56) | func NewRegistry() *Registry {
function isPrefixKey (line 62) | func isPrefixKey(key string) bool {
function recovery (line 326) | func recovery(err *error) {
FILE: base/runtime/registry_test.go
type testRecord (line 15) | type testRecord struct
function makeTestRecord (line 21) | func makeTestRecord(key, value string) record.Record {
type testProvider (line 28) | type testProvider struct
method Get (line 33) | func (tp *testProvider) Get(key string) ([]record.Record, error) {
method Set (line 37) | func (tp *testProvider) Set(r record.Record) (record.Record, error) {
function getTestRegistry (line 41) | func getTestRegistry(t *testing.T) *Registry {
function TestRegistryGet (line 74) | func TestRegistryGet(t *testing.T) {
function TestRegistryQuery (line 103) | func TestRegistryQuery(t *testing.T) {
function TestRegistryRegister (line 129) | func TestRegistryRegister(t *testing.T) {
FILE: base/runtime/singe_record_provider.go
type singleRecordReader (line 8) | type singleRecordReader struct
method Set (line 33) | func (sr *singleRecordReader) Set(_ record.Record) (record.Record, err...
method Get (line 39) | func (sr *singleRecordReader) Get(keyOrPrefix string) ([]record.Record...
function ProvideRecord (line 28) | func ProvideRecord(r record.Record) ValueProvider {
FILE: base/runtime/storage.go
type storageWrapper (line 15) | type storageWrapper struct
method Get (line 20) | func (sw *storageWrapper) Get(key string) (record.Record, error) {
method Put (line 24) | func (sw *storageWrapper) Put(r record.Record) (record.Record, error) {
method Query (line 28) | func (sw *storageWrapper) Query(q *query.Query, local, internal bool) ...
method ReadOnly (line 32) | func (sw *storageWrapper) ReadOnly() bool { return false }
FILE: base/runtime/trace_provider.go
type traceValueProvider (line 13) | type traceValueProvider struct
method Set (line 23) | func (tvp *traceValueProvider) Set(r record.Record) (res record.Record...
method Get (line 31) | func (tvp *traceValueProvider) Get(keyOrPrefix string) (records []reco...
function TraceProvider (line 19) | func TraceProvider(vp ValueProvider) ValueProvider {
FILE: base/template/module.go
type Template (line 11) | type Template struct
method Manager (line 58) | func (t *Template) Manager() *mgr.Manager {
method States (line 63) | func (t *Template) States() *mgr.StateMgr {
method Start (line 68) | func (t *Template) Start() error {
type instance (line 22) | type instance interface
function New (line 25) | func New(instance instance) (*Template, error) {
function Stop (line 76) | func Stop() error {
function serviceWorker (line 80) | func serviceWorker(w *mgr.WorkerCtx) error {
function do (line 94) | func do() error {
FILE: base/utils/atomic.go
type AtomicFileOptions (line 15) | type AtomicFileOptions struct
function CreateAtomic (line 31) | func CreateAtomic(dest string, r io.Reader, opts *AtomicFileOptions) err...
function CopyFileAtomic (line 62) | func CopyFileAtomic(dest string, src string, opts *AtomicFileOptions) er...
function ReplaceFileAtomic (line 90) | func ReplaceFileAtomic(dest string, src string, opts *AtomicFileOptions)...
FILE: base/utils/broadcastflag.go
type BroadcastFlag (line 10) | type BroadcastFlag struct
method NewFlag (line 39) | func (bf *BroadcastFlag) NewFlag() *Flag {
method NotifyAndReset (line 51) | func (bf *BroadcastFlag) NotifyAndReset() {
type Flag (line 19) | type Flag struct
method Signal (line 66) | func (f *Flag) Signal() <-chan struct{} {
method IsSet (line 72) | func (f *Flag) IsSet() bool {
method Refresh (line 77) | func (f *Flag) Refresh() {
function NewBroadcastFlag (line 27) | func NewBroadcastFlag() *BroadcastFlag {
FILE: base/utils/call_limiter.go
type CallLimiter (line 10) | type CallLimiter struct
method Do (line 31) | func (l *CallLimiter) Do(f func()) {
method lead (line 60) | func (l *CallLimiter) lead(f func()) {
function NewCallLimiter (line 22) | func NewCallLimiter(minPause time.Duration) *CallLimiter {
FILE: base/utils/call_limiter2.go
type CallLimiter2 (line 10) | type CallLimiter2 struct
method Do (line 31) | func (l *CallLimiter2) Do(f func()) {
method waitAndExec (line 54) | func (l *CallLimiter2) waitAndExec(f func()) {
function NewCallLimiter2 (line 22) | func NewCallLimiter2(minPause time.Duration) *CallLimiter2 {
FILE: base/utils/call_limiter_test.go
function TestCallLimiter (line 12) | func TestCallLimiter(t *testing.T) {
FILE: base/utils/debug/debug.go
type Info (line 16) | type Info struct
method AddSection (line 46) | func (di *Info) AddSection(name string, flags InfoFlag, content ...str...
method AddVersionInfo (line 84) | func (di *Info) AddVersionInfo() {
method AddGoroutineStack (line 93) | func (di *Info) AddGoroutineStack() {
method AddLastUnexpectedLogs (line 114) | func (di *Info) AddLastUnexpectedLogs() {
type InfoFlag (line 22) | type InfoFlag
constant NoFlags (line 26) | NoFlags InfoFlag = 0
constant UseCodeSection (line 29) | UseCodeSection InfoFlag = 1
constant AddContentLineBreaks (line 33) | AddContentLineBreaks InfoFlag = 2
function useCodeSection (line 36) | func useCodeSection(flags InfoFlag) bool {
function addContentLineBreaks (line 40) | func addContentLineBreaks(flags InfoFlag) bool {
FILE: base/utils/debug/debug_default.go
method AddPlatformInfo (line 13) | func (di *Info) AddPlatformInfo(ctx context.Context) {
FILE: base/utils/fs.go
constant isWindows (line 12) | isWindows = runtime.GOOS == "windows"
function EnsureDirectory (line 16) | func EnsureDirectory(path string, perm FSPermission) error {
function PathExists (line 60) | func PathExists(path string) bool {
FILE: base/utils/mimetypes.go
function MimeTypeByExtension (line 13) | func MimeTypeByExtension(ext string) (mimeType string, ok bool) {
FILE: base/utils/onceagain.go
type OnceAgain (line 17) | type OnceAgain struct
method Do (line 51) | func (o *OnceAgain) Do(f func()) {
method doSlow (line 72) | func (o *OnceAgain) doSlow(f func()) {
FILE: base/utils/onceagain_test.go
function TestOnceAgain (line 12) | func TestOnceAgain(t *testing.T) {
FILE: base/utils/osdetail/colors_windows.go
function EnableColorSupport (line 17) | func EnableColorSupport() bool {
function enableColorSupport (line 28) | func enableColorSupport() bool {
FILE: base/utils/osdetail/command.go
function RunCmd (line 11) | func RunCmd(command ...string) (output []byte, err error) {
FILE: base/utils/osdetail/dnscache_windows.go
function EnableDNSCache (line 9) | func EnableDNSCache() error {
function DisableDNSCache (line 15) | func DisableDNSCache() error {
FILE: base/utils/osdetail/service_windows.go
constant StatusUnknown (line 13) | StatusUnknown uint8 = iota
constant StatusRunningStoppable (line 14) | StatusRunningStoppable
constant StatusRunningNotStoppable (line 15) | StatusRunningNotStoppable
constant StatusStartPending (line 16) | StatusStartPending
constant StatusStopPending (line 17) | StatusStopPending
constant StatusStopped (line 18) | StatusStopped
function GetServiceStatus (line 27) | func GetServiceStatus(name string) (status uint8, err error) {
function StopService (line 53) | func StopService(name string) (err error) {
function SartService (line 85) | func SartService(name string) (err error) {
FILE: base/utils/osdetail/shell_windows.go
function RunPowershellCmd (line 9) | func RunPowershellCmd(script string) (output []byte, err error) {
constant outputSeparator (line 20) | outputSeparator = "pwzzhtuvpwdgozhzbnjj"
function RunTerminalCmd (line 24) | func RunTerminalCmd(command ...string) (output []byte, err error) {
FILE: base/utils/osdetail/svchost_windows.go
function GetServiceNames (line 25) | func GetServiceNames(pid int32) ([]string, error) {
function GetAllServiceNames (line 50) | func GetAllServiceNames() (map[int32][]string, error) {
FILE: base/utils/osdetail/version_windows.go
function WindowsNTVersion (line 23) | func WindowsNTVersion() (string, error) {
function IsAtLeastWindowsNTVersion (line 50) | func IsAtLeastWindowsNTVersion(v string) (bool, error) {
function IsAtLeastWindowsNTVersionWithDefault (line 65) | func IsAtLeastWindowsNTVersionWithDefault(v string, defaultValue bool) b...
function IsAtLeastWindowsVersion (line 74) | func IsAtLeastWindowsVersion(v string) (bool, error) {
function IsAtLeastWindowsVersionWithDefault (line 93) | func IsAtLeastWindowsVersionWithDefault(v string, defaultValue bool) bool {
FILE: base/utils/osdetail/version_windows_test.go
function TestWindowsNTVersion (line 5) | func TestWindowsNTVersion(t *testing.T) {
function TestIsAtLeastWindowsNTVersion (line 11) | func TestIsAtLeastWindowsNTVersion(t *testing.T) {
function TestIsAtLeastWindowsVersion (line 21) | func TestIsAtLeastWindowsVersion(t *testing.T) {
FILE: base/utils/permissions.go
function SetFilePermission (line 8) | func SetFilePermission(path string, perm FSPermission) error {
FILE: base/utils/permissions_windows.go
function init (line 16) | func init() {
function SetFilePermission (line 35) | func SetFilePermission(path string, perm FSPermission) error {
FILE: base/utils/renameio/example_test.go
function ExampleTempFile_justone (line 10) | func ExampleTempFile_justone() { //nolint:testableexamples
function ExampleTempFile_many (line 31) | func ExampleTempFile_many() { //nolint:testableexamples
FILE: base/utils/renameio/symlink_test.go
function TestSymlink (line 12) | func TestSymlink(t *testing.T) {
FILE: base/utils/renameio/tempfile.go
function TempDir (line 17) | func TempDir(dest string) string {
function tempDir (line 21) | func tempDir(dir, dest string) string {
type PendingFile (line 65) | type PendingFile struct
method Cleanup (line 75) | func (t *PendingFile) Cleanup() error {
method CloseAtomicallyReplace (line 95) | func (t *PendingFile) CloseAtomicallyReplace() error {
function TempFile (line 128) | func TempFile(dir, path string) (*PendingFile, error) {
function Symlink (line 139) | func Symlink(oldname, newname string) error {
FILE: base/utils/renameio/tempfile_linux_test.go
function TestTempDir (line 12) | func TestTempDir(t *testing.T) {
FILE: base/utils/renameio/writefile.go
function WriteFile (line 12) | func WriteFile(filename string, data []byte, perm os.FileMode) error {
FILE: base/utils/renameio/writefile_test.go
function TestWriteFile (line 12) | func TestWriteFile(t *testing.T) {
FILE: base/utils/safe.go
function SafeFirst16Bytes (line 9) | func SafeFirst16Bytes(data []byte) string {
function SafeFirst16Chars (line 21) | func SafeFirst16Chars(s string) string {
FILE: base/utils/safe_test.go
function TestSafeFirst16 (line 9) | func TestSafeFirst16(t *testing.T) {
FILE: base/utils/slices.go
function IndexOfString (line 4) | func IndexOfString(a []string, s string) int {
function StringInSlice (line 14) | func StringInSlice(a []string, s string) bool {
function RemoveFromStringSlice (line 19) | func RemoveFromStringSlice(a []string, s string) []string {
function DuplicateStrings (line 28) | func DuplicateStrings(a []string) []string {
function StringSliceEqual (line 35) | func StringSliceEqual(a []string, b []string) bool {
function DuplicateBytes (line 48) | func DuplicateBytes(a []byte) []byte {
FILE: base/utils/slices_test.go
function TestStringInSlice (line 15) | func TestStringInSlice(t *testing.T) {
function TestRemoveFromStringSlice (line 39) | func TestRemoveFromStringSlice(t *testing.T) {
function TestDuplicateStrings (line 53) | func TestDuplicateStrings(t *testing.T) {
function TestStringSliceEqual (line 66) | func TestStringSliceEqual(t *testing.T) {
function TestDuplicateBytes (line 80) | func TestDuplicateBytes(t *testing.T) {
FILE: base/utils/stablepool.go
type StablePool (line 16) | type StablePool struct
method Put (line 31) | func (p *StablePool) Put(x interface{}) {
method Get (line 70) | func (p *StablePool) Get() interface{} {
method Size (line 105) | func (p *StablePool) Size() int {
method Max (line 113) | func (p *StablePool) Max() int {
FILE: base/utils/stablepool_test.go
function TestStablePoolRealWorld (line 12) | func TestStablePoolRealWorld(t *testing.T) {
function TestStablePoolFuzzing (line 75) | func TestStablePoolFuzzing(t *testing.T) {
function TestStablePoolBreaking (line 103) | func TestStablePoolBreaking(t *testing.T) {
FILE: base/utils/structure.go
type FSPermission (line 11) | type FSPermission
method AsUnixPermission (line 23) | func (perm FSPermission) AsUnixPermission() fs.FileMode {
method IsExecPermission (line 42) | func (perm FSPermission) IsExecPermission() bool {
constant AdminOnlyPermission (line 14) | AdminOnlyPermission FSPermission = iota
constant AdminOnlyExecPermission (line 15) | AdminOnlyExecPermission
constant PublicReadPermission (line 16) | PublicReadPermission
constant PublicReadExecPermission (line 17) | PublicReadExecPermission
constant PublicWritePermission (line 18) | PublicWritePermission
constant PublicWriteExecPermission (line 19) | PublicWriteExecPermission
type DirStructure (line 51) | type DirStructure struct
method ChildDir (line 71) | func (ds *DirStructure) ChildDir(dirName string, perm FSPermission) (c...
method Ensure (line 95) | func (ds *DirStructure) Ensure() error {
method EnsureRelPath (line 100) | func (ds *DirStructure) EnsureRelPath(dirPath string) error {
method EnsureRelDir (line 105) | func (ds *DirStructure) EnsureRelDir(dirNames ...string) error {
method EnsureAbsPath (line 111) | func (ds *DirStructure) EnsureAbsPath(dirPath string) error {
method ensure (line 146) | func (ds *DirStructure) ensure(pathDirs []string) error {
function NewDirStructure (line 62) | func NewDirStructure(path string, perm FSPermission) *DirStructure {
FILE: base/utils/structure_test.go
function ExampleDirStructure (line 12) | func ExampleDirStructure() {
FILE: base/utils/uuid.go
function RandomUUID (line 16) | func RandomUUID(ns string) uuid.UUID {
function DerivedUUID (line 32) | func DerivedUUID(input string) uuid.UUID {
function DerivedInstanceUUID (line 37) | func DerivedInstanceUUID(input string) uuid.UUID {
function uuidFromTime (line 41) | func uuidFromTime() uuid.UUID {
FILE: base/utils/uuid_test.go
function TestUUID (line 10) | func TestUUID(t *testing.T) {
FILE: cmds/cmdbase/service.go
type SystemService (line 27) | type SystemService interface
type ServiceInstance (line 33) | type ServiceInstance interface
function RunService (line 56) | func RunService(cmd *cobra.Command, args []string) {
function printStackTo (line 161) | func printStackTo(writer io.Writer, msg string) {
function triggerSystemReboot (line 171) | func triggerSystemReboot() (success bool) {
FILE: cmds/cmdbase/service_linux.go
type LinuxSystemService (line 16) | type LinuxSystemService struct
method Run (line 24) | func (s *LinuxSystemService) Run() {
method RestartService (line 94) | func (s *LinuxSystemService) RestartService() error {
method IsService (line 112) | func (s *LinuxSystemService) IsService() bool {
function NewSystemService (line 20) | func NewSystemService(instance ServiceInstance) *LinuxSystemService {
FILE: cmds/cmdbase/service_windows.go
constant serviceName (line 22) | serviceName = "PortmasterCore"
type WindowsSystemService (line 24) | type WindowsSystemService struct
method Run (line 32) | func (s *WindowsSystemService) Run() {
method Execute (line 58) | func (s *WindowsSystemService) Execute(args []string, changeRequests <...
method IsService (line 182) | func (s *WindowsSystemService) IsService() bool {
method RestartService (line 190) | func (s *WindowsSystemService) RestartService() error {
function NewSystemService (line 28) | func NewSystemService(instance ServiceInstance) *WindowsSystemService {
function serviceCmdName (line 211) | func serviceCmdName(cmd svc.Cmd) string {
FILE: cmds/cmdbase/update.go
function update (line 22) | func update(cmd *cobra.Command, args []string) error {
type updateDummyInstance (line 70) | type updateDummyInstance struct
method Restart (line 72) | func (udi *updateDummyInstance) Restart() ...
method Shutdown (line 73) | func (udi *updateDummyInstance) Shutdown() ...
method Notifications (line 74) | func (udi *updateDummyInstance) Notifications() *notifications.Notific...
method UI (line 75) | func (udi *updateDummyInstance) UI() *ui.UI ...
FILE: cmds/cmdbase/version.go
function Version (line 17) | func Version(cmd *cobra.Command, args []string) error {
FILE: cmds/integrationtest/main.go
function main (line 14) | func main() {
FILE: cmds/integrationtest/netstate.go
function init (line 15) | func init() {
function netState (line 35) | func netState(cmd *cobra.Command, args []string) error {
function netStateMonitor (line 59) | func netStateMonitor(cmd *cobra.Command, args []string) error {
function checkAndPrintConnectionInfoIfNew (line 70) | func checkAndPrintConnectionInfoIfNew(ipv packet.IPVersion, p packet.IPP...
function checkAndPrintBindInfoIfNew (line 84) | func checkAndPrintBindInfoIfNew(ipv packet.IPVersion, p packet.IPProtoco...
function checkAndPrintSocketInfoIfNew (line 96) | func checkAndPrintSocketInfoIfNew(c string, s socket.Info) {
FILE: cmds/trafficgen/main.go
constant dnsResolver (line 15) | dnsResolver = "1.1.1.1:53"
function init (line 24) | func init() {
function main (line 31) | func main() {
function makeHTTPRequest (line 57) | func makeHTTPRequest(i int) {
function lookupDomain (line 79) | func lookupDomain(i int) {
FILE: cmds/winkext-test/main.go
function init (line 30) | func init() {
function main (line 37) | func main() {
function handlePackets (line 123) | func handlePackets() {
FILE: cmds/winkext-test/main_linux.go
function main (line 8) | func main() {
FILE: desktop/angular/e2e/protractor.conf.js
method onPrepare (line 26) | onPrepare() {
FILE: desktop/angular/e2e/src/app.po.ts
class AppPage (line 3) | class AppPage {
method navigateTo (line 4) | navigateTo(): Promise<unknown> {
method getTitleText (line 8) | getTitleText(): Promise<string> {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/app-routing.module.ts
class AppRoutingModule (line 15) | class AppRoutingModule { }
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/app.component.ts
class AppComponent (line 13) | class AppComponent implements OnInit {
method constructor (line 16) | constructor(
method ngOnInit (line 23) | ngOnInit(): void {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/app.module.ts
class AppModule (line 39) | class AppModule { }
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/domain-list/domain-list.component.ts
type DomainRequests (line 6) | interface DomainRequests {
class ExtDomainListComponent (line 25) | class ExtDomainListComponent implements OnInit {
method constructor (line 28) | constructor(
method ngOnInit (line 33) | ngOnInit() {
method updateRequests (line 58) | updateRequests(req: Request[]) {
method loadRequests (line 112) | private loadRequests() {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/header/header.component.ts
class ExtHeaderComponent (line 9) | class ExtHeaderComponent { }
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/interceptor.ts
class AuthIntercepter (line 7) | class AuthIntercepter implements HttpInterceptor {
method constructor (line 14) | constructor() {
method intercept (line 32) | intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEv...
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/request-interceptor.service.ts
class RequestInterceptorService (line 9) | class RequestInterceptorService {
method onUrlRequested (line 17) | get onUrlRequested() {
method onUrlBlocked (line 22) | get onUrlBlocked() {
method constructor (line 26) | constructor() {
method registerCallbacks (line 30) | private registerCallbacks() {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/welcome/intro.component.ts
class IntroComponent (line 16) | class IntroComponent {
method constructor (line 21) | constructor(
method authorizeExtension (line 26) | authorizeExtension() {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/app/welcome/welcome.module.ts
class WelcomeModule (line 18) | class WelcomeModule { }
FILE: desktop/angular/projects/portmaster-chrome-extension/src/background.ts
class BackgroundService (line 6) | class BackgroundService {
method constructor (line 13) | constructor() {
method handleMessage (line 51) | private handleMessage(msg: CallRequest, sender: chrome.runtime.Message...
method handleListRequests (line 85) | private async handleListRequests(msg: ListRequests): Promise<Request[]> {
method handleOnBeforeRequest (line 105) | private handleOnBeforeRequest(details: chrome.webRequest.WebRequestDet...
method handleOnErrorOccured (line 112) | private handleOnErrorOccured(details: chrome.webRequest.WebResponseErr...
method mustGetTab (line 119) | private mustGetTab({ tabId }: { tabId: number }): TabTracker {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/background/commands.ts
type ListRequests (line 3) | interface ListRequests {
type NotifyRequests (line 9) | interface NotifyRequests {
type CallRequest (line 14) | type CallRequest = ListRequests;
FILE: desktop/angular/projects/portmaster-chrome-extension/src/background/tab-tracker.ts
type Request (line 3) | interface Request {
class TabTracker (line 20) | class TabTracker {
method constructor (line 30) | constructor(public readonly tabId: number) { }
method allRequests (line 33) | allRequests(): Request[] {
method forDomain (line 38) | forDomain(domain: string): Request[] {
method trackRequest (line 47) | trackRequest(details: chrome.webRequest.WebRequestDetails) {
method trackError (line 90) | trackError(errorDetails: chrome.webRequest.WebResponseErrorDetails) {
method clearState (line 121) | private clearState() {
FILE: desktop/angular/projects/portmaster-chrome-extension/src/background/tab-utils.ts
function getCurrentTab (line 3) | function getCurrentTab(): Promise<chrome.tabs.Tab> {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/app-profile.service.ts
class AppProfileService (line 19) | class AppProfileService {
method constructor (line 22) | constructor(
method getKey (line 43) | getKey(idOrSourceOrProfile: string | AppProfile, id?: string): string {
method getAppProfile (line 72) | getAppProfile(
method setProfileIcon (line 89) | setProfileIcon(
method getAppProfileFromKey (line 109) | getAppProfileFromKey(key: string): Observable<AppProfile> {
method globalConfig (line 116) | globalConfig(): Observable<FlatConfigObject> {
method tagDescriptions (line 123) | tagDescriptions(): Observable<TagDescription[]> {
method watchAppProfile (line 144) | watchAppProfile(sourceAndId: string, id?: string): Observable<AppProfi...
method saveLocalProfile (line 181) | saveLocalProfile(profile: AppProfile): Observable<void> {
method saveProfile (line 190) | saveProfile(profile: AppProfile): Observable<void> {
method watchProfiles (line 201) | watchProfiles(): Observable<AppProfile[]> {
method watchLayeredProfile (line 215) | watchLayeredProfile(
method getLayeredProfile (line 234) | getLayeredProfile(profile: AppProfile): Observable<LayeredProfile> {
method deleteProfile (line 244) | deleteProfile(profile: AppProfile): Observable<void> {
method getProcessesByProfile (line 248) | getProcessesByProfile(profileOrId: AppProfile | string): Observable<Pr...
method getProcessByPid (line 256) | getProcessByPid(pid: number): Observable<Process> {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/app-profile.types.ts
type ConfigMap (line 5) | interface ConfigMap {
type ConfigObject (line 9) | type ConfigObject = OptionValueType | ConfigMap;
type FlatConfigObject (line 11) | interface FlatConfigObject {
type LayeredProfile (line 16) | interface LayeredProfile extends Record {
type FingerprintType (line 26) | enum FingerprintType {
type FingerpringOperation (line 33) | enum FingerpringOperation {
type Fingerprint (line 39) | interface Fingerprint {
type TagDescription (line 46) | interface TagDescription {
type Icon (line 52) | interface Icon {
type AppProfile (line 58) | interface AppProfile extends Record {
function flattenProfileConfig (line 79) | function flattenProfileConfig(
function getAppSetting (line 113) | function getAppSetting<T extends OptionValueType>(
function getActualValue (line 145) | function getActualValue<S extends BaseSetting<any, any>>(
function setAppSetting (line 164) | function setAppSetting(obj: ConfigObject, path: string, value: any) {
function isConfigMap (line 192) | function isConfigMap(v: any): v is ConfigMap {
function mergeObjects (line 203) | function mergeObjects(
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/config.service.ts
class ConfigService (line 11) | class ConfigService {
method constructor (line 23) | constructor(private portapi: PortapiService) {
method get (line 35) | get(key: string): Observable<Setting> {
method query (line 47) | query(query: string): Observable<Setting[]> {
method save (line 71) | save(s: Setting | string, v?: any): Observable<void> {
method watch (line 86) | watch<T extends Setting>(key: string): Observable<SettingValueType<T>> {
method validate (line 102) | validate<S extends Setting>(spec: S, value: SettingValueType<S>) {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/config.types.ts
type ExpertiseLevel (line 8) | enum ExpertiseLevel {
type ExpertiseLevelNumber (line 14) | enum ExpertiseLevelNumber {
function getExpertiseLevelNumber (line 20) | function getExpertiseLevelNumber(lvl: ExpertiseLevel): ExpertiseLevelNum...
type OptionType (line 37) | enum OptionType {
function optionTypeName (line 49) | function optionTypeName(opt: OptionType): string {
type OptionValueType (line 63) | type OptionValueType = string | string[] | number | boolean;
function isStringType (line 66) | function isStringType(opt: OptionType, vt: OptionValueType): vt is string {
function isStringArrayType (line 71) | function isStringArrayType(opt: OptionType, vt: OptionValueType): vt is ...
function isNumberType (line 76) | function isNumberType(opt: OptionType, vt: OptionValueType): vt is number {
function isBooleanType (line 81) | function isBooleanType(opt: OptionType, vt: OptionValueType): vt is bool...
type ReleaseLevel (line 89) | enum ReleaseLevel {
function releaseLevelFromName (line 95) | function releaseLevelFromName(name: 'stable' | 'beta' | 'experimental'):...
function releaseLevelName (line 112) | function releaseLevelName(level: ReleaseLevel): string {
type ExternalOptionHint (line 128) | enum ExternalOptionHint {
type WellKnown (line 137) | enum WellKnown {
type Annotations (line 156) | interface Annotations<T extends OptionValueType> {
type PossilbeValue (line 173) | interface PossilbeValue<T = any> {
type QuickSetting (line 182) | interface QuickSetting<T extends OptionValueType> {
type CountrySelectionQuickSetting (line 192) | interface CountrySelectionQuickSetting<T extends OptionValueType> extend...
type ValueRequirement (line 198) | interface ValueRequirement {
type BaseSetting (line 208) | interface BaseSetting<T extends OptionValueType, O extends OptionType> e...
type IntSetting (line 245) | type IntSetting = BaseSetting<number, OptionType.Int>;
type StringSetting (line 246) | type StringSetting = BaseSetting<string, OptionType.String>;
type StringArraySetting (line 247) | type StringArraySetting = BaseSetting<string[], OptionType.StringArray>;
type BoolSetting (line 248) | type BoolSetting = BaseSetting<boolean, OptionType.Bool>;
function applyQuickSetting (line 256) | function applyQuickSetting<V extends OptionValueType>(current: V | null,...
function parseSupportedValues (line 289) | function parseSupportedValues<S extends Setting>(s: S): SettingValueType...
function isDefaultValue (line 324) | function isDefaultValue<T extends OptionValueType>(value: T | undefined ...
type SettingValueType (line 343) | type SettingValueType<S extends Setting> = S extends { DefaultValue: inf...
type Setting (line 345) | type Setting = IntSetting
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/core.types.ts
type SecurityLevel (line 3) | enum SecurityLevel {
type RiskLevel (line 10) | enum RiskLevel {
type Identifyable (line 19) | interface Identifyable {
function getEnumKey (line 28) | function getEnumKey(enumLike: any, value: string | number): string {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/debug-api.service.ts
class DebugAPI (line 9) | class DebugAPI {
method constructor (line 10) | constructor(
method ping (line 15) | ping(): Observable<string> {
method ready (line 21) | ready(): Observable<string> {
method getStack (line 27) | getStack(): Observable<string> {
method getDebugInfo (line 33) | getDebugInfo(style = 'github'): Observable<string> {
method getCoreDebugInfo (line 42) | getCoreDebugInfo(style = 'github'): Observable<string> {
method getProfileDebugInfo (line 51) | getProfileDebugInfo(source: string, id: string, style = 'github'): Obs...
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/features.ts
type FeatureID (line 1) | enum FeatureID {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/meta-api.service.ts
type MetaEndpointParameter (line 7) | interface MetaEndpointParameter {
type MetaEndpoint (line 14) | interface MetaEndpoint {
type AuthPermission (line 24) | interface AuthPermission {
type MyProfileResponse (line 31) | interface MyProfileResponse {
type AuthKeyResponse (line 37) | interface AuthKeyResponse {
class MetaAPI (line 43) | class MetaAPI {
method constructor (line 44) | constructor(
method listEndpoints (line 54) | listEndpoints(): Observable<MetaEndpoint[]> {
method permissions (line 58) | permissions(): Observable<AuthPermission> {
method myProfile (line 62) | myProfile(): Observable<MyProfileResponse> {
method requestApplicationAccess (line 66) | requestApplicationAccess(appName: string, read: 'user' | 'admin' = 'us...
method login (line 77) | login(usernameOrBearer: string, password?: string): Observable<boolean> {
method logout (line 108) | logout(): Observable<void> {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/module.ts
type ModuleConfig (line 14) | interface ModuleConfig {
function HttpClientProviderFactory (line 26) | function HttpClientProviderFactory() {
class PortmasterAPIModule (line 42) | class PortmasterAPIModule {
method forRoot (line 49) | static forRoot(cfg: ModuleConfig = {}): ModuleWithProviders<Portmaster...
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/netquery.service.ts
type FieldSelect (line 11) | interface FieldSelect {
type FieldAsSelect (line 15) | interface FieldAsSelect {
type Count (line 22) | interface Count {
type Sum (line 30) | interface Sum {
type Min (line 42) | interface Min {
type Distinct (line 54) | interface Distinct {
type Select (line 58) | type Select = FieldSelect | FieldAsSelect | Count | Distinct | Sum | Min;
type Equal (line 60) | interface Equal {
type NotEqual (line 64) | interface NotEqual {
type Like (line 68) | interface Like {
type In (line 72) | interface In {
type NotIn (line 76) | interface NotIn {
type Greater (line 80) | interface Greater {
type GreaterOrEqual (line 84) | interface GreaterOrEqual {
type Less (line 88) | interface Less {
type LessOrEqual (line 92) | interface LessOrEqual {
type Matcher (line 96) | type Matcher = Equal | NotEqual | Like | In | NotIn | Greater | GreaterO...
type OrderBy (line 98) | interface OrderBy {
type Condition (line 103) | interface Condition {
type TextSearch (line 107) | interface TextSearch {
type Database (line 112) | enum Database {
type Query (line 117) | interface Query {
type NetqueryConnection (line 128) | interface NetqueryConnection {
type ChartResult (line 175) | interface ChartResult {
type QueryResult (line 181) | interface QueryResult extends Partial<NetqueryConnection> {
type Identities (line 185) | interface Identities {
type IProfileStats (line 190) | interface IProfileStats {
type BatchResponse (line 204) | type BatchResponse<T> = {
type BatchRequest (line 208) | interface BatchRequest {
type BandwidthBaseResult (line 212) | interface BandwidthBaseResult {
type ConnKeys (line 218) | type ConnKeys = keyof NetqueryConnection
type BandwidthChartResult (line 220) | type BandwidthChartResult<K extends ConnKeys> = {
type ProfileBandwidthChartResult (line 224) | type ProfileBandwidthChartResult = BandwidthChartResult<'profile'>;
type ConnectionBandwidthChartResult (line 226) | type ConnectionBandwidthChartResult = BandwidthChartResult<'id'>;
class Netquery (line 229) | class Netquery {
method constructor (line 230) | constructor(
method query (line 237) | query(query: Query, origin: string): Observable<QueryResult[]> {
method batch (line 244) | batch<T extends BatchRequest>(queries: T): Observable<BatchResponse<T>> {
method cleanProfileHistory (line 248) | cleanProfileHistory(profileIDs: string | string[]): Observable<HttpRes...
method profileBandwidthChart (line 261) | profileBandwidthChart(profile?: string[], interval?: number): Observab...
method bandwidthChart (line 285) | bandwidthChart<K extends ConnKeys>(query: Condition, groupBy?: K[], in...
method connectionBandwidthChart (line 296) | connectionBandwidthChart(connIds: string[], interval?: number): Observ...
method activeConnectionChart (line 320) | activeConnectionChart(cond: Condition, textSearch?: TextSearch): Obser...
method getActiveProfileIDs (line 364) | getActiveProfileIDs(): Observable<string[]> {
method getActiveProfiles (line 379) | getActiveProfiles(): Observable<AppProfile[]> {
method getProfileStats (line 386) | getProfileStats(query?: Condition): Observable<IProfileStats[]> {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/network.types.ts
type Verdict (line 3) | enum Verdict {
type IPProtocol (line 14) | enum IPProtocol {
type IPVersion (line 24) | enum IPVersion {
type IPScope (line 29) | enum IPScope {
function IsGlobalScope (line 45) | function IsGlobalScope(scope: IPScope): scope is IPScope.GlobalMulitcast...
function IsLANScope (line 51) | function IsLANScope(scope: IPScope): scope is IPScope.SiteLocal | IPScop...
function IsLocalhost (line 56) | function IsLocalhost(scope: IPScope): scope is IPScope.HostLocal {
function IsDenied (line 66) | function IsDenied(v: Verdict): boolean {
type CountryInfo (line 70) | interface CountryInfo {
type ContinentInfo (line 77) | interface ContinentInfo {
type GeoCoordinates (line 83) | interface GeoCoordinates {
type IntelEntity (line 95) | interface IntelEntity {
type ScopeIdentifier (line 133) | enum ScopeIdentifier {
type ProcessContext (line 155) | interface ProcessContext {
type Reason (line 166) | interface Reason {
type ConnectionType (line 179) | enum ConnectionType {
function IsDNSRequest (line 185) | function IsDNSRequest(t: ConnectionType): t is ConnectionType.DNSRequest {
function IsIPConnection (line 189) | function IsIPConnection(t: ConnectionType): t is ConnectionType.IPConnec...
type DNSContext (line 193) | interface DNSContext {
type TunnelContext (line 206) | interface TunnelContext {
type GeoIPInfo (line 212) | interface GeoIPInfo {
type TunnelNode (line 219) | interface TunnelNode {
type CertInfo (line 227) | interface CertInfo<dateType extends string | Date = string> {
type TLSContext (line 235) | interface TLSContext {
type Connection (line 242) | interface Connection extends Record {
type ReasonContext (line 312) | interface ReasonContext {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/platform-specific/tauri/tauri-http-interceptor.ts
function TauriHttpInterceptor (line 19) | function TauriHttpInterceptor(req: HttpRequest<unknown>, next: HttpHandl...
function getRequestBody (line 135) | function getRequestBody(req: HttpRequest<unknown>): any {
function send_tauri_http_request (line 152) | async function send_tauri_http_request(
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/platform-specific/tauri/tauri-websocket-subject.ts
constant LOG_PREFIX (line 5) | const LOG_PREFIX = '[tauri_ws]';
constant PING_INTERVAL_MS (line 6) | const PING_INTERVAL_MS = 10000;
constant PONG_TIMEOUT_MS (line 7) | const PONG_TIMEOUT_MS = 5000;
function createTauriWsConnection (line 26) | function createTauriWsConnection<T>(opts: WebSocketSubjectConfig<T>): We...
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/platform-specific/utils.ts
function IsTauriEnvironment (line 2) | function IsTauriEnvironment(): boolean {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/portapi.service.ts
constant PORTMASTER_WS_API_ENDPOINT (line 42) | const PORTMASTER_WS_API_ENDPOINT = new InjectionToken<string>(
constant PORTMASTER_HTTP_API_ENDPOINT (line 45) | const PORTMASTER_HTTP_API_ENDPOINT = new InjectionToken<string>(
constant RECONNECT_INTERVAL (line 49) | const RECONNECT_INTERVAL = 2000;
type PendingMethod (line 53) | interface PendingMethod {
class PortapiService (line 59) | class PortapiService {
method connected$ (line 73) | get connected$() {
method constructor (line 82) | constructor(
method restartPortmaster (line 155) | restartPortmaster(): Observable<any> {
method shutdownPortmaster (line 163) | shutdownPortmaster(): Observable<any> {
method pause (line 174) | pause(duration: number, onlySPN: boolean): Observable<any> {
method resume (line 181) | resume(): Observable<any> {
method checkForUpdates (line 188) | checkForUpdates(): Observable<any> {
method reloadUI (line 197) | reloadUI(): Observable<any> {
method clearDNSCache (line 205) | clearDNSCache(): Observable<any> {
method resetBroadcastState (line 213) | resetBroadcastState(): Observable<any> {
method reinitSPN (line 222) | reinitSPN(): Observable<any> {
method cleanupHistory (line 230) | cleanupHistory(): Observable<any> {
method getResource (line 244) | getResource(
method exportSettings (line 266) | exportSettings(
method validateSettingsImport (line 285) | validateSettingsImport(
method importSettings (line 302) | importSettings(
method importProfile (line 323) | importProfile(
method validateProfileImport (line 344) | validateProfileImport(
method exportProfile (line 359) | exportProfile(id: string): Observable<string> {
method mergeProfiles (line 374) | mergeProfiles(
method bridgeAPI (line 397) | bridgeAPI(call: string, method: string): Observable<void> {
method _flushPendingMethods (line 407) | private _flushPendingMethods() {
method inspectActiveRequests (line 431) | inspectActiveRequests(): { [key: string]: InspectedActiveRequest } {
method get (line 441) | get<T extends Record>(key: string): Observable<T> {
method query (line 452) | query<T extends Record>(query: string): Observable<DataReply<T>> {
method sub (line 461) | sub<T extends Record>(
method qsub (line 484) | qsub<T extends Record>(
method create (line 504) | create(key: string, data: any): Observable<void> {
method update (line 515) | update(key: string, data: any): Observable<void> {
method insert (line 527) | insert(key: string, data: any): Observable<void> {
method delete (line 537) | delete(key: string): Observable<void> {
method watch (line 575) | watch<T extends Record>(
method watchAll (line 600) | watchAll<T extends Record>(
method close (line 684) | close() {
method request (line 693) | request<M extends RequestType, R extends Record = any>(
method multiplex (line 853) | private multiplex(
method _injectMessage (line 899) | _injectMessage(id: string, msg: DataReply<any>) {
method _injectData (line 919) | _injectData(id: string, data: any, key: string = '') {
method _patchLast (line 930) | _patchLast(id: string, data: any) {
method stripMeta (line 940) | private stripMeta<T extends Record>(obj: T): T {
method createWebsocket (line 954) | private createWebsocket(): WebSocketSubject<ReplyMessage | RequestMess...
function countTruthyDataFields (line 1005) | function countTruthyDataFields(obj: { [key: string]: any }): number {
function isObject (line 1016) | function isObject(item: any): item is Object {
function mergeDeep (line 1020) | function mergeDeep(target: any, ...sources: any): any {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/portapi.types.ts
type ReplyType (line 7) | type ReplyType = 'ok'
type RequestType (line 19) | type RequestType = 'get'
type RecordMeta (line 31) | interface RecordMeta {
type Process (line 48) | interface Process extends Record {
type Record (line 81) | interface Record {
type MessageType (line 88) | type MessageType = RequestType | ReplyType;
type BaseMessage (line 94) | interface BaseMessage<M extends MessageType = MessageType> {
type DoneReply (line 105) | interface DoneReply extends BaseMessage<'done'> { }
type DataReply (line 111) | interface DataReply<T extends Record> extends BaseMessage<'ok' | 'upd' |...
function isDataReply (line 123) | function isDataReply(d: ReplyMessage): d is DataReply<any> {
type SuccessReply (line 135) | interface SuccessReply extends BaseMessage<'success'> { }
type ErrorReply (line 144) | interface ErrorReply extends BaseMessage<'error'> {
type WarningReply (line 155) | interface WarningReply extends BaseMessage<'warning'> {
type QueryRequest (line 166) | interface QueryRequest extends BaseMessage<'query' | 'sub' | 'qsub'> {
type KeyRequest (line 177) | interface KeyRequest extends BaseMessage<'delete' | 'get'> {
type DataRequest (line 188) | interface DataRequest<T> extends BaseMessage<'update' | 'create' | 'inse...
type CancelRequest (line 198) | interface CancelRequest extends BaseMessage<'cancel'> { }
type ReplyMessage (line 203) | type ReplyMessage<T extends Record = any> = DataReply<T>
type RequestMessage (line 212) | type RequestMessage<T = any> = QueryRequest
type Requestable (line 221) | type Requestable<M extends RequestType> = RequestMessage & { type: M };
function isCancellable (line 228) | function isCancellable(m: MessageType): boolean {
type InspectedActiveRequest (line 242) | interface InspectedActiveRequest {
type RetryableOpts (line 261) | interface RetryableOpts {
type ProfileImportResult (line 268) | interface ProfileImportResult extends ImportResult {
type ImportResult (line 272) | interface ImportResult {
function retryPipeline (line 286) | function retryPipeline<T>({ retryDelay, maxRetries }: RetryableOpts = {}...
type WatchOpts (line 302) | interface WatchOpts extends RetryableOpts {
function serializeMessage (line 317) | function serializeMessage(msg: RequestMessage | ReplyMessage): any {
function deserializeMessage (line 373) | function deserializeMessage(event: MessageEvent): RequestMessage | Reply...
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/spn.service.ts
class SPNService (line 10) | class SPNService {
method constructor (line 23) | constructor(
method watchPins (line 51) | watchPins(): Observable<Pin[]> {
method b64EncodeUnicode (line 60) | b64EncodeUnicode(str: string): string {
method login (line 69) | login({ username, password }: { username: string, password: string }):...
method logout (line 84) | logout(purge = false): Observable<HttpResponse<string>> {
method watchEnabledFeatures (line 96) | watchEnabledFeatures(): Observable<(Feature & { enabled: boolean })[]> {
method loadFeaturePackages (line 117) | loadFeaturePackages(): Observable<Feature[]> {
method userProfile (line 135) | userProfile(refresh = false): Observable<UserProfile> {
method watchProfile (line 148) | watchProfile(): Observable<UserProfile | null> {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/spn.types.ts
type SPNStatus (line 5) | interface SPNStatus extends Record {
type Pin (line 15) | interface Pin extends Record {
type Lane (line 31) | interface Lane {
function getPinCoords (line 37) | function getPinCoords(p: Pin): GeoCoordinates | null {
type Device (line 44) | interface Device {
type Subscription (line 49) | interface Subscription {
type Plan (line 56) | interface Plan {
type View (line 64) | interface View {
type UserProfile (line 73) | interface UserProfile extends Record {
type Package (line 86) | interface Package {
type Feature (line 91) | interface Feature {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/utils.ts
function deepClone (line 2) | function deepClone<T = any>(o?: T | null): T {
FILE: desktop/angular/projects/safing/portmaster-api/src/lib/websocket.service.ts
class WebsocketService (line 7) | class WebsocketService {
method constructor (line 8) | constructor() { }
method createConnection (line 15) | createConnection<T>(opts: WebSocketSubjectConfig<T>): WebSocketSubject...
FILE: desktop/angular/projects/safing/ui/src/lib/accordion/accordion-group.ts
class SfngAccordionGroupComponent (line 11) | class SfngAccordionGroupComponent implements OnDestroy {
method headerTemplate (line 20) | set headerTemplate(v: TemplateRef<any> | null) {
method headerTemplate (line 30) | get headerTemplate() { return this._headerTemplate }
method singleMode (line 35) | set singleMode(v: any) {
method singleMode (line 38) | get singleMode() { return this._singleMode }
method disabled (line 43) | set disabled(v: any) {
method disabled (line 49) | get disabled(): boolean { return this._disabled; }
method register (line 61) | register(a: SfngAccordionComponent) {
method unregister (line 85) | unregister(a: SfngAccordionComponent) {
method ngOnDestroy (line 96) | ngOnDestroy() {
method toggle (line 108) | private toggle(a: SfngAccordionComponent) {
FILE: desktop/angular/projects/safing/ui/src/lib/accordion/accordion.module.ts
class SfngAccordionModule (line 19) | class SfngAccordionModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/accordion/accordion.ts
class SfngAccordionComponent (line 16) | class SfngAccordionComponent<T = any> implements OnInit, OnDestroy {
method active (line 36) | set active(v: any) {
method active (line 39) | get active() {
method activeClass (line 57) | get activeClass(): string {
method ngOnInit (line 61) | ngOnInit(): void {
method ngOnDestroy (line 66) | ngOnDestroy(): void {
method toggle (line 75) | toggle(event?: Event) {
method constructor (line 84) | constructor(
FILE: desktop/angular/projects/safing/ui/src/lib/dialog/confirm.dialog.ts
type ConfirmDialogButton (line 4) | interface ConfirmDialogButton {
type ConfirmDialogConfig (line 10) | interface ConfirmDialogConfig {
constant CONFIRM_DIALOG_CONFIG (line 21) | const CONFIRM_DIALOG_CONFIG = new InjectionToken<ConfirmDialogConfig>('C...
class SfngConfirmDialogComponent (line 27) | class SfngConfirmDialogComponent {
method constructor (line 28) | constructor(
method select (line 37) | select(action?: string) {
FILE: desktop/angular/projects/safing/ui/src/lib/dialog/dialog.container.ts
constant SFNG_DIALOG_PORTAL (line 8) | const SFNG_DIALOG_PORTAL = new InjectionToken<Portal<any>>('SfngDialogPo...
type SfngDialogState (line 10) | type SfngDialogState = 'opening' | 'open' | 'closing' | 'closed';
class SfngDialogContainerComponent (line 22) | class SfngDialogContainerComponent<T> {
method constructor (line 27) | constructor(
method attachComponentPortal (line 40) | attachComponentPortal(portal: ComponentPortal<T>): ComponentRef<T> {
method attachTemplatePortal (line 45) | attachTemplatePortal(portal: TemplatePortal<T>): EmbeddedViewRef<T> {
method onAnimationStart (line 54) | onAnimationStart({ toState }: AnimationEvent) {
method onAnimationEnd (line 63) | onAnimationEnd({ toState }: AnimationEvent) {
method _startExit (line 72) | _startExit() {
FILE: desktop/angular/projects/safing/ui/src/lib/dialog/dialog.module.ts
class SfngDialogModule (line 23) | class SfngDialogModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/dialog/dialog.ref.ts
constant SFNG_DIALOG_REF (line 7) | const SFNG_DIALOG_REF = new InjectionToken<SfngDialogRef<any>>('SfngDial...
class SfngDialogRef (line 9) | class SfngDialogRef<T, R = any, D = any> {
method constructor (line 10) | constructor(
method onStateChange (line 28) | get onStateChange(): Observable<SfngDialogState> {
method overlay (line 36) | overlay() { return this._overlayRef }
method contentRef (line 41) | contentRef() { return this.container.ref! }
method onAction (line 52) | onAction<T extends R>(action: T, observer: PartialObserver<T> | ((valu...
method close (line 58) | close(result?: R) {
FILE: desktop/angular/projects/safing/ui/src/lib/dialog/dialog.service.ts
type BaseDialogConfig (line 10) | interface BaseDialogConfig {
type ComponentPortalConfig (line 37) | interface ComponentPortalConfig {
class SfngDialogService (line 42) | class SfngDialogService {
method constructor (line 44) | constructor(
method position (line 49) | position(): OverlayPositionBuilder {
method create (line 55) | create<T>(target: ComponentType<T> | TemplatePortal<T>, opts: BaseDial...
method confirm (line 140) | confirm(opts: ConfirmDialogConfig): SfngDialogRef<SfngConfirmDialogCom...
FILE: desktop/angular/projects/safing/ui/src/lib/dropdown/dropdown.module.ts
class SfngDropDownModule (line 18) | class SfngDropDownModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/dropdown/dropdown.ts
class SfngDropdownComponent (line 20) | class SfngDropdownComponent implements OnInit {
method externalTrigger (line 38) | set externalTrigger(v: any) {
method externalTrigger (line 41) | get externalTrigger() {
method disabled (line 52) | set disabled(v: any) {
method disabled (line 55) | get disabled() {
method offsetY (line 62) | set offsetY(v: any) {
method offsetY (line 65) | get offsetY() { return this._offsetY }
method offsetX (line 70) | set offsetX(v: any) {
method offsetX (line 73) | get offsetX() { return this._offsetX }
method minWidth (line 85) | set minWidth(val: any) {
method minWidth (line 88) | get minWidth() { return this._minWidth }
method maxWidth (line 93) | set maxWidth(val: any) {
method maxWidth (line 96) | get maxWidth() { return this._maxWidth }
method minHeight (line 101) | set minHeight(val: any) {
method minHeight (line 104) | get minHeight() { return this._minHeight }
method maxHeight (line 109) | set maxHeight(val: any) {
method maxHeight (line 112) | get maxHeight() { return this._maxHeight }
method constructor (line 145) | constructor(
method ngOnInit (line 153) | ngOnInit() {
method onOutsideClick (line 157) | onOutsideClick(event: MouseEvent) {
method onOverlayClosed (line 173) | onOverlayClosed() {
method close (line 177) | close() {
method toggle (line 186) | toggle(t: CdkOverlayOrigin | null = this.trigger) {
method show (line 196) | show(t: CdkOverlayOrigin | null = this.trigger) {
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/overlay-stepper-container.ts
constant STEP_CONFIG (line 13) | const STEP_CONFIG = new InjectionToken<StepperConfig>('StepperConfig');
class OverlayStepperContainerComponent (line 53) | class OverlayStepperContainerComponent implements OnInit, OnDestroy, Ste...
method onFinish (line 61) | get onFinish() {
method onClose (line 69) | get onClose() {
method isLast (line 90) | get isLast() {
method constructor (line 94) | constructor(
method next (line 105) | next(): Promise<void> {
method goBack (line 120) | goBack(): Promise<void> {
method close (line 126) | async close(): Promise<void> {
method ngOnInit (line 130) | ngOnInit(): void {
method ngOnDestroy (line 134) | ngOnDestroy(): void {
method attachStep (line 146) | private async attachStep(index: number, forward = true) {
method createStepContentPortal (line 213) | private createStepContentPortal(stepType: ComponentType<Step>, index: ...
method createStepOutletPortal (line 240) | private createStepOutletPortal(contentPortal: ComponentPortal<Step>, d...
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/overlay-stepper.module.ts
class OverlayStepperModule (line 21) | class OverlayStepperModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/overlay-stepper.ts
class OverlayStepper (line 9) | class OverlayStepper {
method constructor (line 10) | constructor(
method create (line 22) | create(config: StepperConfig): StepperRef {
method createInjector (line 46) | private createInjector(config: StepperConfig): Injector {
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/refs.ts
constant STEP_REF (line 10) | const STEP_REF = new InjectionToken<StepRef<any>>('StepRef')
type StepperControl (line 12) | interface StepperControl {
class StepRef (line 48) | class StepRef<T = any> implements StepperControl {
method constructor (line 52) | constructor(
method next (line 61) | next(): Promise<void> {
method goBack (line 65) | goBack(): Promise<void> {
method close (line 69) | close(): Promise<void> {
method save (line 80) | save(data: T): void {
method load (line 89) | load(): T | null {
method registerOnFinish (line 97) | registerOnFinish(fn: () => PromiseLike<void> | void) {
method runOnFinishHooks (line 105) | private async runOnFinishHooks() {
class StepperRef (line 121) | class StepperRef implements StepperControl {
method constructor (line 122) | constructor(private stepContainerRef: OverlayStepperContainerComponent...
method next (line 124) | next(): Promise<void> {
method goBack (line 128) | goBack(): Promise<void> {
method close (line 132) | close(): Promise<void> {
method onFinish (line 136) | get onFinish(): Observable<void> {
method onClose (line 140) | get onClose(): Observable<void> {
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/step-outlet.ts
constant STEP_PORTAL (line 6) | const STEP_PORTAL = new InjectionToken<ComponentPortal<Step>>('STEP_PORT...
constant STEP_ANIMATION_DIRECTION (line 7) | const STEP_ANIMATION_DIRECTION = new InjectionToken<'left' | 'right'>('S...
class StepOutletComponent (line 54) | class StepOutletComponent implements AfterViewInit {
method in (line 62) | get in() {
method out (line 67) | get out() {
method constructor (line 75) | constructor(
method ngAfterViewInit (line 81) | ngAfterViewInit(): void {
FILE: desktop/angular/projects/safing/ui/src/lib/overlay-stepper/step.ts
type Step (line 4) | interface Step {
type StepperConfig (line 47) | interface StepperConfig {
FILE: desktop/angular/projects/safing/ui/src/lib/pagination/dynamic-items-paginator.ts
type Datasource (line 5) | interface Datasource<T> {
class DynamicItemsPaginator (line 10) | class DynamicItemsPaginator<T> implements Pagination<T> {
method total (line 18) | get total() { return this._total; }
method pageNumber$ (line 21) | get pageNumber$() { return this._pageNumber$.asObservable() }
method pageItems$ (line 24) | get pageItems$() { return this._pageItems$.asObservable() }
method pageLoading$ (line 27) | get pageLoading$() { return this._pageLoading$.asObservable() }
method constructor (line 29) | constructor(
method reset (line 34) | reset(newTotal: number) {
method clear (line 40) | clear() {
method openPage (line 47) | openPage(pageNumber: number): void {
method nextPage (line 62) | nextPage(): void { this.openPage(this._pageNumber$.getValue() + 1) }
method prevPage (line 63) | prevPage(): void { this.openPage(this._pageNumber$.getValue() - 1) }
FILE: desktop/angular/projects/safing/ui/src/lib/pagination/pagination.module.ts
class SfngPaginationModule (line 19) | class SfngPaginationModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/pagination/pagination.ts
type Pagination (line 4) | interface Pagination<T> {
class SfngPaginationContentDirective (line 45) | class SfngPaginationContentDirective<T = any> {
method constructor (line 46) | constructor(public readonly templateRef: TemplateRef<T>) { }
type PageChangeEvent (line 49) | interface PageChangeEvent {
class SfngPaginationWrapperComponent (line 59) | class SfngPaginationWrapperComponent<T = any> implements OnChanges, OnDe...
method ngOnChanges (line 74) | ngOnChanges(changes: SimpleChanges) {
method ngOnDestroy (line 80) | ngOnDestroy() {
method subscribeToSource (line 84) | private subscribeToSource(source: Pagination<T>) {
method constructor (line 105) | constructor(private cdr: ChangeDetectorRef) { }
function generatePageNumbers (line 115) | function generatePageNumbers(current: number, countPages: number): numbe...
function clipPage (line 124) | function clipPage(pageNumber: number, total: number): number {
FILE: desktop/angular/projects/safing/ui/src/lib/pagination/snapshot-paginator.ts
class SnapshotPaginator (line 5) | class SnapshotPaginator<T> implements Pagination<T> {
method constructor (line 11) | constructor(
method updatePending (line 34) | get updatePending() {
method pageNumber$ (line 37) | get pageNumber$(): Observable<number> {
method pageNumber (line 40) | get pageNumber(): number {
method total (line 43) | get total(): number {
method pageItems$ (line 46) | get pageItems$(): Observable<T[]> {
method pageItems (line 49) | get pageItems(): T[] {
method snapshot (line 52) | get snapshot(): T[] { return this._itemSnapshot }
method reload (line 54) | reload(): void { this.openPage(this._currentPage.getValue()) }
method nextPage (line 56) | nextPage(): void { this.openPage(this._currentPage.getValue() + 1) }
method prevPage (line 58) | prevPage(): void { this.openPage(this._currentPage.getValue() - 1) }
method openPage (line 60) | openPage(pageNumber: number): void {
FILE: desktop/angular/projects/safing/ui/src/lib/select/item.ts
type SelectOption (line 5) | interface SelectOption<T = any> extends ListKeyManagerOption {
class SfngSelectItemComponent (line 20) | class SfngSelectItemComponent implements ListKeyManagerOption {
method disabled (line 22) | get disabled() {
method getLabel (line 26) | getLabel() {
method constructor (line 30) | constructor(@Optional() private sfngSelectValue: SfngSelectValueDirect...
class SfngSelectValueDirective (line 36) | class SfngSelectValueDirective<T = any> implements SelectOption<T> {
method disabled (line 50) | set disabled(v: any) {
method disabled (line 53) | get disabled() { return this._disabled }
method getLabel (line 56) | getLabel() {
method constructor (line 63) | constructor(public templateRef: TemplateRef<any>) { }
FILE: desktop/angular/projects/safing/ui/src/lib/select/select.module.ts
class SfngSelectModule (line 31) | class SfngSelectModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/select/select.ts
type SelectModes (line 12) | type SelectModes = 'single' | 'multi';
type ModeInput (line 14) | type ModeInput = {
type SelectValue (line 18) | type SelectValue<T, S extends ModeInput> = S['mode'] extends 'single' ? ...
type SortByFunc (line 20) | type SortByFunc = (a: SelectOption, b: SelectOption) => number;
type SelectDisplayMode (line 22) | type SelectDisplayMode = 'dropdown' | 'inline';
class SfngSelectRenderedItemDirective (line 27) | class SfngSelectRenderedItemDirective implements ListKeyManagerOption {
method getLabel (line 31) | getLabel() {
method disabled (line 35) | get disabled() {
method focused (line 40) | set focused(v: boolean) {
method focused (line 43) | get focused() { return this._focused }
method constructor (line 46) | constructor(public readonly elementRef: ElementRef) { }
class SfngSelectComponent (line 61) | class SfngSelectComponent<T> implements AfterViewInit, ControlValueAcces...
method itemLimit (line 122) | set itemLimit(v: any) {
method itemLimit (line 125) | get itemLimit(): number { return this._maxItemLimit }
method allowSearch (line 134) | set allowSearch(v: any) {
method allowSearch (line 137) | get allowSearch(): boolean {
method searchItemThreshold (line 144) | set searchItemThreshold(v: any) {
method searchItemThreshold (line 147) | get searchItemThreshold(): number {
method disableWhenEmpty (line 157) | set disableWhenEmpty(v: any) {
method disableWhenEmpty (line 160) | get disableWhenEmpty() {
method dynamicValues (line 167) | set dynamicValues(v: any) {
method dynamicValues (line 170) | get dynamicValues() {
method sortValues (line 189) | set sortValues(v: any) {
method sortValues (line 192) | get sortValues() {
method disabled (line 214) | set disabled(v: any) {
method disabled (line 218) | get disabled() {
method onEnter (line 225) | onEnter(event: Event) {
method onKeyDown (line 246) | onKeyDown(event: KeyboardEvent) {
method trackItem (line 256) | trackItem(_: number, item: SelectOption) {
method setDisabledState (line 260) | setDisabledState(disabled: boolean) {
method constructor (line 265) | constructor(private cdr: ChangeDetectorRef) { }
method ngAfterViewInit (line 267) | ngAfterViewInit(): void {
method ngOnDestroy (line 356) | ngOnDestroy(): void {
method onBlur (line 361) | onBlur(): void {
method onDropdownOpen (line 366) | onDropdownOpen() {
method onDropdownClose (line 377) | onDropdownClose() {
method onSearch (line 381) | onSearch(text: string) {
method selectItem (line 386) | selectItem(item: SelectOption) {
method updateItems (line 425) | private updateItems() {
method writeValue (line 478) | writeValue(value: SelectValue<T, this>): void {
method registerOnChange (line 487) | registerOnChange(fn: (value: SelectValue<T, this>) => void): void {
method registerOnTouched (line 492) | registerOnTouched(fn: () => void): void {
FILE: desktop/angular/projects/safing/ui/src/lib/tabs/tab-group.ts
type SfngTabContentScrollEvent (line 11) | interface SfngTabContentScrollEvent {
class SfngTabGroupComponent (line 47) | class SfngTabGroupComponent implements AfterContentInit, AfterViewInit, ...
method linkRouter (line 77) | set linkRouter(v: any) {
method linkRouter (line 80) | get linkRouter() { return this._linkRouter }
method customHeader (line 85) | set customHeader(v: any) {
method customHeader (line 88) | get customHeader() { return this._customHeader }
method tabs$ (line 95) | get tabs$() {
method onActivate (line 104) | get onActivate(): Observable<string> { return this.tabActivate$.asObse...
method constructor (line 122) | constructor(
method onKeydown (line 133) | onKeydown(v: KeyboardEvent) {
method ngOnInit (line 137) | ngOnInit(): void {
method ngAfterContentInit (line 161) | ngAfterContentInit(): void {
method ngAfterViewInit (line 246) | ngAfterViewInit(): void {
method activateTab (line 258) | activateTab(idx: number, forceDirection?: 'left' | 'right') {
method getIndex (line 266) | private getIndex(newIdx: string | null): number | null {
method repositionTabBar (line 287) | private repositionTabBar() {
method createTabOutlet (line 315) | private createTabOutlet(tab: SfngTabComponent, animationDir: 'left' | ...
FILE: desktop/angular/projects/safing/ui/src/lib/tabs/tab.ts
constant TAB_PORTAL (line 8) | const TAB_PORTAL = new InjectionToken<TemplatePortal>('TAB_PORTAL');
constant TAB_ANIMATION_DIRECTION (line 11) | const TAB_ANIMATION_DIRECTION = new InjectionToken<'left' | 'right'>('TA...
constant TAB_SCROLL_HANDLER (line 14) | const TAB_SCROLL_HANDLER = new InjectionToken<(_: Event) => void>('TAB_S...
class SfngTabContentDirective (line 22) | class SfngTabContentDirective<T> {
method constructor (line 25) | constructor(
class SfngTabComponent (line 43) | class SfngTabComponent implements ListKeyManagerOption {
method warning (line 60) | set warning(v) {
method warning (line 63) | get warning() { return this._warning }
method disabled (line 72) | set disabled(v: any) {
method disabled (line 75) | get disabled() {
method getLabel (line 81) | getLabel() { return this.title }
class TabOutletComponent (line 131) | class TabOutletComponent implements AfterViewInit {
method in (line 137) | get in() {
method out (line 140) | get out() {
method onTabContentScroll (line 144) | onTabContentScroll(event: Event) {
method constructor (line 153) | constructor(
method ngAfterViewInit (line 160) | ngAfterViewInit(): void {
FILE: desktop/angular/projects/safing/ui/src/lib/tabs/tabs.module.ts
class SfngTabModule (line 28) | class SfngTabModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/anchor.ts
class SfngTipUpAnchorDirective (line 7) | class SfngTipUpAnchorDirective implements SfngTipUpPlacement {
method constructor (line 8) | constructor(
method sfngTipUpAnchor (line 19) | set sfngTipUpAnchor(posSpec: string | undefined) {
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/clone-node.ts
function deepCloneNode (line 10) | function deepCloneNode(node: HTMLElement): HTMLElement {
function transferData (line 34) | function transferData<T extends Element>(selector: string, node: HTMLEle...
function transferInputData (line 51) | function transferInputData(source: Element & { value: string },
function transferCanvasData (line 67) | function transferCanvasData(source: HTMLCanvasElement, clone: HTMLCanvas...
function getTransform (line 84) | function getTransform(x: number, y: number): string {
function matchElementSize (line 95) | function matchElementSize(target: HTMLElement, sourceRect: ClientRect): ...
function extendStyles (line 105) | function extendStyles(dest: CSSStyleDeclaration,
function removeNode (line 123) | function removeNode(node: Node | null) {
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/css-utils.ts
function synchronizeCssStyles (line 2) | function synchronizeCssStyles(src: HTMLElement, destination: HTMLElement...
function cloneStyle (line 17) | function cloneStyle(srcElement: HTMLElement, dstElement: HTMLElement, sk...
function getCssSelector (line 51) | function getCssSelector(el: HTMLElement, rootNode: HTMLElement | null): ...
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/safe.pipe.ts
class SafePipe (line 7) | class SafePipe implements PipeTransform {
method constructor (line 9) | constructor(protected sanitizer: DomSanitizer) { }
method transform (line 11) | public transform(value: any, type: string): SafeHtml | SafeStyle | Saf...
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/tipup-component.ts
class SfngTipUpComponent (line 12) | class SfngTipUpComponent implements OnInit, TipUp<any> {
method constructor (line 20) | constructor(
method ngOnInit (line 27) | ngOnInit() {
method next (line 35) | async next() {
method runAction (line 44) | async runAction(btn: Button<any>) {
method close (line 64) | close() {
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/tipup.module.ts
class SfngTipUpModule (line 31) | class SfngTipUpModule {
method forRoot (line 32) | static forRoot(text: HelpTexts<any>, runner: Type<ActionRunner<any>>):...
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/tipup.ts
class SfngsfngTipUpTriggerDirective (line 20) | class SfngsfngTipUpTriggerDirective implements OnDestroy {
method constructor (line 21) | constructor(
method textKey (line 36) | set textKey(s: string) {
method textKey (line 43) | get textKey() { return this._textKey; }
method asTipUp (line 65) | asTipUp(): TipUp<any> | null {
method anchorRef (line 87) | set anchorRef(ref: ElementRef<any> | HTMLElement | null) {
method ngOnDestroy (line 96) | ngOnDestroy() {
method passive (line 102) | set passive(v: any) {
method passive (line 105) | get passive() { return this._passive; }
method offset (line 109) | set offset(v: any) {
method offset (line 112) | get offset() { return this._defaultOffset }
method onClick (line 119) | onClick(event?: MouseEvent): Promise<any> {
class SfngTipUpIconComponent (line 208) | class SfngTipUpIconComponent implements SfngTipUpPlacement {
method offset (line 224) | set offset(v: any) {
method offset (line 227) | get offset() { return this._offset; }
method constructor (line 230) | constructor(private elementRef: ElementRef<any>) { }
method placement (line 232) | get placement(): SfngTipUpPlacement {
method parent (line 236) | get parent(): HTMLElement | null {
class SfngTipUpService (line 245) | class SfngTipUpService {
method onRegister (line 251) | get onRegister(): Observable<string> {
method onUnregister (line 255) | get onUnregister(): Observable<string> {
method waitFor (line 259) | waitFor(key: string): Observable<void> {
method constructor (line 277) | constructor(
method register (line 287) | register(key: string, trigger: SfngsfngTipUpTriggerDirective) {
method deregister (line 296) | deregister(key: string, trigger: SfngsfngTipUpTriggerDirective) {
method getTipUp (line 303) | getTipUp(key: string): TipUp<any> | null {
method createTipup (line 309) | createTipup(
method _createPreview (line 421) | private _createPreview(element: HTMLElement, shadowRoot: ShadowRoot | ...
method _getPreviewInserationPoint (line 508) | private _getPreviewInserationPoint(shadowRoot: ShadowRoot | null): HTM...
method open (line 518) | async open(key: string) {
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/translations.ts
constant SFNG_TIP_UP_CONTENTS (line 3) | const SFNG_TIP_UP_CONTENTS = new InjectionToken<HelpTexts<any>>('SfngTip...
constant SFNG_TIP_UP_ACTION_RUNNER (line 4) | const SFNG_TIP_UP_ACTION_RUNNER = new InjectionToken<ActionRunner<any>>(...
type Button (line 6) | interface Button<T> {
type TipUp (line 12) | interface TipUp<T> {
type HelpTexts (line 21) | interface HelpTexts<T> {
type ActionRunner (line 25) | interface ActionRunner<T> {
FILE: desktop/angular/projects/safing/ui/src/lib/tipup/utils.ts
constant TIPUP_TOKEN (line 3) | const TIPUP_TOKEN = new InjectionToken<string>('TipUPJSONToken');
type SfngTipUpPlacement (line 5) | interface SfngTipUpPlacement {
FILE: desktop/angular/projects/safing/ui/src/lib/toggle-switch/toggle-switch.ts
class SfngToggleSwitchComponent (line 17) | class SfngToggleSwitchComponent implements ControlValueAccessor {
method onBlur (line 19) | onBlur() {
method disabled (line 23) | set disabled(v: any) {
method disabled (line 26) | get disabled() {
method constructor (line 33) | constructor(private _changeDetector: ChangeDetectorRef) { }
method setDisabledState (line 35) | setDisabledState(isDisabled: boolean) {
method onValueChange (line 40) | onValueChange(value: boolean) {
method writeValue (line 45) | writeValue(value: boolean) {
method registerOnChange (line 51) | registerOnChange(fn: (value: any) => void) {
method registerOnTouched (line 56) | registerOnTouched(fn: () => void) {
FILE: desktop/angular/projects/safing/ui/src/lib/toggle-switch/toggle.module.ts
class SfngToggleSwitchModule (line 18) | class SfngToggleSwitchModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/tooltip/tooltip-component.ts
constant SFNG_TOOLTIP_CONTENT (line 7) | const SFNG_TOOLTIP_CONTENT = new InjectionToken<string | TemplateRef<any...
constant SFNG_TOOLTIP_OVERLAY (line 8) | const SFNG_TOOLTIP_OVERLAY = new InjectionToken<OverlayRef>('SFNG_TOOLTI...
class SfngTooltipComponent (line 40) | class SfngTooltipComponent implements AfterViewInit, OnDestroy {
method onMouseEnter (line 56) | onMouseEnter() { this.directive.show() }
method onMouseLeave (line 63) | onMouseLeave() { this.directive.hide() }
method constructor (line 79) | constructor(
method dispose (line 94) | dispose() {
method animationDone (line 99) | animationDone(event: AnimationEvent) {
method ngOnDestroy (line 105) | ngOnDestroy(): void {
method ngAfterViewInit (line 109) | ngAfterViewInit(): void {
FILE: desktop/angular/projects/safing/ui/src/lib/tooltip/tooltip.module.ts
class SfngTooltipModule (line 22) | class SfngTooltipModule { }
FILE: desktop/angular/projects/safing/ui/src/lib/tooltip/tooltip.ts
type SfngTooltipPosition (line 10) | type SfngTooltipPosition = 'left' | 'right' | 'bottom' | 'top';
class SfngTooltipDirective (line 15) | class SfngTooltipDirective implements OnInit, OnDestroy, OnChanges {
method constructor (line 28) | constructor(
method show (line 35) | show(delay = this.delay) {
method hide (line 47) | hide(delay = this.delay / 2) {
method delay (line 64) | set delay(v: any) {
method delay (line 67) | get delay() { return this._delay }
method offset (line 72) | set offset(v: any) {
method ngOnInit (line 85) | ngOnInit() {
Copy disabled (too large)
Download .json
Condensed preview — 1599 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,126K chars).
[
{
"path": ".angulardoc.json",
"chars": 71,
"preview": "{\n \"repoId\": \"8f466ce7-4b75-4048-8b8a-cad5bf173aa0\",\n \"lastSync\": 0\n}"
},
{
"path": ".earthlyignore",
"chars": 833,
"preview": "# Ignore angular outputs.\ndesktop/angular/node_modules\ndesktop/angular/dist\ndesktop/angular/dist-lib\ndesktop/angular/dis"
},
{
"path": ".gitattributes",
"chars": 229,
"preview": "# Treat all Go files in this repo as binary, with no git magic updating\n# line endings. Windows users contributing to Go"
},
{
"path": ".github/FUNDING.yml",
"chars": 15,
"preview": "github: safing\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 758,
"preview": " \n# Ref: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#c"
},
{
"path": ".github/ISSUE_TEMPLATE/report-bug.md",
"chars": 1136,
"preview": "---\nname: \"🐞 Report a Bug\"\nabout: Report a bug encountered while using the Portmaster\nlabels: bug\n---\n\n<!--\nPlease discl"
},
{
"path": ".github/ISSUE_TEMPLATE/report-compatibility.md",
"chars": 1121,
"preview": "---\nname: \"📝 Make a Compatibility Report\"\nabout: Report Portmaster in/compatibility with Linux Distros, VPN Clients or g"
},
{
"path": ".github/ISSUE_TEMPLATE/suggest-feature.md",
"chars": 224,
"preview": "---\nname: \"💡 Suggest an Improvement or Feature\"\nabout: Suggest an enhancement or a new feature for the Portmaster\nlabels"
},
{
"path": ".github/dependabot.yml",
"chars": 634,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/label-actions.yml",
"chars": 2514,
"preview": "# Configuration for Label Actions - https://github.com/dessant/label-actions\n\ncommunity support:\n comment: |\n Hey @{"
},
{
"path": ".github/workflows/angular.yml",
"chars": 1494,
"preview": "name: Angular\n\non:\n push:\n paths:\n - 'desktop/angular/**'\n branches:\n - main\n - development\n "
},
{
"path": ".github/workflows/go.yml",
"chars": 1656,
"preview": "name: Go\n\non:\n push:\n paths:\n - '**.go'\n - 'cmds/**'\n - 'runtime/**'\n - 'service/**'\n - 'sp"
},
{
"path": ".github/workflows/issues-first-greet.yml",
"chars": 1120,
"preview": "# This workflow responds to first time posters with a greeting message.\n# Docs: https://github.com/actions/first-interac"
},
{
"path": ".github/workflows/issues-label-actions.yml",
"chars": 590,
"preview": "# This workflow responds with a message when certain labels are added to an issue or PR.\n# Docs: https://github.com/dess"
},
{
"path": ".github/workflows/issues-stale.yml",
"chars": 1763,
"preview": "# This workflow warns and then closes stale issues and PRs.\n# Docs: https://github.com/actions/stale\nname: Close Stale I"
},
{
"path": ".github/workflows/kext.yml",
"chars": 937,
"preview": "name: Windows Kernel Extension\n\non:\n push:\n paths:\n - 'windows_kext/**'\n branches:\n - main\n - deve"
},
{
"path": ".github/workflows/release.yml",
"chars": 2588,
"preview": "name: Release v2.X\n\non:\n push:\n branches:\n - main\n - development\n\n tags: \n - v*\n workflow_"
},
{
"path": ".github/workflows/tauri.yml",
"chars": 1532,
"preview": "name: Tauri\n\non:\n push:\n paths:\n - 'desktop/tauri/**'\n branches:\n - main\n - development\n - v1"
},
{
"path": ".github/workflows/windows-dll.yml",
"chars": 1222,
"preview": "name: Windows Portmaster Core DLL\n\non:\n push:\n paths:\n - 'windows_core_dll/**'\n branches:\n - main\n "
},
{
"path": ".gitignore",
"chars": 985,
"preview": "# Compiled binaries\n*.exe\ndist/\n\n# Dist dir\ndist\npackaging/_precompiled/\n\n# Custom dev deops\ngo.mod.*\n\n# vendor dir\nvend"
},
{
"path": ".golangci.yml",
"chars": 1694,
"preview": "# Docs:\n# https://golangci-lint.run/usage/linters/\n\nlinters:\n enable-all: true\n disable:\n - containedctx\n - cont"
},
{
"path": ".travis.yml",
"chars": 522,
"preview": "language: go\n\ngo:\n- 1.x\n\nos:\n - linux\n - windows\n\nbranches:\n only:\n - master\n - develop\n - /^feature\\/travis"
},
{
"path": ".vscode/launch.json",
"chars": 1652,
"preview": "{\n // Use IntelliSense to learn about possible attributes.\n // Hover to view descriptions of existing attributes.\n"
},
{
"path": ".vscode/settings.json",
"chars": 86,
"preview": "{\n \"cSpell.words\": [\n \"netenv\",\n \"safing\",\n \"Warningf\"\n ]\n}"
},
{
"path": "AUTHORS",
"chars": 133,
"preview": "All files in this repository (unless otherwise noted) are authored, owned and copyrighted by Safing ICS Technologies Gmb"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3345,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "Earthfile",
"chars": 28056,
"preview": "VERSION 0.8\n\n# Custom argument: \"custom_version\" to manually set the version of the build (and ignore Git Tag value)\n# U"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 5316,
"preview": "# Get Peace of Mind <br> with [Easy Privacy](https://safing.io/)\n\nPortmaster is a free and open-source application firew"
},
{
"path": "TESTING.md",
"chars": 304,
"preview": "# Testing Portmaster\n\nThis page documents ways to test if Portmaster works as intended.\n\n⚠ Work in Progress. Currently w"
},
{
"path": "TRADEMARKS",
"chars": 753,
"preview": "The names \"Safing\", \"Portmaster\", \"Gate17\" and their logos are trademarks owned by Safing ICS Technologies GmbH (Austria"
},
{
"path": "assets/data/favicons/browserconfig.xml",
"chars": 330,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig><msapplication><tile><square70x70logo src=\"/assets/favicons/ms-ico"
},
{
"path": "assets/data/favicons/head.html",
"chars": 1440,
"preview": "<link rel=\"apple-touch-icon\" sizes=\"57x57\" href=\"/assets/favicons/apple-icon-57x57.png\">\n<link rel=\"apple-touch-icon\" si"
},
{
"path": "assets/data/favicons/manifest.json",
"chars": 829,
"preview": "{\n \"name\": \"App\",\n \"icons\": [\n {\n \"src\": \"\\/assets\\/favicons\\/android-icon-36x36.png\",\n \"sizes\": \"36x36\",\n \"type\""
},
{
"path": "assets/data/fonts/Roboto-300/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-300italic/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-500/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-500italic/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-700/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-700italic/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-italic/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/Roboto-regular/LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "assets/data/fonts/roboto-slimfix.css",
"chars": 4980,
"preview": "@font-face {\n font-family: 'Roboto';\n font-weight: 400;\n font-style: normal;\n src: url('/assets/fonts/Roboto-300/Rob"
},
{
"path": "assets/data/fonts/roboto.css",
"chars": 4980,
"preview": "@font-face {\n font-family: 'Roboto';\n font-weight: 300;\n font-style: normal;\n src: url('/assets/fonts/Roboto-300/Rob"
},
{
"path": "assets/data/icons/README.md",
"chars": 55,
"preview": "# .ICOs\n\nconverted using https://www.icoconverter.com/\n"
},
{
"path": "assets/data/icons/generate_ico.sh",
"chars": 779,
"preview": "#!/bin/sh\n\n# Traymenu icons. Sometimes the wrong size is selected, so leave just one.\nconvert pm_dark_green_512.png -res"
},
{
"path": "assets/data/img/flags/LICENSE.txt",
"chars": 1085,
"preview": "Copyright (c) 2017 Go Squared Ltd. http://www.gosquared.com/\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "assets/data/world-50m.json",
"chars": 538142,
"preview": "{\"type\":\"Topology\",\"objects\":{\"land\":{\"type\":\"MultiPolygon\",\"arcs\":[[[0]],[[1]],[[2]],[[3]],[[4]],[[5]],[[6]],[[7]],[[8]"
},
{
"path": "assets/icons.go",
"chars": 93,
"preview": "package assets\n\nimport (\n\t_ \"embed\"\n)\n\n//go:embed data/icons/pm_light_512.png\nvar PNG []byte\n"
},
{
"path": "assets/icons_default.go",
"chars": 2243,
"preview": "//go:build !windows\n\npackage assets\n\nimport (\n\t\"bytes\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"image\"\n\t\"image/png\"\n\n\t\"golang.org/x/image/dra"
},
{
"path": "assets/icons_windows.go",
"chars": 757,
"preview": "package assets\n\nimport (\n\t_ \"embed\"\n)\n\n// Colored Icon IDs.\nconst (\n\tGreenID = 0\n\tYellowID = 1\n\tRedID = 2\n\tBlueID "
},
{
"path": "base/.gitignore",
"chars": 59,
"preview": "portbase\napitest\nmisc\n\ngo.mod.*\nvendor\ngo.work\ngo.work.sum\n"
},
{
"path": "base/README.md",
"chars": 6852,
"preview": "> **Check out our main project at [safing/portmaster](https://github.com/safing/portmaster)**\n\n# Portbase\n\nPortbase help"
},
{
"path": "base/api/api_bridge.go",
"chars": 4081,
"preview": "package api\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"path\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.c"
},
{
"path": "base/api/auth_wrapper.go",
"chars": 791,
"preview": "package api\n\nimport \"net/http\"\n\n// WrapInAuthHandler wraps a simple http.HandlerFunc into a handler that\n// exposes the "
},
{
"path": "base/api/authentication.go",
"chars": 15492,
"preview": "package api\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.co"
},
{
"path": "base/api/authentication_test.go",
"chars": 4682,
"preview": "package api\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nvar testToken = "
},
{
"path": "base/api/client/api.go",
"chars": 1704,
"preview": "package client\n\n// Get sends a get command to the API.\nfunc (c *Client) Get(key string, handleFunc func(*Message)) *Oper"
},
{
"path": "base/api/client/client.go",
"chars": 5133,
"preview": "package client\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/tevino/abool\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n"
},
{
"path": "base/api/client/const.go",
"chars": 609,
"preview": "package client\n\n// Message Types.\nconst (\n\tmsgRequestGet = \"get\"\n\tmsgRequestQuery = \"query\"\n\tmsgRequestSub = \"sub"
},
{
"path": "base/api/client/message.go",
"chars": 2083,
"preview": "package client\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\n\t\"github.com/tevino/abool\"\n\n\t\"github.com/safing/structures/container\"\n\t\"git"
},
{
"path": "base/api/client/websocket.go",
"chars": 2490,
"preview": "package client\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/gorilla/websocket\"\n\t\"github.com/tevino/abool\"\n\n\t\"github.com/safing"
},
{
"path": "base/api/config.go",
"chars": 2550,
"preview": "package api\n\nimport (\n\t\"flag\"\n\n\t\"github.com/safing/portmaster/base/config\"\n)\n\n// Config Keys.\nconst (\n\tCfgDefaultListenA"
},
{
"path": "base/api/database.go",
"chars": 16362,
"preview": "package api\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/gorilla/websocket\"\n\t\"github.com/tevino"
},
{
"path": "base/api/doc.go",
"chars": 923,
"preview": "/*\nPackage api provides an API for integration with other components of the same software package and also third party c"
},
{
"path": "base/api/endpoints.go",
"chars": 13235,
"preview": "package api\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/go"
},
{
"path": "base/api/endpoints_config.go",
"chars": 612,
"preview": "package api\n\nimport (\n\t\"github.com/safing/portmaster/base/config\"\n)\n\nfunc registerConfigEndpoints() error {\n\tif err := R"
},
{
"path": "base/api/endpoints_debug.go",
"chars": 7027,
"preview": "package api\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"runtime/pprof\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gith"
},
{
"path": "base/api/endpoints_meta.go",
"chars": 3646,
"preview": "package api\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n)\n\nfunc registerMetaEndpoints() error {\n\tif err := Register"
},
{
"path": "base/api/endpoints_test.go",
"chars": 3875,
"preview": "package api\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/safing/portmaste"
},
{
"path": "base/api/enriched-response.go",
"chars": 2035,
"preview": "package api\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n\n// LoggingRespo"
},
{
"path": "base/api/init_test.go",
"chars": 633,
"preview": "package api\n\nimport (\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/config\"\n)\n\ntype testInstance struct {\n\tconfig *con"
},
{
"path": "base/api/main.go",
"chars": 1677,
"preview": "package api\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/service/mgr\"\n)\n\nv"
},
{
"path": "base/api/module.go",
"chars": 1067,
"preview": "package api\n\nimport (\n\t\"errors\"\n\t\"sync/atomic\"\n\n\t\"github.com/safing/portmaster/base/config\"\n\t\"github.com/safing/portmast"
},
{
"path": "base/api/request.go",
"chars": 1603,
"preview": "package api\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/gorilla/mux\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n\n// Requ"
},
{
"path": "base/api/router.go",
"chars": 9228,
"preview": "package api\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n\t\"t"
},
{
"path": "base/api/testclient/root/index.html",
"chars": 957,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<title></title>\n\t<!-- <script src=\"https://cdn.jsdelivr.net/sockjs/1/sockjs.min.js\"></scr"
},
{
"path": "base/api/testclient/serve.go",
"chars": 214,
"preview": "package testclient\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/safing/portmaster/base/api\"\n)\n\nfunc init() {\n\tapi.RegisterHandler"
},
{
"path": "base/apprise/notify.go",
"chars": 4359,
"preview": "package apprise\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/"
},
{
"path": "base/config/basic_config.go",
"chars": 3353,
"preview": "package config\n\nimport (\n\t\"flag\"\n\n\t\"github.com/safing/portmaster/base/log\"\n\t\"github.com/safing/portmaster/service/mgr\"\n)"
},
{
"path": "base/config/database.go",
"chars": 3860,
"preview": "package config\n\nimport (\n\t\"errors\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database\"\n\t\"github.com/safing"
},
{
"path": "base/config/doc.go",
"chars": 87,
"preview": "// Package config provides a versatile configuration management system.\npackage config\n"
},
{
"path": "base/config/expertise.go",
"chars": 2910,
"preview": "package config\n\nimport (\n\t\"sync/atomic\"\n\n\t\"github.com/tevino/abool\"\n)\n\n// ExpertiseLevel allows to group settings by use"
},
{
"path": "base/config/get-safe.go",
"chars": 2732,
"preview": "package config\n\nimport \"sync\"\n\ntype safe struct{}\n\n// Concurrent makes concurrency safe get methods available.\nvar Concu"
},
{
"path": "base/config/get.go",
"chars": 4293,
"preview": "package config\n\nimport (\n\t\"github.com/safing/portmaster/base/log\"\n)\n\ntype (\n\t// StringOption defines the returned functi"
},
{
"path": "base/config/get_test.go",
"chars": 7617,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n\nfunc parseAndRe"
},
{
"path": "base/config/init_test.go",
"chars": 1061,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n)\n\ntype testInstance struct {\n\tdataDir string\n}\n\nvar _ instance = testI"
},
{
"path": "base/config/main.go",
"chars": 2950,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"sync/atomic"
},
{
"path": "base/config/module.go",
"chars": 1061,
"preview": "package config\n\nimport (\n\t\"errors\"\n\t\"sync/atomic\"\n\n\t\"github.com/safing/portmaster/service/mgr\"\n)\n\n// Config provides con"
},
{
"path": "base/config/option.go",
"chars": 14679,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"sync\"\n\n\t\"github.com/mitchellh/copystructure\"\n\t\"g"
},
{
"path": "base/config/persistence.go",
"chars": 5941,
"preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/safing/portmaster/base/l"
},
{
"path": "base/config/persistence_test.go",
"chars": 1554,
"preview": "package config\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"testing\"\n)\n\nvar (\n\tjsonData = `{\n \"a\": \"b\",\n \"c\": {\n \"d\": \"e\","
},
{
"path": "base/config/perspective.go",
"chars": 3536,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n\n// Perspective is a view on configuration d"
},
{
"path": "base/config/registry.go",
"chars": 2965,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n)\n\nvar (\n\toptionsLock sync.RWMutex\n\toptions = m"
},
{
"path": "base/config/registry_test.go",
"chars": 1133,
"preview": "package config\n\nimport (\n\t\"testing\"\n)\n\nfunc TestRegistry(t *testing.T) { //nolint:paralleltest\n\t// reset\n\toptions = make"
},
{
"path": "base/config/release.go",
"chars": 2689,
"preview": "package config\n\nimport (\n\t\"sync/atomic\"\n\n\t\"github.com/tevino/abool\"\n)\n\n// ReleaseLevel is used to define the maturity of"
},
{
"path": "base/config/set.go",
"chars": 6001,
"preview": "package config\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/tevino/abool\"\n)\n\nvar (\n\t// ErrInvalidJSON is returned by SetCon"
},
{
"path": "base/config/set_test.go",
"chars": 5026,
"preview": "//nolint:goconst\npackage config\n\nimport \"testing\"\n\nfunc TestLayersGetters(t *testing.T) { //nolint:paralleltest\n\t// rese"
},
{
"path": "base/config/validate.go",
"chars": 6879,
"preview": "package config\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/safing/portmaster/base/log\"\n)\n\ntype valueCach"
},
{
"path": "base/config/validity.go",
"chars": 788,
"preview": "package config\n\nimport (\n\t\"github.com/tevino/abool\"\n)\n\n// ValidityFlag is a flag that signifies if the configuration has"
},
{
"path": "base/container/container.go",
"chars": 9652,
"preview": "package container\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/safing/structures/varint\"\n)\n\n// Container is []byte sclie on s"
},
{
"path": "base/container/container_test.go",
"chars": 4149,
"preview": "package container\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/utils\"\n)\n\nvar (\n\ttestData ="
},
{
"path": "base/container/doc.go",
"chars": 951,
"preview": "// Package container gives you a []byte slice on steroids, allowing for quick data appending, prepending and fetching as"
},
{
"path": "base/container/serialization.go",
"chars": 455,
"preview": "package container\n\nimport (\n\t\"encoding/json\"\n)\n\n// MarshalJSON serializes the container as a JSON byte array.\nfunc (c *C"
},
{
"path": "base/database/accessor/accessor-json-bytes.go",
"chars": 3304,
"preview": "package accessor\n\nimport (\n\t\"github.com/tidwall/gjson\"\n\t\"github.com/tidwall/sjson\"\n)\n\n// JSONBytesAccessor is a json str"
},
{
"path": "base/database/accessor/accessor-json-string.go",
"chars": 4041,
"preview": "package accessor\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/tidwall/gjson\"\n\t\"github.com/tidwall/sjson\"\n)\n\n// JSONAccessor is a json "
},
{
"path": "base/database/accessor/accessor-struct.go",
"chars": 5363,
"preview": "package accessor\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// StructAccessor is a json string with get functions.\ntype St"
},
{
"path": "base/database/accessor/accessor.go",
"chars": 543,
"preview": "package accessor\n\nconst (\n\temptyString = \"\"\n)\n\n// Accessor provides an interface to supply the query matcher a method to"
},
{
"path": "base/database/accessor/accessor_test.go",
"chars": 8475,
"preview": "//nolint:maligned,unparam\npackage accessor\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/ut"
},
{
"path": "base/database/boilerplate_test.go",
"chars": 1100,
"preview": "package database\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/safing/portmaster/base/database/record\"\n)\n\ntype Example struct {"
},
{
"path": "base/database/controller.go",
"chars": 8120,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/iterator\"\n"
},
{
"path": "base/database/controllers.go",
"chars": 2686,
"preview": "package database\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/safing/portmaster/base/database/storage\"\n)\n\n// Storage"
},
{
"path": "base/database/database.go",
"chars": 586,
"preview": "package database\n\nimport (\n\t\"time\"\n)\n\n// Database holds information about a registered database.\ntype Database struct {\n"
},
{
"path": "base/database/database_test.go",
"chars": 7257,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"reflect\"\n\t\"runtime/pprof\"\n\t\"testing\"\n\t\"time\"\n\n\tq \""
},
{
"path": "base/database/dbmodule/db.go",
"chars": 1464,
"preview": "package dbmodule\n\nimport (\n\t\"errors\"\n\t\"path/filepath\"\n\t\"sync/atomic\"\n\n\t\"github.com/safing/portmaster/base/database\"\n\t\"gi"
},
{
"path": "base/database/dbmodule/maintenance.go",
"chars": 860,
"preview": "package dbmodule\n\nimport (\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database\"\n\t\"github.com/safing/portmaster/base/lo"
},
{
"path": "base/database/doc.go",
"chars": 1475,
"preview": "/*\nPackage database provides a universal interface for interacting with the database.\n\n# A Lazy Database\n\nThe database s"
},
{
"path": "base/database/errors.go",
"chars": 389,
"preview": "package database\n\nimport (\n\t\"errors\"\n)\n\n// Errors.\nvar (\n\tErrNotFound = errors.New(\"database entry not found\")\n\t"
},
{
"path": "base/database/hook.go",
"chars": 2674,
"preview": "package database\n\nimport (\n\t\"github.com/safing/portmaster/base/database/query\"\n\t\"github.com/safing/portmaster/base/datab"
},
{
"path": "base/database/hookbase.go",
"chars": 919,
"preview": "package database\n\nimport (\n\t\"github.com/safing/portmaster/base/database/record\"\n)\n\n// HookBase implements the Hook inter"
},
{
"path": "base/database/interface.go",
"chars": 14559,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/bluele/gcache\"\n\t\"github.com/tevino/"
},
{
"path": "base/database/interface_cache.go",
"chars": 6388,
"preview": "package database\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/record\"\n\t\"github.com/safing/p"
},
{
"path": "base/database/interface_cache_test.go",
"chars": 4079,
"preview": "package database\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/service/mgr\"\n)\n\nfunc ben"
},
{
"path": "base/database/iterator/iterator.go",
"chars": 1070,
"preview": "package iterator\n\nimport (\n\t\"sync\"\n\n\t\"github.com/tevino/abool\"\n\n\t\"github.com/safing/portmaster/base/database/record\"\n)\n\n"
},
{
"path": "base/database/main.go",
"chars": 1487,
"preview": "package database\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\n\t\"github.com/safing/portmaster/base/utils\"\n\t\"github.com/te"
},
{
"path": "base/database/maintenance.go",
"chars": 1322,
"preview": "package database\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// Maintain runs the Maintain method on all storages.\nfunc Maintain(ctx"
},
{
"path": "base/database/migration/error.go",
"chars": 1799,
"preview": "package migration\n\nimport \"errors\"\n\n// DiagnosticStep describes one migration step in the Diagnostics.\ntype DiagnosticSt"
},
{
"path": "base/database/migration/migration.go",
"chars": 6408,
"preview": "package migration\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-version\"\n\n\t\"g"
},
{
"path": "base/database/query/README.md",
"chars": 3134,
"preview": "# Query\n\n## Control Flow\n\n- Grouping with `(` and `)`\n- Chaining with `and` and `or`\n - _NO_ mixing! Be explicit and us"
},
{
"path": "base/database/query/condition-and.go",
"chars": 839,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\n// And combines mul"
},
{
"path": "base/database/query/condition-bool.go",
"chars": 1273,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype bool"
},
{
"path": "base/database/query/condition-error.go",
"chars": 422,
"preview": "package query\n\nimport (\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype errorCondition struct {\n\terr erro"
},
{
"path": "base/database/query/condition-exists.go",
"chars": 641,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype existsCondition"
},
{
"path": "base/database/query/condition-float.go",
"chars": 1909,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype floa"
},
{
"path": "base/database/query/condition-int.go",
"chars": 1800,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype intC"
},
{
"path": "base/database/query/condition-not.go",
"chars": 668,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\n// Not negates the "
},
{
"path": "base/database/query/condition-or.go",
"chars": 829,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\n// Or combines mult"
},
{
"path": "base/database/query/condition-regex.go",
"chars": 1245,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype regex"
},
{
"path": "base/database/query/condition-string.go",
"chars": 1216,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\ntype stri"
},
{
"path": "base/database/query/condition-stringslice.go",
"chars": 1463,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n\t\"github.com/safing/po"
},
{
"path": "base/database/query/condition.go",
"chars": 2071,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\n// Condition is an interface t"
},
{
"path": "base/database/query/condition_test.go",
"chars": 3224,
"preview": "package query\n\nimport \"testing\"\n\nfunc testSuccess(t *testing.T, c Condition) {\n\tt.Helper()\n\n\terr := c.check()\n\tif err !="
},
{
"path": "base/database/query/operators.go",
"chars": 1114,
"preview": "package query\n\nvar (\n\toperatorNames = map[string]uint8{\n\t\t\"==\": Equals,\n\t\t\">\": GreaterThan,\n\t\t\">=\": "
},
{
"path": "base/database/query/operators_test.go",
"chars": 155,
"preview": "package query\n\nimport \"testing\"\n\nfunc TestGetOpName(t *testing.T) {\n\tt.Parallel()\n\n\tif getOpName(254) != \"[unknown]\" {\n\t"
},
{
"path": "base/database/query/parser.go",
"chars": 8162,
"preview": "package query\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype snippet struct {\n\ttext string"
},
{
"path": "base/database/query/parser_test.go",
"chars": 7986,
"preview": "package query\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/davecgh/go-spew/spew\"\n)\n\nfunc TestExtractSnippets(t *testing"
},
{
"path": "base/database/query/query.go",
"chars": 3759,
"preview": "package query\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n\t\"github.com/safing/po"
},
{
"path": "base/database/query/query_test.go",
"chars": 3510,
"preview": "//nolint:unparam\npackage query\n\nimport (\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/database/record\"\n\t\"github.com/s"
},
{
"path": "base/database/record/base.go",
"chars": 4830,
"preview": "package record\n\nimport (\n\t\"errors\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n\t\"github.com/safing/portmaste"
},
{
"path": "base/database/record/base_test.go",
"chars": 172,
"preview": "package record\n\nimport \"testing\"\n\nfunc TestBaseRecord(t *testing.T) {\n\tt.Parallel()\n\n\t// check model interface complianc"
},
{
"path": "base/database/record/key.go",
"chars": 302,
"preview": "package record\n\nimport (\n\t\"strings\"\n)\n\n// ParseKey splits a key into it's database name and key parts.\nfunc ParseKey(key"
},
{
"path": "base/database/record/meta-bench_test.go",
"chars": 7715,
"preview": "package record\n\n// Benchmark:\n// BenchmarkAllocateBytes-8 \t2000000000\t 0.76 ns/op\n// BenchmarkAll"
},
{
"path": "base/database/record/meta-gencode.go",
"chars": 3120,
"preview": "package record\n\nimport (\n\t\"fmt\"\n)\n\n// GenCodeSize returns the size of the gencode marshalled byte slice.\nfunc (m *Meta) "
},
{
"path": "base/database/record/meta-gencode_test.go",
"chars": 597,
"preview": "package record\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n)\n\nvar genCodeTestMeta = &Meta{\n\tCreated: time.Now().Unix(),\n\tM"
},
{
"path": "base/database/record/meta.colf",
"chars": 145,
"preview": "package record\n\ntype course struct {\n Created int64\n Modified int64\n Expires int64\n Deleted int64\n Secret "
},
{
"path": "base/database/record/meta.gencode",
"chars": 116,
"preview": "struct Meta {\n\tCreated int64\n\tModified int64\n\tExpires int64\n\tDeleted int64\n\tSecret bool\n\tCronjewel bool\n}\n"
},
{
"path": "base/database/record/meta.go",
"chars": 3349,
"preview": "package record\n\nimport \"time\"\n\n// Meta holds metadata about the record.\ntype Meta struct {\n\tCreated int64\n\tModified i"
},
{
"path": "base/database/record/record.go",
"chars": 698,
"preview": "package record\n\nimport (\n\t\"github.com/safing/portmaster/base/database/accessor\"\n)\n\n// Record provides an interface for u"
},
{
"path": "base/database/record/record_test.go",
"chars": 81,
"preview": "package record\n\nimport (\n\t\"sync\"\n)\n\ntype TestRecord struct {\n\tBase\n\tsync.Mutex\n}\n"
},
{
"path": "base/database/record/wrapper.go",
"chars": 4209,
"preview": "package record\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/safing/portmaster/base/database/accessor\"\n\t\"github.com/s"
},
{
"path": "base/database/record/wrapper_test.go",
"chars": 1031,
"preview": "package record\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/safing/structures/dsd\"\n)\n\nfunc TestWrapper(t *testing.T) {\n\tt"
},
{
"path": "base/database/registry.go",
"chars": 1457,
"preview": "package database\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tregistry = make(map[string]*Database"
},
{
"path": "base/database/storage/badger/badger.go",
"chars": 5179,
"preview": "package badger\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/dgraph-io/badger\"\n\n\t\"github.com/safing/portma"
},
{
"path": "base/database/storage/badger/badger_test.go",
"chars": 2242,
"preview": "package badger\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/database/qu"
},
{
"path": "base/database/storage/bbolt/bbolt.go",
"chars": 10107,
"preview": "package bbolt\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"go.etcd.io/bbolt\"\n\n\t\"github.com"
},
{
"path": "base/database/storage/bbolt/bbolt_test.go",
"chars": 3310,
"preview": "package bbolt\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/data"
},
{
"path": "base/database/storage/errors.go",
"chars": 182,
"preview": "package storage\n\nimport \"errors\"\n\n// Errors for storages.\nvar (\n\tErrNotFound = errors.New(\"storage entry not foun"
},
{
"path": "base/database/storage/fstree/fstree.go",
"chars": 7745,
"preview": "/*\nPackage fstree provides a dead simple file-based database storage backend.\nIt is primarily meant for easy testing or "
},
{
"path": "base/database/storage/fstree/fstree_test.go",
"chars": 147,
"preview": "package fstree\n\nimport \"github.com/safing/portmaster/base/database/storage\"\n\n// Compile time interface checks.\nvar _ sto"
},
{
"path": "base/database/storage/hashmap/map.go",
"chars": 4607,
"preview": "package hashmap\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/iter"
},
{
"path": "base/database/storage/hashmap/map_test.go",
"chars": 2197,
"preview": "package hashmap\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/safing/portmaster/base/database/query\"\n\t\"github.co"
},
{
"path": "base/database/storage/injectbase.go",
"chars": 1637,
"preview": "package storage\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/iterator\"\n\t\"github."
},
{
"path": "base/database/storage/interface.go",
"chars": 1769,
"preview": "package storage\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/iterator\"\n\t\"github.com/safing"
},
{
"path": "base/database/storage/sinkhole/sinkhole.go",
"chars": 2700,
"preview": "package sinkhole\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/safing/portmaster/base/database/iterator\"\n\t\"github"
},
{
"path": "base/database/storage/sqlite/bobgen.yaml",
"chars": 80,
"preview": "sqlite:\n dsn: \"testdata/schema.db\"\n except:\n migrations:\n\nno_factory: true\n"
},
{
"path": "base/database/storage/sqlite/dberrors/bob_errors.bob.go",
"chars": 1272,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/dberrors/bob_main.bob_test.go",
"chars": 282,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/dberrors/records.bob.go",
"chars": 415,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/dbinfo/bob_types.bob.go",
"chars": 1279,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/dbinfo/records.bob.go",
"chars": 3186,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/bobfactory_context.bob.go",
"chars": 788,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/bobfactory_main.bob.go",
"chars": 1497,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/bobfactory_main.bob_test.go",
"chars": 711,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/bobfactory_random.bob.go",
"chars": 960,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/bobfactory_random.bob_test.go",
"chars": 932,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/factory/records.bob.go",
"chars": 16725,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/migrations/0_settings.sql",
"chars": 335,
"preview": "-- +migrate Up\n-- SQL in section 'Up' is executed when this migration is applied\nPRAGMA auto_vacuum = INCREMENTAL; -- ht"
},
{
"path": "base/database/storage/sqlite/migrations/1_initial.sql",
"chars": 521,
"preview": "-- +migrate Up\n-- SQL in section 'Up' is executed when this migration is applied\nCREATE TABLE records (\n key TEXT PRI"
},
{
"path": "base/database/storage/sqlite/migrations_config.yml",
"chars": 103,
"preview": "development:\n dialect: sqlite3\n datasource: testdata/schema.db\n dir: migrations\n table: migrations\n"
},
{
"path": "base/database/storage/sqlite/models/bob_joins.bob.go",
"chars": 1442,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/models/bob_loaders.bob.go",
"chars": 1406,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/models/bob_types.bob_test.go",
"chars": 370,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/models/bob_where.bob.go",
"chars": 713,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/models/records.bob.go",
"chars": 15472,
"preview": "// Code generated by BobGen sqlite v0.41.1. DO NOT EDIT.\n// This file is meant to be re-generated in place and/or delete"
},
{
"path": "base/database/storage/sqlite/prepared.go",
"chars": 3203,
"preview": "package sqlite\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/stephenafamo/bob\"\n\t\"github.com/stephenafamo/bob/dial"
},
{
"path": "base/database/storage/sqlite/prepared_test.go",
"chars": 1456,
"preview": "package sqlite\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n)\n\nfunc BenchmarkPutMany(b *testing.B) {\n\t// Configure prepared statement"
},
{
"path": "base/database/storage/sqlite/schema.go",
"chars": 1157,
"preview": "package sqlite\n\n// Base command for sql-migrate:\n//go:generate -command migrate go tool github.com/rubenv/sql-migrate/sq"
},
{
"path": "base/database/storage/sqlite/sqlite.go",
"chars": 15642,
"preview": "package sqlite\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/aaro"
},
{
"path": "base/database/storage/sqlite/sqlite_test.go",
"chars": 3771,
"preview": "package sqlite\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/safing/portmast"
},
{
"path": "base/database/storage/storages.go",
"chars": 1083,
"preview": "package storage\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// A Factory creates a new database of it's type.\ntype Factory fun"
}
]
// ... and 1399 more files (download for full content)
About this extraction
This page contains the full source code of the safing/portmaster GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1599 files (10.4 MB), approximately 2.8M tokens, and a symbol index with 22836 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.